diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..33cf0f7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+.DS_Store
+node_modules/
+/dist/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+/unpackage/
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
diff --git a/App.vue b/App.vue
new file mode 100644
index 0000000..d354d28
--- /dev/null
+++ b/App.vue
@@ -0,0 +1,451 @@
+
+
+
diff --git a/README.md b/README.md
index 208f2de..13b3b46 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,89 @@
# mall-app-web
-mall-app-web是一个电商系统的移动端项目,基于uni-app实现。主要包括首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等功能。
+
+
+
+
+
+
+
+
+## 前言
+
+该项目为前后端分离项目的前端部分,后端项目`mall`地址:[传送门](https://github.com/macrozheng/mall)。
+
+## 项目介绍
+
+`mall-app-web`是一个电商系统的移动端项目,基于`uni-app`实现。主要包括首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等功能。
+
+### 项目演示
+
+项目在线演示地址:[http://www.macrozheng.com/app/](http://www.macrozheng.com/app/)
+
+![](../images/mall_app_web_preview_01.png)![](../images/mall_app_web_preview_02.png)
+
+![](../images/mall_app_web_preview_03.png)![](../images/mall_app_web_preview_04.png)
+
+![](../images/mall_app_web_preview_05.png)![](../images/mall_app_web_preview_06.png)
+
+![](../images/mall_app_web_preview_07.png)![](../images/mall_app_web_preview_08.png)
+
+### 技术选型
+
+| 技术 | 说明 | 官网 |
+| ------------ | ---------------- | --------------------------------------- |
+| Vue | 核心前端框架 | https://vuejs.org |
+| Vuex | 全局状态管理框架 | https://vuex.vuejs.org |
+| uni-app | 移动端前端框架 | https://uniapp.dcloud.io |
+| mix-mall | 电商项目模板 | https://ext.dcloud.net.cn/plugin?id=200 |
+| luch-request | HTTP请求框架 | https://github.com/lei-mu/luch-request |
+
+### 项目结构
+
+``` lua
+src -- 源码目录
+├── api -- luch-request网络请求定义
+├── components -- 通用组件封装
+├── js_sdk -- 第三方sdk源码
+├── static -- 图片等静态资源
+├── store -- vuex的状态管理
+├── utils -- 工具类
+└── pages -- 前端页面
+ ├── address -- 地址管理页
+ ├── brand -- 商品品牌页
+ ├── cart -- 购物车页
+ ├── category -- 商品分类页
+ ├── coupon -- 优惠券页
+ ├── index -- 首页
+ ├── money -- 支付页
+ ├── notice -- 通知页
+ ├── order -- 订单页
+ ├── product -- 商品页
+ ├── public -- 登录页
+ ├── set -- 设置页
+ ├── user -- 会员页
+ └── userinfo -- 会员信息页
+```
+
+## 搭建步骤
+
+- 本项目使用了`uni-app`专用开发工具`HBuilder X`(App开发版)开发,下载地址:https://www.dcloud.io/hbuilderx.html
+- 该项目为前后端分离项目,访问本地访问接口需搭建后台环境,搭建请参考后端项目[传送门](https://github.com/macrozheng/mall);
+- 注意由于`mall-app-web`中的接口都在`mall-portal`模块中,所以一定要启动该模块;
+- 访问在线接口无需搭建后台环境,只需将`utils/requestUtil.js`文件中的`config.baseUrl`改为线上地址即可:http://portal-api.macrozheng.com
+- 克隆源代码到本地,使用`HBuilder X`打开;
+- 在`HBuilder X`中使用`运行->运行到浏览器->Chrome`运行项目,运行成功后会自动打开下面地址(将浏览器改为手机模式):http://localhost:8080
+- 如果浏览器没有启动的话,可以直接访问如下地址访问:http://localhost:8080
+
+## 公众号
+
+学习不走弯路,关注公众号「**macrozheng**」,回复「**学习路线**」,获取mall项目专属学习路线!
+
+加微信群交流,公众号后台回复「**加群**」即可。
+
+![公众号图片](http://macro-oss.oss-cn-shenzhen.aliyuncs.com/mall/banner/qrcode_for_macrozheng_258.jpg)
+
+## 许可证
+
+[Apache License 2.0](https://github.com/macrozheng/mall/blob/master/LICENSE)
+
+Copyright (c) 2020-2021 macrozheng
\ No newline at end of file
diff --git a/api/address.js b/api/address.js
new file mode 100644
index 0000000..04053fd
--- /dev/null
+++ b/api/address.js
@@ -0,0 +1,39 @@
+import request from '@/utils/requestUtil'
+
+export function fetchAddressList() {
+ return request({
+ method: 'GET',
+ url: '/member/address/list'
+ })
+}
+
+export function fetchAddressDetail(id) {
+ return request({
+ method: 'GET',
+ url: `/member/address/${id}`
+ })
+}
+
+export function addAddress(data) {
+ return request({
+ method: 'POST',
+ url: '/member/address/add',
+ data:data
+ })
+}
+
+export function updateAddress(data) {
+ return request({
+ method: 'POST',
+ url: `/member/address/update/${data.id}`,
+ data:data
+ })
+}
+
+export function deleteAddress(id) {
+ return request({
+ method: 'POST',
+ url: `/member/address/delete/${id}`
+ })
+}
+
diff --git a/api/brand.js b/api/brand.js
new file mode 100644
index 0000000..fe2e7c8
--- /dev/null
+++ b/api/brand.js
@@ -0,0 +1,24 @@
+import request from '@/utils/requestUtil'
+
+export function getBrandDetail(id) {
+ return request({
+ method: 'GET',
+ url: `/brand/detail/${id}`,
+ })
+}
+
+export function fetchBrandProductList(params) {
+ return request({
+ method: 'GET',
+ url: '/brand/productList',
+ params:params
+ })
+}
+
+export function fetchBrandRecommendList(params) {
+ return request({
+ method: 'GET',
+ url: '/brand/recommendList',
+ params:params
+ })
+}
\ No newline at end of file
diff --git a/api/cart.js b/api/cart.js
new file mode 100644
index 0000000..8050d18
--- /dev/null
+++ b/api/cart.js
@@ -0,0 +1,39 @@
+import request from '@/utils/requestUtil'
+
+export function addCartItem(data) {
+ return request({
+ method: 'POST',
+ url: '/cart/add',
+ data: data
+ })
+}
+
+export function fetchCartList() {
+ return request({
+ method: 'GET',
+ url: '/cart/list'
+ })
+}
+
+export function deletCartItem(params) {
+ return request({
+ method: 'POST',
+ url: '/cart/delete',
+ params:params
+ })
+}
+
+export function updateQuantity(params) {
+ return request({
+ method: 'GET',
+ url: '/cart/update/quantity',
+ params:params
+ })
+}
+
+export function clearCartList() {
+ return request({
+ method: 'POST',
+ url: '/cart/clear'
+ })
+}
\ No newline at end of file
diff --git a/api/coupon.js b/api/coupon.js
new file mode 100644
index 0000000..376ac27
--- /dev/null
+++ b/api/coupon.js
@@ -0,0 +1,23 @@
+import request from '@/utils/requestUtil'
+
+export function fetchProductCouponList(productId) {
+ return request({
+ method: 'GET',
+ url: `/member/coupon/listByProduct/${productId}`,
+ })
+}
+
+export function addMemberCoupon(couponId) {
+ return request({
+ method: 'POST',
+ url: `/member/coupon/add/${couponId}`,
+ })
+}
+
+export function fetchMemberCouponList(useStatus) {
+ return request({
+ method: 'GET',
+ url: '/member/coupon/list',
+ params:{useStatus:useStatus}
+ })
+}
\ No newline at end of file
diff --git a/api/home.js b/api/home.js
new file mode 100644
index 0000000..4866f5c
--- /dev/null
+++ b/api/home.js
@@ -0,0 +1,39 @@
+import request from '@/utils/requestUtil'
+
+export function fetchContent() {
+ return request({
+ method: 'GET',
+ url: '/home/content'
+ })
+}
+
+export function fetchRecommendProductList(params) {
+ return request({
+ method: 'GET',
+ url: '/home/recommendProductList',
+ params:params
+ })
+}
+
+export function fetchProductCateList(parentId) {
+ return request({
+ method: 'GET',
+ url: '/home/productCateList/'+parentId,
+ })
+}
+
+export function fetchNewProductList(params) {
+ return request({
+ method: 'GET',
+ url: '/home/newProductList',
+ params:params
+ })
+}
+
+export function fetchHotProductList(params) {
+ return request({
+ method: 'GET',
+ url: '/home/hotProductList',
+ params:params
+ })
+}
diff --git a/api/member.js b/api/member.js
new file mode 100644
index 0000000..149b24d
--- /dev/null
+++ b/api/member.js
@@ -0,0 +1,19 @@
+import request from '@/utils/requestUtil'
+
+export function memberLogin(data) {
+ return request({
+ method: 'POST',
+ url: '/sso/login',
+ header: {
+ 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
+ },
+ data: data
+ })
+}
+
+export function memberInfo() {
+ return request({
+ method: 'GET',
+ url: '/sso/info'
+ })
+}
diff --git a/api/memberBrandAttention.js b/api/memberBrandAttention.js
new file mode 100644
index 0000000..b95bb6c
--- /dev/null
+++ b/api/memberBrandAttention.js
@@ -0,0 +1,40 @@
+import request from '@/utils/requestUtil'
+
+export function createBrandAttention(data) {
+ return request({
+ method: 'POST',
+ url: '/member/attention/add',
+ data: data
+ })
+}
+
+export function deleteBrandAttention(params) {
+ return request({
+ method: 'POST',
+ url: '/member/attention/delete',
+ params: params
+ })
+}
+
+export function fetchBrandAttentionList(params) {
+ return request({
+ method: 'GET',
+ url: '/member/attention/list',
+ params:params
+ })
+}
+
+export function brandAttentionDetail(params) {
+ return request({
+ method: 'GET',
+ url: '/member/attention/detail',
+ params: params
+ })
+}
+
+export function clearBrandAttention() {
+ return request({
+ method: 'POST',
+ url: '/member/attention/clear'
+ })
+}
\ No newline at end of file
diff --git a/api/memberProductCollection.js b/api/memberProductCollection.js
new file mode 100644
index 0000000..6b16519
--- /dev/null
+++ b/api/memberProductCollection.js
@@ -0,0 +1,40 @@
+import request from '@/utils/requestUtil'
+
+export function createProductCollection(data) {
+ return request({
+ method: 'POST',
+ url: '/member/productCollection/add',
+ data: data
+ })
+}
+
+export function deleteProductCollection(params) {
+ return request({
+ method: 'POST',
+ url: '/member/productCollection/delete',
+ params: params
+ })
+}
+
+export function fetchProductCollectionList(params) {
+ return request({
+ method: 'GET',
+ url: '/member/productCollection/list',
+ params:params
+ })
+}
+
+export function productCollectionDetail(params) {
+ return request({
+ method: 'GET',
+ url: '/member/productCollection/detail',
+ params: params
+ })
+}
+
+export function clearProductCollection() {
+ return request({
+ method: 'POST',
+ url: '/member/productCollection/clear'
+ })
+}
\ No newline at end of file
diff --git a/api/memberReadHistory.js b/api/memberReadHistory.js
new file mode 100644
index 0000000..934bd95
--- /dev/null
+++ b/api/memberReadHistory.js
@@ -0,0 +1,24 @@
+import request from '@/utils/requestUtil'
+
+export function createReadHistory(data) {
+ return request({
+ method: 'POST',
+ url: '/member/readHistory/create',
+ data: data
+ })
+}
+
+export function fetchReadHistoryList(params) {
+ return request({
+ method: 'GET',
+ url: '/member/readHistory/list',
+ params: params
+ })
+}
+
+export function clearReadHistory() {
+ return request({
+ method: 'POST',
+ url: '/member/readHistory/clear'
+ })
+}
\ No newline at end of file
diff --git a/api/order.js b/api/order.js
new file mode 100644
index 0000000..4d34ab8
--- /dev/null
+++ b/api/order.js
@@ -0,0 +1,76 @@
+import request from '@/utils/requestUtil'
+
+export function generateConfirmOrder(data) {
+ return request({
+ method: 'POST',
+ url: '/order/generateConfirmOrder',
+ data: data
+ })
+}
+
+export function generateOrder(data) {
+ return request({
+ method: 'POST',
+ url: '/order/generateOrder',
+ data: data
+ })
+}
+
+export function fetchOrderList(params) {
+ return request({
+ method: 'GET',
+ url: '/order/list',
+ params: params
+ })
+}
+
+export function payOrderSuccess(data) {
+ return request({
+ method: 'POST',
+ url: '/order/paySuccess',
+ header: {
+ 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
+ },
+ data: data
+ })
+}
+
+export function fetchOrderDetail(orderId) {
+ return request({
+ method: 'GET',
+ url: `/order/detail/${orderId}`
+ })
+}
+
+export function cancelUserOrder(data) {
+ return request({
+ method: 'POST',
+ url: '/order/cancelUserOrder',
+ header: {
+ 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
+ },
+ data: data
+ })
+}
+
+export function confirmReceiveOrder(data) {
+ return request({
+ method: 'POST',
+ url: '/order/confirmReceiveOrder',
+ header: {
+ 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
+ },
+ data: data
+ })
+}
+
+export function deleteUserOrder(data) {
+ return request({
+ method: 'POST',
+ url: '/order/deleteOrder',
+ header: {
+ 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
+ },
+ data: data
+ })
+}
\ No newline at end of file
diff --git a/api/product.js b/api/product.js
new file mode 100644
index 0000000..506544f
--- /dev/null
+++ b/api/product.js
@@ -0,0 +1,23 @@
+import request from '@/utils/requestUtil'
+
+export function searchProductList(params) {
+ return request({
+ method: 'GET',
+ url: '/product/search',
+ params: params
+ })
+}
+
+export function fetchCategoryTreeList() {
+ return request({
+ method: 'GET',
+ url: '/product/categoryTreeList'
+ })
+}
+
+export function fetchProductDetail(id) {
+ return request({
+ method: 'GET',
+ url: '/product/detail/'+id
+ })
+}
diff --git a/components/empty.vue b/components/empty.vue
new file mode 100644
index 0000000..4da4df0
--- /dev/null
+++ b/components/empty.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/mix-list-cell.vue b/components/mix-list-cell.vue
new file mode 100644
index 0000000..a60259c
--- /dev/null
+++ b/components/mix-list-cell.vue
@@ -0,0 +1,119 @@
+
+
+
+
+
+ {{title}}
+ {{tips}}
+
+
+
+
+
+
+
+
+
diff --git a/components/mix-loading/mix-loading.vue b/components/mix-loading/mix-loading.vue
new file mode 100644
index 0000000..3c38afe
--- /dev/null
+++ b/components/mix-loading/mix-loading.vue
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/share.vue b/components/share.vue
new file mode 100644
index 0000000..074cd7d
--- /dev/null
+++ b/components/share.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+ {{item.text}}
+
+
+
+ 取消
+
+
+
+
+
+
+
diff --git a/components/uni-load-more/uni-load-more.vue b/components/uni-load-more/uni-load-more.vue
new file mode 100644
index 0000000..6c43365
--- /dev/null
+++ b/components/uni-load-more/uni-load-more.vue
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{status === 'more' ? contentText.contentdown : (status === 'loading' ? contentText.contentrefresh : contentText.contentnomore)}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/components/uni-number-box.vue b/components/uni-number-box.vue
new file mode 100644
index 0000000..8f626ac
--- /dev/null
+++ b/components/uni-number-box.vue
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/upload-images.vue b/components/upload-images.vue
new file mode 100644
index 0000000..71bb4a3
--- /dev/null
+++ b/components/upload-images.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
+ {{item.progress}}%
+
+
+
+
+
+
+
+
+
diff --git a/js_sdk/luch-request/readme.md b/js_sdk/luch-request/readme.md
new file mode 100644
index 0000000..8732fd3
--- /dev/null
+++ b/js_sdk/luch-request/readme.md
@@ -0,0 +1,317 @@
+**插件使用说明**
+
+- 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
+- 支持全局挂载
+- 支持多个全局配置实例
+- 支持自定义验证器
+- 支持文件上传(如不使用可以删除class里upload 方法)
+- 支持` typescript `、` javascript ` 版本(如果不使用ts版本,则可以把luch-request-ts 文件夹删除)
+- 下载后把 http-request 文件夹放到项目 utils/ 目录下
+
+
+**Example**
+---
+创建实例
+
+``` javascript
+const http = new Request();
+```
+
+执行` GET `请求
+
+``` javascript
+http.get('/user/login', {params: {userName: 'name', password: '123456'}}).then(res => {
+
+}).catch(err => {
+
+})
+// 局部修改配置,局部配置优先级高于全局配置
+http.get('/user/login', {
+ params: {userName: 'name', password: '123456'}, /* 会加在url上 */
+ header: {}, /* 会覆盖全局header */
+ dataType: 'json',
+ // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
+ custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
+ // #ifndef MP-ALIPAY || APP-PLUS
+ responseType: 'text',
+ // #endif
+ // #ifdef MP-ALIPAY
+ timeout: 30000, // 仅支付宝小程序支持
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true // 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
+ // #endif
+}).then(res => {
+
+}).catch(err => {
+
+})
+```
+执行` POST `请求
+
+``` javascript
+http.post('/user/login', {userName: 'name', password: '123456'} ).then(res => {
+
+}).catch(err => {
+
+})
+// 局部修改配置,局部配置优先级高于全局配置
+http.post('/user/login', {userName: 'name', password: '123456'}, {
+ params: {}, /* 会加在url上 */
+ header: {}, /* 会覆盖全局header */
+ dataType: 'json',
+ // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
+ custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
+ // #ifndef MP-ALIPAY || APP-PLUS
+ responseType: 'text',
+ // #endif
+ // #ifdef MP-ALIPAY
+ timeout: 30000, // 仅支付宝小程序支持
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true // 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+)
+ // #endif
+}).then(res => {
+
+}).catch(err => {
+
+})
+```
+执行` upload `请求
+
+``` javascript
+http.upload('api/upload/img', {
+ files: [], // 仅5+App支持
+ fileType:'image/video/audio', // 仅支付宝小程序,且必填。
+ filePath: '', // 要上传文件资源的路径。
+ // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
+ custom: {auth: true}, // 可以加一些自定义参数,在拦截器等地方使用。比如这里我加了一个auth,可在拦截器里拿到,如果true就传token
+ name: 'file', // 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
+ header: {},
+ formData: {}, // HTTP 请求中其他额外的 form data
+}).then(res => {
+
+}).catch(err => {
+
+})
+```
+**luch-request API**
+--
+``` javascript
+http.request({
+ method: 'POST', // 请求方法必须大写
+ url: '/user/12345',
+ data: {
+ firstName: 'Fred',
+ lastName: 'Flintstone'
+ },
+ params: { // 会拼接到url上
+ token: '1111'
+ },
+ // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
+ custom: {} // 自定义参数
+})
+
+具体参数说明:[uni.uploadFile](https://uniapp.dcloud.io/api/request/network-file)
+http.upload('api/upload/img', {
+ files: [], // 仅5+App支持
+ fileType:'image/video/audio', // 仅支付宝小程序,且必填。
+ filePath: '', // 要上传文件资源的路径。
+ name: 'file', // 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
+ header: {}, // 如填写,会覆盖全局header,
+ custom: {} // 自定义参数
+ formData: {}, // HTTP 请求中其他额外的 form data
+})
+```
+
+
+请求方法别名 / 实例方法
+
+``` javascript
+http.request(config)
+http.get(url[, config])
+http.upload(url[, config])
+http.delete(url[, data[, config]])
+http.head(url[, data[, config]])
+http.post(url[, data[, config]])
+http.put(url[, data[, config]])
+http.connect(url[, data[, config]])
+http.options(url[, data[, config]])
+http.trace(url[, data[, config]])
+```
+
+**全局请求配置**
+--
+``` javascript
+{
+ baseUrl: '',
+ header: {
+ 'content-type': 'application/json;charset=UTF-8'
+ },
+ method: 'GET',
+ dataType: 'json',
+ // #ifndef MP-ALIPAY || APP-PLUS
+ responseType: 'text',
+ // #endif
+ // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
+ custom: {}, // 全局自定义参数默认值
+ // #ifdef MP-ALIPAY
+ timeout: 30000,
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true
+ // #endif
+}
+```
+
+
+全局配置修改` setConfig `
+
+``` javascript
+/**
+ * @description 修改全局默认配置
+ * @param {Function}
+*/
+http.setConfig((config) => { /* config 为默认全局配置*/
+ config.baseUrl = 'http://www.bbb.cn'; /* 根域名 */
+ config.header = {
+ a: 1,
+ b: 2
+ }
+ return config
+})
+```
+
+自定义验证器` validateStatus `
+
+``` javascript
+/**
+ * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
+ * @param { Number } statusCode - 请求响应体statusCode(只读)
+ * @return { Boolean } 如果为true,则 resolve, 否则 reject
+*/
+http.validateStatus = (statusCode) => { // 默认
+ return statusCode === 200
+}
+
+// 举个栗子
+http.validateStatus = (statusCode) => {
+ return statusCode && statusCode >= 200 && statusCode < 300
+}
+```
+
+**拦截器**
+--
+
+在请求之前拦截
+
+``` javascript
+/**
+ * @param { Function} cancel - 取消请求,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行; 不会进入响应拦截器
+ *
+ * @param {String} text ['handle cancel'| any] - catch((err) => {}) err.errMsg === 'handle cancel'。非必传,默认'handle cancel'
+ * @cancel {Object} config - catch((err) => {}) err.config === config; 非必传,默认为request拦截器修改之前的config
+ * function cancel(text, config) {}
+ */
+http.interceptor.request((config, cancel) => { /* cancel 为函数,如果调用会取消本次请求。需要注意:调用cancel,本次请求的catch仍会执行。必须return config */
+ config.header = {
+ ...config.header,
+ a: 1
+ }
+ // if (config.custom.auth) {
+ // config.header.token = 'token'
+ // }
+ if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
+ cancel('token 不存在', config) // 把修改后的config传入,之后响应就可以拿到修改后的config。 如果调用了cancel但是不传修改后的config,则catch((err) => {}) err.config 为request拦截器修改之前的config
+ }
+ */
+ return config;
+})
+```
+
+在请求之后拦截
+
+``` javascript
+http.interceptor.response((response) => { /* 对响应成功做点什么 (statusCode === 200),必须return response*/
+ // if (response.data.code !== 200) { // 服务端返回的状态码不等于200,则reject()
+ // return Promise.reject(response)
+ // }
+ // if (response.config.custom.verification) { // 演示自定义参数的作用
+ // return response.data
+ // }
+ console.log(response)
+ return response
+}, (response) => { /* 对响应错误做点什么 (statusCode !== 200),必须return response*/
+ console.log(response)
+ return response
+})
+```
+
+**typescript使用**
+--
+在` request.ts `里还暴露了五个接口
+```javascript
+{
+ options, // request 方法配置参数
+ handleOptions, // get/post 方法配置参数
+ config, // init 全局config接口(setConfig 参数接口)
+ requestConfig, // 请求之前参数配置项
+ response // 响应体
+}
+```
+
+**常见问题**
+--
+1. 为什么会请求两次?
+ - 总有些小白问这些很那啥的问题,有两种可能,一种是‘post三次握手’(不知道的请先给个五星好评,然后打自己一巴掌,并问自己,为什么这都不知道),还有一种可能是`本地访问接口时跨域请求,所以浏览器会先发一个option 去预测能否成功,然后再发一个真正的请求`(没有自己观察请求头,Request Method,就跑来问的,请再打自己一巴掌,并问自己,为什么这都不知道,不知道也行,为什么不百度)。
+2. 如何跨域?
+ - 问的人不少,可以先百度了解一下。如何跨域
+3. post 怎么传不了数组的参数啊?
+ - uni-request
+ 可以点击看一下uni-request 的api 文档,data支持的文件类型只有Object/String/ArrayBuffer
这个真跟我没啥关系 0.0
+4. 'Content-Type' 为什么要小写?
+ - hbuilderX 更新至‘2.3.0.20190919’ 后,uni.request post请求,如果 ‘Content-Type’ 大写,就会在后面自动拼接‘ application/json’,请求头变成
+ `Content-Type: application/json;charset=UTF-8 application/json`,导致后端无法解析类型,`Status Code 415`,post 请求失败。但是小写就不会出现这个问题。至于为什么我也没有深究,我现在也不清楚这是他们的bug,还是以后就这样规范了。我能做的只有立马兼容,至于后边uni官方会不会继续变动也不清楚。
+5. 为什么不支持task?
+ - 一方面精力有限,另一方面违背了本人的一些意愿,具体看第6条
+6. 为什么不能配置超时时间?
+ - 配置超时时间,请求时需要task,并且每个请求都需要创建一个定时器,本人认为这个消耗没必要。设置超时时间可以通过manifest.json 配置进行设置。我想用的就是一个小而简单的请求插件。
+
+
+**tip**
+--
+- 不想使用upload 可把class 里的upload 删除
+
+
+**issue**
+--
+有任何问题或者建议可以=> issue提交,先给个五星好评QAQ!!
+
+
+**作者想说**
+--
+- 主体代码9kb
+- 目前该插件已经上项目,遇到任何问题请先检查自己的代码(排除新版本发布的情况)。最近新上了` typescript ` 版本,因为本人没使用过ts,所以写的不好的地方,还请见谅~
+- 写代码很容易,为了让你们看懂写文档真的很lei 0.0
+- 最近发现有插件与我雷同,当初接触uni-app 就发现插件市场虽然有封装的不错的request库,但是都没有对多全局配置做处理,都是通过修改源码的方式配置。我首先推出通过class类,并仿照axios的api实现request请求库,并起名‘仿axios封装request网络请求库,支持拦截器全局配置’。他们虽然修改了部分代码,但是功能与性能并没有优化,反而使代码很冗余。希望能推出新的功能,和性能更加强悍的请求库。
+- 任何形式的‘参考’、‘借鉴’,请标明作者
+ ```javascript
+ luch-request
+ ```
+- 关于问问题
+1. 首先请善于利用搜索引擎,不管百度,还是Google,遇到问题请先自己尝试解决。自己尝试过无法解决,再问。
+2. 不要问类似为什么我的xx无法使用这种问题。请仔细阅读文档,检查代码,或者说明运行环境,把相关代码贴至评论或者发送至我的邮箱,还可以点击上面的issue提交,在里面提问,可能我在里面已经回答了。
+3. 我的代码如果真的出现bug,或者你有好的建议、需求,可以提issue,我看到后会立即解决
+4. 不要问一些弱智问题!!!
+- 如何问问题
+1. 仔细阅读文档,检查代码
+2. 说明运行环境,比如:app端 ios、android 版本号、手机机型、普遍现象还是个别现象(越详细越好)
+3. 发出代码片段或者截图至邮箱(很重要)
+4. 或者可以在上方的'issue提交' 里发出详细的问题描述
+5. 以上都觉得解决不了你的问题,可以加QQ:`370306150`
+
+**土豪赞赏**
+--
+
+
+####创作不易,五星好评你懂得!
diff --git a/js_sdk/luch-request/request.js b/js_sdk/luch-request/request.js
new file mode 100644
index 0000000..17b3246
--- /dev/null
+++ b/js_sdk/luch-request/request.js
@@ -0,0 +1,339 @@
+/**
+ * Request 1.0.5
+ * @Class Request
+ * @description luch-request 1.0.4 http请求插件
+ * @Author lu-ch
+ * @Date 2019-12-12
+ * @Email webwork.s@qq.com
+ * http://ext.dcloud.net.cn/plugin?id=392
+ */
+export default class Request {
+ config = {
+ baseUrl: '',
+ header: {
+ 'content-type': 'application/json;charset=UTF-8'
+ },
+ method: 'GET',
+ dataType: 'json',
+ // #ifndef MP-ALIPAY || APP-PLUS
+ responseType: 'text',
+ // #endif
+ custom: {},
+ // #ifdef MP-ALIPAY
+ timeout: 30000,
+ // #endif
+ // #ifdef APP-PLUS
+ sslVerify: true
+ // #endif
+ }
+
+ static posUrl (url) { /* 判断url是否为绝对路径 */
+ return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
+ }
+
+ static addQueryString (params) {
+ let paramsData = ''
+ Object.keys(params).forEach(function (key) {
+ paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
+ })
+ return paramsData.substring(0, paramsData.length - 1)
+ }
+
+ /**
+ * @property {Function} request 请求拦截器
+ * @property {Function} response 响应拦截器
+ * @type {{request: Request.interceptor.request, response: Request.interceptor.response}}
+ */
+ interceptor = {
+ /**
+ * @param {Request~requestCallback} cb - 请求之前拦截,接收一个函数(config, cancel)=> {return config}。第一个参数为全局config,第二个参数为函数,调用则取消本次请求。
+ */
+ request: (cb) => {
+ if (cb) {
+ this.requestBeforeFun = cb
+ }
+ },
+ /**
+ * @param {Request~responseCallback} cb 响应拦截器,对响应数据做点什么
+ * @param {Request~responseErrCallback} ecb 响应拦截器,对响应错误做点什么
+ */
+ response: (cb, ecb) => {
+ if (cb && ecb) {
+ this.requestComFun = cb
+ this.requestComFail = ecb
+ }
+ }
+ }
+
+ requestBeforeFun (config) {
+ return config
+ }
+
+ requestComFun (response) {
+ return response
+ }
+
+ requestComFail (response) {
+ return response
+ }
+
+ /**
+ * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
+ * @param { Number } statusCode - 请求响应体statusCode(只读)
+ * @return { Boolean } 如果为true,则 resolve, 否则 reject
+ */
+ validateStatus (statusCode) {
+ return statusCode === 200
+ }
+
+ /**
+ * @Function
+ * @param {Request~setConfigCallback} f - 设置全局默认配置
+ */
+ setConfig (f) {
+ this.config = f(this.config)
+ }
+
+ /**
+ * @Function
+ * @param {Object} options - 请求配置项
+ * @prop {String} options.url - 请求路径
+ * @prop {Object} options.data - 请求参数
+ * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
+ * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
+ * @prop {Object} [options.header = config.header] - 请求header
+ * @prop {Object} [options.method = config.method] - 请求方法
+ * @returns {Promise}
+ */
+ async request (options = {}) {
+ options.baseUrl = this.config.baseUrl
+ options.dataType = options.dataType || this.config.dataType
+ // #ifndef MP-ALIPAY || APP-PLUS
+ options.responseType = options.responseType || this.config.responseType
+ // #endif
+ // #ifdef MP-ALIPAY
+ options.timeout = options.timeout || this.config.timeout
+ // #endif
+ options.url = options.url || ''
+ options.data = options.data || {}
+ options.params = options.params || {}
+ options.header = options.header || this.config.header
+ options.method = options.method || this.config.method
+ options.custom = { ...this.config.custom, ...(options.custom || {}) }
+ // #ifdef APP-PLUS
+ options.sslVerify = options.sslVerify === undefined ? this.config.sslVerify : options.sslVerify
+ // #endif
+ return new Promise((resolve, reject) => {
+ let next = true
+
+ let handleRe = {}
+ options.complete = (response) => {
+ response.config = handleRe
+ if (this.validateStatus(response.statusCode)) { // 成功
+ response = this.requestComFun(response)
+ resolve(response)
+ } else {
+ response = this.requestComFail(response)
+ reject(response)
+ }
+ }
+ const cancel = (t = 'handle cancel', config = options) => {
+ const err = {
+ errMsg: t,
+ config: config
+ }
+ reject(err)
+ next = false
+ }
+
+ handleRe = { ...this.requestBeforeFun(options, cancel) }
+ const _config = { ...handleRe }
+ if (!next) return
+ delete _config.custom
+ let mergeUrl = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
+ if (JSON.stringify(_config.params) !== '{}') {
+ const paramsH = Request.addQueryString(_config.params)
+ mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}`
+ }
+ _config.url = mergeUrl
+ uni.request(_config)
+ })
+ }
+
+ get (url, options = {}) {
+ return this.request({
+ url,
+ method: 'GET',
+ ...options
+ })
+ }
+
+ post (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'POST',
+ ...options
+ })
+ }
+
+ // #ifndef MP-ALIPAY
+ put (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'PUT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ delete (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'DELETE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN
+ connect (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'CONNECT',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ head (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'HEAD',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+ options (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'OPTIONS',
+ ...options
+ })
+ }
+
+ // #endif
+
+ // #ifdef APP-PLUS || H5 || MP-WEIXIN
+ trace (url, data, options = {}) {
+ return this.request({
+ url,
+ data,
+ method: 'TRACE',
+ ...options
+ })
+ }
+
+ // #endif
+
+ upload (url, {
+ // #ifdef APP-PLUS
+ files,
+ // #endif
+ // #ifdef MP-ALIPAY
+ fileType,
+ // #endif
+ filePath,
+ name,
+ header,
+ formData,
+ custom
+ }) {
+ return new Promise((resolve, reject) => {
+ let next = true
+ let handleRe = {}
+ const globalHeader = { ...this.config.header }
+ delete globalHeader['content-type']
+ const pubConfig = {
+ baseUrl: this.config.baseUrl,
+ url,
+ // #ifdef APP-PLUS
+ files,
+ // #endif
+ // #ifdef MP-ALIPAY
+ fileType,
+ // #endif
+ filePath,
+ method: 'UPLOAD',
+ name,
+ header: header || globalHeader,
+ formData,
+ custom: { ...this.config.custom, ...(custom || {}) },
+ complete: (response) => {
+ response.config = handleRe
+ if (response.statusCode === 200) { // 成功
+ response = this.requestComFun(response)
+ resolve(response)
+ } else {
+ response = this.requestComFail(response)
+ reject(response)
+ }
+ }
+ }
+ const cancel = (t = 'handle cancel', config = pubConfig) => {
+ const err = {
+ errMsg: t,
+ config: config
+ }
+ reject(err)
+ next = false
+ }
+
+ handleRe = { ...this.requestBeforeFun(pubConfig, cancel) }
+ const _config = { ...handleRe }
+ if (!next) return
+ delete _config.custom
+ _config.url = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
+ uni.uploadFile(_config)
+ })
+ }
+}
+
+/**
+ * setConfig回调
+ * @return {Object} - 返回操作后的config
+ * @callback Request~setConfigCallback
+ * @param {Object} config - 全局默认config
+ */
+/**
+ * 请求拦截器回调
+ * @return {Object} - 返回操作后的config
+ * @callback Request~requestCallback
+ * @param {Object} config - 全局config
+ * @param {Function} [cancel] - 取消请求钩子,调用会取消本次请求
+ */
+/**
+ * 响应拦截器回调
+ * @return {Object} - 返回操作后的response
+ * @callback Request~responseCallback
+ * @param {Object} response - 请求结果 response
+ */
+/**
+ * 响应错误拦截器回调
+ * @return {Object} - 返回操作后的response
+ * @callback Request~responseErrCallback
+ * @param {Object} response - 请求结果 response
+ */
diff --git a/main.js b/main.js
new file mode 100644
index 0000000..c897c41
--- /dev/null
+++ b/main.js
@@ -0,0 +1,37 @@
+import Vue from 'vue'
+import store from './store'
+import App from './App'
+
+const msg = (title, duration=1500, mask=false, icon='none')=>{
+ //统一提示方便全局修改
+ if(Boolean(title) === false){
+ return;
+ }
+ uni.showToast({
+ title,
+ duration,
+ mask,
+ icon
+ });
+}
+
+const prePage = ()=>{
+ let pages = getCurrentPages();
+ let prePage = pages[pages.length - 2];
+ // #ifdef H5
+ return prePage;
+ // #endif
+ return prePage.$vm;
+}
+
+Vue.config.productionTip = false
+Vue.prototype.$fire = new Vue();
+Vue.prototype.$store = store;
+Vue.prototype.$api = {msg, prePage};
+
+App.mpType = 'app'
+
+const app = new Vue({
+ ...App
+})
+app.$mount()
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
new file mode 100644
index 0000000..653c90d
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,74 @@
+{
+ "name" : "mall-app-web",
+ "appid" : "",
+ "description" : "",
+ "versionName" : "1.0.0",
+ "versionCode" : "100",
+ "transformPx" : false,
+ "app-plus" : {
+ /* 5+App特有相关 */
+ "usingComponents" : true,
+ "splashscreen" : {
+ "alwaysShowBeforeRender" : true,
+ "waiting" : true,
+ "autoclose" : true,
+ "delay" : 0
+ },
+ "modules" : {},
+ /* 模块配置 */
+ "distribute" : {
+ /* 应用发布信息 */
+ "android" : {
+ /* android打包配置 */
+ "permissions" : [
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ ]
+ },
+ "ios" : {},
+ /* ios打包配置 */
+ "sdkConfigs" : {}
+ }
+ },
+ /* SDK配置 */
+ "quickapp" : {},
+ /* 快应用特有相关 */
+ "mp-weixin" : {
+ /* 小程序特有相关 */
+ "usingComponents" : true,
+ "appid" : "",
+ "setting" : {
+ "urlCheck" : true
+ }
+ },
+ "h5" : {
+ "devServer" : {
+ "https" : false,
+ "port" : 8060
+ },
+ "domain" : "localhost",
+ "router" : {
+ "base" : ""
+ }
+ }
+}
diff --git a/pages.json b/pages.json
new file mode 100644
index 0000000..f3f96e6
--- /dev/null
+++ b/pages.json
@@ -0,0 +1,292 @@
+{
+ "pages": [
+
+ {
+ "path": "pages/index/index",
+ "style": {
+ // #ifdef MP
+ "navigationBarTitleText": "Mall商城",
+ //"navigationStyle": "custom",
+ // #endif
+ "enablePullDownRefresh": true,
+ "app-plus": {
+ "titleNView": {
+ "type": "transparent",
+ "searchInput": {
+ "backgroundColor": "rgba(231, 231, 231,.7)",
+ "borderRadius": "16px",
+ "placeholder": "请输入商品 如:手机",
+ "disabled": true,
+ "placeholderColor": "#606266"
+ },
+ "buttons": [{
+ "fontSrc": "/static/yticon.ttf",
+ "text": "\ue60d",
+ "fontSize": "26",
+ "color": "#303133",
+ "float": "left",
+ "background": "rgba(0,0,0,0)"
+ },
+ {
+ "fontSrc": "/static/yticon.ttf",
+ "text": "\ue744",
+ "fontSize": "27",
+ "color": "#303133",
+ "background": "rgba(0,0,0,0)",
+ "redDot": true
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "path": "pages/product/product",
+ "style": {
+ "navigationBarTitleText": "详情展示",
+ "app-plus": {
+ "titleNView": {
+ "type": "transparent"
+ }
+ }
+ }
+ }, {
+ "path": "pages/set/set",
+ "style": {
+ "navigationBarTitleText": "设置"
+ }
+ },
+
+ {
+ "path": "pages/userinfo/userinfo",
+ "style": {
+ "navigationBarTitleText": "修改资料"
+ }
+ }, {
+ "path": "pages/cart/cart",
+ "style": {
+ "navigationBarTitleText": "购物车"
+ }
+ }, {
+ "path": "pages/public/login",
+ "style": {
+ "navigationBarTitleText": "",
+ "navigationStyle": "custom",
+ "app-plus": {
+ "titleNView": false,
+ "animationType": "slide-in-bottom"
+ }
+ }
+ }, {
+ "path": "pages/user/user",
+ "style": {
+ "navigationBarTitleText": "我的",
+ // #ifdef MP
+ "navigationStyle": "custom",
+ // #endif
+ "app-plus": {
+ "bounce": "none",
+ "titleNView": {
+ "type": "transparent",
+ "buttons": [{
+ "fontSrc": "/static/yticon.ttf",
+ "text": "\ue60f",
+ "fontSize": "24",
+ "color": "#303133",
+ "width": "46px",
+ "background": "rgba(0,0,0,0)"
+ },
+ {
+ "fontSrc": "/static/yticon.ttf",
+ "text": "\ue744",
+ "fontSize": "28",
+ "color": "#303133",
+ "background": "rgba(0,0,0,0)",
+ "redDot": true
+ }
+ ]
+ }
+ }
+ }
+ }, {
+ "path": "pages/order/order",
+ "style": {
+ "navigationBarTitleText": "我的订单",
+ "app-plus": {
+ "bounce": "none"
+ }
+ }
+ }, {
+ "path": "pages/money/money",
+ "style": {}
+ }, {
+ "path": "pages/order/createOrder",
+ "style": {
+ "navigationBarTitleText": "创建订单"
+ }
+ }, {
+ "path": "pages/order/orderDetail",
+ "style": {
+ "navigationBarTitleText": "订单详情"
+ }
+ }, {
+ "path": "pages/address/address",
+ "style": {
+ "navigationBarTitleText": "收货地址"
+ }
+ }, {
+ "path": "pages/address/addressManage",
+ "style": {
+ "navigationBarTitleText": ""
+ }
+ }, {
+ "path": "pages/money/pay",
+ "style": {
+ "navigationBarTitleText": "支付"
+ }
+ },
+ {
+ "path": "pages/money/paySuccess",
+ "style": {
+ "navigationBarTitleText": "支付成功"
+ }
+ }, {
+ "path": "pages/notice/notice",
+ "style": {
+ "navigationBarTitleText": "通知"
+ }
+ }, {
+ "path": "pages/category/category",
+ "style": {
+ "navigationBarTitleText": "分类",
+ "app-plus": {
+ "bounce": "none"
+ }
+ }
+ }, {
+ "path": "pages/product/list",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "商品列表"
+ }
+ }, {
+ "path": "pages/coupon/couponList",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "优惠券列表"
+ }
+ }, {
+ "path": "pages/brand/brandDetail",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "品牌详情"
+ }
+ }, {
+ "path": "pages/brand/list",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "推荐品牌列表"
+ }
+ }, {
+ "path": "pages/product/newProductList",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "新鲜好物"
+ }
+ }, {
+ "path": "pages/product/hotProductList",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "人气推荐"
+ }
+ }, {
+ "path": "pages/user/readHistory",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "我的足迹",
+ "app-plus": {
+ "titleNView": {
+ "buttons": [{
+ "text": "清空",
+ "fontSize": "16",
+ "color": "#303133",
+ "width": "46px",
+ "background": "rgba(0,0,0,0)"
+ }]
+ }
+ }
+ }
+ },{
+ "path": "pages/user/productCollection",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "我的收藏",
+ "app-plus": {
+ "titleNView": {
+ "buttons": [{
+ "text": "清空",
+ "fontSize": "16",
+ "color": "#303133",
+ "width": "46px",
+ "background": "rgba(0,0,0,0)"
+ }]
+ }
+ }
+ }
+ },{
+ "path": "pages/user/brandAttention",
+ "style": {
+ "enablePullDownRefresh": true,
+ "navigationBarTitleText": "我的关注",
+ "app-plus": {
+ "titleNView": {
+ "buttons": [{
+ "text": "清空",
+ "fontSize": "16",
+ "color": "#303133",
+ "width": "46px",
+ "background": "rgba(0,0,0,0)"
+ }]
+ }
+ }
+ }
+ }
+ ],
+ "globalStyle": {
+ "navigationBarTextStyle": "black",
+ "navigationBarTitleText": "mall-app-web",
+ "navigationBarBackgroundColor": "#FFFFFF",
+ "backgroundColor": "#f8f8f8"
+ },
+ "tabBar": {
+ "color": "#C0C4CC",
+ "selectedColor": "#fa436a",
+ "borderStyle": "black",
+ "backgroundColor": "#ffffff",
+ "list": [{
+ "pagePath": "pages/index/index",
+ "iconPath": "static/tab-home.png",
+ "selectedIconPath": "static/tab-home-current.png",
+ "text": "首页"
+ },
+ {
+ "pagePath": "pages/category/category",
+ "iconPath": "static/tab-cate.png",
+ "selectedIconPath": "static/tab-cate-current.png",
+ "text": "分类"
+ },
+ {
+ "pagePath": "pages/cart/cart",
+ "iconPath": "static/tab-cart.png",
+ "selectedIconPath": "static/tab-cart-current.png",
+ "text": "购物车"
+ },
+ {
+ "pagePath": "pages/user/user",
+ "iconPath": "static/tab-my.png",
+ "selectedIconPath": "static/tab-my-current.png",
+ "text": "我的"
+ }
+ ]
+ }
+}
diff --git a/pages/address/address.vue b/pages/address/address.vue
new file mode 100644
index 0000000..ef26ae9
--- /dev/null
+++ b/pages/address/address.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+ 默认
+ {{item.province}} {{item.city}} {{item.region}} {{item.detailAddress}}
+
+
+ {{item.name}}
+ {{item.phoneNumber}}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/address/addressManage.vue b/pages/address/addressManage.vue
new file mode 100644
index 0000000..5ac2127
--- /dev/null
+++ b/pages/address/addressManage.vue
@@ -0,0 +1,199 @@
+
+
+
+ 姓名
+
+
+
+ 手机号码
+
+
+
+ 邮政编码
+
+
+
+ 所在区域
+
+ {{addressData.province}} {{addressData.city}} {{addressData.region}}
+
+
+
+
+ 详细地址
+
+
+
+
+ 设为默认
+
+
+
+
+
+
+
+
+
diff --git a/pages/brand/brandDetail.vue b/pages/brand/brandDetail.vue
new file mode 100644
index 0000000..4464598
--- /dev/null
+++ b/pages/brand/brandDetail.vue
@@ -0,0 +1,393 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{brand.name}}
+ 品牌首字母:{{brand.firstLetter}}
+
+
+
+
+
+
+ 品牌故事
+
+ {{brand.brandStory}}
+
+
+ 相关商品
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+
+ {{item.price}}
+ 已售 {{item.sale}}
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/brand/list.vue b/pages/brand/list.vue
new file mode 100644
index 0000000..af86882
--- /dev/null
+++ b/pages/brand/list.vue
@@ -0,0 +1,183 @@
+
+
+
+ 相关品牌
+
+
+
+
+
+ {{item.name}}
+ 商品数量:{{item.productCount}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/cart/cart.vue b/pages/cart/cart.vue
new file mode 100644
index 0000000..46c1f89
--- /dev/null
+++ b/pages/cart/cart.vue
@@ -0,0 +1,417 @@
+
+
+
+
+
+
+ 空空如也
+ 随便逛逛>
+
+
+ 空空如也
+ 去登陆>
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+ {{item.spDataStr}}
+ ¥{{item.price}}
+
+
+
+
+
+
+
+
+
+
+
+ 清空
+
+
+
+ ¥{{total}}元
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/category/category.vue b/pages/category/category.vue
new file mode 100644
index 0000000..bf50299
--- /dev/null
+++ b/pages/category/category.vue
@@ -0,0 +1,146 @@
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/coupon/couponList.vue b/pages/coupon/couponList.vue
new file mode 100644
index 0000000..5f80561
--- /dev/null
+++ b/pages/coupon/couponList.vue
@@ -0,0 +1,226 @@
+
+
+
+
+ {{item.text}}
+
+
+
+
+
+
+ {{item.name}}
+ 有效期至{{item.endTime | formatDateTime}}
+
+
+ {{item.amount}}
+ 满{{item.minPoint}}可用
+
+
+
+
+
+ {{item.useType | formatCouponUseType}}
+
+
+
+
+
+
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
new file mode 100644
index 0000000..6c376b3
--- /dev/null
+++ b/pages/index/index.vue
@@ -0,0 +1,848 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{swiperCurrent+1}}
+ /
+ {{swiperLength}}
+
+
+
+
+
+
+ 专题
+
+
+
+ 话题
+
+
+
+ 优选
+
+
+
+ 特惠
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ 商品数量:{{item.productCount}}
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+ ¥{{item.price}}
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+ ¥{{item.price}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+ ¥{{item.price}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+ ¥{{item.price}}
+
+
+
+
+
+
+
+
+
diff --git a/pages/money/money.vue b/pages/money/money.vue
new file mode 100644
index 0000000..8183fd0
--- /dev/null
+++ b/pages/money/money.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
diff --git a/pages/money/pay.vue b/pages/money/pay.vue
new file mode 100644
index 0000000..b369d84
--- /dev/null
+++ b/pages/money/pay.vue
@@ -0,0 +1,164 @@
+
+
+
+ 支付金额
+ {{orderInfo.payAmount}}
+
+
+
+
+
+
+
+ 微信支付
+ 推荐使用微信支付
+
+
+
+
+
+
+ 支付宝支付
+
+
+
+
+
+ 确认支付
+
+
+
+
+
+
diff --git a/pages/money/paySuccess.vue b/pages/money/paySuccess.vue
new file mode 100644
index 0000000..06ef07e
--- /dev/null
+++ b/pages/money/paySuccess.vue
@@ -0,0 +1,62 @@
+
+
+
+ 支付成功
+
+
+ 查看订单
+ 返回首页
+
+
+
+
+
+
+
diff --git a/pages/notice/notice.vue b/pages/notice/notice.vue
new file mode 100644
index 0000000..b8ed92a
--- /dev/null
+++ b/pages/notice/notice.vue
@@ -0,0 +1,153 @@
+
+
+
+ 11:30
+
+ 新品上市,全场满199减50
+
+
+
+
+ 虽然做了一件好事,但很有可能因此招来他人的无端猜测,例如被质疑是否藏有其他利己动机等,乃至谴责。即便如此,还是要做好事。
+
+
+ 查看详情
+
+
+
+
+
+ 昨天 12:30
+
+ 新品上市,全场满199减50
+
+
+
+ 活动结束
+
+
+
+ 查看详情
+
+
+
+
+
+ 2019-07-26 12:30
+
+ 新品上市,全场满199减50
+
+
+
+ 活动结束
+
+
+ 新品上市全场2折起,新品上市全场2折起,新品上市全场2折起,新品上市全场2折起,新品上市全场2折起
+
+ 查看详情
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/order/createOrder.vue b/pages/order/createOrder.vue
new file mode 100644
index 0000000..590ab65
--- /dev/null
+++ b/pages/order/createOrder.vue
@@ -0,0 +1,751 @@
+
+
+
+
+
+
+
+
+ {{currentAddress.name}}
+ {{currentAddress.phoneNumber}}
+
+ {{currentAddress.province}} {{currentAddress.city}} {{currentAddress.region}}
+ {{currentAddress.detailAddress}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+ {{item.productAttr | formatProductAttr}}
+ {{item.promotionMessage}}
+
+ ¥{{item.price}}
+ x {{item.quantity}}
+
+
+
+
+
+
+
+
+
+ 券
+
+ 优惠券
+
+ 选择优惠券
+
+
+
+
+
+ 积
+
+ 积分抵扣
+
+
+
+
+
+
+ 商品合计
+ ¥{{calcAmount.totalAmount}}
+
+
+ 运费
+ ¥{{calcAmount.freightAmount}}
+
+
+ 活动优惠
+ -¥{{calcAmount.promotionAmount}}
+
+
+ 优惠券
+ -¥{{currCoupon.amount}}
+ -¥0
+
+
+ 积分抵扣
+ -¥{{calcIntegrationAmount(useIntegration)}}
+
+
+ 备注
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ 有效期至{{item.endTime | formatDateTime}}
+
+
+ {{item.amount}}
+ 满{{item.minPoint}}可用
+
+
+
+
+
+ {{item.useType | formatCouponUseType}}
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/order/order.vue b/pages/order/order.vue
new file mode 100644
index 0000000..4888764
--- /dev/null
+++ b/pages/order/order.vue
@@ -0,0 +1,654 @@
+
+
+
+
+ {{item.text}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.createTime | formatDateTime}}
+ {{item.status | formatStatus}}
+
+
+
+
+
+ {{orderItem.productName}}
+ {{orderItem.productAttr | formatProductAttr}} x {{orderItem.productQuantity}}
+ {{orderItem.productPrice}}
+
+
+
+
+ 共
+ {{calcTotalQuantity(item)}}
+ 件商品 实付款
+ {{item.payAmount}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/order/orderDetail.vue b/pages/order/orderDetail.vue
new file mode 100644
index 0000000..c787466
--- /dev/null
+++ b/pages/order/orderDetail.vue
@@ -0,0 +1,775 @@
+
+
+
+
+ {{orderStatus.text}}
+
+
+
+
+
+
+
+ {{order.receiverName}}
+ {{order.receiverPhone}}
+
+ {{order.receiverProvince}} {{order.receiverCity}} {{order.receiverRegion}}
+ {{order.receiverDetailAddress}}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+ {{item.productAttr | formatProductAttr}}
+ {{item.promotionName}}
+
+ ¥{{item.productPrice}}
+ x {{item.productQuantity}}
+
+
+
+
+
+
+
+
+ 商品合计
+ ¥{{order.totalAmount}}
+
+
+ 运费
+ ¥{{order.freightAmount}}
+
+
+ 活动优惠
+ -¥{{order.promotionAmount}}
+
+
+ 优惠券
+ -¥{{order.couponAmount}}
+
+
+ 积分抵扣
+ -¥{{order.integrationAmount}}
+
+
+ 备注
+ {{order.note}}
+
+
+
+
+
+
+ 订单编号
+ {{order.orderSn}}
+
+
+ 提交时间
+ {{order.createTime | formatDateTime}}
+
+
+ 支付方式
+ {{order.payType | formatPayType}}
+
+
+ 实付金额
+ ¥{{order.payAmount}}
+
+
+ 付款时间
+ {{order.paymentTime | formatDateTime}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/product/hotProductList.vue b/pages/product/hotProductList.vue
new file mode 100644
index 0000000..618bb47
--- /dev/null
+++ b/pages/product/hotProductList.vue
@@ -0,0 +1,193 @@
+
+
+
+ 相关商品
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+
+ {{item.price}}
+ 已售 {{item.sale}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/product/list.vue b/pages/product/list.vue
new file mode 100644
index 0000000..5ea224d
--- /dev/null
+++ b/pages/product/list.vue
@@ -0,0 +1,440 @@
+
+
+
+
+ 综合排序
+
+
+ 销量优先
+
+
+ 价格
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+
+ {{item.price}}
+ 已售 {{item.sale}}
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+
+ {{tItem.name}}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/product/newProductList.vue b/pages/product/newProductList.vue
new file mode 100644
index 0000000..e6f6e74
--- /dev/null
+++ b/pages/product/newProductList.vue
@@ -0,0 +1,193 @@
+
+
+
+ 相关商品
+
+
+
+
+
+ {{item.name}}
+ {{item.subTitle}}
+
+ {{item.price}}
+ 已售 {{item.sale}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/product/product.vue b/pages/product/product.vue
new file mode 100644
index 0000000..ffec4ad
--- /dev/null
+++ b/pages/product/product.vue
@@ -0,0 +1,1492 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{product.name}}
+ {{product.subTitle}}
+
+ ¥
+ {{product.price}}
+ ¥{{product.originalPrice}}
+ 7折
+
+
+ 销量: {{product.sale}}
+ 库存: {{product.stock}}
+ 浏览量: 768
+
+
+
+
+
+
+
+ 返
+
+ 该商品分享可领49减10红包
+
+
+ 立即分享
+
+
+
+
+
+
+
+ 购买类型
+
+
+ {{sItem.name}}
+
+
+
+
+
+ 商品参数
+
+ 查看
+
+
+
+
+ 优惠券
+ 领取优惠券
+
+
+
+ 促销活动
+
+ {{item}}
+
+
+
+ 服务
+
+ {{item}} ·
+
+
+
+
+
+
+
+
+
+
+ Leo yo
+ 商品收到了,79元两件,质量不错,试了一下有点瘦,但是加个外罩很漂亮,我很喜欢
+
+ 购买类型:XL 红色
+ 2019-04-01 19:21
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{brand.name}}
+ 品牌首字母:{{brand.firstLetter}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 首页
+
+
+
+ 购物车
+
+
+
+ 收藏
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{item.name}}
+ 有效期至{{item.endTime | formatDateTime}}
+
+
+ {{item.amount}}
+ 满{{item.minPoint}}可用
+
+
+
+
+
+ {{item.useType | formatCouponUseType}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/public/login.vue b/pages/public/login.vue
new file mode 100644
index 0000000..0e77f60
--- /dev/null
+++ b/pages/public/login.vue
@@ -0,0 +1,241 @@
+
+
+
+
+
+
+
+ LOGIN
+
+ 欢迎回来!
+
+
+
+ 用户名
+
+
+
+ 密码
+
+
+
+
+
+ 忘记密码?
+
+
+
+ 还没有账号?
+ 马上注册
+
+
+
+
+
+
+
diff --git a/pages/set/set.vue b/pages/set/set.vue
new file mode 100644
index 0000000..4686133
--- /dev/null
+++ b/pages/set/set.vue
@@ -0,0 +1,136 @@
+
+
+
+ 个人资料
+
+
+
+ 收货地址
+
+
+
+ 实名认证
+
+
+
+
+ 消息推送
+
+
+
+ 清除缓存
+
+
+
+ 关于mall-app-web
+
+
+
+ 检查更新
+ 当前版本 1.0.0
+
+
+
+ 退出登录
+
+
+
+
+
+
+
diff --git a/pages/user/brandAttention.vue b/pages/user/brandAttention.vue
new file mode 100644
index 0000000..29436ff
--- /dev/null
+++ b/pages/user/brandAttention.vue
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.brandName}}
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/productCollection.vue b/pages/user/productCollection.vue
new file mode 100644
index 0000000..f336e96
--- /dev/null
+++ b/pages/user/productCollection.vue
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+ {{item.productSubTitle}}
+
+ ¥{{item.productPrice}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/readHistory.vue b/pages/user/readHistory.vue
new file mode 100644
index 0000000..1afab28
--- /dev/null
+++ b/pages/user/readHistory.vue
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+ {{item.productName}}
+ {{item.productSubTitle}}
+
+ ¥{{item.productPrice}}
+ {{item.createTime | formatDateTime}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pages/user/user.vue b/pages/user/user.vue
new file mode 100644
index 0000000..476694b
--- /dev/null
+++ b/pages/user/user.vue
@@ -0,0 +1,377 @@
+
+
+
+
+
+
+
+
+
+
+ {{userInfo.nickname || '游客'}}
+
+
+
+
+
+ 立即开通
+
+
+
+ 黄金会员
+
+ mall移动端商城
+ 黄金及以上会员可享有会员价优惠商品。
+
+
+
+
+
+
+
+
+ {{userInfo.integration || '暂无'}}
+ 积分
+
+
+ {{userInfo.growth || '暂无'}}
+ 成长值
+
+
+ {{couponCount || '暂无'}}
+ 优惠券
+
+
+
+
+
+
+ 全部订单
+
+
+
+ 待付款
+
+
+
+ 待收货
+
+
+
+ 退款/售后
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/userinfo/userinfo.vue b/pages/userinfo/userinfo.vue
new file mode 100644
index 0000000..85a3a16
--- /dev/null
+++ b/pages/userinfo/userinfo.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/static/arc.png b/static/arc.png
new file mode 100644
index 0000000..c7ef6df
Binary files /dev/null and b/static/arc.png differ
diff --git a/static/emptyCart.jpg b/static/emptyCart.jpg
new file mode 100644
index 0000000..be15652
Binary files /dev/null and b/static/emptyCart.jpg differ
diff --git a/static/errorImage.jpg b/static/errorImage.jpg
new file mode 100644
index 0000000..7a76067
Binary files /dev/null and b/static/errorImage.jpg differ
diff --git a/static/hot_product_banner.png b/static/hot_product_banner.png
new file mode 100644
index 0000000..cdb42fa
Binary files /dev/null and b/static/hot_product_banner.png differ
diff --git a/static/icon_close.png b/static/icon_close.png
new file mode 100644
index 0000000..482a9c1
Binary files /dev/null and b/static/icon_close.png differ
diff --git a/static/icon_deliver.png b/static/icon_deliver.png
new file mode 100644
index 0000000..85607e0
Binary files /dev/null and b/static/icon_deliver.png differ
diff --git a/static/icon_finish.png b/static/icon_finish.png
new file mode 100644
index 0000000..986fea4
Binary files /dev/null and b/static/icon_finish.png differ
diff --git a/static/icon_flash_promotion.png b/static/icon_flash_promotion.png
new file mode 100644
index 0000000..328b38a
Binary files /dev/null and b/static/icon_flash_promotion.png differ
diff --git a/static/icon_home_brand.png b/static/icon_home_brand.png
new file mode 100644
index 0000000..dc00132
Binary files /dev/null and b/static/icon_home_brand.png differ
diff --git a/static/icon_hot_product.png b/static/icon_hot_product.png
new file mode 100644
index 0000000..b82e81f
Binary files /dev/null and b/static/icon_hot_product.png differ
diff --git a/static/icon_new_product.png b/static/icon_new_product.png
new file mode 100644
index 0000000..099b204
Binary files /dev/null and b/static/icon_new_product.png differ
diff --git a/static/icon_receive.png b/static/icon_receive.png
new file mode 100644
index 0000000..f652e0a
Binary files /dev/null and b/static/icon_receive.png differ
diff --git a/static/icon_recommend_product.png b/static/icon_recommend_product.png
new file mode 100644
index 0000000..a381f78
Binary files /dev/null and b/static/icon_recommend_product.png differ
diff --git a/static/icon_wait.png b/static/icon_wait.png
new file mode 100644
index 0000000..06e72a5
Binary files /dev/null and b/static/icon_wait.png differ
diff --git a/static/missing-face.png b/static/missing-face.png
new file mode 100644
index 0000000..c9be652
Binary files /dev/null and b/static/missing-face.png differ
diff --git a/static/new_product_banner.png b/static/new_product_banner.png
new file mode 100644
index 0000000..fcd717f
Binary files /dev/null and b/static/new_product_banner.png differ
diff --git a/static/recommend_brand_banner.png b/static/recommend_brand_banner.png
new file mode 100644
index 0000000..f0b4336
Binary files /dev/null and b/static/recommend_brand_banner.png differ
diff --git a/static/select.png b/static/select.png
new file mode 100644
index 0000000..fff0c32
Binary files /dev/null and b/static/select.png differ
diff --git a/static/selected.png b/static/selected.png
new file mode 100644
index 0000000..1719f1b
Binary files /dev/null and b/static/selected.png differ
diff --git a/static/tab-cart-current.png b/static/tab-cart-current.png
new file mode 100644
index 0000000..e8b1c26
Binary files /dev/null and b/static/tab-cart-current.png differ
diff --git a/static/tab-cart.png b/static/tab-cart.png
new file mode 100644
index 0000000..2fb3e8c
Binary files /dev/null and b/static/tab-cart.png differ
diff --git a/static/tab-cate-current.png b/static/tab-cate-current.png
new file mode 100644
index 0000000..406a7a0
Binary files /dev/null and b/static/tab-cate-current.png differ
diff --git a/static/tab-cate.png b/static/tab-cate.png
new file mode 100644
index 0000000..f93cebd
Binary files /dev/null and b/static/tab-cate.png differ
diff --git a/static/tab-home-current.png b/static/tab-home-current.png
new file mode 100644
index 0000000..92947e2
Binary files /dev/null and b/static/tab-home-current.png differ
diff --git a/static/tab-home.png b/static/tab-home.png
new file mode 100644
index 0000000..1b51640
Binary files /dev/null and b/static/tab-home.png differ
diff --git a/static/tab-my-current.png b/static/tab-my-current.png
new file mode 100644
index 0000000..c1f09b5
Binary files /dev/null and b/static/tab-my-current.png differ
diff --git a/static/tab-my.png b/static/tab-my.png
new file mode 100644
index 0000000..f742ffc
Binary files /dev/null and b/static/tab-my.png differ
diff --git a/static/temp/ad-splash.jpg b/static/temp/ad-splash.jpg
new file mode 100644
index 0000000..b4256a7
Binary files /dev/null and b/static/temp/ad-splash.jpg differ
diff --git a/static/temp/ad1.jpg b/static/temp/ad1.jpg
new file mode 100644
index 0000000..4c9a933
Binary files /dev/null and b/static/temp/ad1.jpg differ
diff --git a/static/temp/ad2.jpg b/static/temp/ad2.jpg
new file mode 100644
index 0000000..9d8fe9c
Binary files /dev/null and b/static/temp/ad2.jpg differ
diff --git a/static/temp/ad3.jpg b/static/temp/ad3.jpg
new file mode 100644
index 0000000..a28f11e
Binary files /dev/null and b/static/temp/ad3.jpg differ
diff --git a/static/temp/banner1.jpg b/static/temp/banner1.jpg
new file mode 100644
index 0000000..52d9192
Binary files /dev/null and b/static/temp/banner1.jpg differ
diff --git a/static/temp/banner2.jpg b/static/temp/banner2.jpg
new file mode 100644
index 0000000..7ed865f
Binary files /dev/null and b/static/temp/banner2.jpg differ
diff --git a/static/temp/banner3.jpg b/static/temp/banner3.jpg
new file mode 100644
index 0000000..3529b8f
Binary files /dev/null and b/static/temp/banner3.jpg differ
diff --git a/static/temp/banner4.jpg b/static/temp/banner4.jpg
new file mode 100644
index 0000000..afb1111
Binary files /dev/null and b/static/temp/banner4.jpg differ
diff --git a/static/temp/c1.png b/static/temp/c1.png
new file mode 100644
index 0000000..0ca677f
Binary files /dev/null and b/static/temp/c1.png differ
diff --git a/static/temp/c2.png b/static/temp/c2.png
new file mode 100644
index 0000000..51fc162
Binary files /dev/null and b/static/temp/c2.png differ
diff --git a/static/temp/c3.png b/static/temp/c3.png
new file mode 100644
index 0000000..c72f8a3
Binary files /dev/null and b/static/temp/c3.png differ
diff --git a/static/temp/c4.png b/static/temp/c4.png
new file mode 100644
index 0000000..e72766c
Binary files /dev/null and b/static/temp/c4.png differ
diff --git a/static/temp/c5.png b/static/temp/c5.png
new file mode 100644
index 0000000..5ea4377
Binary files /dev/null and b/static/temp/c5.png differ
diff --git a/static/temp/c6.png b/static/temp/c6.png
new file mode 100644
index 0000000..23d6bc9
Binary files /dev/null and b/static/temp/c6.png differ
diff --git a/static/temp/c7.png b/static/temp/c7.png
new file mode 100644
index 0000000..1179641
Binary files /dev/null and b/static/temp/c7.png differ
diff --git a/static/temp/c8.png b/static/temp/c8.png
new file mode 100644
index 0000000..43b3839
Binary files /dev/null and b/static/temp/c8.png differ
diff --git a/static/temp/cate1.jpg b/static/temp/cate1.jpg
new file mode 100644
index 0000000..c2a4446
Binary files /dev/null and b/static/temp/cate1.jpg differ
diff --git a/static/temp/cate10.jpg b/static/temp/cate10.jpg
new file mode 100644
index 0000000..ac54ab2
Binary files /dev/null and b/static/temp/cate10.jpg differ
diff --git a/static/temp/cate11.jpg b/static/temp/cate11.jpg
new file mode 100644
index 0000000..feb127e
Binary files /dev/null and b/static/temp/cate11.jpg differ
diff --git a/static/temp/cate12.jpg b/static/temp/cate12.jpg
new file mode 100644
index 0000000..9d0b876
Binary files /dev/null and b/static/temp/cate12.jpg differ
diff --git a/static/temp/cate13.jpg b/static/temp/cate13.jpg
new file mode 100644
index 0000000..e87708b
Binary files /dev/null and b/static/temp/cate13.jpg differ
diff --git a/static/temp/cate14.jpg b/static/temp/cate14.jpg
new file mode 100644
index 0000000..649d7c0
Binary files /dev/null and b/static/temp/cate14.jpg differ
diff --git a/static/temp/cate15.jpg b/static/temp/cate15.jpg
new file mode 100644
index 0000000..22166bd
Binary files /dev/null and b/static/temp/cate15.jpg differ
diff --git a/static/temp/cate16.jpg b/static/temp/cate16.jpg
new file mode 100644
index 0000000..3793133
Binary files /dev/null and b/static/temp/cate16.jpg differ
diff --git a/static/temp/cate17.jpg b/static/temp/cate17.jpg
new file mode 100644
index 0000000..e918265
Binary files /dev/null and b/static/temp/cate17.jpg differ
diff --git a/static/temp/cate18.jpg b/static/temp/cate18.jpg
new file mode 100644
index 0000000..46ae363
Binary files /dev/null and b/static/temp/cate18.jpg differ
diff --git a/static/temp/cate19.jpg b/static/temp/cate19.jpg
new file mode 100644
index 0000000..a3af0a6
Binary files /dev/null and b/static/temp/cate19.jpg differ
diff --git a/static/temp/cate2.jpg b/static/temp/cate2.jpg
new file mode 100644
index 0000000..f76c42e
Binary files /dev/null and b/static/temp/cate2.jpg differ
diff --git a/static/temp/cate20.jpg b/static/temp/cate20.jpg
new file mode 100644
index 0000000..6f675cc
Binary files /dev/null and b/static/temp/cate20.jpg differ
diff --git a/static/temp/cate21.jpg b/static/temp/cate21.jpg
new file mode 100644
index 0000000..b0b118b
Binary files /dev/null and b/static/temp/cate21.jpg differ
diff --git a/static/temp/cate22.jpg b/static/temp/cate22.jpg
new file mode 100644
index 0000000..c2980c1
Binary files /dev/null and b/static/temp/cate22.jpg differ
diff --git a/static/temp/cate23.jpg b/static/temp/cate23.jpg
new file mode 100644
index 0000000..1f5efaf
Binary files /dev/null and b/static/temp/cate23.jpg differ
diff --git a/static/temp/cate24.jpg b/static/temp/cate24.jpg
new file mode 100644
index 0000000..4278703
Binary files /dev/null and b/static/temp/cate24.jpg differ
diff --git a/static/temp/cate3.jpg b/static/temp/cate3.jpg
new file mode 100644
index 0000000..2a10362
Binary files /dev/null and b/static/temp/cate3.jpg differ
diff --git a/static/temp/cate4.jpg b/static/temp/cate4.jpg
new file mode 100644
index 0000000..71fd313
Binary files /dev/null and b/static/temp/cate4.jpg differ
diff --git a/static/temp/cate5.jpg b/static/temp/cate5.jpg
new file mode 100644
index 0000000..5caeb6e
Binary files /dev/null and b/static/temp/cate5.jpg differ
diff --git a/static/temp/cate6.jpg b/static/temp/cate6.jpg
new file mode 100644
index 0000000..cc42bcb
Binary files /dev/null and b/static/temp/cate6.jpg differ
diff --git a/static/temp/cate7.jpg b/static/temp/cate7.jpg
new file mode 100644
index 0000000..8851046
Binary files /dev/null and b/static/temp/cate7.jpg differ
diff --git a/static/temp/cate8.jpg b/static/temp/cate8.jpg
new file mode 100644
index 0000000..03a8c77
Binary files /dev/null and b/static/temp/cate8.jpg differ
diff --git a/static/temp/cate9.jpg b/static/temp/cate9.jpg
new file mode 100644
index 0000000..3387f03
Binary files /dev/null and b/static/temp/cate9.jpg differ
diff --git a/static/temp/h1.png b/static/temp/h1.png
new file mode 100644
index 0000000..caa6d19
Binary files /dev/null and b/static/temp/h1.png differ
diff --git a/static/temp/secskill-img.jpg b/static/temp/secskill-img.jpg
new file mode 100644
index 0000000..ea21ae9
Binary files /dev/null and b/static/temp/secskill-img.jpg differ
diff --git a/static/temp/share_moment.png b/static/temp/share_moment.png
new file mode 100644
index 0000000..6fbb733
Binary files /dev/null and b/static/temp/share_moment.png differ
diff --git a/static/temp/share_qq.png b/static/temp/share_qq.png
new file mode 100644
index 0000000..5cedd48
Binary files /dev/null and b/static/temp/share_qq.png differ
diff --git a/static/temp/share_qqzone.png b/static/temp/share_qqzone.png
new file mode 100644
index 0000000..ec4115d
Binary files /dev/null and b/static/temp/share_qqzone.png differ
diff --git a/static/temp/share_wechat.png b/static/temp/share_wechat.png
new file mode 100644
index 0000000..f88a7a7
Binary files /dev/null and b/static/temp/share_wechat.png differ
diff --git a/static/user-bg.jpg b/static/user-bg.jpg
new file mode 100644
index 0000000..2b3db62
Binary files /dev/null and b/static/user-bg.jpg differ
diff --git a/static/vip-card-bg.png b/static/vip-card-bg.png
new file mode 100644
index 0000000..6840371
Binary files /dev/null and b/static/vip-card-bg.png differ
diff --git a/static/yticon.ttf b/static/yticon.ttf
new file mode 100644
index 0000000..966501e
Binary files /dev/null and b/static/yticon.ttf differ
diff --git a/store/index.js b/store/index.js
new file mode 100644
index 0000000..3d2a508
--- /dev/null
+++ b/store/index.js
@@ -0,0 +1,38 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex)
+
+const store = new Vuex.Store({
+ state: {
+ hasLogin: false,
+ userInfo: {},
+ },
+ mutations: {
+ login(state, provider) {
+
+ state.hasLogin = true;
+ state.userInfo = provider;
+ uni.setStorage({//缓存用户登陆状态
+ key: 'userInfo',
+ data: provider
+ })
+ console.log(state.userInfo);
+ },
+ logout(state) {
+ state.hasLogin = false;
+ state.userInfo = {};
+ uni.removeStorage({
+ key: 'userInfo'
+ });
+ uni.removeStorage({
+ key: 'token'
+ })
+ }
+ },
+ actions: {
+
+ }
+})
+
+export default store
diff --git a/uni.scss b/uni.scss
new file mode 100644
index 0000000..df10aef
--- /dev/null
+++ b/uni.scss
@@ -0,0 +1,31 @@
+
+/* 页面左右间距 */
+$page-row-spacing: 30upx;
+$page-color-base: #f8f8f8;
+$page-color-light: #f8f6fc;
+$base-color: #fa436a;
+
+/* 文字尺寸 */
+$font-sm: 24upx;
+$font-base: 28upx;
+$font-lg: 32upx;
+/*文字颜色*/
+$font-color-dark: #303133;
+$font-color-base: #606266;
+$font-color-light: #909399;
+$font-color-disabled: #C0C4CC;
+$font-color-spec: #4399fc;
+/* 边框颜色 */
+$border-color-dark: #DCDFE6;
+$border-color-base: #E4E7ED;
+$border-color-light: #EBEEF5;
+/* 图片加载中颜色 */
+$image-bg-color: #eee;
+/* 行为相关颜色 */
+$uni-color-primary:#fa436a;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+
+
diff --git a/utils/date.js b/utils/date.js
new file mode 100644
index 0000000..7c1a591
--- /dev/null
+++ b/utils/date.js
@@ -0,0 +1,42 @@
+// date.js
+export function formatDate(date, fmt) {
+ if (/(y+)/.test(fmt)) {
+ fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
+ }
+ let o = {
+ 'M+': date.getMonth() + 1,
+ 'd+': date.getDate(),
+ 'h+': date.getHours(),
+ 'm+': date.getMinutes(),
+ 's+': date.getSeconds()
+ };
+ for (let k in o) {
+ if (new RegExp(`(${k})`).test(fmt)) {
+ let str = o[k] + '';
+ fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
+ }
+ }
+ return fmt;
+}
+
+function padLeftZero(str) {
+ return ('00' + str).substr(str.length);
+}
+
+export function str2Date(dateStr, separator) {
+ if (!separator) {
+ separator = "-";
+ }
+ let dateArr = dateStr.split(separator);
+ let year = parseInt(dateArr[0]);
+ let month;
+ //处理月份为04这样的情况
+ if (dateArr[1].indexOf("0") == 0) {
+ month = parseInt(dateArr[1].substring(1));
+ } else {
+ month = parseInt(dateArr[1]);
+ }
+ let day = parseInt(dateArr[2]);
+ let date = new Date(year, month - 1, day);
+ return date;
+}
diff --git a/utils/requestUtil.js b/utils/requestUtil.js
new file mode 100644
index 0000000..2261509
--- /dev/null
+++ b/utils/requestUtil.js
@@ -0,0 +1,86 @@
+import Request from '@/js_sdk/luch-request/request.js'
+
+const http = new Request()
+
+http.setConfig((config) => { /* 设置全局配置 */
+ config.baseUrl = 'http://localhost:8085' /* 根域名不同 */
+ config.header = {
+ ...config.header
+ }
+ return config
+})
+
+/**
+ * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
+ * @param { Number } statusCode - 请求响应体statusCode(只读)
+ * @return { Boolean } 如果为true,则 resolve, 否则 reject
+ */
+http.validateStatus = (statusCode) => {
+ return statusCode === 200
+}
+
+http.interceptor.request((config, cancel) => { /* 请求之前拦截器 */
+ const token = uni.getStorageSync('token');
+ if(token){
+ config.header = {
+ 'Authorization':token,
+ ...config.header
+ }
+ }else{
+ config.header = {
+ ...config.header
+ }
+ }
+ /*
+ if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
+ cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
+ }
+ */
+ return config
+})
+
+http.interceptor.response((response) => { /* 请求之后拦截器 */
+ const res = response.data;
+ if (res.code !== 200) {
+ //提示错误信息
+ uni.showToast({
+ title:res.message,
+ duration:1500
+ })
+ //401未登录处理
+ if (res.code === 401) {
+ uni.showModal({
+ title: '提示',
+ content: '你已被登出,可以取消继续留在该页面,或者重新登录',
+ confirmText:'重新登录',
+ cancelText:'取消',
+ success: function(res) {
+ if (res.confirm) {
+ uni.navigateTo({
+ url: '/pages/public/login'
+ })
+ } else if (res.cancel) {
+ console.log('用户点击取消');
+ }
+ }
+ });
+ }
+ return Promise.reject(response);
+ } else {
+ return response.data;
+ }
+}, (response) => {
+ //提示错误信息
+ console.log('response error', response);
+ uni.showToast({
+ title:response.errMsg,
+ duration:1500
+ })
+ return Promise.reject(response);
+})
+
+export function request (options = {}) {
+ return http.request(options);
+}
+
+export default request
\ No newline at end of file