xiebaomin hace 1 año
padre
commit
8e323b37dd
Se han modificado 48 ficheros con 1224 adiciones y 248 borrados
  1. 4 3
      .env.development
  2. 144 1
      package-lock.json
  3. 4 1
      package.json
  4. 18 0
      src/api/userApi/goods-information.js
  5. 25 0
      src/api/userApi/ins-intention-report.js
  6. 64 2
      src/api/userApi/login.js
  7. 11 0
      src/api/userApi/mine-card.js
  8. 9 0
      src/api/userApi/shopping-mall.js
  9. 31 0
      src/api/userApi/team.js
  10. 140 0
      src/components/field-image-code.vue
  11. 2 2
      src/components/goods-card.vue
  12. 7 10
      src/components/mine-card.vue
  13. 5 5
      src/components/store-card.vue
  14. 11 7
      src/components/team-card.vue
  15. 34 28
      src/permission.js
  16. 1 10
      src/plugin/toast.js
  17. 24 0
      src/router/index.js
  18. 4 1
      src/store/getter.js
  19. 9 1
      src/store/index.js
  20. 54 4
      src/store/user.js
  21. 4 4
      src/util/auth.js
  22. 7 7
      src/util/http.js
  23. 7 7
      src/views/goods-information/components/infoCell.vue
  24. 24 10
      src/views/goods-information/detail.vue
  25. 20 6
      src/views/goods-information/index.vue
  26. 13 8
      src/views/ins-intention-report/add.vue
  27. 1 1
      src/views/ins-intention-report/components/report-select-popup.vue
  28. 2 2
      src/views/ins-intention-report/components/search-head.vue
  29. 62 29
      src/views/ins-intention-report/index.vue
  30. 50 33
      src/views/login/login.vue
  31. 13 11
      src/views/login/pwlogin.vue
  32. 47 11
      src/views/mine-card/index.vue
  33. 43 7
      src/views/mine-card/qrcode.vue
  34. 0 1
      src/views/mine-card/save-card.vue
  35. 6 1
      src/views/mine/index.vue
  36. 53 18
      src/views/my-team/addTeam.vue
  37. 18 5
      src/views/my-team/index.vue
  38. 6 2
      src/views/order-list/address-select.vue
  39. 3 2
      src/views/order-list/components/contact-select.vue
  40. 1 0
      src/views/order-list/components/invoice-information.vue
  41. 16 0
      src/views/order-list/components/payment-records.vue
  42. 16 0
      src/views/order-list/components/payment-voucher.vue
  43. 4 1
      src/views/order-list/index.vue
  44. 15 0
      src/views/order-list/offline-payment.vue
  45. 15 0
      src/views/order-list/online-payment.vue
  46. 157 0
      src/views/order-list/order-detail.vue
  47. 17 2
      src/views/shopping-mall/index.vue
  48. 3 5
      vue.config.js

+ 4 - 3
.env.development

@@ -5,13 +5,14 @@ NODE_ENV = 'development'
 LOCALHOSE = 'https://zp-b.caimei365.com'
 
 # 接口api地址
-BASE_URL = 'https://zplma-b.caimei365.com'
+VUE_APP_URL = 'http://192.168.2.103:18002'
+#VUE_APP_URL = 'https://core-b.caimei365.com'
 
 # 静态资源文件地址
 STATIC_URL = 'https://static.caimei365.com/www/authentic'
 
-# 采美网
-CIMEI_LOCAL = 'https://www-b.caimei365.com'
+# 图片上传
+CIMEI_LOCAL = 'https://core-b.caimei365.com'
 
 # 项目运行地址
 # HOST = "localhost"

+ 144 - 1
package-lock.json

@@ -11,13 +11,16 @@
         "axios": "^1.5.0",
         "core-js": "^3.6.5",
         "element-ui": "^2.15.14",
+        "html2canvas": "^1.4.1",
         "js-cookie": "^3.0.5",
         "nprogress": "^0.2.0",
         "sass": "^1.68.0",
         "vant": "^2.13.0",
         "vue": "^2.6.11",
         "vue-router": "^3.2.0",
-        "vuex": "^3.4.0"
+        "vuex": "^3.4.0",
+        "vuex-persistedstate": "^4.1.0",
+        "weixin-js-sdk": "^1.6.0"
       },
       "devDependencies": {
         "@vue/cli-plugin-babel": "~4.5.19",
@@ -3833,6 +3836,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -5495,6 +5506,14 @@
         "node": ">4"
       }
     },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/css-loader": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz",
@@ -8636,6 +8655,18 @@
         "node": ">=6"
       }
     },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/htmlparser2": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
@@ -13585,6 +13616,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/shvl": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/shvl/-/shvl-2.0.3.tgz",
+      "integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw==",
+      "deprecated": "older versions vulnerable to prototype pollution"
+    },
     "node_modules/side-channel": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -14778,6 +14815,14 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -15625,6 +15670,14 @@
         "node": ">= 0.4.0"
       }
     },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "node_modules/uuid": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -16020,6 +16073,27 @@
         "vue": "^2.0.0"
       }
     },
+    "node_modules/vuex-persistedstate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/vuex-persistedstate/-/vuex-persistedstate-4.1.0.tgz",
+      "integrity": "sha512-3SkEj4NqwM69ikJdFVw6gObeB0NHyspRYMYkR/EbhR0hbvAKyR5gksVhtAfY1UYuWUOCCA0QNGwv9pOwdj+XUQ==",
+      "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
+      "dependencies": {
+        "deepmerge": "^4.2.2",
+        "shvl": "^2.0.3"
+      },
+      "peerDependencies": {
+        "vuex": "^3.0 || ^4.0.0-rc"
+      }
+    },
+    "node_modules/vuex-persistedstate/node_modules/deepmerge": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+      "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/watchpack": {
       "version": "1.7.5",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
@@ -16894,6 +16968,11 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/weixin-js-sdk": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
+      "integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
+    },
     "node_modules/which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -20122,6 +20201,11 @@
         }
       }
     },
+    "base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="
+    },
     "base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -21471,6 +21555,14 @@
         "timsort": "^0.3.0"
       }
     },
+    "css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "css-loader": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz",
@@ -23932,6 +24024,15 @@
         }
       }
     },
+    "html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "requires": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      }
+    },
     "htmlparser2": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
@@ -27891,6 +27992,11 @@
       "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
       "dev": true
     },
+    "shvl": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmmirror.com/shvl/-/shvl-2.0.3.tgz",
+      "integrity": "sha512-V7C6S9Hlol6SzOJPnQ7qzOVEWUQImt3BNmmzh40wObhla3XOYMe4gGiYzLrJd5TFa+cI2f9LKIRJTTKZSTbWgw=="
+    },
     "side-channel": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -28869,6 +28975,14 @@
         }
       }
     },
+    "text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "requires": {
+        "utrie": "^1.0.2"
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -29541,6 +29655,14 @@
       "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
       "dev": true
     },
+    "utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "requires": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "uuid": {
       "version": "3.4.0",
       "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
@@ -29849,6 +29971,22 @@
       "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==",
       "requires": {}
     },
+    "vuex-persistedstate": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmmirror.com/vuex-persistedstate/-/vuex-persistedstate-4.1.0.tgz",
+      "integrity": "sha512-3SkEj4NqwM69ikJdFVw6gObeB0NHyspRYMYkR/EbhR0hbvAKyR5gksVhtAfY1UYuWUOCCA0QNGwv9pOwdj+XUQ==",
+      "requires": {
+        "deepmerge": "^4.2.2",
+        "shvl": "^2.0.3"
+      },
+      "dependencies": {
+        "deepmerge": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.1.tgz",
+          "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
+        }
+      }
+    },
     "watchpack": {
       "version": "1.7.5",
       "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
@@ -30548,6 +30686,11 @@
       "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
       "dev": true
     },
+    "weixin-js-sdk": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
+      "integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
+    },
     "which": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",

+ 4 - 1
package.json

@@ -12,13 +12,16 @@
     "axios": "^1.5.0",
     "core-js": "^3.6.5",
     "element-ui": "^2.15.14",
+    "html2canvas": "^1.4.1",
     "js-cookie": "^3.0.5",
     "nprogress": "^0.2.0",
     "sass": "^1.68.0",
     "vant": "^2.13.0",
     "vue": "^2.6.11",
     "vue-router": "^3.2.0",
-    "vuex": "^3.4.0"
+    "vuex": "^3.4.0",
+    "vuex-persistedstate": "^4.1.0",
+    "weixin-js-sdk": "^1.6.0"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.19",

+ 18 - 0
src/api/userApi/goods-information.js

@@ -0,0 +1,18 @@
+import http from '@/util/http'
+
+export const getArchiveList = params => http({
+  url: '/commodity/reportingClub/archiveList',
+  params,
+  headers: {
+    isToken: true
+  }
+})
+
+// 商品资料详情
+export const archiveDetail = params => http({
+  url: '/commodity/product/archive/detail',
+  params,
+  headers: {
+    isToken: true
+  }
+})

+ 25 - 0
src/api/userApi/ins-intention-report.js

@@ -0,0 +1,25 @@
+import http from '@/util/http'
+
+export const insIntentionReportList = params => http({
+  url: '/commodity/reportingClub/list',
+  params,
+  headers: {
+    isToken: true
+  }
+})
+
+export const insIntentionReportAdd = params => http({
+  url: '/commodity/reportingClub/add',
+  params,
+  headers: {
+    isToken: true
+  }
+})
+
+export const insIntentionReportDetail = params => http({
+  url: '/commodity/reportingClub/details',
+  params,
+  headers: {
+    isToken: true
+  }
+})

+ 64 - 2
src/api/userApi/login.js

@@ -1,7 +1,69 @@
 import http from '@/util/http'
 
+// 分销登录
 export const login = (data) => http({
-  url: '/login',
+  url: `/user/login/distribution?mobileOrEmail=${data.mobileOrEmail}&password=${data.password}`,
   method: 'POST',
-  data
+  headers: {
+    isToken: false
+  }
+})
+
+// 获取验证码
+export const getCode = params => http({
+  url: '/user/login/code',
+  method: 'GET',
+  params,
+  headers: {
+    isToken: false
+  }
+})
+
+// 验证码登录
+export const codeLogin = (data) => http({
+  url: `/user/login/organizeDistribution?mobile=${data.mobile}&code=${data.code}`,
+  method: 'POST',
+  headers: {
+    isToken: false
+  }
+})
+
+// 获取个人信息
+export const getUserInfo = params => http({
+  url: '/user/distribution/home',
+  method: 'GET',
+  params,
+  headers: {
+    isToken: true
+  }
+})
+
+// 更新个人中心
+export const updatedUserInfo = data => http({
+  url: '/user/distribution/setHome',
+  method: 'POST',
+  data,
+  headers: {
+    isToken: true
+  }
+})
+
+// 图形验证码
+export const getImageCode = params => http({
+  url: '/user/captcha',
+  method: 'GET',
+  params,
+  headers: {
+    isToken: false
+  }
+})
+
+// 发送短信接口
+export const getSmsCode = params => http({
+  url: '/user/sms/code',
+  method: 'GET',
+  params,
+  headers: {
+    isToken: false
+  }
 })

+ 11 - 0
src/api/userApi/mine-card.js

@@ -0,0 +1,11 @@
+import http from '@/util/http'
+
+export const uploadImage = data => http({
+  url: '/tools/image/upload/multi',
+  method: 'POST',
+  data,
+  headers: {
+    'Content-Type': 'multipart/form-data',
+    isToken: false
+  }
+})

+ 9 - 0
src/api/userApi/shopping-mall.js

@@ -0,0 +1,9 @@
+import http from '@/util/http'
+
+export const productList = params => http({
+  url: '/commodity/reportingClub/productList',
+  params,
+  headers: {
+    isToken: true
+  }
+})

+ 31 - 0
src/api/userApi/team.js

@@ -0,0 +1,31 @@
+import http from '@/util/http'
+
+// 团队列表
+export const getTeamList = params => http({
+  url: '/user/distribution/getDistributionList',
+  method: 'GET',
+  params,
+  headers: {
+    isToken: true
+  }
+})
+
+// 成员修改
+export const updatedTeam = data => http({
+  url: '/user/distribution/updateStatus',
+  method: 'POST',
+  data,
+  headers: {
+    isToken: true
+  }
+})
+
+// 新增团队成员
+export const addTeam = data => http({
+  url: '/user/distribution/save',
+  method: 'POST',
+  data,
+  headers: {
+    isToken: true
+  }
+})

+ 140 - 0
src/components/field-image-code.vue

@@ -0,0 +1,140 @@
+<template>
+  <div>
+    <van-field
+      placeholder="请输入短信验证码"
+      :rules="[{ validator: validatorVerification, message: '请输入6位数验证码' }]"
+      type="digit"
+      left-icon="smile-o"
+      maxlength="6"
+      v-model="code"
+      @input="$emit('handlerCode', code)"
+    >
+      <template #button>
+        <van-button
+          size="small"
+          type="primary"
+          color="#FF5B00"
+          @click.stop="fetchVerification"
+          >获取验证码</van-button
+        >
+      </template>
+    </van-field>
+    <van-dialog v-model="showImageCode" title="获取验证码">
+      <van-form @submit="submitCode">
+        <van-field
+          v-model="imgCode"
+          class="img-code"
+          placeholder="请输入图片验证码"
+          :rules="[{ validator: validatorImgCode, message: '请输入图片验证码' }]"
+          maxlength="4"
+        />
+        <div class="img-refresh">
+          <van-image></van-image>
+          <div class="refresh">刷新</div>
+        </div>
+        <van-button
+          class="get-code"
+          color="#ff5b00"
+          native-type="submit"
+          >获取验证码</van-button
+        >
+      </van-form>
+    </van-dialog>
+  </div>
+</template>
+
+<script>
+import { Toast } from 'vant'
+import {
+  getCode,
+  getImageCode
+  // getSmsCode
+} from '@/api/userApi/login.js'
+export default {
+  props: {
+    mobile: {
+      type: String,
+      default: () => ''
+    }
+  },
+  data () {
+    return {
+      code: '',
+      showImageCode: false,
+      imgCode: '',
+      dataImage: ''
+    }
+  },
+  methods: {
+    validatorVerification (val) {
+      if (this.mobile && this.code) {
+        return /\d{6}/.test(val)
+      }
+    },
+    async fetchVerification () {
+      getCode({ mobile: this.mobile }).then(async () => {
+        this.showImageCode = true
+        this.dataImage = await getImageCode({ platformType: 1 })
+      })
+      setTimeout(() => {
+        Toast.clear()
+      }, 1000)
+    },
+    validatorImgCode (val) {
+      if (!val) return false
+      else if (this.errMsg) return this.errMsg
+    },
+    submitCode () {
+      // getSmsCode({
+      //  mobile: this.mobile,
+      //  token: this.dataImage.token,
+      //  imgCode: this.imgCode,
+      //  platformType: 1,
+      //  isCheckCaptcha: 0,
+      //  activateCodeType: 7
+      // }).then(() => {
+      //  this.errMsg = ''
+      // }).catch((err) => {
+      //  this.errMsg = err.msg
+      // })
+      // console.log(data)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+::v-deep .van-dialog__footer {
+  display: none;
+}
+::v-deep .van-dialog__content {
+  padding: 3.5vw 4vw;
+  box-sizing: border-box;
+}
+.img-refresh {
+  width: 100%;
+  margin: 2.7vw 0;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .van-image {
+    height: 12vw;
+    width: 50vw;
+    object-fit: cover;
+  }
+  .refresh {
+    width: 20vw;
+    line-height: 12vw;
+    text-align: center;
+    font-size: 3.4vw;
+    color: #ccc;
+  }
+}
+.get-code {
+  width: 100%;
+  height: 10vw;
+}
+.img-code {
+  border: 1px solid #ccc;
+}
+</style>

+ 2 - 2
src/components/goods-card.vue

@@ -1,7 +1,7 @@
 <template>
     <div class="goods-card" @click="$emit('handlerEmit', storeInfo)">
-        <van-image :src="storeInfo.image"></van-image>
-        <div class="info">{{ storeInfo.title || 'Prostrolane Nature-B珀洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液' }}</div>
+        <van-image :src="storeInfo.productImage"></van-image>
+        <div class="info">{{ storeInfo.productName || 'Prostrolane Nature-B珀洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液' }}</div>
     </div>
 </template>
 

+ 7 - 10
src/components/mine-card.vue

@@ -15,7 +15,7 @@
         <div class="card-head">
           <van-image
             :src="
-              userInfo.image && userInfo.image.length > 12
+              (userInfo.image && userInfo.image?.length > 12)
                 ? userInfo.image
                 : 'https://static.caimei365.com/app/img/icon/default-head-new.png'
             "
@@ -32,8 +32,8 @@
           </div>
           <div class="card-info-iphone">
             {{
-              userInfo.contractMobile
-                ? userInfo.contractMobile.replace(/(?=(\d{4})+$)/g, "-")
+              userInfo.mobile
+                ? userInfo.mobile.replace(/(?=(\d{4})+$)/g, "-")
                 : ""
             }}
           </div>
@@ -51,18 +51,15 @@
 
 <script>
 export default {
-  props: {
-    userInfo: {
-      type: Object,
-      default: () => ({})
-    }
-  },
   data () {
     return {
+      userInfo: null,
       imgUrl: 'https://static.caimei365.com/app/img/icon/bg-card.png'
     }
   },
-  mounted () {},
+  mounted () {
+    this.userInfo = this.$store.getters.userInfo
+  },
   methods: {}
 }
 </script>

+ 5 - 5
src/components/store-card.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="card" @click="$emit('handlerClick', storeInfo)">
-    <van-image width="100%" :src="storeInfo.image" />
-    <div class="store-title">{{ storeInfo.title }}</div>
-    <div class="store-price">{{ storeInfo.price }}</div>
+    <van-image width="100%" :src="storeInfo.mainImage" />
+    <div class="store-title">{{ storeInfo.shopName }}</div>
+    <div class="store-price">{{ storeInfo.price }}</div>
   </div>
 </template>
 
@@ -12,8 +12,8 @@ export default {
     storeInfo: {
       type: Object,
       default: () => ({
-        image: 'https://img01.yzcdn.cn/vant/cat.jpeg',
-        title: 'Prostrolane Nature-B珀洛丽肽焕活修颜精华肽焕活修颜精华',
+        mainImage: 'https://img01.yzcdn.cn/vant/cat.jpeg',
+        shopName: 'Prostrolane Nature-B珀洛丽肽焕活修颜精华肽焕活修颜精华',
         price: '¥990.00'
       })
     }

+ 11 - 7
src/components/team-card.vue

@@ -1,22 +1,22 @@
 <template>
   <div class="team_card">
-    <div class="name">赵铭</div>
+    <div class="name">{{ team.name }}</div>
     <div class="phone">
       <div class="phone_label">
         <div>手机号:</div>
-        <div>15889586623</div>
+        <div>{{ team.mobile }}</div>
       </div>
       <div>
-        <slot name="editor" :data="teamList"></slot>
+        <slot name="editor" :data="team"></slot>
       </div>
     </div>
     <div class="phone">
       <div class="phone_label">
         <div>状态:</div>
-        <div>已上线</div>
+        <div>{{ team.status === 90 ? '上线' : '下线' }}</div>
       </div>
       <div>
-        <slot name="online" :data="teamList"></slot>
+        <slot name="online" :data="team"></slot>
       </div>
     </div>
   </div>
@@ -25,9 +25,13 @@
 <script>
 export default {
   props: {
-    teamList: {
+    team: {
       type: Object,
-      default: () => ({})
+      default: () => ({
+        mobile: '',
+        name: '',
+        status: ''
+      })
     }
   }
 }

+ 34 - 28
src/permission.js

@@ -7,37 +7,43 @@ import { Toast } from 'vant'
 
 NProgress.configure({ showSpinner: false })
 
-const whiteList = ['/login', '/pwlogin', '/shopping-mall']
+const whiteList = ['/login', '/pwlogin']
 
 router.beforeEach((to, from, next) => {
   NProgress.start()
-  next()
-  // if (getToken()) {
-  //  /* has token */
-  //  if (to.path === '/login') {
-  //    next({ path: '/' })
-  //    NProgress.done()
-  //  } else {
-  //    store.dispatch('getInfo').then(() => {
-  //      next({ ...to, replace: true })
-  //    }).catch(err => {
-  //      store.dispatch('loginOut').then(() => {
-  //        Toast.fail(err)
-  //        next({ path: '/' })
-  //      })
-  //    })
-  //  }
-  // } else {
-  //  // 没有token
-  //  if (whiteList.indexOf(to.path) !== -1) {
-  //    // 在免登录白名单,直接进入
-  //    next()
-  //  } else {
-  //    Toast.fail('登入失败请检查')
-  //    next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
-  //    NProgress.done()
-  //  }
-  // }
+  if (getToken()) {
+    /* has token */
+    if (to.meta.title) {
+      document.title = to.meta.title
+    }
+    if (to.path === '/login' || to.path === '/pwlogin') {
+      next({ path: '/pwlogin' })
+      NProgress.done()
+    } else {
+      if (!store.getters.userInfo) {
+        store.dispatch('user/getUserInfo', store.getters.userId).then(() => {
+          next()
+        }).catch(err => {
+          console.log(err)
+          store.dispatch('user/loginOut').then(() => {
+            next({ path: '/pwlogin' })
+          })
+        })
+      } else {
+        next()
+      }
+    }
+  } else {
+    // 没有token
+    if (whiteList.indexOf(to.path) !== -1) {
+      // 在免登录白名单,直接进入
+      next()
+    } else {
+      Toast.fail('登入失效请重新登录')
+      next(`/pwlogin?redirect=${to.fullPath}`) // 否则全部重定向到登录页
+      NProgress.done()
+    }
+  }
 })
 
 router.afterEach(() => {

+ 1 - 10
src/plugin/toast.js

@@ -9,13 +9,6 @@ loading.install = (Vue, Options) => {
   document.body.appendChild(tDiv)
   toast.$mount(tDiv)
 
-  // 添加全局方法
-  Vue.showLoading = function () {
-    toast.show = true
-  }
-  Vue.hiddenLoading = function () {
-    toast.show = false
-  }
   // 添加实例方法
   Vue.prototype.$showLoading = function () {
     toast.show = true
@@ -25,6 +18,4 @@ loading.install = (Vue, Options) => {
   }
 }
 
-export default {
-  loading
-}
+export default loading

+ 24 - 0
src/router/index.js

@@ -214,6 +214,30 @@ const routes = [
     meta: {
       title: '支付订单'
     }
+  },
+  {
+    path: '/address-select',
+    name: 'address-select',
+    component: () => import('@/views/order-list/address-select.vue'),
+    meta: {
+      title: '切换地址'
+    }
+  },
+  {
+    path: '/address-edit',
+    name: 'address-edit',
+    component: () => import('@/views/order-list/address-edit.vue'),
+    meta: {
+      title: '编辑地址'
+    }
+  },
+  {
+    path: '/order-detail',
+    name: 'order-detail',
+    component: () => import('@/views/order-list/order-detail.vue'),
+    meta: {
+      title: '订单详情'
+    }
   }
 ]
 

+ 4 - 1
src/store/getter.js

@@ -4,5 +4,8 @@ export default {
   isFindCard: state => state.user.isFindCard,
   suId: state => state.institution.suId,
   spId: state => state.institution.spId,
-  isAddress: state => state.institution.isAddress
+  isAddress: state => state.institution.isAddress,
+  userId: state => state.user.userId,
+  userInfo: state => state.user.userInfo,
+  isManage: state => state.user.isManage
 }

+ 9 - 1
src/store/index.js

@@ -3,6 +3,7 @@ import Vuex from 'vuex'
 import getters from './getter'
 import institution from './institution'
 import user from './user'
+import createPersistedState from 'vuex-persistedstate'
 
 Vue.use(Vuex)
 
@@ -11,5 +12,12 @@ export default new Vuex.Store({
   modules: {
     institution,
     user
-  }
+  },
+  plugins: [
+    createPersistedState({
+      key: 'MyUsersStore',
+      paths: ['user', 'institution'],
+      storage: window.sessionStorage
+    })
+  ]
 })

+ 54 - 4
src/store/user.js

@@ -1,15 +1,31 @@
 // 用户 store
-import { login } from '@/api/userApi/login'
-import { setToken } from '@/util/auth'
+import { login, getUserInfo, codeLogin } from '@/api/userApi/login'
+import { setToken, removeToken } from '@/util/auth'
 
 const state = () => ({
   USERTOKEN: null,
-  isFindCard: false
+  isFindCard: false,
+  userId: null,
+  manage: null,
+  userInfo: null,
+  isManage: false
 })
 
 const mutations = {
-  SET_TOKEN: (k) => {
+  SET_TOKEN: (state, k) => {
     state.USERTOKEN = k
+  },
+  SET_USERID: (state, k) => {
+    state.userId = k
+  },
+  SET_USERINFO: (state, k) => {
+    state.userInfo = k
+  },
+  SET_MANAGE: (state, k) => {
+    state.manage = k
+  },
+  SET_IS_MANAGE: (state, k) => {
+    state.isManage = k
   }
 }
 
@@ -18,6 +34,7 @@ const actions = {
     return new Promise((resolve, reject) => {
       login(userInfo).then(res => {
         setToken(res.token)
+        commit('SET_USERID', res.userId)
         commit('SET_TOKEN', res.token)
         console.log('登录成功', res)
         resolve(res)
@@ -25,6 +42,39 @@ const actions = {
         reject(err)
       })
     })
+  },
+  codeLogin: ({ commit }, userInfo) => {
+    return new Promise((resolve, reject) => {
+      codeLogin(userInfo).then(res => {
+        setToken(res.token)
+        commit('SET_USERID', res.userId)
+        commit('SET_TOKEN', res.token)
+        console.log('登录成功', res)
+        resolve(res)
+      }).catch(err => {
+        reject(err)
+      })
+    })
+  },
+  getUserInfo: ({ commit }, data) => {
+    return new Promise((resolve, reject) => {
+      console.log(data)
+      getUserInfo({ userId: data }).then(res => {
+        commit('SET_USERINFO', res)
+        commit('SET_IS_MANAGE', res.parentId === 0)
+        console.log('用户信息', res)
+        resolve(res)
+      }).catch(err => {
+        reject(err)
+      })
+    })
+  },
+  loginOut: ({ commit }) => {
+    return new Promise((resolve, reject) => {
+      commit('SET_TOKEN', '')
+      removeToken()
+      resolve(resolve)
+    })
   }
 }
 

+ 4 - 4
src/util/auth.js

@@ -1,9 +1,9 @@
-import Cookies from 'js-cookie'
+// import Cookies from 'js-cookie'
 
 const token = 'Dis-Token'
 
-export const getToken = () => Cookies.get(token)
+export const getToken = () => sessionStorage.getItem(token)
 
-export const setToken = (t) => Cookies.set(token, t)
+export const setToken = (t) => sessionStorage.setItem(token, t)
 
-export const removeToken = () => Cookies.remove(token)
+export const removeToken = () => sessionStorage.removeItem(token)

+ 7 - 7
src/util/http.js

@@ -8,14 +8,14 @@ const pendingRequestPool = new Map()
 // 间隔时间小于interval的,被视为重复提交的请求
 const interval = 1000
 
-console.log(process.env)
+console.log(process.env, process.env.VUE_APP_URL)
 // 创建Axios实例
 const request = axios.create({
-  baseURL: process.env.BASE_URL,
+  baseURL: process.env.VUE_APP_URL,
   timeout: 15000 // 60s
 })
 
-request.defaults.headers['Content-Type'] = 'application/json'
+request.defaults.headers['Content-Type'] = 'multipart/form-data'
 
 // Axios请求拦截器
 request.interceptors.request.use(
@@ -29,7 +29,7 @@ request.interceptors.request.use(
     config.requestKey = `${config.method}-${config.url}`
     if (!!isToken && getToken()) {
       // 添加token到请求头
-      config.headers.token = getToken()
+      config.headers['X-Token'] = getToken()
     }
     if (isRepeated) {
       // 防止重复提交请求
@@ -71,10 +71,8 @@ request.interceptors.response.use(
   (response) => {
     const requestKey = response.config.requestKey
     pendingRequestPool.delete(requestKey)
-    console.log(response)
     // 对不同的状态码进行判断处理
     const { code, data, msg } = response.data
-    Vue.$hiddenLoading = false
     // 判断状态码
     if (code === 401) {
       removeToken() // 移除Cookie中的缓存Token信息
@@ -86,16 +84,18 @@ request.interceptors.response.use(
     } else if (code === 601) {
       Toast.fail(msg)
       return Promise.reject(new Error(msg))
-    } else if (code !== 200) {
+    } else if (code !== 0) {
       Toast.fail(msg)
       return Promise.reject(new Error('未知错误,请联系管理员!'))
     } else {
+      Toast.success(msg)
       return Promise.resolve(data)
     }
   },
   (error) => {
     // 超出 2xx 范围的状态码都会触发该函数。
     // 对响应错误做点什么
+    Toast.fail(error.message)
     return Promise.reject(error)
   }
 )

+ 7 - 7
src/views/goods-information/components/infoCell.vue

@@ -1,30 +1,30 @@
+<!-- eslint-disable vue/no-use-v-if-with-v-for -->
 <template>
   <div class="info-container">
     <div class="info-title">{{ handlerType }}</div>
     <div class="content">
       <div class="info-content" v-if="infoList.length > 0">
         <div v-for="item in infoList" :key="item.id">
-          <div class="info-content-title" v-if="infoType !== 3">以色列无针水光JDV/优斐斯/瑞漾小白盒及希腊,无针透
-            皮注入技术</div>
-          <div class="info-content-time" v-if="infoType !== 3">2023-09-19  17:42</div>
+          <div class="info-content-title" v-if="infoType !== 3">{{ item.title }}</div>
+          <div class="info-content-time" v-if="infoType !== 3">{{ item.addTime }}</div>
           <div v-if="item.imageList && infoType === 1" class="image-list">
             <div class="list" v-if="item.imageList > 0">
-              <van-image v-for="i,o in item.imageList" :key="o" :src="i"></van-image>
+              <van-image v-for="i,o in item.imageList" v-if="o < 8" :key="o" :src="i"></van-image>
             </div>
             <div class="more" v-if="item.imageList.length > defaultImageSum">
               <van-button>查看更多</van-button>
             </div>
           </div>
           <div v-if="infoType === 2" class="video">
-            <video src="" width="100%" height="100%"></video>
+            <video :src="item.fileUrl" width="100%" height="100%"></video>
           </div>
           <div v-if="infoType === 3" class="fileList">
             <div class="list">
               <van-image></van-image>
               <div class="file-info">
-                <div class="file-name"></div>
+                <div class="file-name">{{ item.fileName }}</div>
                 <div class="file-time">
-                  <span></span>
+                  <span>{{ item.addTime }}</span>
                   <span>预览文件</span>
                 </div>
               </div>

+ 24 - 10
src/views/goods-information/detail.vue

@@ -2,21 +2,22 @@
   <div>
     <nav-bar title="商品资料" @click-left="$router.back()"/>
     <div class="title">
-      <van-image></van-image>
+      <van-image :src="productImage"></van-image>
       <div class="store-title">
-        液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液洛丽肽焕活修颜精华液
+        {{productName}}
       </div>
     </div>
     <div class="store-info">
       相关资料
     </div>
-    <info-cell :info-type="1" :info-list="infoList"></info-cell>
-    <info-cell :info-type="2" :info-list="infoList"></info-cell>
-    <info-cell :info-type="3" :info-list="infoList"></info-cell>
+    <info-cell :info-type="1" :info-list="imageArchiveList"></info-cell>
+    <info-cell :info-type="2" :info-list="videoArchiveList"></info-cell>
+    <info-cell :info-type="3" :info-list="fileArchiveList"></info-cell>
   </div>
 </template>
 
 <script>
+import { archiveDetail } from '../../api/userApi/goods-information'
 import infoCell from './components/infoCell.vue'
 export default {
   components: {
@@ -24,11 +25,24 @@ export default {
   },
   data () {
     return {
-      infoList: [
-        {
-          id: 12
-        }
-      ]
+      fileArchiveList: [],
+      imageArchiveList: [],
+      videoArchiveList: [],
+      productImage: '',
+      productName: ''
+    }
+  },
+  computed: {
+    queryId () {
+      return this.$route.query.archiveId
+    }
+  },
+  methods: {
+    async archiveDetail () {
+      const data = await archiveDetail({ userId: this.$store.getters.userId, archiveId: this.queryId })
+      this.fileArchiveList = data.fileArchiveList
+      this.imageArchiveList = data.imageArchiveList
+      this.videoArchiveList = data.videoArchiveList
     }
   }
 }

+ 20 - 6
src/views/goods-information/index.vue

@@ -1,27 +1,41 @@
 <template>
   <div class="goods_info">
     <div style="position: sticky;top: 0;z-index: '66';">
-      <nav-bar title="商品详情" @click-left="$router.back()"/>
-      <van-search v-model="searchVal" placeholder="请输入搜索关键词" />
+      <nav-bar title="商品资料" @click-left="$router.back()"/>
+      <van-search v-model="formData.productName" placeholder="请输入搜索关键词" />
     </div>
-    <div class="content">
-      <goods-card @handlerEmit="handlerEmit"/>
+    <div class="content" v-for="good, index in goodsList" :key="index">
+      <goods-card @handlerEmit="handlerEmit" :storeInfo="good"/>
     </div>
   </div>
 </template>
 
 <script>
+import { getArchiveList } from '../../api/userApi/goods-information'
+
 export default {
   data () {
     return {
-      searchVal: ''
+      formData: {
+        productName: '',
+        pageNum: 1,
+        pageSize: 10
+      },
+      hasNextPage: false,
+      goodsList: []
     }
   },
   mounted () {
+    this.getArchiveList()
   },
   methods: {
     handlerEmit ($event) {
-      this.$router.push('/goods-information-detail')
+      this.$router.push(`/goods-information-detail?archiveId=${$event.archiveId}`)
+    },
+    async getArchiveList () {
+      const { data: results, hasNextPage } = await getArchiveList(this.formData)
+      this.hasNextPage = hasNextPage
+      this.goodsList = results
     }
   }
 }

+ 13 - 8
src/views/ins-intention-report/add.vue

@@ -5,15 +5,15 @@
       <van-form @submit="onSubmit">
         <div class="label">机构名称:</div>
         <van-cell-group>
-          <van-field v-model="formData.name" placeholder="请输入用户名" />
+          <van-field v-model="formData.clubName" placeholder="请输入用户名" />
         </van-cell-group>
         <div class="label">联系人:</div>
         <van-cell-group>
-          <van-field v-model="formData.username" placeholder="请输入用户名" />
+          <van-field v-model="formData.linkan" placeholder="请输入用户名" />
         </van-cell-group>
         <div class="label">手机号:</div>
         <van-cell-group>
-          <van-field v-model="formData.phone" placeholder="请输入用户名" />
+          <van-field v-model="formData.mobile" placeholder="请输入用户名" />
         </van-cell-group>
         <div class="label">报备商品:</div>
         <div class="select-store">
@@ -42,6 +42,7 @@
 </template>
 
 <script>
+import { insIntentionReportAdd } from '../../api/userApi/ins-intention-report'
 import ReportSelectPopup from './components/report-select-popup.vue'
 import ReportTips from './components/report-tips.vue'
 export default {
@@ -52,11 +53,11 @@ export default {
   data () {
     return {
       showModal: false,
-      showTips: false,
-      showPopup: true,
+      showTips: true,
+      showPopup: false,
       disabled: false,
       formData: {
-        name: ''
+        clubName: ''
       },
       fileList: []
     }
@@ -66,14 +67,18 @@ export default {
     tipsHidden (val) {
       this.showTips = val
     },
-    onSubmit () {}
+    onSubmit () {},
+    async insIntentionReportAdd () {
+      const data = await insIntentionReportAdd(this.formData)
+      console.log(data)
+    }
   }
 }
 </script>
 
 <style lang="scss" scoped>
 .add-report {
-  padding: 8vw 3.2vw 14vw 3.2vw;
+  padding: 8vw 3.2vw 3.2vw 3.2vw;
   background: #fff;
   .label {
     color: #333333;

+ 1 - 1
src/views/ins-intention-report/components/report-select-popup.vue

@@ -13,7 +13,7 @@
 export default {
   data () {
     return {
-      showPopup: true,
+      showPopup: false,
       value: '',
       radio: ''
     }

+ 2 - 2
src/views/ins-intention-report/components/search-head.vue

@@ -1,10 +1,10 @@
 <template>
   <div>
-    <van-tabs v-model="active" @click="$emit('handlerSelect', active)">
+    <van-tabs v-model="active" @click="$emit('handlerSelect', active)" v-if="$store.getters.isManage">
       <van-tab title="我的报备" />
       <van-tab title="成员报备" />
     </van-tabs>
-    <van-search v-model="value" placeholder="请输入搜索关键词" @search="$emit('onSearch', value)"/>
+    <van-search v-model="value" placeholder="请输入搜索关键词" @input="$emit('onSearch', value)" @search="$emit('onSearch', value)"/>
   </div>
 </template>
 

+ 62 - 29
src/views/ins-intention-report/index.vue

@@ -2,20 +2,22 @@
   <div>
     <nav-bar title="机构意向订单报备" @click-left="$router.back()">
       <template>
-        <search-head @handlerSelect="handlerSelect" @onSearch="onSearch"/>
+        <search-head @handlerSelect="handlerSelect" @onSearch="onSearch" />
       </template>
     </nav-bar>
-    <div class="report-list">
-      <order-report-card :style="{padding: isManage ? '13.3vw 3.2vw 5.3vw 3.2vw' : '5.3vw 3.2vw'}">
-        <template #InsUsername="{ username }">
-          <div class="name">
-            成员:{{ username.username }}
-          </div>
+    <div class="report-list" v-for="item,index in dataList" :key="index">
+      <order-report-card
+        :style="{
+          padding: $store.getters.isManage ? '13.3vw 3.2vw 5.3vw 3.2vw' : '5.3vw 3.2vw',
+        }"
+      >
+        <template #InsUsername="{ username }" v-if="$store.getters.isManage">
+          <div class="name">成员:{{ username.username }}</div>
         </template>
         <template #card-foot="{ data }">
           <div class="examine">
-            <div>审核状态:<span style="color: #333333;">审核通过</span></div>
-            <div>锁定状态:<span style="color: #FF9100;">未锁定</span></div>
+            <div>审核状态:<span style="color: #333333">审核通过</span></div>
+            <div>锁定状态:<span style="color: #ff9100">未锁定</span></div>
           </div>
           <div class="detail-btn" v-if="true">
             <van-button @click="handlerDetail(data)">查看详情</van-button>
@@ -26,27 +28,58 @@
           </div>
         </template>
       </order-report-card>
-      <div class="to-report">
-        <van-button color="#FF5B00" @click="$router.push('/ins-intention-add')">去报备</van-button>
-      </div>
+    </div>
+    <div class="to-report">
+      <van-button color="#FF5B00" @click="$router.push('/ins-intention-add')"
+        >去报备</van-button
+      >
     </div>
   </div>
 </template>
 
 <script>
+import { insIntentionReportList, insIntentionReportDetail } from '../../api/userApi/ins-intention-report'
 import SearchHead from './components/search-head'
 export default {
   components: { SearchHead },
   data () {
     return {
-      isManage: true
+      formData: {
+        pageNo: 1,
+        pageSize: 10,
+        clubName: ''
+      },
+      active: 0,
+      dataList: [],
+      hasNextPage: false
     }
   },
+  mounted () {
+    this.getInsIntentionReportList(this.active)
+  },
   methods: {
-    handlerSelect ($event) {},
-    onSearch ($event) {},
+    handlerSelect ($event) {
+      this.active = $event
+      this.dataList = []
+      this.getInsIntentionReportList($event)
+    },
+    onSearch ($event) {
+      this.formData.clubName = $event
+      this.getInsIntentionReportList(this.active)
+    },
     handlerDetail ($event) {
       this.$router.push('/ins-intention-detail')
+    },
+    async getInsIntentionReportList ($event) {
+      const form = Object.assign(
+        this.formData,
+        $event === 0
+          ? { id: this.$store.getters.userInfo.id }
+          : { parentId: this.$store.getters.userInfo.id }
+      )
+      const { results: data, hasNextPage } = await insIntentionReportList(form)
+      this.hasNextPage = hasNextPage
+      this.dataList = data
     }
   }
 }
@@ -64,7 +97,7 @@ export default {
     color: #fff;
     line-height: 6.9vw;
     text-align: center;
-    background: #FF5B00;
+    background: #ff5b00;
     border-top-right-radius: 1.2vw;
     border-bottom-right-radius: 1.2vw;
   }
@@ -92,19 +125,19 @@ export default {
       border-radius: 1.2vw;
     }
   }
-  .to-report {
-    @include display-flex-center;
-    position: fixed;
-    left: 0;
-    bottom: 0;
-    width: 100%;
-    height: 17.3vw;
-    background: #fff;
-    ::v-deep .van-button {
-      width: 86.4vw;
-      height: 13vw;
-      border-radius: 1.2vw;
-    }
+}
+.to-report {
+  @include display-flex-center;
+  position: fixed;
+  left: 0;
+  bottom: 0;
+  width: 100%;
+  height: 17.3vw;
+  background: #fff;
+  ::v-deep .van-button {
+    width: 86.4vw;
+    height: 13vw;
+    border-radius: 1.2vw;
   }
 }
 </style>

+ 50 - 33
src/views/login/login.vue

@@ -3,71 +3,88 @@
     <div class="login-icon"></div>
     <van-form @submit="submitLogin">
       <van-field
-        v-model="form.phone"
+        v-model="form.mobile"
         name="validator"
         placeholder="请输入手机号"
-        :rules="[{ validator: validatorPhone, message: '请输入正确的手机号' }]"
+        :rules="[{ validator: validatorMobile, message: '请输入正确的手机号' }]"
         label=""
         type="digit"
         maxlength="11"
         left-icon="smile-o"
       />
-      <van-field
-        v-model="form.password"
-        name="validator"
-        placeholder="请输入短信验证码"
-        :rules="[{ validator: validatorVerification, message: '请输入6位数验证码' }]"
-        type="digit"
-        left-icon="smile-o"
-        maxlength="6"
-      >
-        <template #button>
-          <van-button size="small" type="primary" color="#FF5B00" @click="fetchVerification">获取验证码</van-button>
-        </template>
-      </van-field>
+      <field-image-code :mobile="form.mobile" @handlerCode="handlerCode" />
       <div class="pwLogin">
         <div @click="$ApiRouter('/pwlogin')">密码登录</div>
       </div>
-      <van-button :class="disabled ? 'login-btn-disable' : 'login-btn'" :disabled="disabled" native-type="submit">登录</van-button>
+      <van-button
+        :class="disabled ? 'login-btn-disable' : 'login-btn'"
+        :disabled="disabled"
+        native-type="submit"
+        >登录</van-button
+      >
     </van-form>
   </div>
 </template>
 
 <script>
 import { Toast } from 'vant'
-
+import { getCode, getImageCode, getSmsCode } from '@/api/userApi/login.js'
 export default {
   name: 'login-index',
   data () {
     return {
       form: {
-        phone: '',
-        password: ''
+        mobile: '',
+        code: '666666'
       },
-      disabled: false
+      disabled: false,
+      imgCode: '',
+      showImageCode: ''
     }
   },
-  mounted () {
-  },
+  mounted () {},
   methods: {
-    validatorPhone (val) {
+    validatorMobile (val) {
       return /1\d{10}/.test(val)
     },
     validatorVerification (val) {
-      return /\d{6}/.test(val)
+      if (this.form.mobile) {
+        return /\d{6}/.test(val)
+      } else {
+        this.validatorMobile(this.form.mobile)
+      }
     },
-    onFailed (errorInfo) {
-      console.log('failed', errorInfo)
+    handlerCode (e) {
+      this.form.code = e
     },
-    fetchVerification () {
+    async fetchVerification () {
+      getCode({ mobile: this.form.mobile }).then(() => {
+        getImageCode({ platformType: 0 }).then((res) => {
+          console.log(res)
+          getSmsCode({
+            mobile: this.form.mobile,
+            token: res.token,
+            imgCode: this.imgCode,
+            platformType: 0,
+            isCheckCaptcha: 0,
+            activateCodeType: 7
+          }).then((r) => {
+            console.log(r)
+          })
+        })
+      })
       Toast.loading('验证码已发送')
       setTimeout(() => {
         Toast.clear()
       }, 1000)
     },
     submitLogin ($event) {
-      console.log($event)
-      this.$ApiRouter('/shopping-mall')
+      if ($event.validator) {
+        this.$store.dispatch('user/codeLogin', this.form).then((res) => {
+          console.log(res)
+          this.$ApiRouter('/shopping-mall')
+        })
+      }
     }
   }
 }
@@ -89,27 +106,27 @@ export default {
   .van-form {
     width: 80vw;
     .van-cell {
-      border-bottom: 1px solid #E1E1E1;
+      border-bottom: 1px solid #e1e1e1;
     }
   }
   .pwLogin {
     display: flex;
     flex-direction: row-reverse;
     font-size: 3.2vw;
-    color: #FF5B00;
+    color: #ff5b00;
     margin-top: 2.3vw;
     width: 80vw;
   }
   .login-btn-disable {
     margin-top: 16vw;
     width: 80vw;
-    background: #FFDCC8;
+    background: #ffdcc8;
     color: #fff;
   }
   .login-btn {
     margin-top: 16vw;
     width: 80vw;
-    background: #FF5B00;
+    background: #ff5b00;
     color: #fff;
   }
 }

+ 13 - 11
src/views/login/pwlogin.vue

@@ -3,10 +3,10 @@
     <div class="login-icon"></div>
     <van-form @submit="submitLogin">
       <van-field
-        v-model="form.phone"
+        v-model="form.mobileOrEmail"
         name="validator"
         placeholder="请输入手机号"
-        :rules="[{ validator: validatorPhone, message: '请输入正确的手机号' }]"
+        :rules="[{ validator: validatormobileOrEmail, message: '请输入正确的手机号' }]"
         label=""
         type="digit"
         maxlength="11"
@@ -14,10 +14,10 @@
       />
       <van-field
         v-model="form.password"
-        name="validator"
+        name="密码"
         placeholder="请输入密码"
-        :rules="[{ validator: validatorVerification, message: '请输入密码' }]"
-        type="digit"
+        :rules="[{ required: true, message: '请输入密码' }]"
+        type="password"
         left-icon="smile-o"
         maxlength="8"
       />
@@ -38,7 +38,7 @@ export default {
   data () {
     return {
       form: {
-        phone: '',
+        mobileOrEmail: '',
         password: ''
       },
       disabled: false
@@ -47,12 +47,9 @@ export default {
   mounted () {
   },
   methods: {
-    validatorPhone (val) {
+    validatormobileOrEmail (val) {
       return /1\d{10}/.test(val)
     },
-    validatorVerification (val) {
-      return /\d{6}/.test(val)
-    },
     onFailed (errorInfo) {
       console.log('failed', errorInfo)
     },
@@ -63,7 +60,12 @@ export default {
       }, 1000)
     },
     submitLogin ($event) {
-      console.log($event)
+      this.$showLoading()
+      this.$store.dispatch('user/userLogin', this.form).then(res => {
+        this.$ApiRouter('/shopping-mall')
+        this.$hiddenLoading()
+        Toast.loading('登录成功')
+      })
     }
   }
 }

+ 47 - 11
src/views/mine-card/index.vue

@@ -1,37 +1,71 @@
 <template>
   <div class="mine-card">
-    <nav-bar title="我的名片" @click-left="$router.back()"/>
+    <nav-bar title="我的名片" @click-left="$router.back()" />
     <div class="card-item" @click="show = true">
       <div>头像</div>
       <div class="card-img">
-        <van-image src=""></van-image>
+        <van-image :src="userInfo.image"></van-image>
       </div>
       <i class="van-icon van-icon-arrow van-cell__right-icon"></i>
     </div>
     <div class="card-item" @click="$router.push('/mine-qrcode')">
       <div>二维码</div>
       <div class="card-img">
-        <van-image src=""></van-image>
+        <van-image :src="userInfo.qrCode"></van-image>
       </div>
       <i class="van-icon van-icon-arrow van-cell__right-icon"></i>
     </div>
-    <van-action-sheet v-model="show" :actions="actions" @select="onSelect" />
+    <van-action-sheet
+      v-model="show"
+      cancel-text="取消"
+      :actions="actions"
+      @select="onSelect"
+    />
+    <input
+      class="file"
+      ref="uploadImageRef"
+      type="file"
+      accept="image/png,image/jpeg,image/gif,image/jpg"
+      @change="uploadImage"
+    />
   </div>
 </template>
 
 <script>
+import { uploadImage } from '@/api/userApi/mine-card.js'
+import { updatedUserInfo } from '@/api/userApi/login'
+
 export default {
   data () {
     return {
-      actions: [{ name: '手机相册', id: 1 }, { name: '取消', id: 2 }],
-      show: false
+      actions: [{ name: '手机相册', id: 1 }],
+      show: false,
+      userInfo: {}
     }
   },
+  mounted () {
+    this.getUserInfo()
+  },
   methods: {
+    async getUserInfo () {
+      this.userInfo = await this.$store.dispatch(
+        'user/getUserInfo',
+        this.$store.getters.userId
+      )
+    },
     onSelect ($event) {
-      if ($event.id === 2) {
-        this.show = false
+      if ($event.id === 1) {
+        this.$refs.uploadImageRef.click()
       }
+    },
+    async uploadImage (file) {
+      const formData = new FormData()
+      formData.append('file', file.target.files[0])
+      const data = await uploadImage(formData)
+      this.userInfo.image = data
+      updatedUserInfo(this.userInfo).then((res) => {
+        console.log(res)
+      })
     }
   }
 }
@@ -40,14 +74,13 @@ export default {
 <style lang="scss" scoped>
 .mine-card {
   background: #fff;
-  padding: 4.3vw;
   .card-item {
-    padding: 2vw 6vw 2vw 2.1vw;
+    padding: 2vw 4.3vw 2vw 4.3vw;
     display: flex;
     position: relative;
     justify-content: space-between;
     align-items: center;
-    border-bottom: 1px solid #E1E1E1;
+    border-bottom: 1px solid #e1e1e1;
     ::v-deep .van-icon {
       position: absolute;
       right: 0;
@@ -68,4 +101,7 @@ export default {
     }
   }
 }
+.file {
+  display: none;
+}
 </style>

+ 43 - 7
src/views/mine-card/qrcode.vue

@@ -1,25 +1,58 @@
 <template>
   <div>
-    <nav-bar title="我的名片" @click-left="$router.back()"/>
+    <nav-bar title="我的名片" @click-left="$router.back()" />
     <div class="qrcode">
-      <div class="upload">
+      <div class="upload" @click="upload">
         <div>点击上传二维码</div>
       </div>
-      <van-button color="#FF5B00">上传二维码</van-button>
+      <van-button color="#FF5B00" @click="upload">上传二维码</van-button>
       <van-button color="#FF5B00" @click="$router.push('/save-card')">保存</van-button>
     </div>
+    <input
+      class="file"
+      ref="uploadImageRef"
+      type="file"
+      accept="image/png,image/jpeg,image/gif,image/jpg"
+      @change="uploadImage"
+    />
   </div>
 </template>
 
 <script>
+import { uploadImage } from '@/api/userApi/mine-card.js'
+import { updatedUserInfo } from '@/api/userApi/login'
 export default {
-
+  data () {
+    return {
+      userInfo: {}
+    }
+  },
+  methods: {
+    async getUserInfo () {
+      this.userInfo = await this.$store.dispatch(
+        'user/getUserInfo',
+        this.$store.getters.userId
+      )
+    },
+    upload () {
+      this.$refs.uploadImageRef.click()
+    },
+    async uploadImage (file) {
+      const formData = new FormData()
+      formData.append('file', file.target.files[0])
+      const data = await uploadImage(formData)
+      this.userInfo.image = data
+      updatedUserInfo(this.userInfo).then((res) => {
+        console.log(res)
+      })
+    }
+  }
 }
 </script>
 
 <style lang="scss" scoped>
 .qrcode {
- padding-top: 12vw;
+  padding-top: 12vw;
   display: flex;
   align-items: center;
   flex-direction: column;
@@ -28,13 +61,13 @@ export default {
     width: 53.3vw;
     height: 53.3vw;
     border-radius: 1.1vw;
-    border: 1px dotted #B2B2B2;
+    border: 1px dotted #b2b2b2;
     margin-bottom: 13.5vw;
     display: flex;
     justify-content: center;
     align-items: center;
     div {
-      color: #B2B2B2;
+      color: #b2b2b2;
       font-size: 3.2vw;
     }
   }
@@ -45,4 +78,7 @@ export default {
   border-radius: 1.1vw;
   margin-bottom: 4vw;
 }
+.file {
+  display: none;
+}
 </style>

+ 0 - 1
src/views/mine-card/save-card.vue

@@ -10,7 +10,6 @@
 
 <script>
 export default {
-
 }
 </script>
 

+ 6 - 1
src/views/mine/index.vue

@@ -6,7 +6,7 @@
           lazy-load
           src="https://img01.yzcdn.cn/vant/cat.jpeg"
         />
-        <div class="user_name">赵铭</div>
+        <div class="user_name">{{ $store.getters.userInfo.name }}</div>
       </div>
     </div>
     <order-type-list :obj-cell="ObjCell">
@@ -36,6 +36,8 @@
 </template>
 
 <script>
+import { mapState } from 'vuex'
+
 export default {
   data () {
     return {
@@ -139,6 +141,9 @@ export default {
         }
       ]
     }
+  },
+  computed: {
+    ...mapState([''])
   }
 }
 </script>

+ 53 - 18
src/views/my-team/addTeam.vue

@@ -12,51 +12,86 @@
       />
       <van-field
         placeholder="请输入手机号"
-        v-model="formData.phone"
+        v-model="formData.mobile"
         maxlength="11"
       />
       <van-field
         readonly
         clickable
         name="picker"
-        :value="formData.state"
+        :value="formData.active"
         placeholder="状态"
         @click="showPicker = true"
       />
     </van-form>
-    <van-popup v-model="showPicker" position="bottom">
-      <van-picker
-        show-toolbar
-        :columns="columns"
-        @confirm="onConfirm"
-        @cancel="showPicker = false"
-      />
-    </van-popup>
+    <van-action-sheet v-model="showPicker" :actions="actions" @select="onSelect" />
     <div class="add_btn">
-      <van-button :disabled="disabled" :class="disabled ? 'add' : 'disabled'" @click="save">保存</van-button>
+      <van-button :disabled="disabled" :class="disabled ? 'disabled' : 'add'" @click="save">保存</van-button>
     </div>
   </div>
 </template>
 
 <script>
+// eslint-disable-next-line no-unused-vars
+import { updatedTeam, addTeam } from '@/api/userApi/team.js'
+import { getUserInfo } from '@/api/userApi/login'
+
 export default {
   data () {
     return {
-      disabled: false,
+      disabled: true,
       formData: {
-        phone: '',
+        mobile: '',
         name: '',
-        state: ''
+        status: '',
+        active: ''
       },
-      columns: ['上线', '下线'],
+      actions: [{ status: 90, name: '上线' }, { status: 91, name: '下线' }],
       showPicker: false
     }
   },
+  mounted () {
+    if (this.queryUserId) {
+      this.getUserInfo()
+    }
+  },
+  computed: {
+    queryUserId () {
+      return this.$route.query.userId
+    }
+  },
+  watch: {
+    formData: {
+      handler (val) {
+        if (val.name && val.status && val.mobile) {
+          this.disabled = false
+        } else {
+          this.disabled = true
+        }
+      },
+      deep: true
+    }
+  },
   methods: {
-    save () {},
-    onConfirm ($event) {
+    async getUserInfo () {
+      const data = await getUserInfo({ userId: this.queryUserId })
+      this.formData = data
+      this.formData.active = data.status === 90 ? '上线' : '下线'
+    },
+    async save () {
+      if (this.queryUserId) {
+
+      } else {
+        addTeam(Object.assign(this.formData, { parentId: this.$store.getters.userInfo.id })).then(res => {
+          console.log(res)
+        })
+      }
+      this.$router.back()
+    },
+    onSelect ($event) {
       this.showPicker = false
-      this.formData.state = $event
+      this.formData.status = $event.status
+      this.formData.active = $event.name
     }
   }
 }

+ 18 - 5
src/views/my-team/index.vue

@@ -6,12 +6,12 @@
       @click-left="$router.back()"
     />
     <div class="team_list" v-if="teamList.length > 0">
-      <team-card v-for="item,index in teamList" :key="index" :teamList="item">
+      <team-card v-for="item,index in teamList" :key="index" :team="item">
         <template #editor="{ data }">
           <van-button size="small" color="#E4F4FF" class="editor" @click="editor(data)">编辑</van-button>
         </template>
         <template #online="{ data }">
-          <van-button size="small" color="#FFEEE4" class="online" @click="online(data)">上线</van-button>
+          <van-button size="small" color="#FFEEE4" class="online" @click="online(data)">{{ data.status === 90 ? '下线' : '上线' }}</van-button>
         </template>
       </team-card>
     </div>
@@ -25,18 +25,31 @@
 </template>
 
 <script>
+import { getTeamList, updatedTeam } from '@/api/userApi/team.js'
+
 export default {
   data () {
     return {
       teamList: []
     }
   },
+  mounted () {
+    this.getTeamList()
+  },
   methods: {
+    async getTeamList () {
+      const data = await getTeamList({ parentId: 2 })
+      this.teamList = data
+    },
     editor ($event) {
-      console.log($event)
+      this.$router.push(`/addTeam?userId=${$event.userId}`)
     },
-    online ($event) {
-      console.log($event)
+    async online ($event) {
+      this.$showLoading()
+      updatedTeam({ userId: $event.userId, status: $event.status === 90 ? 91 : 90 }).then(res => {
+        this.getTeamList()
+        this.$hiddenLoading()
+      })
     }
   }
 }

+ 6 - 2
src/views/order-list/address-select.vue

@@ -44,8 +44,12 @@ export default {
     }
   },
   methods: {
-    onAdd () {},
-    onEdit ($event) {}
+    onAdd () {
+      this.$router.push('/address-edit')
+    },
+    onEdit ($event) {
+      this.$router.push('/address-edit')
+    }
   }
 }
 </script>

+ 3 - 2
src/views/order-list/components/contact-select.vue

@@ -18,6 +18,7 @@
       @click="onAdd"
       :editable="editable"
     />
+    <slot name="address-tips"></slot>
   </div>
 </template>
 
@@ -35,7 +36,7 @@ export default {
     },
     handlerAddress () {
       if (this.isAddress) {
-        this.$router.push()
+        this.$router.push('/address-select')
       }
     }
   }
@@ -44,11 +45,11 @@ export default {
 
 <style lang="scss" scoped>
 .address-select {
-  padding: 5vw 4vw;
   box-sizing: border-box;
   background: #fff;
   .address {
     @include display-flex-between;
+    padding: 5vw 4vw;
     .address-img {
       width: 4.5vw;
       height: 5vw;

+ 1 - 0
src/views/order-list/components/invoice-information.vue

@@ -1,6 +1,7 @@
 <template>
   <div class="invoice">
     <van-cell title="发票信息" value="不要发票" @click="showInvoice = true" is-link/>
+    <slot name="content"></slot>
   </div>
 </template>
 

+ 16 - 0
src/views/order-list/components/payment-records.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="records">
+    <van-cell title="支付记录" value="" is-link/>
+    <slot name="content"></slot>
+  </div>
+</template>
+
+<script>
+export default {
+
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 16 - 0
src/views/order-list/components/payment-voucher.vue

@@ -0,0 +1,16 @@
+<template>
+  <div class="voucher">
+    <van-cell title="线下支付凭证" value="" is-link/>
+    <slot name="content"></slot>
+  </div>
+</template>
+
+<script>
+export default {
+
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 4 - 1
src/views/order-list/index.vue

@@ -16,7 +16,7 @@
       </div>
     </nav-bar>
     <div class="order-list">
-      <order-list-card>
+      <order-list-card @click.native="handlerOrder">
         <template #order-head>
           <div class="order-place">
             <div class="order-No">订单号:X156368767111348</div>
@@ -97,6 +97,9 @@ export default {
   methods: {
     handlerManage (id) {
       this.activeBtn = id
+    },
+    handlerOrder () {
+      this.$router.push('/order-detail')
     }
   }
 }

+ 15 - 0
src/views/order-list/offline-payment.vue

@@ -0,0 +1,15 @@
+<template>
+  <div>
+
+  </div>
+</template>
+
+<script>
+export default {
+
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 15 - 0
src/views/order-list/online-payment.vue

@@ -0,0 +1,15 @@
+<template>
+  <div>
+
+  </div>
+</template>
+
+<script>
+export default {
+
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 157 - 0
src/views/order-list/order-detail.vue

@@ -0,0 +1,157 @@
+<template>
+  <div class="detail">
+    <nav-bar title="订单详情" @click-left="$router.back()" />
+    <contact-select>
+      <template #address-tips>
+        <div class="tips">
+          为保障会员权益,特殊类商品(包括耗材/配件/私密商品等),除
+          外观跟质量问题之外,其他原因均不支持退货!
+        </div>
+      </template>
+    </contact-select>
+    <div class="order-card">
+      <order-goods-info></order-goods-info>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="label">商品总额:<span>¥1695.00</span></div>
+      <div class="leave-msg">留言:<span>无</span></div>
+    </div>
+    <invoice-information>
+      <template #content>
+        <div class="content" v-if="orderInfo.invoice.length > 0">
+
+        </div>
+        <div class="content" v-else>暂无支付凭证</div>
+      </template>
+    </invoice-information>
+    <payment-records>
+      <template #content>
+        <div class="content" v-if="orderInfo.records.length > 0">
+          <div class="time">2023-09-20  16:13:34</div>
+          <div class="images">
+            <van-image></van-image>
+          </div>
+          <div class="notes">备注:无</div>
+        </div>
+        <div class="content" v-else>暂无支付凭证</div>
+      </template>
+    </payment-records>
+    <payment-voucher>
+      <template #content>
+        <div class="content" v-if="orderInfo.voucher.length > 0">
+
+        </div>
+        <div class="content" v-else>
+          暂无支付凭证
+        </div>
+      </template>
+    </payment-voucher>
+    <div class="order-btn">
+      <order-btn-type></order-btn-type>
+    </div>
+  </div>
+</template>
+
+<script>
+import OrderBtnType from './components/order-btn-type'
+import PaymentVoucher from './components/payment-voucher'
+import PaymentRecords from './components/payment-records'
+import InvoiceInformation from './components/invoice-information'
+import ContactSelect from './components/contact-select'
+
+export default {
+  components: {
+    OrderBtnType,
+    PaymentVoucher,
+    PaymentRecords,
+    InvoiceInformation,
+    ContactSelect
+  },
+  data () {
+    return {
+      orderInfo: {
+        records: [],
+        invoice: [],
+        voucher: []
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.tips {
+  padding: 3.7vw;
+  line-height: 5.3vw;
+  color: #F94B4B;
+  background: #FFF1F1;
+  font-size: 3.2vw;
+}
+.order-card {
+  padding: 5vw 5vw 3vw 5vw;
+  background: #fff;
+  margin: 3.2vw 0;
+  .label {
+    display: flex;
+    justify-content: space-between;
+    font-size: 3.7vw;
+    color: #999999;
+    margin-bottom: 2vw;
+    span {
+      color: #333;
+    }
+  }
+  .leave-msg {
+    padding-top: 3vw;
+    font-size: 3.5vw;
+    color: #999999;
+    border-top: 1px solid #999999;
+    span {
+      color: #333;
+    }
+  }
+}
+.content {
+  padding: 3.2vw;
+  font-size: 3.7vw;
+  color: #666;
+  background: #fff;
+  .time {
+    font-size: 3.5vw;
+    color: #666;
+    margin-bottom: 3.2vw;
+  }
+  .notes {
+    font-size: 3.5vw;
+    color: #666;
+  }
+  .images {
+    display: flex;
+    flex-wrap: wrap;
+    ::v-deep .van-image {
+      width: 27.7vw;
+      height: 27.7vw;
+      margin: 0 3.5vw 5.5vw 0;
+    }
+  }
+}
+.records {
+  margin: 3.2vw 0;
+}
+.order-btn {
+  padding: 3.2vw;
+  background: #fff;
+  position: sticky;
+  bottom: 0;
+  ::v-deep .van-button {
+    margin-left: 2vw;
+    width: 21.3vw;
+    height: 8.5vw;
+    white-space: nowrap;
+  }
+}
+</style>

+ 17 - 2
src/views/shopping-mall/index.vue

@@ -1,21 +1,36 @@
 <template>
   <div class="shop-mall">
-    <store-card v-for="i in 10" :key="i" @handlerClick="handlerClick"/>
+    <store-card v-for="i in dataList" :storeInfo="i" :key="i.id" @handlerClick="handlerClick"/>
   </div>
 </template>
 
 <script>
+import { productList } from '../../api/userApi/shopping-mall'
+
 export default {
   data () {
     return {
-      show: true
+      show: true,
+      formData: {
+        pageSize: 10,
+        pageNum: 1,
+        id: this.$store.getters.isManage ? this.$store.getters.userInfo.id : this.$store.getters.userInfo.parentId
+      },
+      hasNextPage: false,
+      dataList: []
     }
   },
   mounted () {
+    this.productList()
   },
   methods: {
     handlerClick ($event) {
       this.$router.push('/goods-detail')
+    },
+    async productList () {
+      const { results: data, hasNextPage } = await productList(this.formData)
+      this.dataList = data
+      this.hasNextPage = hasNextPage
     }
   }
 }

+ 3 - 5
vue.config.js

@@ -11,14 +11,12 @@ module.exports = {
     }
   },
   devServer: {
-    host: '0.0.0.0',
-    open: true,
     proxy: {
-      [process.env.BASE_URL]: {
-        target: 'http://localhost:8080',
+      '/api': {
+        target: process.env.VUE_APP_URL,
         changeOrigin: true,
         pathRewrite: {
-          ['^' + process.env.BASE_URL]: ''
+          '^/api': ''
         }
       }
     }