commit message

master
Chopper 2021-05-13 10:56:04 +08:00
commit ec3e958037
728 changed files with 132685 additions and 0 deletions

View File

@ -0,0 +1,17 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</value>
</option>
<codeStyleSettings language="JavaScript">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="0" />
<option name="TAB_SIZE" value="2" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

12
.idea/lili-shop-ui.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/lili-shop-ui.iml" filepath="$PROJECT_DIR$/.idea/lili-shop-ui.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

380
.idea/workspace.xml Normal file
View File

@ -0,0 +1,380 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BranchesTreeState">
<expand>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
</path>
<path>
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
<item name="GROUP_NODE:origin" type="e8cecc67:BranchNodeDescriptor" />
</path>
</expand>
<select />
</component>
<component name="ChangeListManager">
<list default="true" id="7e964aa0-753b-43f7-854a-2942a3e76fe4" name="默认更改列表" comment="店铺设置">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<<<<<<< HEAD
<change beforePath="$PROJECT_DIR$/buyer/src/pages/home/orderCenter/AddAddress.vue" beforeDir="false" afterPath="$PROJECT_DIR$/buyer/src/pages/home/orderCenter/AddAddress.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/manager/src/config/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/config/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/seller/src/config/index.js" beforeDir="false" afterPath="$PROJECT_DIR$/seller/src/config/index.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/seller/src/views/statistics/goods/goodsStatistics.vue" beforeDir="false" afterPath="$PROJECT_DIR$/seller/src/views/statistics/goods/goodsStatistics.vue" afterDir="false" />
=======
<change beforePath="$PROJECT_DIR$/manager/src/views/goods-unit/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/views/goods-unit/index.vue" afterDir="false" />
<change beforePath="$PROJECT_DIR$/manager/src/views/sensitiveWords/index.vue" beforeDir="false" afterPath="$PROJECT_DIR$/manager/src/views/sensitiveWords/index.vue" afterDir="false" />
>>>>>>> new-lmr
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Vue File" />
<option value="Vue Single File Component" />
<option value="JavaScript File" />
</list>
</option>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectId" id="1gGPnr0TWcTGoYhLT7QHFe5MrX4" />
<component name="ProjectLevelVcsManager">
<ConfirmationsSetting value="2" id="Add" />
</component>
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<<<<<<< HEAD
<property name="last_opened_file_path" value="$PROJECT_DIR$/manager/src/api" />
=======
<property name="last_opened_file_path" value="$PROJECT_DIR$/manager/src/views/sys/setting-manage" />
>>>>>>> new-lmr
<property name="node.js.detected.package.eslint" value="true" />
<property name="node.js.detected.package.tslint" value="true" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="node.js.path.for.package.tslint" value="project" />
<property name="node.js.selected.package.eslint" value="(autodetect)" />
<property name="node.js.selected.package.tslint" value="(autodetect)" />
<property name="nodejs_package_manager_path" value="npm" />
<property name="settings.editor.selected.configurable" value="preferences.sourceCode.XML" />
<property name="ts.external.directory.path" value="$APPLICATION_HOME_DIR$/plugins/JavaScriptLanguage/jsLanguageServicesImpl/external" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<<<<<<< HEAD
<recent name="$PROJECT_DIR$/manager/src/api" />
<recent name="$PROJECT_DIR$/manager/src/views/my-components" />
=======
<recent name="$PROJECT_DIR$/manager/src/views/sys/setting-manage" />
>>>>>>> new-lmr
<recent name="$PROJECT_DIR$/buyer/src/components/verify" />
<recent name="$PROJECT_DIR$/buyer/src/components/change" />
</key>
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/buyer/src/components/change" />
<recent name="$PROJECT_DIR$/buyer/src/pages/home/memberCenter" />
<recent name="$PROJECT_DIR$/buyer/src/pages/home/orderCenter" />
<recent name="$PROJECT_DIR$/buyer/src/pages/home" />
<recent name="$PROJECT_DIR$/buyer/src/components/home/order" />
</key>
</component>
<component name="RunManager">
<configuration name="Home.vue" type="JavascriptDebugType" temporary="true" nameIsGenerated="true" uri="http://localhost:63342/lili-shop-ui/buyer/src/page/user/Home.vue" useBuiltInWebServerPort="true">
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="JavaScript Debug.Home.vue" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="7e964aa0-753b-43f7-854a-2942a3e76fe4" name="默认更改列表" comment="" />
<created>1597738125477</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1597738125477</updated>
<workItem from="1597738127938" duration="6268000" />
<workItem from="1597825716012" duration="3768000" />
<workItem from="1597830090678" duration="7632000" />
<workItem from="1597972262326" duration="865000" />
<workItem from="1597974893526" duration="112000" />
<workItem from="1597975021121" duration="17000" />
<workItem from="1597975216701" duration="17254000" />
<workItem from="1598184961388" duration="14000" />
<workItem from="1598233017859" duration="10307000" />
<workItem from="1598259954059" duration="2720000" />
<workItem from="1598318520176" duration="726000" />
<workItem from="1598319433942" duration="106000" />
<workItem from="1598319554477" duration="13265000" />
<workItem from="1598406300597" duration="6030000" />
<workItem from="1598422866858" duration="7787000" />
<workItem from="1598491104901" duration="37245000" />
<workItem from="1606876680167" duration="61000" />
<workItem from="1611131536390" duration="5616000" />
<workItem from="1611537245379" duration="828000" />
<workItem from="1611538362285" duration="350000" />
<workItem from="1611560515629" duration="834000" />
<workItem from="1611650051294" duration="3000" />
<workItem from="1611818003333" duration="239000" />
<workItem from="1613989205923" duration="7005000" />
<workItem from="1614076082765" duration="8973000" />
<workItem from="1614142479169" duration="2129000" />
<workItem from="1614162982178" duration="8343000" />
<workItem from="1614228135182" duration="3456000" />
<workItem from="1614248866969" duration="8023000" />
<workItem from="1614313313338" duration="83000" />
<workItem from="1614313447954" duration="211000" />
</task>
<task id="LOCAL-00001" summary="管理端页面优化">
<created>1613996019944</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1613996019944</updated>
</task>
<task id="LOCAL-00002" summary="修复修改商家地址报错问题">
<created>1613996389449</created>
<option name="number" value="00002" />
<option name="presentableId" value="LOCAL-00002" />
<option name="project" value="LOCAL" />
<updated>1613996389449</updated>
</task>
<task id="LOCAL-00003" summary="去掉id">
<created>1614076370139</created>
<option name="number" value="00003" />
<option name="presentableId" value="LOCAL-00003" />
<option name="project" value="LOCAL" />
<updated>1614076370139</updated>
</task>
<task id="LOCAL-00004" summary="选择物流规则不能选择物流模板">
<created>1614080544415</created>
<option name="number" value="00004" />
<option name="presentableId" value="LOCAL-00004" />
<option name="project" value="LOCAL" />
<updated>1614080544415</updated>
</task>
<task id="LOCAL-00005" summary="修改查询条件样式">
<created>1614143298555</created>
<option name="number" value="00005" />
<option name="presentableId" value="LOCAL-00005" />
<option name="project" value="LOCAL" />
<updated>1614143298555</updated>
</task>
<task id="LOCAL-00006" summary="修改样式">
<created>1614143902874</created>
<option name="number" value="00006" />
<option name="presentableId" value="LOCAL-00006" />
<option name="project" value="LOCAL" />
<updated>1614143902874</updated>
</task>
<task id="LOCAL-00007" summary="修改更新时间为NAN">
<created>1614144541858</created>
<option name="number" value="00007" />
<option name="presentableId" value="LOCAL-00007" />
<option name="project" value="LOCAL" />
<updated>1614144541858</updated>
</task>
<task id="LOCAL-00008" summary="修复app版本无法添加和修改">
<created>1614230386509</created>
<option name="number" value="00008" />
<option name="presentableId" value="LOCAL-00008" />
<option name="project" value="LOCAL" />
<updated>1614230386509</updated>
</task>
<task id="LOCAL-00009" summary="去掉打印">
<created>1614230407722</created>
<option name="number" value="00009" />
<option name="presentableId" value="LOCAL-00009" />
<option name="project" value="LOCAL" />
<updated>1614230407722</updated>
</task>
<task id="LOCAL-00010" summary="去掉多选">
<created>1614230544808</created>
<option name="number" value="00010" />
<option name="presentableId" value="LOCAL-00010" />
<option name="project" value="LOCAL" />
<updated>1614230544808</updated>
</task>
<task id="LOCAL-00011" summary="修改消息标题宽度">
<created>1614230627881</created>
<option name="number" value="00011" />
<option name="presentableId" value="LOCAL-00011" />
<option name="project" value="LOCAL" />
<updated>1614230627881</updated>
</task>
<task id="LOCAL-00012" summary="店铺相关js提交">
<created>1614231645143</created>
<option name="number" value="00012" />
<option name="presentableId" value="LOCAL-00012" />
<option name="project" value="LOCAL" />
<updated>1614231645143</updated>
</task>
<task id="LOCAL-00013" summary="店铺修改">
<created>1614231785359</created>
<option name="number" value="00013" />
<option name="presentableId" value="LOCAL-00013" />
<option name="project" value="LOCAL" />
<updated>1614231785359</updated>
</task>
<task id="LOCAL-00014" summary="优化页面">
<created>1614249105672</created>
<option name="number" value="00014" />
<option name="presentableId" value="LOCAL-00014" />
<option name="project" value="LOCAL" />
<updated>1614249105672</updated>
</task>
<task id="LOCAL-00015" summary="页面优化">
<created>1614258980903</created>
<option name="number" value="00015" />
<option name="presentableId" value="LOCAL-00015" />
<option name="project" value="LOCAL" />
<updated>1614258980903</updated>
</task>
<task id="LOCAL-00016" summary="页面优化">
<created>1614259068248</created>
<option name="number" value="00016" />
<option name="presentableId" value="LOCAL-00016" />
<option name="project" value="LOCAL" />
<updated>1614259068248</updated>
</task>
<task id="LOCAL-00017" summary="页面优化">
<created>1614313690732</created>
<option name="number" value="00017" />
<option name="presentableId" value="LOCAL-00017" />
<option name="project" value="LOCAL" />
<updated>1614313690732</updated>
</task>
<option name="localTasksCounter" value="18" />
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="Vcs.Log.History.Properties">
<option name="COLUMN_ID_ORDER">
<list>
<option value="Default.Root" />
<option value="Default.Author" />
<option value="Default.Date" />
<option value="Default.Subject" />
</list>
</option>
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="1">
<value>
<State>
<option name="SHOW_ONLY_AFFECTED_CHANGES" value="true" />
<option name="FILTERS">
<map>
<entry key="branch">
<value>
<list>
<option value="HEAD" />
</list>
</value>
</entry>
<entry key="structure">
<value>
<list>
<option value="dir:/Users/liushuai/Documents/workspace/lili-shop-ui/seller/src/router" />
</list>
</value>
</entry>
</map>
</option>
</State>
</value>
</entry>
<entry key="MAIN">
<value>
<State>
<option name="COLUMN_ORDER" />
</State>
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="店铺设置" />
<MESSAGE value="文件排序问题处理" />
<MESSAGE value="管理端页面优化" />
<MESSAGE value="修复修改商家地址报错问题" />
<MESSAGE value="去掉id" />
<MESSAGE value="选择物流规则不能选择物流模板" />
<MESSAGE value="修改查询条件样式" />
<MESSAGE value="修改样式" />
<MESSAGE value="修改更新时间为NAN" />
<MESSAGE value="修复app版本无法添加和修改" />
<MESSAGE value="去掉打印" />
<MESSAGE value="去掉多选" />
<MESSAGE value="修改消息标题宽度" />
<MESSAGE value="店铺相关js提交" />
<MESSAGE value="店铺修改" />
<MESSAGE value="优化页面" />
<MESSAGE value="页面优化" />
<option name="LAST_COMMIT_MESSAGE" value="页面优化" />
</component>
<component name="WindowStateProjectService">
<state x="2074" y="292" key="CommitChangelistDialog2" timestamp="1614313690605">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="2074" y="292" key="CommitChangelistDialog2/0.23.3440.1333@0.23.3440.1333" timestamp="1614313690605" />
<state x="1660" y="123" width="1572" height="1133" key="DiffContextDialog" timestamp="1614231764977">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="1660" y="123" width="1572" height="1133" key="DiffContextDialog/0.23.3440.1333@0.23.3440.1333" timestamp="1614231764977" />
<state x="2046" y="418" key="Vcs.Push.Dialog.v2" timestamp="1614313692405">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="2046" y="418" key="Vcs.Push.Dialog.v2/0.23.3440.1333@0.23.3440.1333" timestamp="1614313692405" />
<state x="2055" y="414" width="782" height="550" key="find.popup" timestamp="1614256597933">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="2055" y="414" width="782" height="550" key="find.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1614256597933" />
<state x="2111" y="325" key="run.anything.popup" timestamp="1613991372498">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="2111" y="325" key="run.anything.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1613991372498" />
<state x="2111" y="327" width="670" height="676" key="search.everywhere.popup" timestamp="1614254687317">
<screen x="0" y="23" width="3440" height="1333" />
</state>
<state x="2111" y="327" width="670" height="676" key="search.everywhere.popup/0.23.3440.1333@0.23.3440.1333" timestamp="1614254687317" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" type="javascript">
<url>file://$PROJECT_DIR$/manager/src/views/sys/monitor/monitor.vue</url>
<line>5</line>
<option name="timeStamp" value="2" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
</project>

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:9999",
"webRoot": "${workspaceFolder}"
}
]
}

6
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"cSpell.ignoreWords": [
"cancel",
"role"
]
}

12
buyer/.babelrc Normal file
View File

@ -0,0 +1,12 @@
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}

9
buyer/.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

4
buyer/.eslintignore Normal file
View File

@ -0,0 +1,4 @@
/build/
/config/
/dist/
/*.js

33
buyer/.eslintrc.js Normal file
View File

@ -0,0 +1,33 @@
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true,
},
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/essential',
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
],
// required to lint *.vue files
plugins: [
'vue'
],
// add your custom rules here
rules: {
"semi": [0, "never"],
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
"vue/no-parsing-error": [2, {
"x-invalid-end-tag": false
}]
}
}

15
buyer/.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# or directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
package-lock.json

10
buyer/.postcssrc.js Normal file
View File

@ -0,0 +1,10 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
"postcss-import": {},
"postcss-url": {},
// to target browsers: use "browserslist" field in package.json
"autoprefixer": {}
}
}

10
buyer/.travis.yml Normal file
View File

@ -0,0 +1,10 @@
language: node_js
node_js:
- '8'
install:
- npm i npm install && npm install
script:
- npm run build

8
buyer/Dockerfile Normal file
View File

@ -0,0 +1,8 @@
FROM nginx:alpine
RUN mkdir -p /app/
COPY ./dist /app/
COPY ./nginx.conf /etc/nginx/nginx.conf
EXPOSE 80

201
buyer/LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

0
buyer/README-ZH.md Normal file
View File

25
buyer/README.md Normal file
View File

@ -0,0 +1,25 @@
### 全局css src/assets/styles
### 工具类 src/plugins
### 顶部广告页 src/components/advertising
### 全部商品分类 components/nav
### 底部导航栏 components/footer
### 发票模态框 components/invoiceModal
### 商品详情 pages/GoodsDetail.vue
#### 商品详情组件 components/goodsDetail
### 全部商品分类 pages/AllCategories.vue
### 意见反馈 pages/Feedback.vue
### 卡片的封装 components/card
### 购物车 pages/Cart.vue

41
buyer/build/build.js Normal file
View File

@ -0,0 +1,41 @@
'use strict'
require('./check-versions')()
process.env.NODE_ENV = 'production'
const ora = require('ora')
const rm = require('rimraf')
const path = require('path')
const chalk = require('chalk')
const webpack = require('webpack')
const config = require('../config')
const webpackConfig = require('./webpack.prod.conf')
const spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, (err, stats) => {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})

View File

@ -0,0 +1,54 @@
'use strict'
const chalk = require('chalk')
const semver = require('semver')
const packageConfig = require('../package.json')
const shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
const versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
}
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
const warnings = []
for (let i = 0; i < versionRequirements.length; i++) {
const mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (let i = 0; i < warnings.length; i++) {
const warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}

110
buyer/build/utils.js Normal file
View File

@ -0,0 +1,110 @@
'use strict'
const path = require('path')
const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const packageConfig = require('../package.json')
exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
}
}
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less' , { javascriptEnabled : true }),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass').concat(
{
loader: 'sass-resources-loader',
options: {
//你自己的scss全局文件的路径
resources: path.resolve(__dirname, '../src/assets/styles/global.scss')
}
}
),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
const output = []
const loaders = exports.cssLoaders(options)
for (const extension in loaders) {
const loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
exports.createNotifierCallback = () => {
const notifier = require('node-notifier')
return (severity, errors) => {
if (severity !== 'error') return
const error = errors[0]
const filename = error.file && error.file.split('!').pop()
notifier.notify({
title: packageConfig.name,
message: severity + ': ' + error.name,
subtitle: filename || '',
icon: path.join(__dirname, 'logo.png')
})
}
}

View File

@ -0,0 +1,22 @@
'use strict'
const utils = require('./utils')
const config = require('../config')
const isProduction = process.env.NODE_ENV === 'production'
const sourceMapEnabled = isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap
module.exports = {
loaders: utils.cssLoaders({
sourceMap: sourceMapEnabled,
extract: isProduction
}),
cssSourceMap: sourceMapEnabled,
cacheBusting: config.dev.cacheBusting,
transformToRequire: {
video: ['src', 'poster'],
source: 'src',
img: 'src',
image: 'xlink:href'
}
}

View File

@ -0,0 +1,103 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
})
module.exports = {
context: path.resolve(__dirname, '../'),
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
}
},
module: {
rules: [
// ...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
// {
// test: /\.less$/,
// loader: "style-loader!css-loader!less-loader",
// },
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
node: {
// prevent webpack from injecting useless setImmediate polyfill because Vue
// source contains it (although only uses it if it's native).
setImmediate: false,
// prevent webpack from injecting mocks to Node native modules
// that does not make sense for the client
dgram: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty'
}
}

View File

@ -0,0 +1,95 @@
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})

View File

@ -0,0 +1,145 @@
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env')
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: false,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vendor modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig

8
buyer/config/dev.env.js Normal file
View File

@ -0,0 +1,8 @@
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_URL:''
})

84
buyer/config/index.js Normal file
View File

@ -0,0 +1,84 @@
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
// const api = 'http://www.baidu.com'
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
// '/api': {
// target:api,
// changeOrigin:true,
// pathRewrite:{
// '^/api':''
// }
// }
},
// Various Dev Server settings
host: '0.0.0.0', // can be overwritten by process.env.HOST
port: 8889, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
// Use Eslint Loader?
// If true, your code will be linted during bundling and
// linting errors and warnings will be shown in the console.
useEslint: false,
// If true, eslint errors and warnings will also be shown in the error overlay
// in the browser.
showEslintErrorsInOverlay: false,
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
/**
* Source Maps
*/
productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}

5
buyer/config/prod.env.js Normal file
View File

@ -0,0 +1,5 @@
'use strict'
module.exports = {
NODE_ENV: '"production"',
BASE_URL:'http://www.baidu.com'
}

1
buyer/docker.sh Normal file
View File

@ -0,0 +1 @@
docker build -t registry.cn-beijing.aliyuncs.com/lili-images/buyer-ui-1.0.1:0.0.1 .

14
buyer/index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="./static/logo.ico" type="image/x-icon">
<!-- <script src = 'https://webapi.amap.com/maps?v=2.0&key=b440952723253aa9fe483e698057bf7d'></script> -->
<title>LILI</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

51
buyer/nginx.conf Normal file
View File

@ -0,0 +1,51 @@
#这个文件给docker用的
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
client_max_body_size 10m;
gzip on;
gzip_min_length 5k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 4;
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
server {
listen 80;
server_name localhost;
location / {
root /app;
try_files $uri $uri/ /index.html $uri/ =404;
index index.html index.htm;
}
}
}

90
buyer/package.json Normal file
View File

@ -0,0 +1,90 @@
{
"name": "lilishop-vue",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"lint": "eslint --ext .js,.vue src",
"build": "node build/build.js"
},
"dependencies": {
"@amap/amap-jsapi-loader": "0.0.7",
"axios": "^0.19.2",
"js-cookie": "^2.2.1",
"less": "^3.12.2",
"less-loader": "^5.0.0",
"psl": "^1.8.0",
"qs": "^6.9.4",
"swiper": "^6.4.1",
"uuid": "^8.3.2",
"v-distpicker": "^1.0.17",
"view-design": "^4.3.2",
"vue": "^2.5.2",
"vue-awesome": "^4.0.2",
"vue-awesome-swiper": "^4.1.1",
"vue-piczoom": "^1.0.6",
"vue-qr": "^2.3.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-eslint": "^8.2.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"chalk": "^2.0.1",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.28.0",
"eslint": "^4.15.0",
"eslint-config-standard": "^10.2.1",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.0.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-webpack-plugin": "^2.30.1",
"node-notifier": "^5.1.2",
"node-sass": "^4.14.1",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"sass-loader": "^7.3.1",
"sass-resources-loader": "^2.0.3",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^0.5.8",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

37
buyer/src/App.vue Normal file
View File

@ -0,0 +1,37 @@
<template>
<div id="app">
<router-view/>
</div>
</template>
<script>
import {v4 as uuidv4} from 'uuid';
import storage from '@/plugins/storage';
import {getLogo} from '@/api/common.js';
export default {
name: 'App',
mounted () {
let uuid = storage.getItem('uuid');
if (!uuid) {
uuid = uuidv4();
storage.setItem('uuid', uuid);
}
if (!this.Cookies.getItem('logo')) {
setTimeout(() => {
getLogo().then(res => {
if (res.success) {
let logoObj = JSON.parse(res.result.settingValue)
this.Cookies.setItem('logo', logoObj.buyerSideLogo)
}
})
}, 1000)
}
}
};
</script>
<style lang="scss">
#app{
min-height: 100%;
@include background_color($light_background_color);
}
</style>

59
buyer/src/api/account.js Normal file
View File

@ -0,0 +1,59 @@
// import {
// getRequest,
// postRequest,
// putRequest,
// deleteRequest,
// importRequest,
// getRequestWithNoToken
// } from '@/axios/index.js';
import request, {Method} from '@/plugins/request.js'
// 获取密码状态
export function getPwdStatus (params) {
return request({
url: '/buyer/members/wallet/check',
method: Method.GET,
needToken: true,
params
})
}
// 设置密码
export function setPwd (params) {
return request({
url: '/buyer/members/wallet/set-password',
method: Method.POST,
needToken: true,
data: params
})
}
// 设置支付密码
export function setUpdatePwdOrdinary (params) {
return request({
url: '/buyer/members/wallet/update-password/ordinary',
method: Method.GET,
needToken: true,
data: params
})
}
// 修改会员资料
export function editMemberInfo (params) {
return request({
url: '/buyer/members/editOwn',
method: Method.PUT,
needToken: true,
data: params
})
}
// 修改密码
export function editPwd (params) {
return request({
url: `/buyer/members/modifyPass`,
method: Method.PUT,
needToken: true,
data: params
})
}

60
buyer/src/api/address.js Normal file
View File

@ -0,0 +1,60 @@
import request, {
Method, commonUrl
} from '@/plugins/request.js';
// 会员收货地址列表
export function memberAddress () {
return request({
url: '/buyer/memberAddress',
needToken: true,
method: Method.GET
});
}
// 添加收货地址
export function newMemberAddress (params) {
return request({
url: '/buyer/memberAddress',
needToken: true,
method: Method.POST,
data: params
});
}
// 编辑收货地址
export function editMemberAddress (params) {
return request({
url: '/buyer/memberAddress',
needToken: true,
method: Method.PUT,
params
});
}
// 删除收货地址
export function delMemberAddress (id) {
return request({
url: `/buyer/memberAddress/delById/${id}`,
needToken: true,
method: Method.DELETE
});
}
// 根据id获取会员地址详情
export function getAddrDetail (id) {
return request({
url: `/buyer/memberAddress/get/${id}`,
needToken: true,
method: Method.GET
});
}
// 传给后台citycode 获取城市街道等id
export function handleRegion (params) {
return request({
url: `${commonUrl}/common/region/region`,
needToken: true,
method: Method.GET,
params
});
}

214
buyer/src/api/cart.js Normal file
View File

@ -0,0 +1,214 @@
import request, {
Method
} from '@/plugins/request.js';
/**
* 清空购物车
*/
export function clearCart () {
return request({
url: '/buyer/trade/carts',
method: Method.DELETE,
needToken: true
});
}
/**
* 获取购物车页面购物车详情
*/
export function cartGoodsAll () {
return request({
url: '/buyer/trade/carts/all',
method: Method.GET,
needToken: true
});
}
/**
* 获取购物车商品数量
*/
export function cartCount () {
return request({
url: '/buyer/trade/carts/count',
method: Method.GET,
needToken: true
});
}
/**
* 获取结算页面购物车详情
*/
export function cartGoodsPay (params) {
return request({
url: '/buyer/trade/carts/checked',
method: Method.GET,
needToken: true,
params
});
}
/**
* 向购物车添加一个商品
* @param skuId skuId
* @param num 购买数量
*/
export function addCartGoods (params) {
return request({
url: '/buyer/trade/carts',
method: Method.POST,
needToken: true,
params
});
}
/**
* 创建交易
* @param client 客户端H5/移动端 PC/PC端,WECHAT_MP/小程序端,APP/移动应用端
* @param way 购物车购买CART/立即购买BUY_NOW / 积分购买POINT
* @param remark 备注 非必填
*/
export function createTrade (data) {
return request({
url: '/buyer/trade/carts/create/trade',
method: Method.POST,
needToken: true,
headers: {'Content-Type': 'application/json'},
data
});
}
/**
* 选择优惠券
* @param memberCouponId 优惠券id
* @param way 购物车购买CART/立即购买BUY_NOW/ 积分购买POINT
* @param used 使用true 弃用 false
*/
export function selectCoupon (params) {
return request({
url: '/buyer/trade/carts/select/coupon',
method: Method.GET,
needToken: true,
params
});
}
/**
* 可用优惠券数量
*/
export function couponNum (params) {
return request({
url: '/buyer/trade/carts/coupon/num',
method: Method.GET,
needToken: true,
params
});
}
/**
* 选择收货地址
* @param shippingAddressId 地址id
* @param way 购物车类型
*/
export function selectAddr (params) {
return request({
url: `/buyer/trade/carts/shippingAddress`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 选中购物车所有商品
* @param checked 设置选中 01
*/
export function setCheckedAll (params) {
return request({
url: `/buyer/trade/carts/sku/checked`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 批量设置某商家的商品为选中或不选中
* @param checked 是否选中
* @param storeId 商家id
*/
export function setCheckedSeller (params) {
return request({
url: `/buyer/trade/carts/store/${params.storeId}`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 选中购物车中单个产品
* @param skuId 产品id
* @param checked 设置选中01
*/
export function setCheckedGoods (params) {
return request({
url: `/buyer/trade/carts/sku/checked/${params.skuId}`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 更新购物车中单个产品数量
* @param skuId 产品id
* @param num 产品数量
*/
export function setCartGoodsNum (params) {
return request({
url: `/buyer/trade/carts/sku/num/${params.skuId}`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 删除购物车中一个或多个产品
* @param skuIds 产品id数组
*/
export function delCartGoods (params) {
return request({
url: `/buyer/trade/carts/sku/remove`,
method: Method.DELETE,
needToken: true,
params
});
}
/**
* 选择配送方式
* @param shippingMethod SELF_PICK_UP(自提),LOCAL_TOWN_DELIVERY(同城配送),LOGISTICS(物流)
* @param way 购物方式
*/
export function shippingMethod (params) {
return request({
url: `/buyer/trade/carts/shippingMethod`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 选择发票
* @param receiptId 发票Id
* @param way 购物方式
*/
export function receiptSelect (params) {
return request({
url: `/buyer/trade/carts/select/receipt`,
method: Method.GET,
needToken: true,
params
});
}

83
buyer/src/api/common.js Normal file
View File

@ -0,0 +1,83 @@
import request, {Method, commonUrl} from '@/plugins/request.js';
/**
* 获取拼图验证
*/
export function getVerifyImg (verificationEnums) {
return request({
url: `${commonUrl}/common/slider/${verificationEnums}`,
method: Method.GET,
needToken: false
});
}
/**
* 验证码校验
*/
export function postVerifyImg (params) {
return request({
url: `${commonUrl}/common/slider/${params.verificationEnums}`,
method: Method.POST,
needToken: false,
params
});
}
/**
* 发送短信验证码
*/
export function sendSms (params) {
return request({
url: `${commonUrl}/common/sms/${params.verificationEnums}/${params.mobile}`,
method: Method.GET,
needToken: false,
params
});
}
/**
* 发送短信验证码
*/
export function getLogo () {
return request({
url: `${commonUrl}/common/logo`,
method: Method.GET,
needToken: false
});
}
// 地区数据,用于三级联动
export function getRegion (id) {
return request({
url: `${commonUrl}/common/region/item/${id}`,
needToken: true,
method: Method.GET
});
}
/**
* 分页获取文章列表
* @param cateId 文章分类id
*/
export function articleList (params) {
return request({
url: `/buyer/article`,
method: Method.GET,
params
});
}
/**
* 获取帮助中心文章分类列表
* @param cateId 文章分类id
*/
export function articleCateList () {
return request({
url: `/buyer/article/articleCategory/list`,
method: Method.GET
});
}
// 通过id获取文章
export function articleDetail (id) {
return request({
url: `/buyer/article/get/${id}`,
method: Method.GET
});
}

73
buyer/src/api/goods.js Normal file
View File

@ -0,0 +1,73 @@
import request, {
Method
} from '@/plugins/request.js';
// 商品列表
export function goodsList (params) {
return request({
url: '/buyer/goods/es',
method: Method.GET,
needToken: false,
params
});
}
// 商品分类 筛选条件 品牌, 尺寸等
export function filterList (params) {
return request({
url: '/buyer/goods/es/related',
method: Method.GET,
needToken: false,
params
});
}
// id获取商品详情
export function goodsDetail (goodsId) {
return request({
url: `/buyer/goods/get/${goodsId}`,
method: Method.GET,
needToken: false
});
}
// id获取商品Sku详情
export function goodsSkuDetail (params) {
return request({
url: `/buyer/goods/sku/${params.goodsId}/${params.skuId}`,
method: Method.GET,
needToken: false,
params
});
}
// 获取所有商品分类
export function getCategory (parentId) {
return request({
url: `/buyer/category/get/${parentId}`,
method: Method.GET,
needToken: false
});
}
// 当前拼团活动未成团会员
export function pintuanMembers (pintuanId) {
return request({
url: `/buyer/promotion/pintuan/${pintuanId}/members`,
method: Method.GET,
needToken: false
});
}
/**
* @param {Number} start 搜索起始下标
* @param {Number} end 搜索结束下标
*/
export function hotWords (params) {
return request({
url: `/buyer/goods/hot-words`,
method: Method.GET,
needToken: false,
params
});
}

35
buyer/src/api/index.js Normal file
View File

@ -0,0 +1,35 @@
import request, {Method} from '@/plugins/request.js'
// 获取首页楼层装修数据
export function indexData (params) {
return request({
url: '/buyer/pageData/getIndex',
method: Method.GET,
needToken: false,
params
})
}
/**
* 楼层装修数据
* @param pageClientType 客户端类型,可用值:PC,H5,WECHAT_MP,APP
* @param pageType 页面类型,可用值:INDEX,STORE,SPECIAL
*/
export function pageData (params) {
return request({
url: `/buyer/pageData`,
method: Method.GET,
needToken: false,
params
})
}
/**
* 刷新token
*/
export function handleRefreshToken (token) {
return request({
url: `/buyer/members/refresh/${token}`,
method: Method.GET,
needToken: false
})
}

94
buyer/src/api/login.js Normal file
View File

@ -0,0 +1,94 @@
import request, {Method, buyerUrl} from '@/plugins/request.js';
/**
* 注册
*/
export function regist (params) {
return request({
url: '/buyer/members/register',
method: Method.POST,
needToken: false,
data: params
});
}
/**
* 账号密码登录
*/
export function login (params) {
return request({
url: '/buyer/members/userLogin',
method: Method.POST,
needToken: false,
data: params,
headers: { 'clientType': 'PC' }
});
}
/**
* 手机号验证码登录
*/
export function smsLogin (params) {
return request({
url: '/buyer/members/smsLogin',
method: Method.POST,
needToken: false,
data: params,
headers: { 'clientType': 'PC' }
});
}
/**
* 获取用户信息
*/
export function getMemberMsg (params) {
return request({
url: '/buyer/members',
method: Method.GET,
needToken: true,
params
});
}
/**
* 第三方登录 支付宝微博qq,微信
*/
export function webLogin (type) {
window.open(`${buyerUrl}/buyer/connect/login/web/${type}`, 'blank');
}
/**
* 第三方登录成功 回调接口
*/
export function loginCallback (uuid) {
return request({
url: `/buyer/connect/result?state=${uuid}`,
method: Method.GET,
needToken: false
});
}
/**
* 忘记密码 验证手机验证码
*/
export function validateCode (params) {
return request({
url: `/buyer/members/resetByMobile`,
method: Method.POST,
needToken: false,
params
});
}
/**
* 忘记密码 重置密码
*/
export function resetPassword (params) {
return request({
url: `/buyer/members/resetPassword`,
method: Method.POST,
needToken: false,
params
});
}

443
buyer/src/api/member.js Normal file
View File

@ -0,0 +1,443 @@
import request, {Method} from '@/plugins/request.js';
// 查询账户余额
export function getMembersWallet () {
return request({
url: '/buyer/members/wallet',
method: Method.GET,
needToken: true
});
}
// 查询余额列表
export function getDepositLog (params) {
return request({
url: '/buyer/wallet/log',
method: Method.GET,
needToken: true,
params
});
}
// 查询充值记录
export function getRecharge (params) {
return request({
url: '/buyer/member/recharge',
method: Method.GET,
needToken: true,
params
});
}
// 查询提现记录
export function getWithdrawApply (params) {
return request({
url: '/buyer/member/withdrawApply',
method: Method.GET,
needToken: true,
params
});
}
// 在线充值
export function recharge (params) {
return request({
url: '/buyer/trade/recharge',
method: Method.POST,
needToken: true,
data: params
});
}
// 提现
export function withdrawalApply (params) {
return request({
url: '/buyer/members/wallet/withdrawal',
method: Method.POST,
needToken: true,
data: params
});
}
// 收藏商品、店铺
export function collectGoods (type, id) {
return request({
url: `/buyer/member/collection/add/${type}/${id}`,
method: Method.POST,
needToken: true
});
}
// 取消 收藏商品、店铺
export function cancelCollect (type, id) {
return request({
url: `/buyer/member/collection/delete/${type}/${id}`,
method: Method.DELETE,
needToken: true
});
}
// 查看是否收藏
export function isCollection (type, goodsId) {
return request({
url: `/buyer/member/collection/isCollection/${type}/${goodsId}`,
method: Method.GET,
needToken: true
});
}
// 会员收藏列表
export function collectList (params) {
return request({
url: `/buyer/member/collection/${params.type}`,
method: Method.GET,
needToken: true,
params
});
}
// 单个商品评价
export function goodsComment (params) {
return request({
url: `/buyer/memberEvaluation/${params.goodsId}/goodsEvaluation`,
method: Method.GET,
needToken: false,
params
});
}
// 商品各评价类别数量
export function goodsCommentNum (goodsId) {
return request({
url: `/buyer/memberEvaluation/${goodsId}/evaluationNumber`,
method: Method.GET,
needToken: false
});
}
// 添加会员评价
export function addEvaluation (params) {
return request({
url: `/buyer/memberEvaluation`,
method: Method.POST,
needToken: true,
params
});
}
// 会员评价详情
export function evaluationDetail (id) {
return request({
url: `/buyer/memberEvaluation/get/${id}`,
method: Method.GET,
needToken: true
});
}
// 发票分页列表
export function receiptList () {
return request({
url: `/buyer/trade/receipt`,
method: Method.GET,
needToken: true
});
}
// 保存发票信息
export function saveReceipt (params) {
return request({
url: `/buyer/trade/receipt`,
method: Method.POST,
needToken: true,
params
});
}
// 获取可领取优惠券列表
export function couponList (params) {
return request({
url: `/buyer/promotion/coupon`,
method: Method.GET,
needToken: true,
params
});
}
// 会员优惠券列表
export function memberCouponList (params) {
return request({
url: `/buyer/promotion/coupon/getCoupons`,
method: Method.GET,
needToken: true,
params
});
}
// 会员优惠券列表
export function canUseCouponList (params) {
return request({
url: `/buyer/promotion/coupon/canUse`,
method: Method.GET,
needToken: true,
params
});
}
// 领取优惠券
export function receiveCoupon (couponId) {
return request({
url: `/buyer/promotion/coupon/receive/${couponId}`,
method: Method.GET,
needToken: true
});
}
// 获取申请售后列表
export function afterSaleList (params) {
return request({
url: `/buyer/afterSale/page`,
method: Method.GET,
needToken: true,
params
});
}
// 获取申请售后页面信息
export function afterSaleInfo (sn) {
return request({
url: `/buyer/afterSale/applyAfterSaleInfo/${sn}`,
method: Method.GET,
needToken: true
});
}
// 获取申请售后、投诉原因
export function afterSaleReason (serviceType) {
return request({
url: `/buyer/afterSale/get/afterSaleReason/${serviceType}`,
method: Method.GET,
needToken: true
});
}
// 获取申请售后详情
export function afterSaleDetail (sn) {
return request({
url: `/buyer/afterSale/get/${sn}`,
method: Method.GET,
needToken: true
});
}
// 售后日志
export function afterSaleLog (sn) {
return request({
url: `/buyer/afterSale/get/getAfterSaleLog/${sn}`,
method: Method.GET,
needToken: true
});
}
// 申请售后
export function applyAfterSale (params) {
return request({
url: `/buyer/afterSale/save/${params.orderItemSn}`,
method: Method.POST,
needToken: true,
params
});
}
// 取消售后申请
export function cancelAfterSale (afterSaleSn) {
return request({
url: `/buyer/afterSale/cancel/${afterSaleSn}`,
method: Method.POST,
needToken: true
});
}
// 投诉商品
export function handleComplain (data) {
return request({
url: `/buyer/complain`,
method: Method.POST,
needToken: true,
data
});
}
// 分页获取我的投诉列表
export function complainList (params) {
return request({
url: `/buyer/complain`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 获取投诉详情
*/
export function getComplainDetail (id) {
return request({
url: `/buyer/complain/${id}`,
method: Method.GET,
needToken: true
});
}
/**
* 取消投诉
*/
export function clearComplain (id) {
return request({
url: `/buyer/complain/status/${id}`,
method: Method.PUT,
needToken: true
});
}
/**
* 获取当前会员分销信息
*/
export function distribution () {
return request({
url: `/buyer/distribution`,
method: Method.GET,
needToken: true
});
}
/**
* 申请成为分销商
* @param idNumber 身份证号
* @param name 名字
*/
export function applyDistribution (params) {
return request({
url: `/buyer/distribution`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 获取分销商订单列表
*/
export function getDistOrderList (params) {
return request({
url: `/buyer/distribution/distributionOrder`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 获取分销商商品列表
*/
export function getDistGoodsList (params) {
return request({
url: `/buyer/distributionGoods`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 选择分销商品
* @param distributionGoodsId 分销商品id
*/
export function selectDistGoods (distributionGoodsId) {
return request({
url: `/buyer/distributionGoods/checked/${distributionGoodsId}`,
method: Method.GET,
needToken: true
});
}
/**
* 分销商提现历史
*/
export function distCashHistory (params) {
return request({
url: `/buyer/distribution/cash`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 分销商提现
*/
export function distCash (params) {
return request({
url: `/buyer/distribution/cash`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 我的足迹
* @param {Number} pageNumber 页码
* @param {Number} pageSize 页数
*/
export function tracksList (params) {
return request({
url: `/buyer/footprint`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 清空足迹
*/
export function clearTracks () {
return request({
url: `/buyer/footprint`,
method: Method.DELETE,
needToken: true
});
}
/**
* 根据id删除足迹
* @param {String} ids id集合
*/
export function clearTracksById (ids) {
return request({
url: `/buyer/footprint/delByIds/${ids}`,
method: Method.DELETE,
needToken: true
});
}
/**
* 获取会员积分
*/
export function memberPoint (params) {
return request({
url: `/buyer/member/memberPointsHistory/getMemberPointsHistoryVO`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 积分历史
*/
export function memberPointHistory (params) {
return request({
url: `/buyer/member/memberPointsHistory/getByPage`,
method: Method.GET,
needToken: true,
params
});
}

98
buyer/src/api/order.js Normal file
View File

@ -0,0 +1,98 @@
import request, {
Method
} from '@/plugins/request.js';
// 查询会员订单列表
export function getOrderList (params) {
return request({
url: `/buyer/orders`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 订单明细
* @param {orderSn} 订单编号
*/
export function orderDetail (orderSn) {
return request({
url: `/buyer/orders/${orderSn}`,
method: Method.GET,
needToken: true
});
}
/**
* 取消订单
* @param {orderSn} 订单编号
* @param reason 取消订单原因
*/
export function cancelOrder (params) {
return request({
url: `/buyer/orders/${params.orderSn}/cancel`,
method: Method.POST,
needToken: true,
params
});
}
/**
* 删除订单
* @param {orderSn} 订单编号
*/
export function delOrder (orderSn) {
return request({
url: `/buyer/orders/${orderSn}`,
method: Method.DELETE,
needToken: true
});
}
/**
* 确认收货
* @param {orderSn} 订单编号
*/
export function sureReceived (orderSn) {
return request({
url: `/buyer/orders/${orderSn}/receiving`,
method: Method.POST,
needToken: true
});
}
/**
* 查询物流
* @param {orderSn} 订单编号
*/
export function getTraces (orderSn) {
return request({
url: `/buyer/orders/getTraces/${orderSn}`,
method: Method.POST,
needToken: true
});
}
/**
* 评价列表
*
*/
export function evolutionList (params) {
return request({
url: `/buyer/memberEvaluation`,
method: Method.GET,
needToken: true,
params
});
}
// 添加交易投诉对话
export function communication (params) {
return request({
url: `/buyer/complain/communication`,
method: Method.POST,
needToken: true,
params
});
}

48
buyer/src/api/pay.js Normal file
View File

@ -0,0 +1,48 @@
import request, {
Method
} from '@/plugins/request.js';
/**
* 获取支付详情
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
* @param sn 订单编号
* @param clientType 调起方式PC
*/
export function tradeDetail (params) {
return request({
url: '/buyer/cashier/tradeDetail',
needToken: true,
method: Method.GET,
params
});
}
/**
* 支付
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
* @param paymentMethod 支付方式 可用值:ALIPAY,WECHAT
* @param payClient 调起方式 可用值APP,NATIVE,JSAPI,H5
* @param sn 订单编号
*/
export function pay (params) {
return request({
url: `/buyer/cashier/pay/${params.paymentMethod}/${params.paymentClient}`,
needToken: true,
method: Method.GET,
params
});
}
/**
* 支付结果查询
* @param orderType 交易类型,可用值:TRADE,ORDER,RECHARGE
* @param sn 订单编号
*/
export function payCallback (params) {
return request({
url: `/buyer/cashier/result`,
needToken: true,
method: Method.GET,
params
});
}

View File

@ -0,0 +1,48 @@
import request, {
Method
} from '@/plugins/request.js';
/**
* 获取当天限时抢购信息
*/
export function seckillByDay (params) {
return request({
url: '/buyer/promotion/seckill',
method: Method.GET,
params
});
}
/**
* 获取某个时刻限时抢购信息
*/
export function seckillByTimeline (timeline) {
return request({
url: `/buyer/promotion/seckill/${timeline}`,
method: Method.GET
});
}
/**
* 获取积分商品分类列表
*/
export function pointGoodsCategory (params) {
return request({
url: `/buyer/promotion/pointsGoods/category`,
method: Method.GET,
needToken: true,
params
});
}
/**
* 获取积分商品列表
*/
export function pointGoods (params) {
return request({
url: `/buyer/promotion/pointsGoods`,
method: Method.GET,
needToken: true,
params
});
}

View File

@ -0,0 +1,77 @@
import request, {
Method
} from '@/plugins/request.js'
// 店铺分页列表
export function shopList (params) {
return request({
url: '/buyer/store',
needToken: true,
method: Method.GET,
params
})
}
// 申请店铺第一步-填写企业信息
export function applyFirst (params) {
return request({
url: '/buyer/store/apply/first',
needToken: true,
method: Method.PUT,
params
})
}
// 申请店铺第一步-填写企业信息
export function applySecond (params) {
return request({
url: '/buyer/store/apply/second',
needToken: true,
method: Method.PUT,
params
})
}
// 申请店铺第一步-填写企业信息
export function applyThird (params) {
return request({
url: '/buyer/store/apply/third',
needToken: true,
method: Method.PUT,
params
})
}
// 店铺详情
export function getDetailById (id) {
return request({
url: `/buyer/store/get/detail/${id}`,
needToken: true,
method: Method.GET
})
}
// 店铺分类
export function getCateById (id) {
return request({
url: `/buyer/store/label/get/${id}`,
needToken: true,
method: Method.GET
})
}
// 店铺入驻协议
export function agreement () {
return request({
url: `/buyer/article/get/1349291301250293760`,
needToken: true,
method: Method.GET
})
}
// 获取当前登录会员的店铺信息
export function applyStatus () {
return request({
url: `/buyer/store/apply`,
needToken: true,
method: Method.GET
})
}

View File

@ -0,0 +1,41 @@
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1608105836276'); /* IE9 */
src: url('iconfont.eot?t=1608105836276#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAdMAAsAAAAADPQAAAb9AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDVgqMUIodATYCJAMcCxAABCAFhG0HWRvmCsiOkUtOluX/f0k8/LOfu+9PRBKZs9KQTCTiSURCgdOJVgN9AiXs+HfTeyS0aaCioU7FjYpvyLyI1mDmsHm7OQtTozMxZGL+ZQfHUj+twfK+7V0qAyvx6fkpajywyKYfbfi8CQ1wyFtgZ1s+k3Q5ARQFiYeWeXV8IOAEdUDBvkYlAcJlgceQA6F3CDk0DegdmIhkJuMqgDf95+MfUoMASDBTIOy6tlchh+IxfHDB9P+fYYCKAGl5LjBHgRQwAtIgHkM91zBTNdI1ZNjv4OqAMgIDPkavy14Pff36g8v//4zBpRBygc1FTIMMLJe0P/+8yAKpKQN2PZsFY5D5ZMAY8UmBcRmfBIyH8kmD8WuXMLdSkKwWDzksrwIDkCRo/QQBN6JJzeJCMQhRSUSkE5tydyKRZ0V0PIpmk95u7FDKZ6zlJd/6SmB/I7K9FmqMG/2WR28ww2IL2XU+cv1Z9b1sfoYtUT1Bi9f70PakZZTdLkJWq2CR7zarFxraZdQvYnWbDLRQWdm1Xr+hf1Hl6q79kXzRYVtQBhF1OE1aLHy9r1GS0pC+nrTZhEHu5RZlJlFmx0ZJWWclVcbFXsYVvuZ93vvscaYjcYdtlg67KIMovwhE2XaXbrakrz97/nCPnzftQyOaEvc2LaOO2CP2WauX7fFnIxYi5SRtYrEAlCQ8+tlSbBWMRXZbr9vClTbeWUuApfimRQDG5b5LzBEbWEXejdUdtyl42Xa+nnPSwl9Kdm3Wm1ndm6gLeVeKTFTF4kav4RN8xZ5ktlZv2FdRWYK311gD7eMjmYR00pC3wG19hl0i3PnGxUvMGzZRIspEoVD+ZGRQGTeDfgOrewsy0FlGL6O3t4ky0CLa53L5Xkv0UWuO+VxWN+uAPe6Ejb/4YnjXdT+aWnbiwrkY85pBff4wm23gVkv5+vD087bc67Y0u2jTBTOHo4eonwNRB7YFGBd5X7IK6Y00bTCxkOlczKIVHKOR9KGLUQkMJHlae+Fxm1cXvdREmawFt7iY5Aru6opfEYWqSGm1T0eMMN14eadAON2ZqAjOCI7zI/OCMsxzc5xNwvozP29Mv+rIizGswEcalrcwQBz068w2xDjyjgIsPZFXPa+Szn88//TVufz3/xdQ6F/kM+cezuXi90ShKlIU9iJzx1FCHj+WU3k9ucGVIZyqlaE+aHJft+rTpBBpW1GDn2peUxP7R5SnhwBpWxjVjCqtWADNhm6YZyMSyq/KXQb5t/j/93dR95APPR+S7CpfhQ3E6tTbcUnDnqZ+uule5rduo4uPfFCIGhs9LbQZBqaP//17nFTitBU/bi+fDo7KCvh+3Scasz/flbcN71rIcGuMIphMJ7/4R48Dq1x0XDnlfo3iuwR2524O3JzHFDmVVu8P3J+7APNrCWoKEHAhc7PBF4lS53qiUl+tsPDpU1FhS5nvt7CUuSBcuPq2jX80Mp/j27Zy4hAYCr42pw0L7vVkYYefujAwp3ZEdR1xMsBzvt98T48Jucxdb7+MFPkLZkrFgB4YpuXI4BpQ0UuTRtRXXlRfll9oDLoDSHFDj3Mw8Fr2/Pb1QXhP+LU1azKSl0QuSc4wbrdYqYYRlzO+fg0r9wIsjwH4CH8qc2G7OLv1hj/zr2CyCMJulmQyVGMb7v7mT91dF/glg2hecea/mzNbxvO9t8mxn073ijgZjjcGxI+Xb4/jMTz8cwasxV5GqvRB72T/4ZLwk1LvnuaAloP5o8flajIuO/mQZGr6mOSQc/Pr2+94cGoKL8/c//WI+xEnaBryRi3oS212LDbM5vCGZFNmAjOsIFjVWW4NrGSnw2iLXiJ1vewAgwDmK7FnmBRgfhw7jZUCzHGnmVgxAOlgrAyTXq+bwWtRyJcW1/xfBOsWHvj9/7Rdr5rrcYTpAY5HLaSWXp3WNCpN8ZUL1lz63UHWho5UI4cGAhzhJkWxB1yVgabH5ek6qaUPAJ23DQlHgZBCCEemsfGQwZIOWYQiKIpTeXSJpyEwKO0EYNFUAhA3O4DBxQnAuLmGxLGPgMnHJ3DgFhiQhOF5SpbI0JBlQxSSYQo5Vzqaq5FpO5WSfRhpFPZSqIa3S4Y45TpFqBgyVBPnpiQme/OVik7FkDL2GDpClTpsmJKrHKLt4PKIqyna27Vc3RBtq0I2LFE9bJguNylJGbZnokzbAaQyQyhIDFM55bikRgtqyGh1UvYfhvR9fy8KKsO1kxgS0/ETFlLYuxoNrJ4rRaLkFMhKTWeqjm0pH2oElVTD0KXEleuH0OrAxUOXQruY0eLShW/USkFmmETqHCmdXEnYTZlWk1i/rmM5T0CR8Eq5YCAM4YiJHJAjIoBxMthhpEIzStNJjFFrlMOlEi3eptDLHUdpJKM10uHMiLBUCwAAAAA=') format('woff2'),
url('iconfont.woff?t=1608105836276') format('woff'),
url('iconfont.ttf?t=1608105836276') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1608105836276#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-qq:before {
content: "\e6e6";
}
.icon-weixin:before {
content: "\e643";
}
.icon-zhifubao:before {
content: "\e601";
}
.icon-kefu:before {
content: "\e673";
}
.icon-xiayibu:before {
content: "\e600";
}
.icon-weibo:before {
content: "\eb0e";
}

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,51 @@
{
"id": "2274088",
"name": "lili shop",
"font_family": "iconfont",
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "829012",
"name": "QQ",
"font_class": "qq",
"unicode": "e6e6",
"unicode_decimal": 59110
},
{
"icon_id": "2450774",
"name": "微信",
"font_class": "weixin",
"unicode": "e643",
"unicode_decimal": 58947
},
{
"icon_id": "7010369",
"name": "支付宝",
"font_class": "zhifubao",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "10615183",
"name": "服务评价-客服",
"font_class": "kefu",
"unicode": "e673",
"unicode_decimal": 58995
},
{
"icon_id": "13090705",
"name": "下一步",
"font_class": "xiayibu",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "14510226",
"name": "微博",
"font_class": "weibo",
"unicode": "eb0e",
"unicode_decimal": 60174
}
]
}

View File

@ -0,0 +1,44 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>
<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="qq" unicode="&#59110;" d="M512 865.009172c-265.653359 0-480.988706-215.344556-480.988706-481.012242 0-265.661545 215.335347-481.006102 480.988706-481.006102s480.988706 215.344556 480.988706 481.006102C992.987682 649.664615 777.653359 865.009172 512 865.009172L512 865.009172zM776.822434 234.085642c-12.421914-11.596106-33.748638 1.032516-54.248531 29.399587-8.900717-24.019043-20.496823-46.170552-33.95637-66.051345 28.987195-10.352789 47.625694-26.504654 47.625694-44.725644 0-31.472805-55.698556-56.941873-124.443243-56.941873-40.790008 0-76.818573 8.898671-99.593276 22.776749-22.564925-13.877055-58.799174-22.776749-99.590206-22.776749-68.744687 0-124.443243 25.469068-124.443243 56.941873 0 18.014282 18.637476 34.372855 47.625694 44.725644-13.666254 19.8767-25.055652 42.033325-33.95944 66.051345-20.4958-28.15627-41.821501-40.996716-54.248531-29.399587-16.977673 15.940041-10.555403 72.262814 14.70184 125.687584 5.799076 12.215206 12.009522 23.188118 18.427698 32.716122 3.518127 155.296949 105.804744 279.9469 231.280504 279.9469l0.413416 0c125.474736 0 227.762377-124.443243 231.280504-279.9469 6.417153-9.526981 12.633738-20.500916 18.426675-32.716122C787.176247 306.348456 793.805224 250.025683 776.822434 234.085642L776.822434 234.085642zM776.822434 234.085642" horiz-adv-x="1024" />
<glyph glyph-name="weixin" unicode="&#58947;" d="M579.6 384.4c-11.7 0-23.4-10.8-23.4-24.2 0-10.8 11.7-21.7 23.4-21.7 17.5 0 30 10.8 30 21.7 0 13.4-12.5 24.2-30 24.2M502.8 497c18.4 0 30 11.7 30 29.2 0 18.4-11.7 29.2-30 29.2-17.5 0-34.2-10.8-34.2-29.2 0-17.5 16.7-29.2 34.2-29.2M512 896C229.2 896 0 666.8 0 384s229.2-512 512-512 512 229.2 512 512S794.8 896 512 896m-96.8-641.7c-30.9 0-53.4 5-82.6 13.3l-84.3-42.5 24.2 71.7c-59.2 41.7-94.3 94.3-94.3 158.5 0 113.5 106.8 200.2 236.9 200.2 115.1 0 217.7-68.4 237.7-165.2-8.3 1.7-15.9 2.5-22.5 2.5-113.5 0-201-85.1-201-187.7 0-17.5 2.5-33.4 6.7-50.1-6.6-0.7-14.1-0.7-20.8-0.7m347.9-81.8l16.7-60.1-63.4 35.9c-24.2-5-47.5-12.5-71.7-12.5-111.8 0-200.2 76.7-200.2 171.8s88.4 171.8 200.2 171.8c105.9 0 201-76.7 201-171.8 0-53.3-35.9-100.9-82.6-135.1M337.7 555.4c-17.5 0-35.9-10.8-35.9-29.2 0-17.5 18.4-29.2 35.9-29.2 16.7 0 30 11.7 30 29.2 0 18.4-13.4 29.2-30 29.2m372.8-171c-12.5 0-23.4-10.8-23.4-24.2 0-10.8 10.8-21.7 23.4-21.7 16.7 0 29.2 10.8 29.2 21.7 0 13.4-12.5 24.2-29.2 24.2m0 0z" horiz-adv-x="1024" />
<glyph glyph-name="zhifubao" unicode="&#58881;" d="M264.504 327.279c-10.624-8.55-22.01-21.032-25.317-36.9-4.5-21.68-0.94-48.815 19.975-70.103 25.338-25.806 63.842-32.869 80.473-34.083 45.176-3.267 93.326 19.136 129.619 44.687 14.224 10.038 38.583 30.19 61.866 61.279-52.18 26.94-117.314 56.74-186.946 53.824-35.57-1.487-61.044-8.863-79.67-18.704z m661.692-119.131C949.223 262.206 962 321.626 962 384c0 248.126-201.854 450-450 450S62 632.126 62 384c0-248.146 201.854-450 450-450 149.752 0 282.56 73.585 364.422 186.437-77.341 38.445-204.81 101.72-283.324 140.009-37.468-42.711-92.857-85.52-155.426-104.146-39.307-11.68-74.74-16.141-111.796-8.57-36.685 7.514-63.704 24.692-79.454 41.91-8.022 8.784-17.237 19.956-23.91 33.24a62.622 62.622 0 0 1 1.057-2.68s-3.834 6.613-6.769 17.139a75.58 75.58 0 0 0-2.936 15.946 82.193 82.193 0 0 0-0.175 11.465c-0.333 6.77-0.058 13.872 1.467 21.15 3.679 17.785 11.27 38.505 30.913 57.737 43.122 42.222 100.879 44.491 130.794 44.315 44.315-0.254 121.324-19.644 186.163-42.574 17.961 38.25 29.484 79.162 36.92 106.436H330.337v29.151h138.444V539.27H301.185v29.153H468.78v58.284c0 8.003 1.584 14.576 14.575 14.576h65.584v-72.86h182.19v-29.153H548.94v-58.304h145.74s-14.634-81.587-60.398-162c101.564-36.274 244.449-92.152 291.914-110.817z" horiz-adv-x="1024" />
<glyph glyph-name="kefu" unicode="&#58995;" d="M870.1 333.6v25.5c2 116.5-32.2 214.5-99.6 284-32.2 33.2-71 58.2-116 75.6-7.2 62.8-74.6 112.4-156.8 112.4-82.2 0-150.2-49.5-156.8-112.4-45-17.4-83.8-42.4-116-75.6-67.4-69.5-101.7-167-99.6-283.5v-31.2c-17.4-17.9-31.2-44.4-20.9-82.2 7.7-28.1 28.1-48.5 53.1-57.7 12.8-8.2 27.6-12.8 43.9-12.8 32.2-141 148.1-237 299.9-237 151.7 0 267.7 96 299.9 237.5 1 0 2-0.5 3.1-0.5 19.9 0 38.3 7.2 53.1 18.9 18.9 10.7 33.7 29.1 39.8 52.1 10.7 41-7.2 69.1-27.1 86.9z m-88.9-77.1c0-18.9-1.5-36.8-4.1-54.1-49.5-79.7-131.3-131.8-232.9-143-7.7 10.2-23 16.9-40.9 16.9-25.5 0-46-13.8-46-31.2 0-16.9 20.4-31.2 46-31.2 23 0 41.4 11.2 45.5 26.1 32.7 3.6 63.9 11.7 93.5 23.5 41.9 16.9 78.7 41.9 109.8 73.6 5.1 5.1 9.7 10.2 14.3 15.8-36.8-113-135.4-185.5-263.6-185.5h-1c-165 0-279.9 119-279.9 289.1l-0.5 16.3c0 7.2 1 26.6 2 45 68.5 25 130.3 120.6 155.3 164.5 23-31.2 75.6-91.4 156.3-122.6 30.1-11.7 60.8-17.9 90.9-24.5 59.8-12.8 116.5-25 154.8-75.1l1.5-1.5-1-2.1z m0 0" horiz-adv-x="1024" />
<glyph glyph-name="xiayibu" unicode="&#58880;" d="M1024.950857 384c0 2.706286-1.097143 5.193143-1.536 7.826286-0.585143 3.145143-0.658286 6.363429-1.901714 9.362285l-0.146286 0.365715c-1.682286 3.949714-4.388571 7.314286-7.021714 10.605714-1.024 1.316571-1.462857 2.925714-2.706286 4.096 0 0-0.146286 0-0.146286 0.146286l-241.590857 240.274285a45.714286 45.714286 0 0 1-64.365714-64.877714l162.889143-162.084571H46.665143a45.714286 45.714286 0 1 1 0-91.428572h821.76L705.536 176.201143a45.714286 45.714286 0 1 1 64.365714-64.877714l241.517715 240.274285 0.219428 0.146286c1.170286 1.243429 1.682286 2.779429 2.706286 4.096 2.633143 3.291429 5.339429 6.582857 7.021714 10.605714l0.146286 0.365715c1.243429 2.925714 1.316571 6.217143 1.901714 9.362285 0.438857 2.633143 1.462857 5.12 1.462857 7.753143V384c0 0.073143 0 0 0 0z" horiz-adv-x="1025" />
<glyph glyph-name="weibo" unicode="&#60174;" d="M413.422 292.65c-20.053 0-38.503-16.509-38.813-34.706-0.253-15.525 12.797-27.338 30.291-27.338 20.813-0.028 38.222 15.638 38.362 34.481 0.141 16.059-12.403 27.563-29.841 27.563zM463.316 306.487c-5.962-2.925-11.7-7.228-15.806-12.431-0.872-1.125 5.231-7.763 10.181-14.878 6.356 6.975 12.094 10.997 14.203 16.425 0.928 2.334-7.594 11.391-8.578 10.884zM589.259 385.378c-9.675 6.047-20.081 11.109-30.712 15.412-35.578 14.231-72.9 18.45-110.841 15.131-57.375-4.978-110.362-21.881-151.566-64.434-47.784-49.303-41.316-111.712 14.934-150.834 38.081-26.438 81.309-35.522 126.984-34.425 8.297 0 16.622-0.647 24.863 0.113 52.003 4.978 99.9 20.756 139.584 55.941 57.994 51.328 52.172 122.006-13.247 163.097z m-64.35-144.928c-19.744-29.925-54.703-48.094-92.672-48.291-47.869-0.309-83.784 26.578-90.141 68.4-1.406 8.55-1.013 17.944 0.928 26.325 9.647 41.034 38.053 63.956 76.725 74.306 38.194 10.125 73.716 3.516 101.503-26.831 23.006-25.116 23.934-63.394 3.656-93.909zM512.028 834C263.487 834 62 632.513 62 384s201.487-450 450-450c248.512 0 450 201.487 450 450 0 248.512-201.459 450-449.972 450z m214.594-584.353c-38.447-59.147-97.509-88.481-163.491-104.653-31.922-7.875-65.25-10.294-82.575-12.938-81.816 2.025-145.097 14.119-202.162 49.584-71.916 44.691-92.869 111.656-55.266 187.594 40.387 81.45 103.219 141.694 185.681 180.422 15.3 7.172 32.709 11.25 49.5 13.331 34.594 4.303 54.787-15.328 53.916-50.147-0.197-7.622-1.913-15.131-2.362-22.809-0.337-6.553 0.141-13.219 0.309-19.8 6.722 1.097 13.5 1.8 20.081 3.263 26.663 5.709 53.044 15.244 79.903 16.678 46.631 2.475 67.528-25.763 53.353-70.059-6.103-18.872-1.547-25.228 16.088-31.556 66.319-23.906 85.416-79.903 47.025-138.909z m-34.791 248.316c-10.969 13.95-35.859 17.184-43.734 17.269-11.644 0.084-21.037 9.619-20.925 21.234 0.084 11.588 9.506 20.897 21.037 20.897h0.169c5.147 0 51.3-1.322 76.556-33.328 10.013-12.684 20.278-35.241 12.15-70.341-2.25-9.788-10.941-16.369-20.531-16.369a19.75 19.75 0 0 0-4.725 0.591c-11.363 2.616-18.422 13.95-15.806 25.256 3.544 15.356 2.166 26.747-4.191 34.791zM815.834 429c-1.659-10.35-10.575-17.831-20.813-17.831-1.041 0-2.194 0.141-3.291 0.309-11.475 1.772-19.322 12.572-17.55 24.075 7.819 49.753-0.141 88.453-23.766 114.891-41.119 46.069-116.494 43.341-117.253 43.341-11.756-0.478-21.487 8.522-21.994 20.109-0.478 11.616 8.578 21.459 20.166 21.994 3.909 0.141 96.188 3.375 150.525-57.347 32.4-36.366 43.819-86.681 33.975-149.541z" horiz-adv-x="1024" />
</font>
</defs></svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

View File

@ -0,0 +1,92 @@
.coupon-list {
display: flex;
flex-wrap: wrap;
}
.coupon-item {
width: 380px;
height: 145px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
position: relative;
border: 1px solid #eee;
.c-left {
width: 100%;
padding: 20px;
>div, > p {
margin-bottom: 10px;
}
>div {
.price{
color: $theme_color;
font-size: 20px;
}
.describe{
background-color: #fff4ec;
color: $theme_color;
padding: 0 5px;
margin-left: 10px;
font-size: 13px;
}
}
p:nth-of-type(1){
font-weight: bold;
}
p:nth-of-type(2){
color: #999;
}
}
b{
position: absolute;
z-index: 2;
top: 0;
right: 50px;
display: block;
width: 3px;
height: 100%;
}
.c-right {
position: absolute;
right: 0;
top: 0;
width: 52px;
height: 100%;
background-color: $theme_color;
color: #fff;
font-size: 16px;
padding: 20px;
&:hover{
font-weight: bold;
}
}
i{
position: absolute;
width: 20px;
height: 20px;
right: 42px;
border: 1px solid #eee;
background-color: #fff;
border-radius: 20px;
&:after{
content: '';
position: absolute;
width: 25px;
height: 20px;
left: -2px;
background-color: #fff;
}
}
i.circle-top{
top: -10px;
&::after{
top: -11px;
}
}
i.circle-bottom{
bottom: -10px;
&::after{
bottom: -11px;
}
}
}

View File

@ -0,0 +1,125 @@
/*
* @Author: LMR
* @Date: 2020-08-11 10:12:34
* @Last Modified by: LMR
* @Last Modified time: 2020-08-18 16:00:10
*/
//
@import "./theme.scss";
.global_color{
color: $theme_color;
}
.global_background_color{
background-color: $theme_color;
}
.global_text_left {
text-align: left;
}
.global_text_right {
text-align: right;
}
.global_float_left {
float: left;
}
.global_float_right {
float: right;
}
.clearfix::after{
content: '';
display: block;
clear: both;
}
.width_1200{width: 1200px;}
.width_800{width: 800px;}
.width_400{width: 400px;}
.width_300{width: 300px;}
.width_200{width: 200px;}
.width_100{width: 100px;}
.fontsize_12{font-size: 12px;}
.fontsize_14{font-size: 14px;}
.fontsize_16{font-size: 16px;}
.fontsize_18{font-size: 18px;}
.mb_20{margin-bottom: 20px;}
.mt_20{margin-top: 20px;}
.ml_20{margin-left: 20px;}
.mr_20{margin-right: 20px;}
.mb_10{margin-bottom: 10px;}
.mt_10{margin-top: 10px;}
.ml_10{margin-left: 10px;}
.mr_10{margin-right: 10px;}
.pb_20{padding-bottom: 20px;}
.pt_20{padding-top: 20px;}
.pl_20{padding-left: 20px;}
.pr_20{padding-right: 20px;}
.pb_10{padding-bottom: 10px;}
.pt_10{padding-top: 10px;}
.pl_10{padding-left: 10px;}
.pr_10{padding-right: 10px;}
.color999{
color: #999;
}
html,
body {
height: 100%;
width: 100%;
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
// overflow: hidden;
margin: 0;
padding: 0;
}
li{
list-style: none;
}
.hover-color:hover{
color: $theme_color!important;
cursor: pointer;
}
.hover-pointer{
cursor: pointer;
}
.center{
margin: 0 auto;
}
.relative{
position: relative;
}
.ellipsis{
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.promotion-decorate{
width: 200px;
text-align: center;
font-size: 25px;
position: relative;
font-weight: bold;
margin: 30px auto 30px;
&::before,&::after{
content: '';
display: inline-block;
width: 25px;
height: 20px;
background-size: 50px 20px;
background-repeat: no-repeat;
background-position: 0 0;
position: absolute;
top: 10px;
left: -3px;
}
&::after{
background-position: -24px 0;
right: -3px;
left: auto;
}
}

View File

@ -0,0 +1,58 @@
.text-danger {
color: $theme_color;
}
.seckill-price{
margin-right: 5px;
font-size: 25px;
font-weight: bold;
}
.goods-list {
display: flex;
flex-wrap: wrap;
width: 1200px;
margin: 0 auto;
}
.goods-show-info {
width: 235px;
padding: 6px;
margin: 10px 0px;
margin-left: 5px;
position: relative;
border: 1px solid #fff;
cursor: pointer;
background-color: #fff;
}
.goods-show-info:hover {
border: 1px solid #ccc;
box-shadow: 0px 0px 15px #ccc;
}
.goods-show-price {
margin-top: 6px;
}
.goods-show-detail {
font-size: 12px;
margin: 6px 0px;
}
.goods-show-num {
font-size: 12px;
margin-bottom: 6px;
color: #666;
}
.goods-show-num {
font-size: 12px;
margin-bottom: 6px;
color: #009688;
}
.goods-show-num span {
color: #005aa0;
font-weight: bold;
}
.goods-show-seller {
font-size: 12px;
color: $theme_color;
}
.goods-page {
margin:10px auto ;
text-align: right;
width: 1200px;
}

View File

@ -0,0 +1,84 @@
@import '~view-design/src/styles/index.less';
@primary-color: #ed3f14;
@table-thead-bg : #f8f8f9;
@table-td-stripe-bg : #f8f8f9;
@table-td-hover-bg : #ededed;
@table-td-highlight-bg : #ededed;
//
//.colorPaletteMixin() {
// @functions: ~`(function() {
// var hueStep = 2;
// var saturationStep = 0.16;
// var saturationStep2 = 0.05;
// var brightnessStep1 = 0.05;
// var brightnessStep2 = 0.15;
// var lightColorCount = 5;
// var darkColorCount = 4;
//
// var getHue = function(hsv, i, isLight) {
// var hue;
// if (hsv.h >= 60 && hsv.h <= 240) {
// hue = isLight ? hsv.h - hueStep * i : hsv.h + hueStep * i;
// } else {
// hue = isLight ? hsv.h + hueStep * i : hsv.h - hueStep * i;
// }
// if (hue < 0) {
// hue += 360;
// } else if (hue >= 360) {
// hue -= 360;
// }
// return Math.round(hue);
// };
// var getSaturation = function(hsv, i, isLight) {
// var saturation;
// if (isLight) {
// saturation = hsv.s - saturationStep * i;
// } else if (i === darkColorCount) {
// saturation = hsv.s + saturationStep;
// } else {
// saturation = hsv.s + saturationStep2 * i;
// }
// if (saturation > 1) {
// saturation = 1;
// }
// if (isLight && i === lightColorCount && saturation > 0.1) {
// saturation = 0.1;
// }
// if (saturation < 0.06) {
// saturation = 0.06;
// }
// return Number(saturation.toFixed(2));
// };
// var getValue = function(hsv, i, isLight) {
// var value;
// if (isLight) {
// value = hsv.v + brightnessStep1 * i;
// }else{
// value = hsv.v - brightnessStep2 * i
// }
// if (value > 1) {
// value = 1;
// }
// return Number(value.toFixed(2))
// };
//
// this.colorPalette = function(color, index) {
// var isLight = index <= 6;
// var hsv = tinycolor(color).toHsv();
// var i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1;
// return tinycolor({
// h: getHue(hsv, i, isLight),
// s: getSaturation(hsv, i, isLight),
// v: getValue(hsv, i, isLight),
// }).toHexString();
// };
//})()`;
//}
//.colorPaletteMixin();

View File

@ -0,0 +1,114 @@
/*
* @Author: LMR
* @Date: 2020-08-14 11:04:12
* @Last Modified by: LMR
* @Last Modified time: 2020-08-18 14:21:41
*/
//
//
$primary_color: #2d8cf0;
$primary_light_color: #0f1011;
$primary_dark_color: #2b85e4;
$success_color: #19be6b;
$warning_color: #ff9900;
$error_color: #ed3f14;
$handle-btn-color: #438cde;
$theme_color: #ed3f14;
$border_color: #dddee1;
$title_color: #8c8c8c;
$light_title_color: #1c2438;
$light_content_color: #495060;
$light_sub_color: #80848f;
$light_background_color: #f8f8f9;
$light_white_background_color :#fff;
//
$dark_background_color: #141414;
$dark_sub_background_color: #1d1d1d; //
$dark_content_color: #d5d5d5;
/***** 封装一些方法可用于 黑暗主题 ,明亮主题 *****/
//
@mixin background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
//
@mixin sub_background_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_background_color;
}
}
@mixin white_background_color() {
/*通过该函数设置字体颜色,后期方便统一管理;*/
background-color: $light_white_background_color;
transition: 0.35s;
[data-theme="dark"] & {
background-color: $dark_sub_background_color;
}
[data-theme="light"] & {
background-color: $light_white_background_color;
}
}
//
@mixin content_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_content_color;
}
}
//
@mixin sub_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_sub_color;
}
}
//
@mixin title_color($color) {
/*通过该函数设置字体颜色,后期方便统一管理;*/
color: $color;
[data-theme="dark"] & {
color: $dark_content_color;
}
[data-theme="light"] & {
color: $light_title_color;
}
}

View File

@ -0,0 +1,149 @@
<template>
<div>
<div class="container">
<img
:src="logoImg"
v-if="showLogo"
class="logo-img"
alt=""
@click="$router.push('/')"
/>
<i-input
v-model="searchData"
size="large"
class="search"
placeholder="输入你想查找的商品"
@keyup.enter.native="search"
>
<Button v-if="!store" slot="append" @click="search"></Button>
</i-input>
<div v-if="store" class="btn-div">
<Button class="store-search" type="warning" @click="searchStore"></Button>
<Button class="store-search" type="primary" @click="search"></Button>
</div>
<template v-if="showTag">
<div style="height:12px" v-if="promotionTags.length === 0"></div>
<div v-else>
<Tag
v-for="(item, index) in promotionTags"
:key="index"
>
<span class="hover-color" @click="selectTags(item)">{{ item }}</span>
</Tag>
</div>
</template>
</div>
</div>
</template>
<script>
import {getLogo} from '@/api/common.js'
import {hotWords} from '@/api/goods.js'
export default {
name: 'search',
props: {
showTag: { //
type: Boolean,
default: true
},
showLogo: { // logo
type: Boolean,
default: true
},
store: { //
type: Boolean,
default: false
}
},
data () {
return {
searchData: '', //
logoImg: '', // pclogo
promotionTags: [] //
};
},
methods: {
selectTags (item) {
this.searchData = item;
this.search();
},
search () {
this.$router.push({
path: '/goodsList',
query: { keyword: this.searchData }
});
},
searchStore () {
this.$emit('search', this.searchData)
}
},
mounted () {
if (!this.Cookies.getItem('logo')) {
getLogo().then(res => {
if (res.success) {
let logoObj = JSON.parse(res.result.settingValue)
this.Cookies.setItem('logo', logoObj.buyerSideLogo)
this.logoImg = logoObj.buyerSideLogo
}
})
} else {
this.logoImg = this.Cookies.getItem('logo')
}
this.searchData = this.$route.query.keyword
hotWords({start: 1, end: 5}).then(res => {
if (res.success) this.promotionTags = res.result
})
}
};
</script>
<style scoped lang="scss">
.container {
margin: 30px auto;
width: 460px;
position: relative;
}
.search {
margin: 10px 0px 5px 0;
/deep/ .ivu-input.ivu-input-large {
border: 2px solid $theme_color;
font-size: 12px;
height: 34px;
&:focus {
box-shadow: none;
}
}
/deep/ .ivu-input-group-append {
border: 1px solid $theme_color;
border-left: none;
height: 30px;
background-color: $theme_color;
color: #ffffff;
button {
font-size: 14px;
font-weight: 600;
line-height: 1;
}
}
}
.logo-img {
position: absolute;
left: -360px;
top: -9px;
width: 150px;
cursor: pointer;
}
.store-search{
padding: 0 9px;
border-radius: 0;
&:nth-child(2){
margin-left: -5px;
}
}
.btn-div{
position: relative;
height: 0px;
top: -38px;
left: 336px;
}
</style>

View File

@ -0,0 +1,173 @@
<template>
<div>
<Modal v-model="showAddr" width="800" title="收件人地址">
<Form
:model="formData"
ref="form"
label-position="left"
:label-width="100"
:rules="ruleInline"
>
<FormItem label="收件人" prop="name">
<i-input v-model="formData.name" style="width: 600px"></i-input>
</FormItem>
<FormItem label="收件地区" prop="address">
<i-input
v-model="formData.address"
disabled
style="width: 600px"
></i-input>
<Button type="primary" size="small" @click="$refs.map.showMap = true">选择</Button>
</FormItem>
<FormItem label="详细地址" prop="detail">
<i-input v-model="formData.detail" style="width: 600px"></i-input>
</FormItem>
<FormItem label="手机号码" prop="mobile">
<i-input v-model="formData.mobile" style="width: 600px"></i-input>
</FormItem>
<FormItem label="地址别名">
<i-input
v-model="formData.alias"
length
:maxlength="4"
placeholder="请输入地址别名,例如公司"
style="width: 600px"
></i-input>
</FormItem>
<FormItem label="默认地址">
<i-switch v-model="formData.isDefault" />
</FormItem>
</Form>
<div class="mt_20" slot="footer">
<Button @click="hide"></Button>
<Button type="primary" class="mr_10" :loading="loading" @click="save"></Button>
</div>
</Modal>
<lili-map ref="map" @getAddress="getAddress"></lili-map>
</div>
</template>
<script>
import liliMap from '@/components/map';
import {
newMemberAddress,
editMemberAddress,
getAddrDetail
} from '@/api/address';
export default {
name: 'addressManage',
props: {
id: {
defalut: '',
type: String
}
},
data () {
return {
showAddr: false, //
formData: { //
isDefault: false
},
ruleInline: { //
name: [{ required: true, message: '请输入收件人姓名', trigger: 'blur' }],
address: [{ required: true, message: '请输入地址', trigger: 'change' }],
detail: [
{ required: true, message: '请输入详细地址', trigger: 'blur' }
],
mobile: [
{ required: true, message: '手机号不能为空', trigger: 'blur' },
{
type: 'string',
pattern: /^1[3|4|5|6|7|8][0-9]{9}$/,
message: '手机号格式出错',
trigger: 'blur'
}
]
},
loading: false, //
mapMsg: {} //
};
},
methods: {
save () {
this.$refs.form.validate((valid) => {
if (valid) {
const params = JSON.parse(JSON.stringify(this.formData));
params.consigneeAddressPath = params.address.replace(/\s/g, ',');
delete params.address;
this.loading = true;
if (this.id) {
editMemberAddress(params).then((res) => {
this.loading = false;
if (res.code === 200) {
this.$Message.success('编辑地址成功');
this.$emit('change', true);
this.hide();
}
}).catch(() => { this.loading = false; });
} else {
newMemberAddress(params).then((res) => {
this.loading = false;
if (res.code === 200) {
this.$Message.success('新增地址成功');
this.$emit('change', true);
this.hide();
}
}).catch(() => { this.loading = false; });
}
}
});
},
getAddrById (id) {
//
getAddrDetail(id).then((res) => {
if (res.code === 200) {
console.log(res);
const data = res.result;
data.address = res.result.consigneeAddressPath.replace(/,/g, ' ');
this.formData = data;
}
});
},
getAddress (item) {
//
console.log(item);
this.mapMsg = item;
this.$set(this.formData, 'address', item.addr);
this.$set(this.formData, 'consigneeAddressIdPath', item.addrId);
this.$set(this.formData, 'detail', item.detail);
this.formData.lat = item.position.lat;
this.formData.lon = item.position.lng;
},
show () {
this.showAddr = true;
},
hide () {
this.showAddr = false;
}
},
watch: {
id: {
immediate: true,
handler: function (v) {
console.log(v);
if (v) {
this.getAddrById(v);
} else {
this.formData = {}
this.$refs.form.resetFields();
}
}
}
},
components: {
liliMap
}
};
</script>
<style scoped lang="scss">
.add-box {
margin: 40px 0;
}
</style>

View File

@ -0,0 +1,42 @@
<template>
<!-- 头部广告 -->
<div class="advertising" v-if="show" :style="{'background-color': data.bgColor}">
<img :src="data.img" class="hover-pointer" @click="linkTo(data.url)"/>
<Icon type="md-close-circle" size="20" @click="show = false" />
</div>
</template>
<script>
export default {
props: {
data: { // 广
type: Object,
default: null
}
},
data () {
return {
show: true // 广
}
}
};
</script>
<style scoped lang="scss">
.advertising {
height: 80px;
width: 100%;
background-color: $theme_color;
text-align: center;
overflow: hidden;
position: relative;
> img {
width: 1200px;
height: 100%;
}
*:nth-child(2){
position: relative;
right: 36px;
top: -57px;
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,2 @@
# 广告
## FixedTop 顶部广告

View File

@ -0,0 +1,12 @@
## 自定义card -
### 参数
>_Title 卡片头部
>_More 右侧栏显示内容 -- 默认不显示
>_Src 右侧内容显示之后的src路径
>_Tabs 传入数组 -- 默认无
>_Change 点击数组返回的index

View File

@ -0,0 +1,149 @@
<template>
<Card class="_Card" :bordered="false" :dis-hover="true">
<div slot="title" class="cardTitle">
<span :style="{fontSize:`${_Size}px`}">{{_Title}}</span>
<div v-if="_Tabs" class="cardTabs">
<div @click="tabsChange(index)" :class="{active:(isActive==index)}" class="cardTabsItem" :style="{fontSize:`${_Size-2}px`}" v-for="(item,index) in _Tabs"
:key="index">
{{item}}
</div>
</div>
</div>
<div slot="extra" class="cardExtra" v-if="_More" @click="callBack()">
{{_More}}
</div>
<div>
</div>
</Card>
</template>
<script>
export default {
name: 'index',
props:
{
_Tabs: { // tab
type: null,
default: ''
},
//
_Title: { //
type: null,
default: '卡片头部'
},
//
_More: {
type: null,
default: false
},
_Size: { //
type: Number,
default: 16
},
//
_Src: {
type: null,
default: function (val) {
if (this._More) {
return val;
} else {
return false;
}
}
}
},
data () {
return {
isActive: 0 // tab
};
},
mounted () {},
methods: {
//
callBack () {
let _this = this;
if (this._Src !== '' || this._Src != null) {
this.$router.push({
path: _this._Src
});
}
},
// tab
tabsChange (index) {
// index
this.isActive = index;
this.$emit('_Change', index);
}
}
};
</script>
<style scoped lang="scss">
.cardTitle {
display: flex;
cursor: pointer;
}
.active{
color: $theme_color;
position: relative;
&::before{
content: '';
position: absolute;
width: 100%;
height: 3px;
bottom: 0;
left: 0;
background: $theme_color;
}
}
.cardTabs {
display: flex;
padding: 0 12px;
> .cardTabsItem {
padding: 0 12px;
}
> .cardTabsItem:hover {
color: $theme_color;
}
}
/deep/ .ivu-card, .ivu-card-head, ._Card {
margin-bottom: 20px;
@include white_background_color();
}
/deep/ .ivu-card-head {
position: relative;
padding: 0 14px;
height: 50px;
line-height: 50px;
&::before {
content: '';
width: 3px;
height: 50%;
top: 25%;
background: $theme_color;
position: absolute;
left: 0;
}
}
.cardExtra {
color: $theme_color;
cursor: pointer;
}
/deep/ .ivu-card-body {
padding: 0 !important;
display: none;
}
</style>

View File

@ -0,0 +1,110 @@
<template>
<div class="wrapper">
<empty v-if="list.length==0" />
<ul class="coupon-list" v-else>
<li v-for="(item, index) in list" class="coupon-item" :key="index">
<div class="c-left">
<div>
<span v-if="item.couponType === 'PRICE'" class="fontsize_12 global_color">¥<span class="price">{{item.price | unitPrice}}</span></span>
<span v-if="item.couponType === 'DISCOUNT'" class="fontsize_12 global_color"><span class="price">{{item.discount}}</span></span>
<span class="describe">{{item.consumeThreshold}}元可用</span>
</div>
<p>使用范围{{useScope(item.scopeType, item.storeName)}}</p>
<p>有效期{{item.endTime}}</p>
</div>
<b></b>
<a class="c-right" @click="go(item)">使</a>
<i class="circle-top"></i>
<i class="circle-bottom"></i>
</li>
</ul>
<Page :total="total" @on-change="changePageNum"
v-if="list.length && total > params.pageNumber"
class="pageration"
@on-page-size-change="changePageSize"
:page-size="params.pageSize"
show-sizer>
</Page>
<Spin v-if="loading" fix></Spin>
</div>
</template>
<script>
import { memberCouponList } from '@/api/member.js';
export default {
data () {
return {
loading: false, //
params: { //
pageNumber: 1,
pageSize: 10
},
total: 0, //
list: [] //
};
},
methods: {
getList () {
this.loading = true
memberCouponList(this.params).then(res => {
this.loading = false
if (res.success) {
this.list = res.result.records
this.total = res.result.total
}
})
},
go (item) { // 使
if (item.storeId !== 'platform') {
this.$router.push({path: '/merchant', query: {id: item.storeId}})
} else {
if (item.scopeType === 'PORTION_GOODS_CATEGORY') {
this.$router.push({path: '/goodsList', query: {categoryId: item.scopeId}})
} else {
this.$router.push({path: '/goodsList'})
}
}
},
changePageNum (val) {
this.params.pageNumber = val;
this.getList()
},
changePageSize (val) {
this.pageNumber = 1;
this.params.pageSize = val;
this.getList()
},
useScope (type, storeName) {
let shop = '平台';
let goods = '全部商品'
if (storeName !== 'platform') shop = storeName
switch (type) {
case 'ALL':
goods = '全部商品'
break;
case 'PORTION_GOODS':
goods = '部分商品'
break;
case 'PORTION_GOODS_CATEGORY':
goods = '部分分类商品'
break;
}
return `${shop}${goods}可用`
}
},
mounted () {
this.getList()
}
};
</script>
<style scoped lang="scss">
@import '../../assets/styles/coupon.scss';
.pageration{
text-align: right;
}
</style>

View File

@ -0,0 +1,323 @@
<template>
<div class="content-drawer">
<div v-if="title === '购物车'" class="cart-con">
<ul>
<li v-for="(goods,goodsIndex) in cartList" :key="goodsIndex">
<div>
<img :src="goods.goodsSku.thumbnail" width="90" height="90" alt="">
</div>
<div>
<p class="hover-color" @click="linkTo(`/goodsDetail?skuId=${goods.goodsSku.id}&goodsId=${goods.goodsSku.goodsId}`)">{{goods.goodsSku.goodsName}}</p>
<p class="price">{{goods.goodsSku.price | unitPrice('¥')}}<span>&nbsp; x{{goods.num}}</span></p>
</div>
<span class="del hover-color" @click="delGoods(goods.goodsSku.id)"></span>
</li>
</ul>
<Button size="large" class="mt_10" type="primary" @click="linkTo('/cart')" long>去购物车结算</Button>
</div>
<div v-else-if="title === ''" class="order-con">
<ul>
<li v-for="(order,orderIndex) in orderList" :key="orderIndex">
<div class="order-status"><span>{{filterOrderStatus(order.orderStatus)}}</span><span>{{order.createTime}}</span></div>
<div class="goods-img">
<img :src="img.image"
@click="linkTo(`/goodsDetail?skuId=${img.skuId}&goodsId=${img.goodsId}`)"
v-for="(img,imgIndex) in order.orderItems"
:key="imgIndex" width="40" height="40" alt="">
</div>
<div class="order-handle"><span>{{ order.flowPrice | unitPrice("¥") }}</span><span class="hover-color" @click="linkTo(`home/OrderDetail?sn=${order.sn}`)"></span></div>
</li>
</ul>
<Button type="primary" @click="linkTo('/home/MyOrder')" long>查看全部订单</Button>
</div>
<div v-else-if="title === ''" class="coupon-con">
<ul class="coupon-list">
<li v-for="(coupon, index) in couponList" class="coupon-item" :key="index">
<div class="c-left">
<div>
<span v-if="coupon.couponType === 'PRICE'" class="fontsize_12 global_color">¥<span class="price">{{coupon.price | unitPrice}}</span></span>
<span v-if="coupon.couponType === 'DISCOUNT'" class="fontsize_12 global_color"><span class="price">{{coupon.discount}}</span></span>
<span class="describe">{{coupon.consumeThreshold}}元可用</span>
</div>
<p>使用范围{{useScope(coupon.scopeType, coupon.storeName)}}</p>
<p>有效期{{coupon.endTime}}</p>
</div>
<b></b>
<a class="c-right" @click="receive(coupon)"></a>
<i class="circle-top"></i>
<i class="circle-bottom"></i>
</li>
</ul>
</div>
<div v-else-if="title === ''" class="tracks-con">
<ul>
<li v-for="(track,trackIndex) in tracksList" :key="trackIndex">
<img :src="track.thumbnail" :alt="track.thumbnail" @click="linkTo(`/goodsDetail?skuId=${track.id}&goodsId=${track.goodsId}`)" width="100" height="100">
<div @click="addToCart(track.id)"></div>
<p class="global_color">{{track.price | unitPrice('¥')}}</p>
</li>
</ul>
<div class="hover-color" style="text-align:center;" @click="linkTo('/home/MyTracks')">>></div>
</div>
<div v-else-if="title === ''" class="collect-con">
<ul>
<li v-for="(collect,collectIndex) in collectList" :key="collectIndex">
<img :src="collect.image" :alt="collect.image" @click="linkTo(`/goodsDetail?skuId=${collect.skuId}&goodsId=${collect.goodsId}`)" width="100" height="100">
<div @click="addToCart(collect.skuId)"></div>
<span class="del-icon" @click.stop="cancelCollect(collect.skuId)">
<Icon type="md-trash" />
</span>
<p class="global_color">{{collect.price | unitPrice('¥')}}</p>
</li>
</ul>
<div class="hover-color" style="text-align:center;" @click="linkTo('/home/Favorites')">>></div>
</div>
<Spin v-if="loading" fix></Spin>
</div>
</template>
<script>
import {cartGoodsAll, delCartGoods, addCartGoods, cartCount} from '@/api/cart.js'
import { getOrderList } from '@/api/order';
import {couponList, receiveCoupon, tracksList, collectList, cancelCollect} from '@/api/member.js'
export default {
name: 'Drawer',
props: {
title: {
default: '',
type: String
}
},
watch: {
title (val) {
switch (val) {
case '购物车':
this.getCartList()
break;
case '我的订单':
this.getOrderList()
break;
case '我的足迹':
this.getTracksList()
break;
case '优惠券':
this.getCouponList()
break;
case '我的收藏':
this.getCollectList()
break;
}
}
},
data () {
return {
loading: false, // spin
cartList: [], //
couponList: [], //
orderList: [], //
collectList: [], //
tracksList: [], //
orderStatusList: [ //
{
name: '未付款',
status: 'UNPAID'
},
{
name: '已付款',
status: 'PAID'
},
{
name: '待发货',
status: 'UNDELIVERED'
},
{
name: '已发货',
status: 'DELIVERED'
},
{
name: '已完成',
status: 'COMPLETED'
},
{
name: '待核验',
status: 'TAKE'
},
{
name: '已取消',
status: 'CANCELLED'
}
]
};
},
components: {},
mounted () {},
methods: {
getCartList () { //
this.loading = true
cartGoodsAll().then(res => {
this.loading = false
this.cartList = res.result.skuList
})
},
//
delGoods (id) {
delCartGoods({ skuIds: id }).then((res) => {
if (res.code === 200) {
this.$Message.success('删除成功');
this.getCartList();
cartCount().then(res => {
this.$store.commit('SET_CARTNUM', res.result)
this.Cookies.setItem('cartNum', res.result)
})
} else {
this.$Message.error(res.message);
}
});
},
filterOrderStatus (status) { //
const ob = this.orderStatusList.filter(e => { return e.status === status });
return ob[0].name
},
receive (item) { //
receiveCoupon(item.id).then(res => {
if (res.success) {
this.$Modal.confirm({
title: '领取优惠券',
content: '<p>优惠券领取成功,可到我的优惠券页面查看</p>',
okText: '我的优惠券',
cancelText: '立即使用',
onOk: () => {
this.$router.push('/home/Coupons')
},
onCancel: () => {
if (item.storeId !== 'platform') {
this.$router.push({path: '/merchant', query: {id: item.storeId}})
} else {
if (item.scopeType === 'PORTION_GOODS_CATEGORY') {
this.$router.push({path: '/goodsList', query: {categoryId: item.scopeId}})
} else {
this.$router.push({path: '/goodsList'})
}
}
}
});
}
})
},
useScope (type, storeName) { // 使
let shop = '平台';
let goods = '全部商品'
if (storeName !== 'platform') shop = storeName
switch (type) {
case 'ALL':
goods = '全部商品'
break;
case 'PORTION_GOODS':
goods = '部分商品'
break;
case 'PORTION_GOODS_CATEGORY':
goods = '部分分类商品'
break;
}
return `${shop}${goods}可用`
},
addToCart (id) { //
const params = {
num: 1,
skuId: id
}
this.loading = true;
addCartGoods(params).then(res => {
this.loading = false;
if (res.code === 200) {
this.$Message.success('商品已成功添加到购物车')
} else {
this.$Message.warning(res.message);
}
}).catch(() => { this.loading = false });
},
getCouponList () { //
// this.loading = true;
const params = {
pageNumber: 1,
pageSize: 10
}
couponList(params).then(res => {
this.loading = false
if (res.success) {
this.couponList = res.result.records
}
}).catch(() => { this.loading = false })
},
getOrderList () { //
this.loading = true
const params = {
pageNumber: 1,
pageSize: 10,
tag: 'ALL'
}
getOrderList(params).then(res => {
this.loading = false
if (res.success) {
this.orderList = res.result.records;
}
});
},
getCollectList () { //
const params = {
pageNumber: 1,
pageSize: 10,
type: 'GOODS'
}
this.loading = true
collectList(params).then(res => {
this.loading = false
this.collectList = res.result.records
})
},
cancelCollect (id) { //
cancelCollect('GOODS', id).then(res => {
if (res.success) {
this.$Message.success('取消收藏成功')
this.getCollectList();
}
})
},
getTracksList () { //
const params = {
pageNumber: 1,
pageSize: 20
}
this.loading = true
tracksList(params).then(res => {
this.tracksList = res.result
this.loading = false
}).catch(() => { this.loading = false })
}
}
};
</script>
<style scoped lang="scss">
@import '../../assets/styles/coupon.scss';
@import './drawer.scss';
.coupon-item{
overflow: hidden;
background-color: #fff;
height: 120px;
.c-left{
padding: 15px;
}
.c-right{
width: 38px;
padding: 13px;
font-size: 14px;
}
i{
right: 30px;
background-color: #eee;
}
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<div>
<div class="wrapper" :style="{right:handleDrawer ? '300px' : '0px'}">
<div class="barItem" @mouseenter="showCartNum(item)" @click="clickBar(item)" v-for="(item,index) in resetConfig.menuList" :key="index">
<Tooltip placement="left" :content="item.title">
<Icon size="20" :type="item.icon"/>
<p class="barTitle" v-if="item.titleShow"> {{item.title}}</p>
<div class="circle" v-if="item.title === '购物车'">
{{cartNum < 100 ? cartNum : 99}}
</div>
</Tooltip>
</div>
</div>
<Drawer width="300" class="popup" :title="drawerData.title" :mask="resetConfig.mask" :closable="resetConfig.closable"
v-model="handleDrawer">
<drawerPage :title="drawerData.title" />
</Drawer>
</div>
</template>
<script>
import Storage from '@/plugins/storage.js';
import Configuration from './config';
import drawerPage from './Drawer'
import {cartCount} from '@/api/cart.js'
export default {
name: 'Main',
data () {
return {
resetConfig: Configuration, //
handleDrawer: false, //
drawerData: '' //
}
},
components: {drawerPage},
computed: {
userInfo () {
return Storage.getItem('userInfo');
},
cartNum () {
return this.$store.state.cartNum
}
},
methods: {
showCartNum (item) {
if (this.userInfo && item.title === '购物车') {
this.getCartList()
}
},
clickBar (val) {
if (!this.userInfo) {
this.$Modal.confirm({
title: '请登录',
content: '<p>请登录后执行此操作</p>',
okText: '立即登录',
cancelText: '继续浏览',
onOk: () => {
this.$router.push({
path: '/login',
query: {
rePath: this.$router.history.current.path,
query: JSON.stringify(this.$router.history.current.query)
}
});
}
});
} else {
if (val.display) {
this.handleDrawer = true
this.drawerData = val
} else {
this.handleDrawer = false
switch (val.title) {
case '会员中心':
this.openBlank('/home')
break;
case '我的资产':
this.openBlank('/home/MoneyManagement')
break;
}
}
}
},
openBlank (path) {
let routerUrl = this.$router.resolve({
path: path
})
window.open(routerUrl.href, '_blank')
},
getCartList () { //
cartCount().then(res => {
this.$store.commit('SET_CARTNUM', res.result)
this.Cookies.setItem('cartNum', res.result)
})
}
}
}
</script>
<style scoped lang="scss">
.wrapper {
background-color: #000!important;
}
.barItem {
text-align: center;
padding: 13px 0;
cursor: pointer;
color: #fff;
&:hover{
background-color: $theme_color;
.circle{
color: $theme_color;
background-color: #fff;
}
}
}
.barTitle {
writing-mode: vertical-lr;
letter-spacing: 2px;
padding: 4px 0;
}
.circle {
width: 20px;
height: 20px;
border-radius: 50%;
color: #fff;
background: $theme_color;
}
.wrapper {
width: 40px;
position: fixed;
transition: .35s;
height: 100%;
z-index: 9999;
background: $dark_background_color;
top: 0;
display: flex;
justify-content: center;
flex-direction: column;
}
/deep/.popup .ivu-drawer-body{
padding: 0!important;
background-color: #eee;
}
/deep/.popup .ivu-drawer-wrap{
z-index: 3001;
}
</style>

View File

@ -0,0 +1,42 @@
# 右侧侧边栏组件
> 本组件依赖于iview的组件基础上进行封装
>项目结构
>* Main -- 组件用于挂在右侧的横栏
>* drawer -- 右侧横栏的内容
>* config -- 用于设置大小
#### config设置
```
/**
menuList // 组件的menu
display //是否显示此menu
badge //显示徽标数
titleShow //是否显示title
*/
//实例代码
width : 50, //bar的大小
menuList:[
{
icon
}
]
```
> 账户信息
> 购物车
> 我的订单
> 优惠券
> 我的资产
> 我的足迹
> 我的收藏
> 邮箱订阅
## 如何使用
1.

View File

@ -0,0 +1,63 @@
const config = {
closable: true, // 是否显示右上角关闭按钮
mask: true, // 是否显示遮罩层
menuList: [{
icon: 'md-person', // menu的icon
title: '会员中心', // menu的标题
titleShow: false,
path: '', // menu点击的路径
display: false // 是否显示此menu
},
{
icon: 'ios-cart', // menu的icon
title: '购物车', // menu的标题
path: '', // menu点击的路径
display: true, // 是否显示此menu
badge: 12,
titleShow: true
},
{
icon: 'md-clipboard', // menu的icon
title: '我的订单', // menu的标题
path: '', // menu点击的路径
display: true, // 是否显示此menu
badge: '',
titleShow: false
},
{
icon: 'md-pricetag', // menu的icon
title: '优惠券', // menu的标题
path: '', // menu点击的路径
display: true, // 是否显示此menu
badge: '',
titleShow: false
},
{
icon: 'logo-usd', // menu的icon
title: '我的资产', // menu的标题
path: '', // menu点击的路径
display: false, // 是否显示此menu
badge: '',
titleShow: false
},
{
icon: 'ios-eye', // menu的icon
title: '我的足迹', // menu的标题
path: '', // menu点击的路径
display: true, // 是否显示此menu
badge: '',
titleShow: false
},
{
icon: 'md-star', // menu的icon
title: '我的收藏', // menu的标题
path: '', // menu点击的路径
display: true, // 是否显示此menu
badge: '',
titleShow: false
}
]
}
export default config

View File

@ -0,0 +1,130 @@
.content-drawer {
height: 100%;
font-size: 12px;
}
//
.cart-con{
position: relative;
background: #fff;
height: 100%;
ul>li{
font-size: 12px;
border-bottom: 1px dashed #999;
margin: 0 10px;
display: flex;
padding: 10px 0;
align-items: center;
position: relative;
p{margin-bottom: 10px;}
.del{
position: absolute;
right: 10px;
bottom: 30px;
}
.price {
color: $theme_color;
span{color: #999;}
}
&:last-child{border: none;}
}
}
//
.order-con{
ul>li {
margin: 10px;
background-color: #fff;
.order-status {
display: flex;
background-color: #666;
border-radius: 3px 3px 0 0;
color: #fff;
justify-content: space-between;
padding: 0 10px;
}
.goods-img {
padding-left: 10px;
padding-top: 10px;
img{
border: 1px solid #eee;
margin-right: 10px;
&:hover{
cursor: pointer;
}
}
}
.order-handle{
display: flex;
justify-content: space-between;
padding:5px 10px;
border-top: 1px solid #eee;
span:nth-child(1){
color: $theme_color;
}
}
}
}
//
.coupon-con{
margin-top: 10px;
}
//
.tracks-con,.collect-con{
ul{
display: flex;
flex-wrap: wrap;
padding: 10px;
}
li {
background-color: #fff;
margin: 10px;
width: 120px;
position: relative;
text-align: center;
&:hover{
div,.del-icon{
display: block;
}
}
img{
cursor: pointer;
}
div{
display: none;
position: absolute;
bottom: 18px;
width: 100%;
background-color: #666;
color: #fff;
&:hover{
background-color: $theme_color;
cursor: pointer;
}
}
.del-icon{
display: none;
font-size: 20px;
position: absolute;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
right: 0;
top: 0;
cursor: pointer;
color: $theme_color;
}
}
}
//
.collect-con{
}

View File

@ -0,0 +1,45 @@
<template>
<div class="empty">
<img
class="empty-img"
:style="{ width: _Size + 'px' }"
src="../../assets/images/empty.png"
alt=""
/>
<p v-if="_Title">{{ _Title }}</p>
</div>
</template>
<script>
export default {
name: 'Main',
data () {
return {
};
},
props: {
_Title: { //
type: null,
default: '暂无更多'
},
_Size: { //
type: Number,
default: 150
}
}
};
</script>
<style scoped lang="scss">
.empty {
margin: 30px 0;
text-align: center;
width: 100%;
}
p {
cursor: pointer;
@include sub_color($light_sub_color);
}
</style>

View File

@ -0,0 +1,10 @@
# 空状态封装
```
// _Title
<empty></empty> //默认显示
q
<empty _Title='暂无更多了' ></empty> //自定义返回标题
```

View File

@ -0,0 +1,189 @@
<template>
<div>
<footer class="footer">
<div class="clearfix"></div>
<div class="icon-row">
<div class="footer-icon">
<h5 class="footer-icon-child"></h5>
<span class="footer-icon-text">品类齐全轻松购物</span>
</div>
<div class="footer-icon">
<h5 class="footer-icon-child footer-icon-child-2"></h5>
<span class="footer-icon-text">多仓直发极速配送</span>
</div>
<div class="footer-icon">
<h5 class="footer-icon-child footer-icon-child-3"></h5>
<span class="footer-icon-text">正品行货精致服务</span>
</div>
<div class="footer-icon">
<h5 class="footer-icon-child footer-icon-child-4"></h5>
<span class="footer-icon-text">天天低价畅选无忧</span>
</div>
</div>
<div class="service-intro">
<div class="servece-type">
<div class="servece-type-info" v-for="(guide, index) in guideArr" :key="index">
<ul>
<li v-for="(item, index) in guide" :key="index" @click="goArticle">{{item}}</li>
</ul>
</div>
</div>
<div class="clearfix"></div>
<div class="friend-link">
<div class="friend-link-item">
<ul>
<li v-for="(link, index) in moreLink" :key="index" @click="goArticle">
<span class="link-item" :class="{'link-last-item': index === 4}">{{link}}</span>
</li>
</ul>
</div>
</div>
<div class="clearfix"></div>
<div class="copyright">
<p>Copyright © LILI</p>
</div>
</div>
</footer>
</div>
</template>
<script>
export default {
name: 'Footer',
data () {
return {
guideArr: [ //
[ '购物指南', '购物流程', '会员介绍', '生活旅行', '常见问题', '大家电', '联系客服' ],
[ '配送方式', '上门自提', '211限时达', '配送服务查询', '收取标准', '海外配送' ],
[ '支付方式', '货到付款', '在线支付', '分期付款', '邮局汇款', '公司转账' ],
[ '售后服务', '售后政策', '价格保护', '退款说明', '返修/退换货', '取消订单' ]
],
moreLink: ['关于我们', '联系我们', '联系客服', '商家帮助', '隐私政策'] //
};
},
methods: {
goArticle () { //
let routeUrl = this.$router.resolve({
path: '/article'
})
window.open(routeUrl.href, '_blank')
}
}
};
</script>
<style scoped lang="scss">
/*****************************底 部 开 始*****************************/
.footer {
width: 100%;
height: 450px;
padding-top: 30px;
@include background_color($light_background_color);
}
.icon-row {
margin: 15px auto;
padding-top: 8px;
width: 1000px;
height: 64px;
}
.footer-icon {
margin-left: 17px;
margin-right: 17px;
float: left;
}
.footer-icon-child {
margin-top: 10px;
overflow: hidden;
position: absolute;
width: 36px;
height: 42px;
background-image: url("../../assets/images/footer/ico_service.png");
text-indent: -999px;
}
.footer-icon-child-2 {
background-position: 0 -43px;
}
.footer-icon-child-3 {
background-position: 0 -86px;
}
.footer-icon-child-4 {
background-position: 0 -129px;
}
.footer-icon-text{
margin-left: 45px;
font-size: 18px;
font-weight: bold;
line-height: 64px;
}
.service-intro {
width: 100%;
border-top: 1px solid $border_color;
}
.servece-type {
margin: 15px auto;
height: 200px;
width: 800px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.servece-type-info ul {
list-style: none;
}
.servece-type-info li {
font-size: 14px;
cursor: pointer;
line-height: 26px;
}
.servece-type-info li:first-child {
font-size: 16px;
line-height: 28px;
font-weight: bold;
}
.friend-link {
display: flex;
align-items: center;
width: 908px;
height: 30px;
margin: 0px auto;
border-top: 1px solid $border_color;
}
.friend-link-item {
margin: 0px auto;
}
.friend-link-item ul {
list-style: none;
}
.friend-link-item li {
padding: 5px 0px;
float: left;
}
.link-item {
padding: 0px 8px;
cursor: pointer;
border-right: 1px solid $border_color;
}
.link-last-item {
border: none;
}
.copyright {
width: 100%;
line-height: 30px;
text-align: center;
}
.copyright a{
color: #232323;
font-size: 20px;
}
.footer-icon-text{
@include title_color($light_title_color)
}
.copyright,.friend-link,.servece-type-info {
@include sub_color($light_sub_color)
}
/*****************************底 部 结 束*****************************/
</style>

View File

@ -0,0 +1,54 @@
// 全局组件配置
import empty from './empty/Main' // 空状态组件
import drawer from './drawer/Main' // 右侧bar
import Header from '@/components/header/Header'; // 头部组件
import FixedTopPage from '@/components/advertising/FixedTop'; // 顶部广告
import Footer from '@/components/footer/Footer'; // 底部栏
import Search from '@/components/Search' // 搜索框
import card from '@/components/card' // 个人中心 卡片
import cateNav from '@/components/nav/cateNav' // 个人中心 卡片
empty.install = function (Vue) {
Vue.component('empty', empty);
};
drawer.install = function (Vue) {
Vue.component('drawer', drawer);
};
Header.install = function (Vue) {
Vue.component('BaseHeader', Header);
};
FixedTopPage.install = function (Vue) {
Vue.component('FixedTopPage', FixedTopPage);
};
Footer.install = function (Vue) {
Vue.component('BaseFooter', Footer);
};
Search.install = function (Vue) {
Vue.component('Search', Search);
};
card.install = function (Vue) {
Vue.component('card', card)
}
cateNav.install = function (Vue) {
Vue.component('cateNav', cateNav)
}
// 引用本js中所有的组件
export function InstallAll (Vue) {
Vue.use(empty)
Vue.use(drawer)
Vue.use(Header)
Vue.use(FixedTopPage)
Vue.use(Footer)
Vue.use(Search)
Vue.use(card)
Vue.use(cateNav)
}

View File

@ -0,0 +1,123 @@
<template>
<div>
<div class="wrapper" v-if="type === 'goodsDetail'">
<div class="wr-l"><Icon size="23" type="ios-alarm-outline" /> 秒杀活动</div>
<div class="count-down" v-if="end === ''">
<p>倒计时</p><span>{{ hours }}</span><span>{{ minutes }}</span><span>{{ seconds }}</span>
</div>
<div v-else>{{end}}</div>
</div>
<span v-else class="cart-promotion">
<span v-if="end === ''"><span>{{ hours }}</span> : <span>{{ minutes }}</span> : <span>{{ seconds }}</span></span>
<span v-else></span>
</span>
</div>
</template>
<script>
export default {
props: {
time: { //
default: 1718977559428
},
type: {
default: 'goodsDetail', // goodsDetailcart
type: String
}
},
data () {
return {
end: '', //
hours: '', //
minutes: '', //
seconds: '', //
interval: '' //
};
},
mounted () {
this.init()
},
methods: {
countDown (val) {
function addZero (i) {
return i < 10 ? '0' + i : i + '';
}
var nowtime = new Date();
var endtime = new Date(val);
var lefttime = parseInt((endtime.getTime() - nowtime.getTime()) / 1000);
var h = parseInt((lefttime / (60 * 60)) % 24);
var m = parseInt((lefttime / 60) % 60);
var s = parseInt(lefttime % 60);
h = addZero(h);
m = addZero(m);
s = addZero(s);
this.hours = h;
this.minutes = m
this.seconds = s;
if (lefttime <= 0) {
this.end = `活动已结束`;
clearInterval(this.interval)
}
},
init () {
this.interval = setInterval((item) => {
this.countDown(this.time);
}, 1000);
}
}
};
</script>
<style scoped lang="scss">
.cart-promotion{
font-size: 13px;
color: #999;
margin-left: 10px;
}
.wrapper {
background-image: linear-gradient(266deg, #ff0b33, #ff4257, #ff5f7c, #fa78a2);
height: 32px;
color: #fff;
line-height: 32px;
font-size: 16px;
padding: 0 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.wr-r{
font-size: 13px;
}
.count-down {
margin-right: -20px;
p{
float: left;
line-height: 20px;
}
> span {
position: relative;
float: left;
width: 20px;
height: 20px;
text-align: center;
background-color: #2f3430;
margin-right: 20px;
color: white;
font-size: 14px;
line-height: 20px;
&::after {
content: ":";
display: block;
position: absolute;
right: -20px;
font-weight: bolder;
font-size: 14px;
width: 20px;
height: 100%;
top: 0;
}
}
> span:last-child::after {
content: "";
}
}
</style>

View File

@ -0,0 +1,658 @@
<template>
<div class="wrapper">
<div class="item-detail-show">
<!-- 详情左侧展示数据图片收藏举报 -->
<div class="item-detail-left">
<!-- 大图放大镜 -->
<div class="item-detail-big-img">
<pic-zoom :url="imgList[imgIndex].url" :scale="2"></pic-zoom>
</div>
<div class="item-detail-img-row">
<div
class="item-detail-img-small"
@mouseover="imgIndex = index"
v-for="(item, index) in imgList"
:key="index"
>
<img :src="item.url" />
</div>
</div>
<div class="goodsConfig mt_10">
<span @click="collect" ><Icon type="ios-heart" :color="isCollected ? '#ed3f14' : '#666'" />{{isCollected?'已收藏':'收藏'}}</span>
<!-- <span>举报</span> -->
</div>
</div>
<!-- 右侧商品信息活动信息操作展示 -->
<div class="item-detail-right">
<div class="item-detail-title">
<p>
{{ skuDetail.goodsName }}
</p>
</div>
<!-- 限时秒杀 -->
<Promotion v-if="promotionMap['SECKILL']" :time="promotionMap['SECKILL'].endTime"></Promotion>
<!-- 商品详细 价格优惠券促销 -->
<div class="item-detail-price-row">
<div class="item-price-left">
<!-- 商品原价 -->
<div class="item-price-row" v-if="!skuDetail.promotionPrice">
<p>
<span class="item-price-title"> &nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="item-price">{{skuDetail.price | unitPrice("¥")}}</span>
</p>
</div>
<!-- 秒杀价格 -->
<div class="item-price-row" v-if="skuDetail.promotionPrice">
<p>
<span class="item-price-title" v-if="promotionMap['SECKILL']"> &nbsp;&nbsp;</span>
<span class="item-price">{{skuDetail.promotionPrice | unitPrice("¥")}}</span>
<span class="item-price-old">{{skuDetail.price | unitPrice("¥")}}</span>
</p>
</div>
<!-- 优惠券展示 -->
<div class="item-price-row" v-if="promotionMap['COUPON'].length">
<p>
<span class="item-price-title"> </span>
<span
class="item-coupon"
v-for="(item, index) in promotionMap['COUPON']"
:key="index"
@click="receiveCoupon(item.id)"
>
<span v-if="item.couponType == 'PRICE'">{{ item.consumeThreshold }}{{item.price}}</span>
<span v-if="item.couponType == 'DISCOUNT'">{{ item.consumeThreshold }}{{item.couponDiscount}}</span>
</span>
</p>
</div>
<!-- 满减展示 -->
<div class="item-price-row" v-if="promotionMap['FULL_DISCOUNT']">
<p>
<span class="item-price-title">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>
<span class="item-promotion">满减</span>
<span class="item-desc-pintuan" v-if="promotionMap['FULL_DISCOUNT'].fullMinus">{{ promotionMap['FULL_DISCOUNT'].fullMoney }}{{ promotionMap['FULL_DISCOUNT'].fullMinus}}</span>
<span class="item-desc-pintuan" v-if="promotionMap['FULL_DISCOUNT'].fullRate">{{ promotionMap['FULL_DISCOUNT'].fullMoney }}{{ promotionMap['FULL_DISCOUNT'].fullRate}}</span>
</p>
</div>
</div>
<div class="item-price-right">
<div class="item-remarks-sum">
<p>累计评价</p>
<p>
<span class="item-remarks-num">{{ skuDetail.commentNum || 0 }} </span>
</p>
</div>
</div>
</div>
<!-- 选择颜色 -->
<div class="item-select" v-for="(sku, index) in formatList" :key="sku.id">
<div class="item-select-title">
<p>{{ sku.name }}</p>
</div>
<div class="item-select-column">
<div class="item-select-row" v-for="(item) in sku.values" :key="item.id">
<div class="item-select-box" @click="select(index, sku.id, item.id)"
:class="{ 'item-select-box-active': item.id === currentSelceted[index] }"
>
<div class="item-select-intro">
<p>{{ item.value }}</p>
</div>
</div>
</div>
</div>
</div>
<br />
<div class="add-buy-car-box">
<div class="item-select">
<div class="item-select-title">
<p>数量</p>
</div>
<div class="item-select-row">
<InputNumber :min="1" :disabled="skuDetail.quantity === 0" v-model="count"></InputNumber>
<span class="inventory"> 库存{{skuDetail.quantity}}</span>
</div>
</div>
<div class="item-select">
<div class="item-select-title">
<p>重量</p>
</div>
<div class="item-select-row">
<span class="inventory"> {{skuDetail.weight}}kg</span>
</div>
</div>
<div class="add-buy-car">
<Button type="error" :loading="loading" :disabled="skuDetail.quantity === 0" @click="addShoppingCartBtn"></Button>
<Button type="warning" :loading="loading1" :disabled="skuDetail.quantity === 0" @click="buyNow"></Button>
</div>
</div>
</div>
<!-- <div class="item-detail-see">
<Divider>更多推荐</Divider>
<Row>
<Col :span="24" class="see-Item">
<img class="see-Img" src="https://demo.dscmall.cn/storage/images/201703/thumb_img/0_thumb_G_1489099128797.jpg" alt="" />
<p>
名龙堂i7 6700升7700 GTX1060 6G台式电脑主机DIY游戏组装整机
升6GB独显 送正版WIN10 一年上门
</p>
<p class="global_color">2500.00</p>
</Col>
<Col :span="24" class="see-Item">
<img
class="see-Img"
src="https://demo.dscmall.cn/storage/images/201703/thumb_img/0_thumb_G_1489099128797.jpg"
alt=""
/>
<p>
名龙堂i7 6700升7700 GTX1060 6G台式电脑主机DIY游戏组装整机
升6GB独显 送正版WIN10 一年上门
</p>
<p class="global_color">2500.00</p>
</Col>
</Row>
</div> -->
</div>
</div>
</template>
<script>
import Promotion from './Promotion.vue';
import PicZoom from 'vue-piczoom'; // https://github.com/826327700/vue-piczoom
import { collectGoods, isCollection, receiveCoupon, cancelCollect } from '@/api/member.js';
import { addCartGoods } from '@/api/cart.js';
export default {
name: 'ShowGoods',
props: {
detail: {
type: Object,
default: null
}
},
data () {
return {
count: 1, //
imgIndex: 0, //
currentSelceted: [], // sku
imgList: this.detail.data.specList[0].specImage, //
skuDetail: this.detail.data, // sku
goodsSpecList: this.detail.specs, // spec
promotionMap: { //
SECKILL: null,
FULL_DISCOUNT: null,
COUPON: []
}, //
formatList: [], //
loading: false, // loading
loading1: false, // loading
isCollected: false //
};
},
components: {
PicZoom,
Promotion
},
methods: {
select (index, id, valueId) { //
this.$set(this.currentSelceted, index, valueId);
let selectedSkuId = this.goodsSpecList.find((i) => {
let matched = true;
let specValues = i.specValues.filter((j) => j.specName !== 'images');
for (let n = 0; n < specValues.length; n++) {
if (specValues[n].specValueId !== this.currentSelceted[n]) {
matched = false;
return;
}
}
if (matched) {
return i;
}
});
console.log(selectedSkuId);
this.$router.push({
path: '/goodsDetail',
query: { skuId: selectedSkuId.skuId, goodsId: this.skuDetail.goodsId }
});
},
addShoppingCartBtn () { //
const params = {
num: this.count,
skuId: this.skuDetail.id
};
this.loading = true;
addCartGoods(params).then(res => {
this.loading = false;
if (res.code === 200) {
this.$router.push({path: '/shoppingCart', query: {detail: this.skuDetail, count: this.count}});
} else {
this.$Message.warning(res.message);
}
});
},
buyNow () { //
const params = {
num: this.count,
skuId: this.skuDetail.id,
cartType: 'BUY_NOW'
};
this.loading1 = true;
addCartGoods(params).then(res => {
this.loading1 = false;
if (res.code === 200) {
this.$router.push({path: '/pay', query: {way: 'BUY_NOW'}});
} else {
this.$Message.warning(res.message);
}
});
},
async collect () { //
if (this.isCollected) {
let cancel = await cancelCollect('GOODS', this.skuDetail.id)
if (cancel.success) {
this.$Message.success('取消收藏成功')
this.isCollected = false
}
} else {
let collect = await collectGoods('GOODS', this.skuDetail.id);
if (collect.code === 200) {
this.isCollected = true;
this.$Message.success('收藏商品成功,可以前往个人中心我的收藏查看');
}
}
},
formatSku (list) {
//
let arr = [{}];
list.forEach((item, index) => {
item.specValues.forEach((spec, specIndex) => {
let id = spec.specNameId;
let name = spec.specName;
let values = {
id: spec.specValueId,
value: spec.specValue,
quantity: item.quantity
};
if (name === 'images') {
return;
}
arr.forEach((arrItem, arrIndex) => {
if (
arrItem.name === name &&
arrItem.values &&
!arrItem.values.find((i) => i.id === values.id)
) {
arrItem.values.push(values);
}
let keys = arr.map((key) => {
return key.name;
});
if (!keys.includes(name)) {
arr.push({
id: id,
name: name,
values: [values]
});
}
});
});
});
arr.shift();
this.formatList = arr;
let cur = list.filter((i) => i.skuId === this.$route.query.skuId)[0];
if (cur) {
cur.specValues.filter((i) => i.specName !== 'images')
.forEach((value, _index) => {
this.currentSelceted[_index] = value.specValueId;
});
}
this.skuList = list;
},
receiveCoupon (id) { //
receiveCoupon(id).then(res => {
if (res.success) {
this.$Message.success('优惠券领取成功')
} else {
this.$Message.warning(res.message)
}
})
},
promotion () { //
let keysArr = Object.keys(this.detail.promotionMap);
if (keysArr.length === 0) return false;
for (let i = 0; i < keysArr.length; i++) {
let key = keysArr[i].split('-')[0]
if (key === 'COUPON') {
this.promotionMap[key].push(this.detail.promotionMap[keysArr[i]])
} else {
this.promotionMap[key] = this.detail.promotionMap[keysArr[i]]
}
}
}
},
mounted () {
if (this.Cookies.getItem('userInfo')) {
isCollection('GOODS', this.skuDetail.id).then(res => {
if (res.success && res.result) {
this.isCollected = true;
}
})
}
this.formatSku(this.goodsSpecList);
this.promotion()
document.title = this.skuDetail.goodsName
}
};
</script>
<style scoped lang="scss">
/******************商品图片及购买详情开始******************/
.item-detail-see {
width: 175px;
margin-left: 30px;
}
.inventory {
padding-left: 4px;
@include sub_color($light_sub_color);
}
.global_color {
text-align: center;
}
.see-Img {
width: 100%;
height: 175px;
}
.see-Item {
> p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.Report {
color: $theme_color !important;
}
.wrapper {
@include white_background_color();
}
.item-sale-flex {
width: 29%;
padding: 0 3%;
}
.item-sale {
margin: 10px 0;
> h3 {
width: 13%;
text-align: center;
font-size: 20px;
line-height: 60px;
box-sizing: border-box;
border-right: 1px solid $border_color;
}
height: 60px;
justify-content: center;
align-items: center;
display: flex;
width: 1200px;
margin: 0 auto;
margin-bottom: 10px;
border: 1px solid $border_color;
background: #f7f7f7;
}
.item-detail-show {
width: 1200px;
margin: 0 auto;
padding: 30px;
display: flex;
flex-direction: row;
}
.item-detail-left {
width: 350px;
margin-right: 30px;
}
.item-detail-big-img {
width: 350px;
height: 350px;
box-shadow: 0px 0px 8px $border_color;
cursor: pointer;
}
.item-detail-big-img img {
width: 100%;
}
.item-detail-img-row {
margin-top: 15px;
display: flex;
}
.item-detail-img-small {
width: 68px;
height: 68px;
box-shadow: 0px 0px 8px #ccc;
cursor: pointer;
margin-left: 5px;
}
.item-detail-img-small img {
height: 100%;
width: 100%;
}
/*商品选购详情*/
.item-detail-right {
flex: 1;
display: flex;
flex-direction: column;
}
.item-detail-title p {
@include content_color($light_content_color);
font-weight: bold;
font-size: 20px;
padding: 8px 0;
}
.item-detail-express {
font-size: 14px;
padding: 2px 3px;
border-radius: 3px;
background-color: $theme_color;
color: #fff;
}
/*商品标签*/
.item-detail-tag {
padding: 8px 0;
font-size: 12px;
color: $theme_color;
}
/*价格详情等*/
.item-detail-price-row {
padding: 10px;
display: flex;
// width: 555px;
flex-direction: row;
justify-content: space-between;
// @include background_color($light_background_color);
background: url("../../assets/images/goodsDetail/price-bg.png");
}
.item-price-left {
display: flex;
flex-direction: column;
}
.item-price-title {
color: #999999;
font-size: 14px;
margin-right: 15px;
}
.item-price-row {
margin: 5px 0px;
}
.item-price {
color: $theme_color;
font-size: 20px;
cursor: pointer;
}
.item-price-old {
color: gray;
text-decoration: line-through;
font-size: 14px;
margin-left: 5px;
}
.item-coupon {
margin-right: 5px;
padding: 3px;
color: $theme_color;
font-size: 12px;
background-color: #ffdedf;
border: 1px dotted $theme_color;
cursor: pointer;
}
.item-promotion {
margin-right: 5px;
padding: 3px;
color: $theme_color;
font-size: 12px;
border: 1px solid $theme_color;
}
.item-remarks-sum {
padding-left: 8px;
border-left: 1px solid $border_color;
}
.item-remarks-sum p {
color: #999999;
font-size: 12px;
line-height: 10px;
text-align: center;
}
.item-remarks-num {
line-height: 18px;
color: #005eb7;
}
.item-select {
display: flex;
flex-direction: row;
margin-top: 15px;
}
.item-select-title {
@include content_color($light_content_color);
font-size: 14px;
margin-right: 15px;
width: 60px;
}
.item-select-column {
display: flex;
flex-wrap: wrap;
flex: 1;
}
.item-select-row {
// display: flex;
// flex-direction: row;
// flex-wrap: wrap;
margin-bottom: 8px;
}
.item-select-box {
display: flex;
flex-direction: row;
align-items: center;
}
.item-select-img {
width: 36px;
}
.item-select-box {
padding: 5px;
margin-right: 8px;
@include background_color($light_background_color);
border: 0.5px solid $border_color;
cursor: pointer;
@include content_color($light_content_color);
}
.item-select-box:hover {
border: 0.5px solid $theme_color;
}
.item-select-box-active {
border: 0.5px solid $theme_color;
}
.item-select-box-disabled {
background-color: gray;
}
.item-select-img img {
width: 100%;
}
.item-select-intro p {
margin: 0px;
padding: 5px;
}
.item-select-class {
padding: 5px;
margin-right: 8px;
@include sub_background_color($light_background_color);
border: 0.5px solid #ccc;
cursor: pointer;
}
.item-select-class:hover {
border: 0.5px solid $theme_color;
}
.add-buy-car-box {
width: 100%;
margin-top: 15px;
border-top: 1px dotted $border_color;
}
.add-buy-car {
margin-top: 15px;
}
.goodsConfig {
display: flex;
justify-content: space-between;
> span {
padding-right: 10px;
&:hover{
cursor: pointer;
color: $theme_color;
}
}
}
/******************商品图片及购买详情结束******************/
</style>

View File

@ -0,0 +1,489 @@
<template>
<div>
<div class="item-intro-show">
<!-- <div class="item-intro-recommend">
<div class="item-recommend-title">
<p>店铺热销</p>
</div>
<div class="item-intro-recommend-column">
<div class="item-recommend-column" v-for="(item, index) in hotList" :key="index">
<div class="item-recommend-img">
<img :src="item.img" alt="">
</div>
<div class="item-recommend-intro">
<span>
<span class="item-recommend-top-num">{{index + 1}}</span> 热销{{item.sale}}</span>
<span class="item-recommend-price">{{item.price | unitPrice}}</span>
</div>
</div>
</div>
</div> -->
<div class="item-intro-detail" ref="itemIntroDetail">
<div class="item-intro-nav item-tabs">
<Tabs :animated="false" @on-click="tabClick">
<TabPane label="商品介绍">
<div class="item-intro-img" ref="itemIntroGoods">
<div v-html="skuDetail.intro" v-if="skuDetail.intro"></div>
<div v-else style="margin:20px;">暂无商品介绍</div>
</div>
</TabPane>
<TabPane label="商品评价">
<div class="remarks-container" ref="itemGoodsComment">
<div class="remarks-analyse-box">
<div class="remarks-analyse-goods">
<i-circle :percent="skuDetail.grade || 100" stroke-color="#5cb85c">
<span class="remarks-analyse-num">{{skuDetail.grade || 100}}%</span>
<p class="remarks-analyse-title">好评率</p>
</i-circle>
</div>
</div>
<div class="remarks-bar">
<span @click="searchByGrade('')" :class="{selectedBar: commentParams.grade === ''}">全部({{commentTypeNum.all}})</span>
<span @click="searchByGrade('GOOD')" :class="{selectedBar: commentParams.grade === 'GOOD'}">好评({{commentTypeNum.good}})</span>
<span @click="searchByGrade('MODERATE')" :class="{selectedBar: commentParams.grade === 'MODERATE'}">中评({{commentTypeNum.moderate}})</span>
<span @click="searchByGrade('WORSE')" :class="{selectedBar: commentParams.grade === 'WORSE'}">差评({{commentTypeNum.worse}})</span>
</div>
<div style="text-align: center;margin-top: 20px;" v-if="commentList.length === 0">
暂无评价数据
</div>
<div class="remarks-box" v-for="(item,index) in commentList" :key="index" v-else>
<div class="remarks-user">
<Avatar :src="item.memberProfile" />
<span class="remarks-user-name">{{item.memberName | secrecyMobile}}</span>
</div>
<div class="remarks-content-box">
<p>
<Rate disabled :value="Number(item.descriptionScore)" allow-half class="remarks-star"></Rate>
</p>
<p class="remarks-content">{{item.content}}</p>
<div class="comment-img" v-if="item.haveImage">
<div v-for="(img, imgIndex) in item.image.split(',')"
@click="previewImg(img, item)"
:class="{borderColor:img === item.previewImg}"
:key="imgIndex">
<img :src="img" alt="">
</div>
</div>
<div class="preview-img" v-if="item.previewImg" @click.prevent="hidePreviewImg(item)">
<div>
<span @click.stop="rotatePreviewImg(0, item)"><Icon type="md-refresh" />左转</span>
<span @click.stop="rotatePreviewImg(1, item)"><Icon type="md-refresh" />右转</span>
</div>
<img :src="item.previewImg" :style="{transform:`rotate(${item.deg}deg)`}" width="198" alt="">
</div>
<p class="remarks-sub">
<span class="remarks-item">{{item.goodsName}}</span>
<span class="remarks-time">{{item.createTime}}</span>
</p>
</div>
</div>
<div class="remarks-page">
<Page :total="commentTotal" size="small"
@on-change="changePageNum"
@on-page-size-change="changePageSize"
:page-size="commentParams.pageSize"
></Page>
</div>
</div>
</TabPane>
<!-- <TabPane label="商品问答">
<ShowGoodsQuestion/>
</TabPane> -->
</Tabs>
</div>
</div>
</div>
</div>
</template>
<script>
import ShowGoodsQuestion from '@/components/goodsDetail/ShowGoodsQuestion';
import { goodsComment, goodsCommentNum } from '@/api/member.js';
export default {
name: 'ShowGoodsDetail',
props: {
detail: { //
type: Object,
default: null
}
},
data () {
return {
commentList: [], //
commentParams: { //
pageNumber: 1,
pageSize: 10,
grade: '',
goodsId: ''
},
commentTypeNum: {}, //
commentTotal: 0, //
onceFlag: true //
};
},
computed: {
skuDetail () {
return this.detail.data;
}
},
methods: {
changeHeight (name) {
let heightCss = window.getComputedStyle(this.$refs[name]).height;
heightCss = parseInt(heightCss.substr(0, heightCss.length - 2)) + 89;
this.$refs.itemIntroDetail.style.height = heightCss + 'px';
},
changePageNum (val) {
this.commentParams.pageNumber = val;
this.getList();
},
changePageSize (val) {
this.commentParams.pageNumber = 1;
this.commentParams.pageSize = val;
this.getList();
},
getList () { //
this.commentParams.goodsId = this.skuDetail.goodsId;
goodsComment(this.commentParams).then(res => {
if (res.code === 200) {
this.commentList = res.result.records;
this.commentTotal = res.result.total;
}
});
goodsCommentNum(this.skuDetail.goodsId).then(res => {
if (res.code === 200) {
this.commentTypeNum = res.result;
}
});
},
searchByGrade (grade) {
this.$set(this.commentParams, 'grade', grade);
this.commentParams.pageNumber = 1;
this.getList();
},
tabClick (name) {
if (name === 0) {
this.$nextTick(() => {
this.changeHeight('itemIntroGoods')
});
} else {
this.$nextTick(() => {
this.changeHeight('itemGoodsComment')
});
}
},
previewImg (img, item) { //
this.$set(item, 'previewImg', img);
this.$nextTick(() => {
this.changeHeight('itemGoodsComment')
});
},
hidePreviewImg (item) { //
this.$set(item, 'previewImg', '');
this.$nextTick(() => {
this.changeHeight('itemGoodsComment')
});
},
rotatePreviewImg (type, item) { //
if (type) {
if (item.deg) {
this.$set(item, 'deg', item.deg + 90);
} else {
this.$set(item, 'deg', 90);
}
} else {
if (item.deg) {
this.$set(item, 'deg', item.deg - 90);
} else {
this.$set(item, 'deg', -90);
}
}
},
handleScroll () {
if (this.onceFlag) {
this.$nextTick(() => {
this.changeHeight('itemIntroGoods')
});
this.onceFlag = false
}
}
},
mounted () {
this.$nextTick(() => {
setTimeout(this.changeHeight('itemIntroGoods'), 2000);
});
window.addEventListener('scroll', this.handleScroll)
this.getList();
},
components: {
ShowGoodsQuestion
}
};
</script>
<style scoped lang="scss">
/***************商品详情介绍和推荐侧边栏开始***************/
.item-intro-show{
width: 1200px;
margin: 15px auto;
display: flex;
flex-direction: row;
}
.item-intro-recommend{
width: 200px;
display: flex;
flex-direction: column;
}
.item-intro-recommend-column{
display: flex;
flex-direction: column;
box-shadow: 0px 0px 5px #999;
}
.item-recommend-title{
width: 100%;
height: 38px;
font-size: 16px;
line-height: 38px;
color: #fff;
background-color: $theme_color;
box-shadow: 0px 0px 5px $theme_color;
text-align: center;
}
.item-recommend-column{
margin-top: 15px;
}
.item-recommend-intro{
padding: 5px 15px;
display: flex;
flex-direction: row;
justify-content: space-between;
font-size: 12px;
color: #999;
cursor: pointer;
}
.item-recommend-img{
width: 80%;
margin: 0px auto;
cursor: pointer;
}
.item-recommend-img img{
width: 100%;
}
.item-recommend-top-num{
color: #fff;
margin: 0px 2px;
padding: 1px 5px;
border-radius: 12px;
background-color: $theme_color;
}
.item-recommend-price{
color: $theme_color;
font-weight: bolder;
}
.item-intro-detail{
margin: 0 30px;
// min-height: 1500px;
width: 100%;
}
.item-intro-nav{
width: 100%;
height: 38px;
background-color: #F7F7F7;
// border-bottom: 1px solid $theme_color;
}
.item-intro-nav ul{
margin: 0px;
padding: 0px;
list-style: none;
}
.item-intro-nav li{
float: left;
height: 100%;
width: 120px;
line-height: 38px;
text-align: center;
color: $theme_color;
}
.item-intro-nav li:first-child{
background-color: $theme_color;
color: #fff;
}
.item-intro-img {
width: 100%;
min-height: 300px;
}
.item-intro-img img{
max-width: 1000px;
}
/************* 商品参数 *************/
.item-param-container {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: space-between;
}
.item-param-box {
padding: 5px;
padding-left: 30px;
width: 240px;
height: 36px;
font-size: 14px;
/* text-align: center; */
/* background-color: #ccc; */
}
.item-param-title {
color: #232323;
}
.item-param-content {
color: #999;
}
.remarks-title {
padding-left: 15px;
height: 36px;
font-size: 16px;
font-weight: bolder;
line-height: 36px;
color: #666666;
background-color: #F7F7F7;
}
.remarks-analyse-box {
padding: 15px;
display: flex;
align-items: center;
}
.remarks-analyse-goods {
margin-left: 15px;
margin-right: 15px;
}
.remarks-analyse-num {
font-size: 26px;
}
.remarks-analyse-title {
font-size: 12px;
line-height: 20px;
}
.remarks-bar {
padding-left: 15px;
height: 36px;
line-height: 36px;
color: #666666;
background-color: #F7F7F7;
.selectedBar{
color: $theme_color;
}
}
.remarks-bar span {
margin-right: 15px;
&:hover{
color: $theme_color;
cursor: pointer;
}
}
.remarks-box {
padding: 15px;
display: flex;
flex-direction: row;
border-bottom: 1px #ccc dotted;
}
.remarks-user {
width: 180px;
}
.remarks-user-name {
padding-left: 15px;
}
.remarks-content-box {
width: calc(100% - 180px);
.comment-img{
display: flex;
.borderColor{
border-color: $theme_color;
}
div{
border: 1px solid #999;
margin-right: 5px;
width: 50px;
height: 50px;
img{width: 100%;}
}
}
.preview-img{
position: relative;
border: 1px solid #eee;
margin: 10px 0;
width: 200px;
div{
position: absolute;
top: 3px;
left: 3px;
z-index: 3;
span{
display: inline-block;
background-color: rgba(0,0,0,.5);
padding:3px 5px;
color: #fff;
border-radius: 4px;
cursor: pointer;
}
span:nth-child(1) .ivu-icon {
transform: rotateY(180deg);
}
}
img:hover{
cursor: url(require('../../../static/small.cur')),auto;
}
}
}
.remarks-content {
font-size: 14px;
color: #232323;
line-height: 28px;
}
.remarks-sub {
margin-top: 5px;
color: #ccc;
}
.remarks-time {
margin-left: 15px;
}
.remarks-page {
margin: 15px;
display: flex;
justify-content:flex-end;
}
/***************商品详情介绍和推荐侧边栏结束***************/
/* 改变便签页样式 */
.ivu-tabs-ink-bar {
background-color: $theme_color !important;
}
/deep/.ivu-tabs-bar{
border: none;
}
.item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab{
border-radius: 0px;
color: #999;
height: 38px;
// background: #F7F7F7;
}
.item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab-active{
color: #fff;
background-color: $theme_color;
}
.item-tabs > .ivu-tabs > .ivu-tabs-bar .ivu-tabs-tab-active:before{
content: '';
display: block;
width: 100%;
height: 1px;
color: #fff;
background: #F7F7F7;
position: absolute;
top: 0;
left: 0;
}
.ivu-rate-star-full:before, .ivu-rate-star-half .ivu-rate-star-content:before {
color: $theme_color;
}
</style>

View File

@ -0,0 +1,53 @@
<template>
<div class="wrapper">
<div v-if="true" class="question-list">
<div class="-item" v-for="index in 6" :key="index">
<!-- 提问 -->
<div class="-item-put -item-div">
<div class="-item-div-l blod">
<Tag color="warning"></Tag>
有屏幕调节亮度吗
</div>
<div class="-item-div-r">2020年10月21日17:03:35</div>
</div>
<!-- 解答 -->
<div class="-item-reply -item-div">
<div class="-item-div-l">
<Tag color="success"></Tag>
能调节点屏幕上方有一条调整带可正负2调整
</div>
<div class="-item-div-r">2020年10月21日17:03:35</div>
</div>
</div>
</div>
<div v-else class="question-empty">
<empty></empty>
</div>
</div>
</template>
<script>
export default {};
</script>
<style scoped lang="scss">
.-item-div {
padding: 10px 0;
display: flex;
align-items: center;
justify-content: space-between;
margin: 10px 0;
}
.-item-div-l {
display: flex;
@include content_color($light_content_color);
}
.-item-div-r {
@include sub_color($light_content_color);
}
.blod {
font-weight: bold;
}
.-item {
margin: 10px 0;
border-bottom: 1px solid $border_color;
}
</style>

View File

@ -0,0 +1,85 @@
<template>
<div>
<div class="remarks-title">
<span>售后保障</span>
</div>
<div class="item-protect-container">
<div class="item-protect-box">
<p class="item-protect-title-box">
<Avatar style="background-color: #e4393c" icon="ribbon-a" />
<span class="item-protect-title">卖家服务</span>
</p>
<p class="item-protect-detail">
高品质敢承诺7天无理由退货30天免费换新质量问题商家承担来回运费换新如需发票请在确认收货无误后联系商家开出*发票不随货品一同发出
</p>
</div>
<div class="item-protect-box">
<p class="item-protect-title-box">
<Avatar style="background-color: #e4393c" icon="cash" />
<span class="item-protect-title">平台承诺</span>
</p>
<p class="item-protect-detail">
平台卖家销售并发货的商品由平台卖家提供发票和相应的售后服务请您放心购买<br> 因厂家会在没有任何提前通知的情况下更改产品包装产地或者一些附件本司不能确保客户收到的货物与商城图片产地附件说明完全一致只能确保为原厂正货并且保证与当时市场上同样主流新品一致若本商城没有及时更新请大家谅解
</p>
</div>
<div class="item-protect-box">
<p class="item-protect-title-box">
<Avatar style="background-color: #e4393c" icon="locked" />
<span class="item-protect-title">正品行货</span>
</p>
<p class="item-protect-detail">
BIT商城向您保证所售商品均为正品行货BIT自营商品开具机打发票或电子发票
</p>
</div>
<div class="item-protect-box">
<p class="item-protect-title-box">
<Avatar style="background-color: #e4393c" icon="settings" />
<span class="item-protect-title">全国联保</span>
</p>
<p class="item-protect-detail">
凭质保证书及BIT商城发票可享受全国联保服务奢侈品钟表除外奢侈品钟表由BIT联系保修享受法定三包售后服务与您亲临商场选购的商品享受相同的质量保证BIT商城还为您提供具有竞争力的商品价格和运费政策请您放心购买<br><br> 因厂家会在没有任何提前通知的情况下更改产品包装产地或者一些附件本司不能确保客户收到的货物与商城图片产地附件说明完全一致只能确保为原厂正货并且保证与当时市场上同样主流新品一致若本商城没有及时更新请大家谅解
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ShowProductWarranty'
};
</script>
<style scoped lang="scss">
.remarks-title {
padding-left: 15px;
height: 36px;
font-size: 16px;
font-weight: bolder;
line-height: 36px;
color: #666666;
background-color: #F7F7F7;
}
.item-protect-container {
padding: 15px;
}
.item-protect-box {
margin-bottom: 30px;
}
.item-protect-title-box {
display: flex;
align-items: center;
}
.item-protect-title {
padding-left: 15px;
font-size: 20px;
font-weight: bolder;
color: $theme_color;
}
.item-protect-detail {
padding-top: 5px;
padding-left: 46px;
font-size: 14px;
color: #999;
}
</style>

View File

@ -0,0 +1,426 @@
<template>
<div class="box">
<div class="nav">
<ul class="location">
<li><router-link to="/" v-if="$route.path !== '/'" class="home-page" ><Icon type="md-home" />首页</router-link></li>
<li>
<Dropdown placement="bottom-start">
<a href="javascript:void(0)">
<Icon type="ios-pin" class="icon"></Icon>
{{ city }}
</a>
<DropdownMenu slot="list">
<div class="city">
<p v-for="(items, index) in cityArr" :key="index">
<span
v-for="(item, index) in items"
class="city-item"
:key="index"
@click="changeCity(item)"
>{{ item }}</span>
</p>
</div>
</DropdownMenu>
</Dropdown>
</li>
</ul>
<ul class="detail">
<!-- <li class="first hover-pointer" @click="handleClickTheme()"></li> -->
<li class="first" v-show="!userInfo.username">
<router-link :to="`/login?rePath=${$route.path}&query=${JSON.stringify($route.query)}`">
<span style="border:none" class="tipsLogin">请登录</span>
</router-link>
</li>
<li v-show="!!userInfo.username">
<Dropdown>
<p class="username-p">
<Avatar class="person-icon" :src="userInfo.face" icon="person" size="small" />
<span class="username">{{ userInfo.nickName? userInfo.nickName : userInfo.username | secrecyMobile }}</span>
</p>
<DropdownMenu slot="list">
<div class="my-page">
<div class="my-info" @click="myInfo">
<Icon type="md-home"></Icon>
<p>我的主页</p>
</div>
<div class="sign-out" @click="signOutFun">
<Icon type="md-exit"></Icon>
<p>退出登陆</p>
</div>
</div>
</DropdownMenu>
</Dropdown>
</li>
<li class="hover-color" @click="goUserCenter('home/MyOrder')"><span class="nav-item">我的订单</span></li>
<li class="hover-color" @click="goUserCenter('home/MyTracks')"><span class="nav-item">我的足迹</span></li>
<li v-if="$route.name !== 'Cart'" style="position:relative;" @mouseenter="getCartList">
<i class="cart-badge" v-show="cartNum">{{cartNum < 100 ? cartNum : '99'}}</i>
<Dropdown placement="bottom-start">
<router-link to="cart" target="_blank">
<Icon
size="18"
class="cart-icon"
type="ios-cart-outline"
></Icon>
购物车
</router-link>
<DropdownMenu slot="list">
<div class="shopping-cart-null" style="width:200px" v-show="shoppingCart.length <= 0">
<Icon type="ios-cart-outline" class="cart-null-icon"></Icon>
<span>你的购物车没有宝贝哦</span>
<span>赶快去添加商品吧~</span>
</div>
<div class="shopping-cart-list" v-show="shoppingCart.length > 0">
<div
class="shopping-cart-box"
v-for="(item, index) in shoppingCart"
@click="goToPay"
:key="index"
>
<div class="shopping-cart-img">
<img :src="item.goodsSku.thumbnail" class="hover-pointer" />
</div>
<div class="shopping-cart-info">
<div class="shopping-cart-title ">
<p class="hover-pointer goods-title">{{ item.goodsSku.goodsName }}</p>
</div>
<div class="shopping-cart-detail">
<p>
数量:
<span class="shopping-cart-text">{{ item.num }}</span>
价钱:
<span class="shopping-cart-text">{{ item.purchasePrice | unitPrice('¥') }}</span>
</p>
</div>
</div>
</div>
<div class="go-to-buy">
<Button type="error" size="small" @click="goToPay"></Button>
</div>
</div>
</DropdownMenu>
</Dropdown>
</li>
<li>
<span class="nav-item" @click="shopEntry"></span>
</li>
<!-- <li>
<router-link to="/feedback">意见反馈</router-link>
</li>-->
</ul>
</div>
</div>
</template>
<script>
import storage from '@/plugins/storage.js';
import {cartGoodsAll, cartCount} from '@/api/cart.js'
export default {
name: 'M-Header',
created () {
if (storage.getItem('userInfo')) {
this.userInfo = JSON.parse(storage.getItem('userInfo'));
}
},
data () {
return {
//
themeType: 'light',
city: '珠海', //
cityArr: [
['北京', '上海', '天津', '重庆', '广州'],
['深圳', '河南', '辽宁', '吉林', '江苏'],
['江西', '四川', '海南', '贵州', '云南'],
['西藏', '陕西', '甘肃', '青海', '珠海']
],
userInfo: {}, //
shoppingCart: [] //
};
},
computed: {
cartNum () {
return this.$store.state.cartNum
}
},
methods: {
handleClickTheme () {
this.themeType === 'light'
? (this.themeType = 'dark')
: (this.themeType = 'light');
window.document.documentElement.setAttribute(
'data-theme',
this.themeType
);
},
changeCity (city) {
this.city = city;
},
goToPay () {
let url = this.$router.resolve({
path: '/cart'
})
window.open(url.href, '_blank')
},
myInfo () {
let url = this.$router.resolve({
path: '/home'
})
window.open(url.href, '_blank')
},
signOutFun () {
storage.removeItem('accessToken');
storage.removeItem('refreshToken');
storage.removeItem('userInfo');
this.$router.push('/login');
},
goUserCenter (path) { //
if (this.userInfo.username) {
this.$router.push({path: path})
} else {
this.$Modal.confirm({
title: '请登录',
content: '<p>请登录后执行此操作</p>',
okText: '立即登录',
cancelText: '继续浏览',
onOk: () => {
this.$router.push({
path: '/login',
query: {
rePath: this.$router.history.current.path,
query: JSON.stringify(this.$router.history.current.query)
}
});
}
});
}
},
shopEntry () { //
if (storage.getItem('accessToken')) {
let routeUrl = this.$router.resolve({
path: '/shopEntry',
query: {id: 1}
});
window.open(routeUrl.href, '_blank');
} else {
this.$router.push('login');
}
},
getCartList () { //
if (this.userInfo.username) {
cartCount().then(res => {
this.$store.commit('SET_CARTNUM', res.result)
this.Cookies.setItem('cartNum', res.result)
})
cartGoodsAll().then(res => {
this.shoppingCart = res.result.skuList
})
}
}
}
};
</script>
<style scoped lang="scss">
.shopping-cart-detail,
.shopping-cart-text,
.shopping-cart-info,
.nav a,
.location,
.first,
.username,
.shopping-cart-null span {
@include sub_color($light_sub_color);
}
.tipsLogin {
color: $theme_color;
}
.box {
width: 100%;
// height: 35px;
@include background_color($light_white_background_color);
}
.nav {
margin: 0 auto;
width: 1200px;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.nav ul {
list-style: none;
}
.nav li {
float: left;
font-size: 14px;
line-height: 35px;
margin-right: 15px;
font-weight: bold;
}
.nav a,.nav-item {
text-decoration: none;
padding-left: 15px;
border-left: 1px solid #ccc;
color: #999;
cursor: pointer;
}
.location a {
border-left: none;
}
.nav a:hover {
color: $theme_color;
}
.icon {
color: gray;
vertical-align: middle;
}
.first a:first-child {
padding-left: 3px;
border-left: none;
}
.city {
padding: 10px 15px;
}
.city-item {
font-weight: bold;
cursor: pointer;
padding: 5px;
}
.city-item:hover {
color: $theme_color;
}
.person-icon {
color: $theme_color;
background-color: #f0cdb2;
}
.shopping-cart-list {
padding: 10px 15px;
box-sizing: border-box;
height: 300px;
overflow: scroll;
}
.shopping-cart-box {
margin: 8px 0px;
margin-top: 15px;
padding-bottom: 15px;
height: 40px;
display: flex;
align-items: center;
border-bottom: 1px #ccc dotted;
}
.shopping-cart-box:first-child {
margin-top: 8px;
}
.shopping-cart-img {
margin-right: 15px;
width: 40px;
height: 40px;
}
.shopping-cart-img img {
width: 100%;
}
.shopping-cart-info {
display: flex;
flex-direction: column;
justify-content: space-between;
align-content: space-between;
width: 200px;
overflow: hidden;
font-size: 12px;
line-height: 20px;
}
.go-to-buy {
display: flex;
justify-content: flex-end;
}
.shopping-cart-null {
padding: 15px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cart-null-icon {
font-size: 38px;
margin-bottom: 15px;
}
.shopping-cart-null span {
font-size: 12px;
line-height: 16px;
}
.username-p {
cursor: pointer;
}
.my-page {
padding: 3px 5px;
width: 180px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.my-page a {
margin: 0px;
padding: 0px;
border: none;
}
.my-info {
padding: 5px;
width: 50%;
height: 100%;
text-align: center;
cursor: pointer;
}
.my-info:hover {
box-shadow: 0px 0px 5px #ccc;
}
.my-info i {
font-size: 28px;
}
.my-info p {
font-size: 12px;
}
.sign-out {
padding: 5px;
width: 50%;
height: 100%;
text-align: center;
cursor: pointer;
}
.sign-out:hover {
box-shadow: 0px 0px 5px $border_color;
}
.sign-out i {
font-size: 28px;
}
.sign-out p {
font-size: 12px;
}
.cart-icon{
padding: 0 6px;
}
.goods-title:hover {
color: $theme_color;
}
.cart-badge {
position: absolute;
right: -8px;
font-style: normal;
background-color: $theme_color;
color: #fff;
font-size: 12px;
width: 17px;
height: 17px;
border-radius: 10px;
line-height: 17px;
text-align: center;
z-index: 3;
top: 3px;
}
</style>

View File

@ -0,0 +1,102 @@
<template>
<div class="shop-box">
<div class="shop-container">
<div class="shop-title">
<div class="shop-title-content">
<p><router-link :to="`/merchant?id=${skuDetail.storeId}`">{{ skuDetail.storeName }}</router-link></p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ShopHeader',
props: {
detail: {
type: Object,
default: null
}
},
computed: {
skuDetail () {
return this.detail;
}
}
};
</script>
<style scoped>
/* 店铺介绍 */
.shop-box {
width: 100%;
height: 50px;
background-color: #484848;
}
.shop-container {
width: 1200px;
height: 100%;
margin: 0px auto;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: #fff;
}
.shop-title {
display: flex;
flex-direction: row;
}
.shop-title-icon {
font-size: 46px;
}
.shop-title-content {
padding-top: 8px;
margin-left: 15px;
display: flex;
}
.shop-title-content p {
line-height: 26px;
font-size: 20px;
}
.shop-title-content p:nth-child(2) {
font-size: 16px;
margin-left: 20px;
}
.shop-title-content a {
color: #fff;
}
.shop-another-item {
display: flex;
flex-direction: row;
}
.shop-another-item-detail {
display: flex;
flex-direction: row;
align-items: center;
margin-left: 15px;
}
.shop-another-item-img {
height: 80px;
border-radius: 40px;
overflow: hidden;
}
.shop-another-item-img img {
width: 80px;
}
.shop-anoter-item-intro {
margin-left: 15px;
}
</style>

View File

@ -0,0 +1,93 @@
<template>
<div class="scroll-show">
<div class="content clearfix">
<cateNav class="cate" :showNavBar="false"></cateNav>
<Search class="search-con" :showLogo="false" :showTag="false"></Search>
<Icon type="ios-cart-outline" @click="goCartList" class="cart-icon" @mouseenter.native="getCartList" />
<i class="cart-badge">{{cartNum < 100 ? cartNum : '99'}}</i>
</div>
</div>
</template>
<script>
import {cartCount} from '@/api/cart.js'
import storage from '@/plugins/storage.js';
export default {
data () {
return {
userInfo: {} //
}
},
computed: {
cartNum () { //
return this.$store.state.cartNum
}
},
methods: {
goCartList () {
let routerUrl = this.$router.resolve({
path: '/cart'
})
window.open(routerUrl.href, '_blank')
},
getCartList () { //
if (storage.getItem('userInfo')) {
cartCount().then(res => {
this.$store.commit('SET_CARTNUM', res.result)
this.Cookies.setItem('cartNum', res.result)
})
}
}
},
mounted () {
if (storage.getItem('userInfo')) {
this.userInfo = JSON.parse(storage.getItem('userInfo'));
}
}
}
</script>
<style lang="scss" scoped>
.content{
width: 1200px;
height: 40px;
margin: 10px auto;
position: relative;
}
.cate {
float: left;
width: 200px!important;
}
.search-con{
float: left;
width: 800px;
overflow: hidden;
margin-top: -27px;
}
.cart-icon {
width: 30px;
float: left;
font-size: 25px;
margin-top: 8px;
color: $theme_color;
z-index: 1;
position: relative;
&:hover{
cursor: pointer;
}
}
.cart-badge {
position: absolute;
font-style: normal;
right: 165px;
display: block;
background-color: $theme_color;
color: #fff;
font-size: 12px;
width: 17px;
height: 17px;
border-radius: 10px;
line-height: 17px;
text-align: center;
z-index: 5;
top: 3px;
}
</style>

View File

@ -0,0 +1,33 @@
<template>
<div class="model-form">
<div class="model-content">
<template v-for="(element, index) in data.list">
<model-form-item
v-if="element && element.key"
:key="element.key"
:element="element"
:index="index"
:data="data"
></model-form-item>
</template>
</div>
</div>
</template>
<script>
import ModelFormItem from './modelFormItem.vue';
export default {
name: 'modelForm',
components: {
ModelFormItem
},
props: ['data']
};
</script>
<style lang="scss" scoped>
.model-content {
width: 1200px;
margin: 0 auto;
background: #fff;
min-height: 1200px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More