Browse Source

代码提交

lzm_web
Linzm 8 months ago
parent
commit
ac240bc142
  1. 4
      .env.development
  2. 6
      .env.gray
  3. 8
      .env.production
  4. 26
      components.d.ts
  5. 1025
      package-lock.json
  6. 8
      package.json
  7. 188
      pnpm-lock.yaml
  8. 32
      src/api/multiPrint.ts
  9. 12
      src/api/my_order.ts
  10. 33
      src/api/photo_3d.ts
  11. 20
      src/api/pic_video.ts
  12. 28
      src/api/queue.ts
  13. 41
      src/api/receive_address.ts
  14. 22
      src/api/short_url.ts
  15. BIN
      src/assets/about/hands.png
  16. BIN
      src/assets/about/mail.png
  17. BIN
      src/assets/about/map.png
  18. BIN
      src/assets/about/tel.png
  19. BIN
      src/assets/order/gou.png
  20. BIN
      src/assets/order/gou_1.png
  21. BIN
      src/assets/order/gray_yuan.png
  22. BIN
      src/assets/order/jingdong.png
  23. BIN
      src/assets/order/line.png
  24. BIN
      src/assets/order/line_gou.png
  25. BIN
      src/assets/order/look-delivery.png
  26. BIN
      src/assets/order/more.png
  27. BIN
      src/assets/order/no-order.png
  28. BIN
      src/assets/order/shunfeng.png
  29. BIN
      src/assets/order/tag.png
  30. BIN
      src/assets/order/tel.png
  31. BIN
      src/assets/photo3D/buy.png
  32. BIN
      src/assets/photo3D/edit.png
  33. BIN
      src/assets/photo3D/hint.png
  34. BIN
      src/assets/photo3D/icon_3d_ar.png
  35. BIN
      src/assets/photo3D/icon_3d_ar_gray.png
  36. BIN
      src/assets/photo3D/icon_3d_bg.png
  37. BIN
      src/assets/photo3D/icon_3d_bg_gray.png
  38. BIN
      src/assets/photo3D/icon_3d_buy.png
  39. BIN
      src/assets/photo3D/icon_3d_buy_gray.png
  40. BIN
      src/assets/photo3D/icon_3d_share.png
  41. BIN
      src/assets/photo3D/icon_3d_share_gray.png
  42. BIN
      src/assets/photo3D/icon_exit.png
  43. BIN
      src/assets/photo3D/music_forbid.png
  44. BIN
      src/assets/photo3D/music_play.png
  45. BIN
      src/assets/photo3D/reset.png
  46. BIN
      src/assets/photo3D/rotate.png
  47. BIN
      src/assets/photo3D/save.png
  48. BIN
      src/assets/photo3D/stop.png
  49. BIN
      src/assets/photo3D/vector.png
  50. BIN
      src/assets/takePhoto/bg.png
  51. BIN
      src/assets/takePhoto/code.png
  52. BIN
      src/assets/takePhoto/fresh.png
  53. BIN
      src/assets/takePhoto/status_btn_01.png
  54. BIN
      src/assets/takePhoto/status_btn_02.png
  55. BIN
      src/assets/takePhoto/status_btn_03.png
  56. BIN
      src/assets/takePhoto/status_btn_04.png
  57. 30
      src/router/address.ts
  58. 42
      src/router/index.ts
  59. 39
      src/router/multiPrint.ts
  60. 31
      src/router/my_order.ts
  61. 42
      src/router/photo_3d.ts
  62. 30
      src/router/queue.ts
  63. 50
      src/router/short_url.ts
  64. 17
      src/shims-vue.d.ts
  65. 331
      src/views/about/index.vue
  66. 13
      src/views/address/edit.vue
  67. 349
      src/views/address/index.vue
  68. 546
      src/views/badge/cropper.vue
  69. 269
      src/views/badge/index.vue
  70. 75
      src/views/delivery/index.vue
  71. 173
      src/views/multiPrint/detail.vue
  72. 273
      src/views/multiPrint/index.vue
  73. 189
      src/views/multiPrint/orderDetail.vue
  74. 768
      src/views/my_order/detail.vue
  75. 543
      src/views/my_order/index.vue
  76. 161
      src/views/photo_3d/ar.vue
  77. 1190
      src/views/photo_3d/gsplat.vue
  78. 1124
      src/views/photo_3d/index.vue
  79. 1071
      src/views/photo_3d/threejs.vue
  80. 610
      src/views/queue/index.vue
  81. 57
      src/views/queue/succeed.vue
  82. 52
      src/views/queue/utils/type.ts
  83. 62
      src/views/short_url/actions.vue
  84. 54
      src/views/short_url/components/orderTrackItem.vue
  85. 28
      src/views/short_url/dict.ts
  86. 171
      src/views/short_url/orderInfo.vue
  87. 72
      src/views/short_url/orderTrack.vue
  88. 170
      src/views/short_url/printOrderInfo.vue
  89. 34
      src/views/short_url/utils.ts
  90. 377
      src/views/user/index.vue
  91. 191
      src/views/user/person.vue
  92. 34
      src/views/user/utils.ts

4
.env.development

@ -1,7 +1,7 @@
VITE_APP_PREVIEW=true VITE_APP_PREVIEW=true
# VITE_APP_API_BASE_URL=http://172.16.0.29:28499/ # VITE_APP_API_BASE_URL=http://172.16.0.29:28499/
VITE_APP_API_BASE_URL=https://web.api.suwa3d.com/ VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/
VITE_APP_API_WX_URL=https://wechat.api.suwa3d.com/ VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/
# http://web.suwa3d.dev:28499/ # http://web.suwa3d.dev:28499/
VITE_HTTP_MOCK=true VITE_HTTP_MOCK=true
WECHAT_AUTH_URL=http://localhost:28499/api/auth/page WECHAT_AUTH_URL=http://localhost:28499/api/auth/page

6
.env.gray

@ -1,5 +1,5 @@
NODE_ENV=production NODE_ENV=production
VITE_APP_PREVIEW=false VITE_APP_PREVIEW=false
VITE_APP_API_BASE_URL=https://web.api.suwa3d.com/ VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/
VITE_APP_API_URL=https://web.api.suwa3d.com/ VITE_APP_API_URL=https://wechat.api.puabadge.com/
WECHAT_AUTH_URL=https://wechat.api.suwa3d.com/api/auth/page WECHAT_AUTH_URL=https://wechat.api.puabadge.com/api/auth/page

8
.env.production

@ -1,6 +1,6 @@
NODE_ENV=production NODE_ENV=production
VITE_APP_PREVIEW=false VITE_APP_PREVIEW=false
VITE_APP_API_BASE_URL=https://web.api.suwa3d.com/ VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/
VITE_APP_API_URL=https://web.api.suwa3d.com/ VITE_APP_API_URL=https://wechat.api.puabadge.com/
VITE_APP_API_WX_URL=https://wechat.api.suwa3d.com/ VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/
WECHAT_AUTH_URL=https://wechat.api.suwa3d.com/api/auth/page WECHAT_AUTH_URL=https://wechat.api.puabadge.com/api/auth/page

26
components.d.ts vendored

@ -18,44 +18,18 @@ declare module '@vue/runtime-core' {
Loading: typeof import('./src/components/loading/index.vue')['default'] Loading: typeof import('./src/components/loading/index.vue')['default']
Model: typeof import('./src/components/model/index.vue')['default'] Model: typeof import('./src/components/model/index.vue')['default']
ModelGsplat: typeof import('./src/components/modelGsplat/index.vue')['default'] ModelGsplat: typeof import('./src/components/modelGsplat/index.vue')['default']
OrderTrackItem: typeof import('./src/views/short_url/components/orderTrackItem.vue')['default']
Tabbar: typeof import('./src/components/tabbar/index.vue')['default'] Tabbar: typeof import('./src/components/tabbar/index.vue')['default']
Tensorflow: typeof import('./src/components/arFrame/tensorflow.vue')['default'] Tensorflow: typeof import('./src/components/arFrame/tensorflow.vue')['default']
VanActionSheet: typeof import('vant/es')['ActionSheet'] VanActionSheet: typeof import('vant/es')['ActionSheet']
VanButton: typeof import('vant/es')['Button'] VanButton: typeof import('vant/es')['Button']
VanCard: typeof import('vant/es')['Card']
VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup']
VanCheckbox: typeof import('vant/es')['Checkbox']
VanDatePicker: typeof import('vant/es')['DatePicker']
VanDialog: typeof import('vant/es')['Dialog']
VanDivider: typeof import('vant/es')['Divider'] VanDivider: typeof import('vant/es')['Divider']
VanEmpty: typeof import('vant/es')['Empty']
VanField: typeof import('vant/es')['Field']
VanForm: typeof import('vant/es')['Form']
VanGrid: typeof import('vant/es')['Grid'] VanGrid: typeof import('vant/es')['Grid']
VanGridItem: typeof import('vant/es')['GridItem'] VanGridItem: typeof import('vant/es')['GridItem']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']
VanImage: typeof import('vant/es')['Image'] VanImage: typeof import('vant/es')['Image']
VanList: typeof import('vant/es')['List']
VanLoading: typeof import('vant/es')['Loading']
VanNavBar: typeof import('vant/es')['NavBar']
VanOverlay: typeof import('vant/es')['Overlay']
VanPicker: typeof import('vant/es')['Picker']
VanPopup: typeof import('vant/es')['Popup']
VanProgress: typeof import('vant/es')['Progress']
VanPullRefresh: typeof import('vant/es')['PullRefresh']
VanSearch: typeof import('vant/es')['Search']
VanStep: typeof import('vant/es')['Step']
VanSteps: typeof import('vant/es')['Steps']
VanSubmitBar: typeof import('vant/es')['SubmitBar']
VanSwipe: typeof import('vant/es')['Swipe'] VanSwipe: typeof import('vant/es')['Swipe']
VanSwipeItem: typeof import('vant/es')['SwipeItem'] VanSwipeItem: typeof import('vant/es')['SwipeItem']
VanTab: typeof import('vant/es')['Tab']
VanTabbar: typeof import('vant/es')['Tabbar'] VanTabbar: typeof import('vant/es')['Tabbar']
VanTabbarItem: typeof import('vant/es')['TabbarItem'] VanTabbarItem: typeof import('vant/es')['TabbarItem']
VanTabs: typeof import('vant/es')['Tabs']
VanTag: typeof import('vant/es')['Tag']
VanUploader: typeof import('vant/es')['Uploader']
} }
} }

1025
package-lock.json generated

File diff suppressed because it is too large Load Diff

8
package.json

@ -60,6 +60,7 @@
"vite": "^5.3.3", "vite": "^5.3.3",
"vue": "^3.3.4", "vue": "^3.3.4",
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",
"vue-cropperjs": "^5.0.0",
"vue-i18n": "^9.9.0", "vue-i18n": "^9.9.0",
"vue-router": "^4.2.2", "vue-router": "^4.2.2",
"vue-router-better-scroller": "^0.0.0", "vue-router-better-scroller": "^0.0.0",
@ -77,9 +78,14 @@
"@types/store": "^2.0.2", "@types/store": "^2.0.2",
"@types/three": "^0.160.0", "@types/three": "^0.160.0",
"@types/ua-parser-js": "^0.7.39", "@types/ua-parser-js": "^0.7.39",
"@types/vue": "^2.0.0",
"@vitejs/plugin-legacy": "^3.0.2", "@vitejs/plugin-legacy": "^3.0.2",
"@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue": "^4.2.3",
"@vitejs/plugin-vue-jsx": "^3.0.1", "@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue/compiler-sfc": "^3.5.16",
"@vue/runtime-core": "^3.5.16",
"@vue/runtime-dom": "^3.5.16",
"@vue/tsconfig": "^0.7.0",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"babel-plugin-module-resolver": "^4.1.0", "babel-plugin-module-resolver": "^4.1.0",
"commitizen": "^4.3.0", "commitizen": "^4.3.0",
@ -108,7 +114,7 @@
"vite-plugin-mkcert": "^1.17.5", "vite-plugin-mkcert": "^1.17.5",
"vite-plugin-vconsole": "^1.3.1", "vite-plugin-vconsole": "^1.3.1",
"vitest": "^0.25.8", "vitest": "^0.25.8",
"vue-tsc": "^1.6.5" "vue-tsc": "^1.8.27"
}, },
"pnpm": { "pnpm": {
"peerDependencyRules": { "peerDependencyRules": {

188
pnpm-lock.yaml

@ -122,6 +122,9 @@ importers:
vue-clipboard3: vue-clipboard3:
specifier: ^2.0.0 specifier: ^2.0.0
version: 2.0.0 version: 2.0.0
vue-cropperjs:
specifier: ^5.0.0
version: 5.0.0(vue@3.5.13(typescript@4.9.5))
vue-i18n: vue-i18n:
specifier: ^9.9.0 specifier: ^9.9.0
version: 9.14.2(vue@3.5.13(typescript@4.9.5)) version: 9.14.2(vue@3.5.13(typescript@4.9.5))
@ -168,9 +171,24 @@ importers:
'@types/ua-parser-js': '@types/ua-parser-js':
specifier: ^0.7.39 specifier: ^0.7.39
version: 0.7.39 version: 0.7.39
'@types/vue':
specifier: ^2.0.0
version: 2.0.0(typescript@4.9.5)
'@vitejs/plugin-vue-jsx': '@vitejs/plugin-vue-jsx':
specifier: ^3.0.1 specifier: ^3.0.1
version: 3.1.0(vite@5.4.14(@types/node@18.19.76)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@4.9.5)) version: 3.1.0(vite@5.4.14(@types/node@18.19.76)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@4.9.5))
'@vue/compiler-sfc':
specifier: ^3.5.16
version: 3.5.16
'@vue/runtime-core':
specifier: ^3.5.16
version: 3.5.16
'@vue/runtime-dom':
specifier: ^3.5.16
version: 3.5.16
'@vue/tsconfig':
specifier: ^0.7.0
version: 0.7.0(typescript@4.9.5)(vue@3.5.13(typescript@4.9.5))
autoprefixer: autoprefixer:
specifier: ^10.4.14 specifier: ^10.4.14
version: 10.4.20(postcss@8.5.2) version: 10.4.20(postcss@8.5.2)
@ -242,7 +260,7 @@ importers:
version: 0.12.2(@vueuse/core@12.6.1(typescript@4.9.5))(rollup@3.29.5) version: 0.12.2(@vueuse/core@12.6.1(typescript@4.9.5))(rollup@3.29.5)
unplugin-vue-components: unplugin-vue-components:
specifier: ^0.22.12 specifier: ^0.22.12
version: 0.22.12(@babel/parser@7.26.9)(rollup@3.29.5)(vue@3.5.13(typescript@4.9.5)) version: 0.22.12(@babel/parser@7.27.5)(rollup@3.29.5)(vue@3.5.13(typescript@4.9.5))
vite-plugin-mkcert: vite-plugin-mkcert:
specifier: ^1.17.5 specifier: ^1.17.5
version: 1.17.6(vite@5.4.14(@types/node@18.19.76)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)) version: 1.17.6(vite@5.4.14(@types/node@18.19.76)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))
@ -253,7 +271,7 @@ importers:
specifier: ^0.25.8 specifier: ^0.25.8
version: 0.25.8(less@4.2.2)(sass@1.85.0)(terser@5.39.0) version: 0.25.8(less@4.2.2)(sass@1.85.0)(terser@5.39.0)
vue-tsc: vue-tsc:
specifier: ^1.6.5 specifier: ^1.8.27
version: 1.8.27(typescript@4.9.5) version: 1.8.27(typescript@4.9.5)
packages: packages:
@ -372,10 +390,18 @@ packages:
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/helper-string-parser@7.27.1':
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.25.9': '@babel/helper-validator-identifier@7.25.9':
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.27.1':
resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.25.9': '@babel/helper-validator-option@7.25.9':
resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -393,6 +419,11 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
'@babel/parser@7.27.5':
resolution: {integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9': '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9':
resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==} resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@ -804,6 +835,10 @@ packages:
resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/types@7.27.3':
resolution: {integrity: sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==}
engines: {node: '>=6.9.0'}
'@commitlint/config-validator@19.5.0': '@commitlint/config-validator@19.5.0':
resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==} resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==}
engines: {node: '>=v18'} engines: {node: '>=v18'}
@ -1636,6 +1671,10 @@ packages:
'@types/unist@2.0.11': '@types/unist@2.0.11':
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
'@types/vue@2.0.0':
resolution: {integrity: sha512-WDElkBv/o4lVwu6wYHB06AXs4Xo2fwDjJUpvPRc1QQdzkUSiGFjrYuSCy8raxLE5FObgKq8ND7R5gSZTFLK60w==}
deprecated: This is a stub types definition for vuejs (https://github.com/vuejs/vue). vuejs provides its own type definitions, so you don't need @types/vue installed!
'@types/web-bluetooth@0.0.16': '@types/web-bluetooth@0.0.16':
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
@ -1772,15 +1811,27 @@ packages:
'@vue/compiler-core@3.5.13': '@vue/compiler-core@3.5.13':
resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
'@vue/compiler-core@3.5.16':
resolution: {integrity: sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ==}
'@vue/compiler-dom@3.5.13': '@vue/compiler-dom@3.5.13':
resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==}
'@vue/compiler-dom@3.5.16':
resolution: {integrity: sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ==}
'@vue/compiler-sfc@3.5.13': '@vue/compiler-sfc@3.5.13':
resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
'@vue/compiler-sfc@3.5.16':
resolution: {integrity: sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw==}
'@vue/compiler-ssr@3.5.13': '@vue/compiler-ssr@3.5.13':
resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==}
'@vue/compiler-ssr@3.5.16':
resolution: {integrity: sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A==}
'@vue/devtools-api@6.6.4': '@vue/devtools-api@6.6.4':
resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
@ -1795,12 +1846,21 @@ packages:
'@vue/reactivity@3.5.13': '@vue/reactivity@3.5.13':
resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
'@vue/reactivity@3.5.16':
resolution: {integrity: sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA==}
'@vue/runtime-core@3.5.13': '@vue/runtime-core@3.5.13':
resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==}
'@vue/runtime-core@3.5.16':
resolution: {integrity: sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ==}
'@vue/runtime-dom@3.5.13': '@vue/runtime-dom@3.5.13':
resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==}
'@vue/runtime-dom@3.5.16':
resolution: {integrity: sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww==}
'@vue/server-renderer@3.5.13': '@vue/server-renderer@3.5.13':
resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==}
peerDependencies: peerDependencies:
@ -1809,6 +1869,20 @@ packages:
'@vue/shared@3.5.13': '@vue/shared@3.5.13':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
'@vue/shared@3.5.16':
resolution: {integrity: sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg==}
'@vue/tsconfig@0.7.0':
resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==}
peerDependencies:
typescript: 5.x
vue: ^3.4.0
peerDependenciesMeta:
typescript:
optional: true
vue:
optional: true
'@vueuse/core@12.6.1': '@vueuse/core@12.6.1':
resolution: {integrity: sha512-FpgM1tXGAHsAC5n4Tflyg0vSoJUmdevfKaAhKFdxiK9BTIdHOHOiWmo+xivwdzjYFIvI8cEeJWYuqs646jOM2w==} resolution: {integrity: sha512-FpgM1tXGAHsAC5n4Tflyg0vSoJUmdevfKaAhKFdxiK9BTIdHOHOiWmo+xivwdzjYFIvI8cEeJWYuqs646jOM2w==}
@ -2263,6 +2337,9 @@ packages:
typescript: typescript:
optional: true optional: true
cropperjs@1.6.2:
resolution: {integrity: sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==}
cross-env@7.0.3: cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@ -3657,6 +3734,11 @@ packages:
mute-stream@0.0.8: mute-stream@0.0.8:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
nanoid@3.3.8: nanoid@3.3.8:
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -4063,6 +4145,10 @@ packages:
resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
postcss@8.5.4:
resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==}
engines: {node: ^10 || ^12 || >=14}
prelude-ls@1.2.1: prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -4838,6 +4924,11 @@ packages:
vue-clipboard3@2.0.0: vue-clipboard3@2.0.0:
resolution: {integrity: sha512-Q9S7dzWGax7LN5iiSPcu/K1GGm2gcBBlYwmMsUc5/16N6w90cbKow3FnPmPs95sungns4yvd9/+JhbAznECS2A==} resolution: {integrity: sha512-Q9S7dzWGax7LN5iiSPcu/K1GGm2gcBBlYwmMsUc5/16N6w90cbKow3FnPmPs95sungns4yvd9/+JhbAznECS2A==}
vue-cropperjs@5.0.0:
resolution: {integrity: sha512-RhnC8O33uRZNkn74aiHZwNHnBJOXWlS4P6gsRI0lw4cZlWjKSCywZI9oSI9POlIPI6OYv30jvnHMXGch85tw7w==}
peerDependencies:
vue: '>=3.0.0'
vue-demi@0.14.10: vue-demi@0.14.10:
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -5220,8 +5311,12 @@ snapshots:
'@babel/helper-string-parser@7.25.9': {} '@babel/helper-string-parser@7.25.9': {}
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.25.9': {} '@babel/helper-validator-identifier@7.25.9': {}
'@babel/helper-validator-identifier@7.27.1': {}
'@babel/helper-validator-option@7.25.9': {} '@babel/helper-validator-option@7.25.9': {}
'@babel/helper-wrap-function@7.25.9': '@babel/helper-wrap-function@7.25.9':
@ -5241,6 +5336,10 @@ snapshots:
dependencies: dependencies:
'@babel/types': 7.26.9 '@babel/types': 7.26.9
'@babel/parser@7.27.5':
dependencies:
'@babel/types': 7.27.3
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.9)': '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.9)':
dependencies: dependencies:
'@babel/core': 7.26.9 '@babel/core': 7.26.9
@ -5765,6 +5864,11 @@ snapshots:
'@babel/helper-string-parser': 7.25.9 '@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9 '@babel/helper-validator-identifier': 7.25.9
'@babel/types@7.27.3':
dependencies:
'@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.27.1
'@commitlint/config-validator@19.5.0': '@commitlint/config-validator@19.5.0':
dependencies: dependencies:
'@commitlint/types': 19.5.0 '@commitlint/types': 19.5.0
@ -6450,6 +6554,12 @@ snapshots:
'@types/unist@2.0.11': {} '@types/unist@2.0.11': {}
'@types/vue@2.0.0(typescript@4.9.5)':
dependencies:
vue: 3.5.13(typescript@4.9.5)
transitivePeerDependencies:
- typescript
'@types/web-bluetooth@0.0.16': {} '@types/web-bluetooth@0.0.16': {}
'@types/web-bluetooth@0.0.20': {} '@types/web-bluetooth@0.0.20': {}
@ -6623,7 +6733,7 @@ snapshots:
'@babel/helper-module-imports': 7.25.9 '@babel/helper-module-imports': 7.25.9
'@babel/helper-plugin-utils': 7.26.5 '@babel/helper-plugin-utils': 7.26.5
'@babel/parser': 7.26.9 '@babel/parser': 7.26.9
'@vue/compiler-sfc': 3.5.13 '@vue/compiler-sfc': 3.5.16
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -6635,11 +6745,24 @@ snapshots:
estree-walker: 2.0.2 estree-walker: 2.0.2
source-map-js: 1.2.1 source-map-js: 1.2.1
'@vue/compiler-core@3.5.16':
dependencies:
'@babel/parser': 7.27.5
'@vue/shared': 3.5.16
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.2.1
'@vue/compiler-dom@3.5.13': '@vue/compiler-dom@3.5.13':
dependencies: dependencies:
'@vue/compiler-core': 3.5.13 '@vue/compiler-core': 3.5.13
'@vue/shared': 3.5.13 '@vue/shared': 3.5.13
'@vue/compiler-dom@3.5.16':
dependencies:
'@vue/compiler-core': 3.5.16
'@vue/shared': 3.5.16
'@vue/compiler-sfc@3.5.13': '@vue/compiler-sfc@3.5.13':
dependencies: dependencies:
'@babel/parser': 7.26.9 '@babel/parser': 7.26.9
@ -6652,11 +6775,28 @@ snapshots:
postcss: 8.5.2 postcss: 8.5.2
source-map-js: 1.2.1 source-map-js: 1.2.1
'@vue/compiler-sfc@3.5.16':
dependencies:
'@babel/parser': 7.27.5
'@vue/compiler-core': 3.5.16
'@vue/compiler-dom': 3.5.16
'@vue/compiler-ssr': 3.5.16
'@vue/shared': 3.5.16
estree-walker: 2.0.2
magic-string: 0.30.17
postcss: 8.5.4
source-map-js: 1.2.1
'@vue/compiler-ssr@3.5.13': '@vue/compiler-ssr@3.5.13':
dependencies: dependencies:
'@vue/compiler-dom': 3.5.13 '@vue/compiler-dom': 3.5.13
'@vue/shared': 3.5.13 '@vue/shared': 3.5.13
'@vue/compiler-ssr@3.5.16':
dependencies:
'@vue/compiler-dom': 3.5.16
'@vue/shared': 3.5.16
'@vue/devtools-api@6.6.4': {} '@vue/devtools-api@6.6.4': {}
'@vue/language-core@1.8.27(typescript@4.9.5)': '@vue/language-core@1.8.27(typescript@4.9.5)':
@ -6677,11 +6817,20 @@ snapshots:
dependencies: dependencies:
'@vue/shared': 3.5.13 '@vue/shared': 3.5.13
'@vue/reactivity@3.5.16':
dependencies:
'@vue/shared': 3.5.16
'@vue/runtime-core@3.5.13': '@vue/runtime-core@3.5.13':
dependencies: dependencies:
'@vue/reactivity': 3.5.13 '@vue/reactivity': 3.5.13
'@vue/shared': 3.5.13 '@vue/shared': 3.5.13
'@vue/runtime-core@3.5.16':
dependencies:
'@vue/reactivity': 3.5.16
'@vue/shared': 3.5.16
'@vue/runtime-dom@3.5.13': '@vue/runtime-dom@3.5.13':
dependencies: dependencies:
'@vue/reactivity': 3.5.13 '@vue/reactivity': 3.5.13
@ -6689,6 +6838,13 @@ snapshots:
'@vue/shared': 3.5.13 '@vue/shared': 3.5.13
csstype: 3.1.3 csstype: 3.1.3
'@vue/runtime-dom@3.5.16':
dependencies:
'@vue/reactivity': 3.5.16
'@vue/runtime-core': 3.5.16
'@vue/shared': 3.5.16
csstype: 3.1.3
'@vue/server-renderer@3.5.13(vue@3.5.13(typescript@4.9.5))': '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@4.9.5))':
dependencies: dependencies:
'@vue/compiler-ssr': 3.5.13 '@vue/compiler-ssr': 3.5.13
@ -6697,6 +6853,13 @@ snapshots:
'@vue/shared@3.5.13': {} '@vue/shared@3.5.13': {}
'@vue/shared@3.5.16': {}
'@vue/tsconfig@0.7.0(typescript@4.9.5)(vue@3.5.13(typescript@4.9.5))':
optionalDependencies:
typescript: 4.9.5
vue: 3.5.13(typescript@4.9.5)
'@vueuse/core@12.6.1(typescript@4.9.5)': '@vueuse/core@12.6.1(typescript@4.9.5)':
dependencies: dependencies:
'@types/web-bluetooth': 0.0.20 '@types/web-bluetooth': 0.0.20
@ -7232,6 +7395,8 @@ snapshots:
optionalDependencies: optionalDependencies:
typescript: 4.9.5 typescript: 4.9.5
cropperjs@1.6.2: {}
cross-env@7.0.3: cross-env@7.0.3:
dependencies: dependencies:
cross-spawn: 7.0.6 cross-spawn: 7.0.6
@ -8869,6 +9034,8 @@ snapshots:
mute-stream@0.0.8: {} mute-stream@0.0.8: {}
nanoid@3.3.11: {}
nanoid@3.3.8: {} nanoid@3.3.8: {}
natural-compare-lite@1.4.0: {} natural-compare-lite@1.4.0: {}
@ -9298,6 +9465,12 @@ snapshots:
picocolors: 1.1.1 picocolors: 1.1.1
source-map-js: 1.2.1 source-map-js: 1.2.1
postcss@8.5.4:
dependencies:
nanoid: 3.3.11
picocolors: 1.1.1
source-map-js: 1.2.1
prelude-ls@1.2.1: {} prelude-ls@1.2.1: {}
prettier@1.19.1: {} prettier@1.19.1: {}
@ -9965,7 +10138,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
unplugin-vue-components@0.22.12(@babel/parser@7.26.9)(rollup@3.29.5)(vue@3.5.13(typescript@4.9.5)): unplugin-vue-components@0.22.12(@babel/parser@7.27.5)(rollup@3.29.5)(vue@3.5.13(typescript@4.9.5)):
dependencies: dependencies:
'@antfu/utils': 0.7.10 '@antfu/utils': 0.7.10
'@rollup/pluginutils': 5.1.4(rollup@3.29.5) '@rollup/pluginutils': 5.1.4(rollup@3.29.5)
@ -9979,7 +10152,7 @@ snapshots:
unplugin: 1.16.1 unplugin: 1.16.1
vue: 3.5.13(typescript@4.9.5) vue: 3.5.13(typescript@4.9.5)
optionalDependencies: optionalDependencies:
'@babel/parser': 7.26.9 '@babel/parser': 7.27.5
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
- supports-color - supports-color
@ -10095,6 +10268,11 @@ snapshots:
dependencies: dependencies:
clipboard: 2.0.11 clipboard: 2.0.11
vue-cropperjs@5.0.0(vue@3.5.13(typescript@4.9.5)):
dependencies:
cropperjs: 1.6.2
vue: 3.5.13(typescript@4.9.5)
vue-demi@0.14.10(vue@3.5.13(typescript@4.9.5)): vue-demi@0.14.10(vue@3.5.13(typescript@4.9.5)):
dependencies: dependencies:
vue: 3.5.13(typescript@4.9.5) vue: 3.5.13(typescript@4.9.5)

32
src/api/multiPrint.ts

@ -1,32 +0,0 @@
import request from '@/utils/request'
// 参数为 page, size, pid
export const page = (params: any) => {
return request('/printBatchOrder/page', { params, method: 'GET' })
}
// 批次详情
export const detailPage = (data: any) => {
return request('/printBatchOrder/detailPage', { data, method: 'POST' })
}
// 主要参数为pid
export const add = (params: any) => {
return request('/printBatchOrder/grossWeight', { params, method: 'POST' })
}
// 签名
export const getPutSignURL = (data: any) => {
return request('/printBatchOrder/putSignURL', { data, method: 'POST' })
}
// oss
export const uploadToOss = (putSignUrl: any, file: any) => {
return request({
url: putSignUrl,
headers: {
"Content-Type": "application/octet-stream"
},
data: file, method: 'PUT', withCredentials: false, })
}

12
src/api/my_order.ts

@ -1,12 +0,0 @@
import request from '@/utils/request'
// 参数为 page, size, pid
export const page = (params: any) => {
return request('/myOrder/page', { params, method: 'GET' })
}
// 主要参数为pid
export const detail = (pid: number) => {
return request('/myOrder/detail', { params: { pid }, method: 'GET' })
}

33
src/api/photo_3d.ts

@ -1,33 +0,0 @@
import request from '@/utils/request'
import requestWx from '@/utils/requestWx'
export const glb = (id: number, file_type: string,isShare: string, extParams?: any) => {
return request('model/glb', {
method: 'GET',
params: Object.assign({}, {
file_type,
s: isShare,
id,
type: 1,
without_head: 1,
}, extParams),
})
}
export const get3dBgList = (pid: number) => {
return request('material/bg', {
method: 'GET',
params: {
pid,
},
})
}
export const getWechatConfig = (url: string) => {
return requestWx('wechatConfig/config', {
method: 'GET',
data: {
url: url.split('#')[0],
},
})
}

20
src/api/pic_video.ts

@ -1,20 +0,0 @@
import request from '@/utils/request'
// 参数为 page, size
export const list = (params: any) => {
return request('/picVideo/list', { params, method: 'GET' })
}
// 参数为 id, print_id, from_u
export const info = (id: number) => {
return request('/picVideo/info', { params: { id }, method: 'GET' })
}
// 参数为 id, print_id, from_u
export const share = (id: number) => {
return request('/picVideo/share', { params: { id }, method: 'GET' })
}
// 参数为 id, print_id
export const downloadUrl = (id: number) => {
return request('/picVideo/downloadUrl', { params: { id }, method: 'GET' })
}

28
src/api/queue.ts

@ -1,28 +0,0 @@
import request from '@/utils/request'
export const calc = (data: any) => {
return request('queue/calc', {
method: 'POST',
data,
})
}
export const queueAdd = (data: any) => {
return request('queue/addNew', {
method: 'POST',
data,
})
}
// export const queueAdd = (data: any) => {
// return request('queue/add', {
// method: 'POST',
// data,
// })
// }
export const attr = (params: any) => {
return request('queue/attr', {
method: 'GET',
params,
})
}

41
src/api/receive_address.ts

@ -1,41 +0,0 @@
import request from '@/utils/request'
// 参数为 shop_id, pid
export const list = (params: any) => {
return request('/receiveAddress/list', { params, method: 'GET' })
}
// 参数为 id
export const info = (id: number) => {
return request('/receiveAddress/info', { params: { id }, method: 'GET' })
}
// 无参数
export const Default = () => {
return request('/receiveAddress/default', { method: 'GET' })
}
// add
/**
* @param data
* @returns
*/
export const add = (data: any) => {
return request('/receiveAddress/add', { data, method: 'POST' })
}
/**
*
* @param data
* @returns
*/
export const edit = (data: any) => {
return request('/receiveAddress/update', { data, method: 'POST' })
}
/**
*
* @param data
* @returns
*/
export const del = (params: any) => {
return request('/receiveAddress/delete', { params, method: 'POST' })
}

22
src/api/short_url.ts

@ -1,22 +0,0 @@
import request from '@/utils/request'
// 参数为 code
export const actions = (code: string) => {
return request('/shortUrl/actions', { params: { code }, method: 'GET' })
}
// 参数为 code, 订单履历
export const orderTrack = (code: string) => {
return request('/shortUrl/orderTrack', { params: { code }, method: 'GET' })
}
// 参数为 code, 订单信息
export const orderInfo = (code: string) => {
return request('/shortUrl/orderInfo', { params: { code }, method: 'GET' })
}
// 参数为 code, 打印信息
export const printOrderInfo = (code: string) => {
return request('/shortUrl/printOrderInfo', { params: { code }, method: 'GET' })
}

BIN
src/assets/about/hands.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/about/mail.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/about/map.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/about/tel.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/order/gou.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 B

BIN
src/assets/order/gou_1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 528 B

BIN
src/assets/order/gray_yuan.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

BIN
src/assets/order/jingdong.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1011 B

BIN
src/assets/order/line.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

BIN
src/assets/order/line_gou.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 648 B

BIN
src/assets/order/look-delivery.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 436 B

BIN
src/assets/order/more.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

BIN
src/assets/order/no-order.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/order/shunfeng.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

BIN
src/assets/order/tag.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

BIN
src/assets/order/tel.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 B

BIN
src/assets/photo3D/buy.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 431 B

BIN
src/assets/photo3D/edit.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

BIN
src/assets/photo3D/hint.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

BIN
src/assets/photo3D/icon_3d_ar.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

BIN
src/assets/photo3D/icon_3d_ar_gray.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

BIN
src/assets/photo3D/icon_3d_bg.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/assets/photo3D/icon_3d_bg_gray.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

BIN
src/assets/photo3D/icon_3d_buy.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/assets/photo3D/icon_3d_buy_gray.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

BIN
src/assets/photo3D/icon_3d_share.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

BIN
src/assets/photo3D/icon_3d_share_gray.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/photo3D/icon_exit.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/assets/photo3D/music_forbid.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/photo3D/music_play.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

BIN
src/assets/photo3D/reset.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

BIN
src/assets/photo3D/rotate.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

BIN
src/assets/photo3D/save.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

BIN
src/assets/photo3D/stop.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

BIN
src/assets/photo3D/vector.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

BIN
src/assets/takePhoto/bg.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 B

BIN
src/assets/takePhoto/code.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

BIN
src/assets/takePhoto/fresh.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

BIN
src/assets/takePhoto/status_btn_01.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

BIN
src/assets/takePhoto/status_btn_02.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

BIN
src/assets/takePhoto/status_btn_03.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

BIN
src/assets/takePhoto/status_btn_04.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

30
src/router/address.ts

@ -1,30 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import Address from '@/views/address/index.vue'
import AddressEdit from '@/views/address/edit.vue'
// 定义路由,每个路由都需要映射到一个组件
const routes = [
{
path: '/address',
name: 'address',
component: Address,
meta: {
needGuard: true,
title: '地址管理',
},
},
{
path: '/address/edit',
name: 'edit',
meta: {
title: "地址编辑"
},
component: AddressEdit,
}
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

42
src/router/index.ts

@ -3,16 +3,8 @@ import { createRouter, createWebHashHistory } from 'vue-router'
import NProgress from 'nprogress' import NProgress from 'nprogress'
import 'nprogress/nprogress.css' import 'nprogress/nprogress.css'
// 导入路由组件 // 导入路由组件
import { mergeRoutes } from './queue'
import * as myOrderRouter from './my_order'
import * as photo3dRouter from './photo_3d'
import * as shortUrlRouter from './short_url'
import * as multiPrintRouter from './multiPrint'
import * as badgeRouter from './badge' import * as badgeRouter from './badge'
import mian from '@/views/index.vue' import mian from '@/views/index.vue'
import User from '@/views/user/index.vue'
import Person from '@/views/user/person.vue'
import About from '@/views/about/index.vue'
import Login from '@/views/login/index.vue' import Login from '@/views/login/index.vue'
import { useTokenStore } from '@/stores/token' import { useTokenStore } from '@/stores/token'
import {useStore} from '@/stores' import {useStore} from '@/stores'
@ -31,23 +23,6 @@ const routes = [
title: '首页', title: '首页',
}, },
}, },
{
path: '/user',
name: 'user',
component: User,
meta: {
needGuard: true,
title: "个人中心",
},
},
{
path: "/person",
name: "person",
meta: {
title: "个人信息"
},
component: Person
},
{ {
path: '/login', path: '/login',
name: 'login', name: 'login',
@ -56,21 +31,8 @@ const routes = [
title: '登录', title: '登录',
}, },
}, },
{
path: '/about',
name: 'about',
component: About,
meta: {
title: '关于我们',
},
},
] ]
mergeRoutes(routes)
myOrderRouter.mergeRoutes(routes)
photo3dRouter.mergeRoutes(routes)
shortUrlRouter.mergeRoutes(routes)
multiPrintRouter.mergeRoutes(routes)
badgeRouter.mergeRoutes(routes) badgeRouter.mergeRoutes(routes)
// 创建路由实例并传递 `routes` 配置 // 创建路由实例并传递 `routes` 配置
const router = createRouter({ const router = createRouter({
@ -86,7 +48,7 @@ router.beforeEach((_to, _from, next) => {
tokenStore.login(String(token)) tokenStore.login(String(token))
let url = store.redirectUrl() let url = store.redirectUrl()
if (_to.path !== '/queue') { if (_to.path !== '/badge') {
if (url) { if (url) {
store.setRedirect('') store.setRedirect('')
next(url) next(url)
@ -111,7 +73,6 @@ router.beforeEach((_to, _from, next) => {
next(`/login`) next(`/login`)
} else { } else {
if (_to.path === '/') { if (_to.path === '/') {
// next('/myOrder')
next('/badge') next('/badge')
} else { } else {
next() next()
@ -123,7 +84,6 @@ router.beforeEach((_to, _from, next) => {
if (!tokenStore.isLoggedIn()) { if (!tokenStore.isLoggedIn()) {
next() next()
} else { } else {
// next('/myOrder')
next('/badge') next('/badge')
} }
} else { } else {

39
src/router/multiPrint.ts

@ -1,39 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import multiPrint from '@/views/multiPrint/index.vue'
import multiPrintDetail from '@/views/multiPrint/detail.vue'
import orderDetail from '@/views/multiPrint/orderDetail.vue'
// 定义路由,每个路由都需要映射到一个组件
const routes = [
{
path: '/multiPrint',
name: 'multiPrint',
component: multiPrint,
meta: {
needGuard: true,
title: '称毛重管理',
},
},
{
path: '/multiPrintDetail',
name: 'multiPrintDetail',
meta: {
title: "称毛重"
},
component: multiPrintDetail,
},
{
path: '/orderDetail',
name: 'orderDetail',
meta: {
title: "批次详情"
},
component: orderDetail,
},
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

31
src/router/my_order.ts

@ -1,31 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import myOrder from '@/views/my_order/index.vue'
import OrderDetail from '@/views/my_order/detail.vue'
// 定义路由,每个路由都需要映射到一个组件
const routes = [
{
path: '/myOrder',
name: 'myOrder',
component: myOrder,
meta: {
needGuard: true,
title: '我的订单',
},
},
{
path: '/myOrder/detail',
name: 'detail',
meta: {
needGuard: true,
title: "订单详情"
},
component: OrderDetail,
}
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

42
src/router/photo_3d.ts

@ -1,42 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import Photo3d from '@/views/photo_3d/index.vue'
import Gsplat from '@/views/photo_3d/gsplat.vue'
import Ar from '@/views/photo_3d/ar.vue'
// 定义路由,每个路由都需要映射到一个组件
const routes = [
{
path: '/photo3d',
name: 'photo3d',
component: Photo3d,
meta: {
needGuard: true,
title: '3d相册',
},
},
{
path: '/photo3d/gsplat',
name: 'gsplat',
component: Gsplat,
meta: {
needGuard: true,
title: '3d高斯相册',
},
},
{
path: '/ar',
name: 'ar',
component: Ar,
meta: {
needGuard: true,
title: 'ar',
},
},
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

30
src/router/queue.ts

@ -1,30 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import queue from '@/views/queue/index.vue'
import queueSucceed from '@/views/queue/succeed.vue'
// 定义路由,每个路由都需要映射到一个组件
export const routes = [
{
path: '/queue',
name: 'queue',
component: queue,
meta: {
needGuard: true,
title: '排队',
},
},
{
path: '/queue/succeed',
name: 'queue.succeed',
component: queueSucceed,
meta: {
needGuard: true,
title: '排队成功',
},
},
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

50
src/router/short_url.ts

@ -1,50 +0,0 @@
// https://router.vuejs.org/zh/
import 'nprogress/nprogress.css'
import actions from '@/views/short_url/actions.vue'
import orderInfo from '@/views/short_url/orderInfo.vue'
import orderTrack from '@/views/short_url/orderTrack.vue'
import printOrderInfo from '@/views/short_url/printOrderInfo.vue'
// 定义路由,每个路由都需要映射到一个组件
const routes = [
{
path: '/shortUrl/actions',
name: 'shortUrl.actions',
component: actions,
meta: {
needGuard: true,
title: '功能',
},
},
{
path: '/shortUrl/orderInfo',
name: 'shortUrl.orderInfo',
component: orderInfo,
meta: {
needGuard: true,
title: '订单信息',
},
},
{
path: '/shortUrl/orderTrack',
name: 'shortUrl.orderTrack',
component: orderTrack,
meta: {
needGuard: true,
title: '订单履历',
},
},
{
path: '/shortUrl/printOrderInfo',
name: 'shortUrl.printOrderInfo',
component: printOrderInfo,
meta: {
needGuard: true,
title: '打印信息',
},
},
]
export function mergeRoutes(allRoutes: any[]) {
allRoutes.push(...routes)
}

17
src/shims-vue.d.ts vendored

@ -0,0 +1,17 @@
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
declare module '@vue/runtime-dom' {
export * from '@vue/runtime-dom/dist/runtime-dom'
}
declare module 'vue' {
export interface GlobalComponents {
view: any
image: any
canvas: any
}
}

331
src/views/about/index.vue

@ -1,331 +0,0 @@
<template>
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" left-text="返回" left-arrow
@click-left="returnClick" safe-area-inset-top/>
<div>
<div class="page">
<div class="section">
<div class="section-title">
<div class="s-title">SUWA3D</div>
<div class="l-title">关于我们</div>
</div>
<div class="description">速相科技成立于2016年总部在福建厦门<br />目前是全球首家商业化3D人像摄影专业机构<br />产品材料安全环保细节还原度高<br />旗下的品牌速哇为国内首家数字人3D真人手办连锁品牌<br />速哇3D手办亲人朋友恋人宠物的各种美好时刻记录下来</div>
<div class="info-box">
<img src="@/assets/about/mail.png" class="info-icon"/>
<div class="info-detail">
<div class="info-label">邮箱</div>
<div class="info-value">business@suwa3d.com</div>
</div>
</div>
<div class="info-box" @click="call(1)">
<img src="@/assets/about/hands.png" class="info-icon"/>
<div class="info-detail">
<div class="info-label">合作热线</div>
<div class="info-value">400&nbsp;6667&nbsp;215</div>
</div>
</div>
<div class="info-box" @click="call(2)">
<img src="@/assets/about/tel.png" class="info-icon"/>
<div class="info-detail">
<div class="info-label">招商电话</div>
<div class="info-value">18046215201</div>
</div>
</div>
</div>
<div class="info-box" @click="call(1)">
<img src="@/assets/about/hands.png" class="info-icon"/>
<div class="info-detail">
<div class="info-label">合作热线</div>
<div class="info-value">400&nbsp;6667&nbsp;215</div>
</div>
</div>
<div class="info-box" @click="call(2)">
<img src="@/assets/about/tel.png" class="info-icon"/>
<div class="info-detail">
<div class="info-label">招商电话</div>
<div class="info-value">18046215201</div>
</div>
</div>
</div>
<div class="section">
<div class="section-title">
<div class="s-title">SUWA3D</div>
<div class="l-title">全国门店</div>
</div>
<img src="@/assets/about/map.png" class="map_img"/>
<div class="group_6">
<div class="shop-count">
<div class="under_border"></div>
<div class="count">49+</div>
</div>
<div class="text_25">家门店</div>
<div class="point">
<div class="group_7"></div>
<div class="group_8"></div>
</div>
<div class="text-wrapper_4">
<div class="text_26">速哇加盟门店城市</div>
<div class="text_27">速哇待开业门店</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {useStore} from '@/stores'
const store = useStore();
import { useTokenStore } from '@/stores/token'
const tokenStore = useTokenStore();
const userInfo = ref("")
const {isWechat} = tokenStore;
onMounted(()=> {
userInfo.value = tokenStore.userInfo;
})
const returnClick = () => history.back()
const call = (num: number) => {
const a = document.createElement("a");
let phoneNum = ""
switch(num) {
case 1: phoneNum = "4006667215";break;
case 2: phoneNum = "18046215201";break;
}
a.href = "tel:" + phoneNum;
a.click();
}
</script>
<style lang="less" scoped>
.page {
background-color: rgba(255, 255, 255, 1.000000);
position: relative;
width: 375px;
height: 100vh;
overflow: scroll;
display: flex;
flex-direction: column;
}
.section {
width: 375px;
display: flex;
flex-direction: column;
margin-bottom: 50px;
.section-title {
width: 157px;
height: 40px;
flex-direction: row;
display: flex;
margin: 25px auto 0 auto;
.s-title {
overflow-wrap: break-word;
font-size: 36px;
font-family: Source Han Sans CN-Heavy;
font-weight: 900;
text-align: center;
white-space: nowrap;
line-height: 36px;
webkit-background-clip: text;
webkit-text-fill-color: transparent;
color: mintcream;
}
.l-title {
overflow-wrap: break-word;
color: rgba(61, 61, 61, 1.000000);
font-size: 24px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
text-align: center;
white-space: nowrap;
line-height: 24px;
margin: 16px 30px 0 -126px;
}
}
}
.description {
width: 345px;
height: 108px;
overflow-wrap: break-word;
color: rgba(102, 102, 102, 1.000000);
font-size: 12px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: center;
line-height: 18px;
margin: 30px auto 15px auto;
}
.info-box {
width: 205px;
height: 54px;
display: flex;
justify-content: space-between;
margin: 30px auto 0 auto;
.info-icon {
width: 54px;
height: 54px;
}
.info-detail {
width: 131px;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
.info-label {
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 16px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
white-space: nowrap;
line-height: 16px;
}
.info-value {
overflow-wrap: break-word;
color: rgba(153, 153, 153, 1.000000);
font-size: 12px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
white-space: nowrap;
line-height: 12px;
}
}
}
.text-group_7 {
width: 157px;
height: 40px;
flex-direction: row;
display: flex;
margin: 50px 0 31px 109px;
}
.map_img {
width: 345px;
height: 283px;
margin: 50px auto 0 auto;
}
.group_6 {
width: 305px;
height: 44px;
flex-direction: row;
display: flex;
margin: 30px auto;
}
.shop-count {
position: relative;
width: 73px;
height: 44px;
display: flex;
flex-direction: column;
}
.under_border {
display: flex;
flex-direction: column;
background-image: linear-gradient(90deg, rgba(85, 176, 56, 0.000000) 0, rgba(108, 217, 73, 1.000000) 100.000000%);
width: 73px;
height: 16px;
margin-top: 28px;
}
.count {
position: absolute;
left: 0px;
top: 0px;
width: 73px;
height: 36px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 40px;
font-family: Source Han Sans CN-Heavy;
font-weight: 900;
text-align: left;
white-space: nowrap;
line-height: 36px;
}
.text_25 {
width: 48px;
height: 16px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 16px;
font-family: Source Han Sans CN-Heavy;
font-weight: 900;
text-align: center;
white-space: nowrap;
line-height: 16px;
margin: 18px 0 0 5px;
}
.point {
width: 8px;
height: 38px;
display: flex;
flex-direction: column;
justify-content: space-between;
margin: 3px 0 0 49px;
}
.group_7 {
background-color: rgba(85, 176, 56, 1.000000);
border-radius: 100%;
width: 8px;
height: 8px;
display: flex;
flex-direction: column;
}
.group_8 {
background-color: rgba(255, 94, 94, 1.000000);
border-radius: 100%;
width: 8px;
height: 8px;
margin-top: 22px;
display: flex;
flex-direction: column;
}
.text-wrapper_4 {
width: 112px;
height: 44px;
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.text_26 {
width: 112px;
height: 14px;
overflow-wrap: break-word;
color: rgba(61, 61, 61, 1.000000);
font-size: 14px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 14px;
}
.text_27 {
width: 83px;
height: 14px;
overflow-wrap: break-word;
color: rgba(61, 61, 61, 1.000000);
font-size: 14px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 14px;
margin-top: 16px;
}
</style>

13
src/views/address/edit.vue

@ -1,13 +0,0 @@
<template>
<div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

349
src/views/address/index.vue

@ -1,349 +0,0 @@
<template>
<div>
<!-- 收件信息页 -->
<div class="container">
<!-- <mp-dialog
show="{{ dialogShow }}"
bindbuttontap="tapDialogButton"
buttons="{{ buttons }}">
<div>
<div class="calcelTitle">
确定要删除地址
</div>
</div>
</mp-dialog> -->
<van-dialog message="确定要删除地址?" v-model:show="dialogShow"
@confirm="tapDialogButton" showCancelButton confirm-button-color="#AAAAAA"
cancel-button-color="#009944" round />
<div class="main">
<block v-if="address_list[0]">
<div class="top">
<div class="controller" @click="controlEdit" >{{ currentIndex == false ? '管理' : '完成'}}</div>
</div>
<div class="content">
<block v-for="item, index in address_list" :key="index">
<div class="item" @click="onSelect" data-item="{{item}}">
<div class="item_wrap">
<div class="info">
<div class="detail">
<div class="user">{{item.receive_contact}}</div>
<div class="phoneNumber">{{item.receive_mobile}}</div>
<div class="status" v-if="item.is_default == 1">默认</div>
<div class="shop_status" v-if="item.shop_id > 0">门店</div>
</div>
<div class="address">{{item.province_name}} {{item.city_name}} {{item.county_name}} {{item.receive_address}}</div>
</div>
<div class="edit_box {{!editShow ? 'floatRight' : ''}}">
<van-checkbox
v-if="!select && !editShow"
icon-size="25px"
value="{{ addressId == item.id }}"
checked-color="#009944"
></van-checkbox>
<van-icon v-if="editShow" name="edit" size="25" @click.stop="editClick(item.id)"/>
<van-icon v-if="editShow" name="cross" size="25" @click.stop="deleteClick(item.shop_id, item.id)"/>
</div>
</div>
</div>
</block>
</div>
</block>
<div class="empty" v-else>
<div class="text">您还没有收件地址快添加一个吧~</div>
</div>
</div>
<router-link class="add_btn" to="/address/edit">
<div class="add_btn">添加收件地址</div>
</router-link>
</div>
</div>
</template>
<script setup lang="ts">
const router = useRouter()
const currentIndex = ref(false) //
const isCover = ref(false) //
const editShow= ref(false) //
const baseInfo = ref("") // baseInfo
const address_list = ref("") //
const addressId = ref(0) // id
const select = ref(false) //
const dialogShow = ref(false) //
const current_id = ref(0) // id
const shop_id = ref(0) // id
onMounted(()=> {
// this.setData({
// addressId: options.id,
// shop_id: options.shopid,
// pid: options.pid,
// select: options.select
// })
getAddress();
})
//
const controlEdit = () => {
currentIndex.value = !currentIndex.value;
editShow.value = !editShow.value;
}
//
const tapDialogButton = () => {
deleteConfirm();
dialogShow.value = false
}
//
const editClick = (id) => {
router.push({
path: '/packageAddress/pages/address/edit/edit?id=' + id,
})
}
//
const deleteClick = (sid, id) => {
addressId.value = id;
current_id.value = sid;
dialogShow.value = true;
}
//
const deleteConfirm = () => {
// let id = this.data.addressId;
// const u = wx.getStorageSync('userInfo');
// let params = {
// id: id,
// open_id: u.openid,
// union_id: u.unionid,
// }
// if(this.data.current_id > 0) {
// setTimeout(()=> {
// wx.showToast({
// title: "",
// icon: "error"
// })
// }, 500)
// return false
// }
// app.api.deleteAddress(params).then(res=>{
// console.log(res)
// if(res.code == 1000) {
// this.setData({
// isCover: true
// })
// setTimeout(()=> {
// this.setData({
// isCover: false
// })
// }, 2000)
// wx.showToast({
// icon: 'none',
// title: res.message
// });
// setTimeout(()=> {
// this.getAddress();
// }, 200)
// }
// })
}
//
const getAddress = () => {
// let _this = this;
// const u = wx.getStorageSync('userInfo');
// let obj = {
// shop_id: this.data.shop_id,
// pid: this.data.pid,
// open_id: u.openid,
// union_id: u.unionid,
// }
// app.api.addressList(obj).then(res=> {
// console.log(res)
// if(res.code == 1000) {
// let address_list = res.data;
// _this.setData({
// address_list
// })
// }else {
// wx.showToast({
// icon: 'none',
// title: res.message
// });
// }
// })
}
const onSelect = (e) => {
if(editShow.value || select.value) {
return false
}
// const data = e.currentTarget.dataset.item;
// const prevPage = getCurrentPages()[getCurrentPages().length - 2];
// prevPage.setData({
// id: data.id,
// receive_contact: data.receive_contact,
// receive_mobile: data.receive_mobile,
// receive_address: data.receive_address,
// city_name: data.city_name,
// county_name: data.county_name,
// province_name: data.province_name,
// shop_id: data.shop_id,
// });
// wx.navigateBack()
}
</script>
<style lang="less" scoped>
.container {
// background: #f7f7f7;
height: 100vh;
background: #f8f8f8;
.main {
width: 100%;
.top {
display: flex;
justify-content: flex-end;
align-items: center;
width: 90%;
height: 30px;
margin: 0 auto;
.controller {
font-size: 15px;
color: #009944;
}
}
.content {
width: 100%;
height: 100%;
.item {
width: 100%;
height: 62.5px;
background: #ffffff;
border: 1px solid #d8d8d8;
.item_wrap {
display: flex;
justify-content: space-between;
align-items: center;
width: 328px;
height: 100%;
margin: 0 auto;
.info {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
font-size: 12px;
max-width: 250px;
height: 100%;
box-sizing: border-box;
.detail {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 7.5px;
.user {
font-size: 15px;
color: #333333;
margin-right: 7.5px;
max-width: 125px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.phoneNumber {
color: #6c6c6c;
margin-right: 7.5px;
}
.status {
display: flex;
justify-content: center;
align-items: center;
width: 35px;
height: 15px;
border-radius: 7.5px;
background: #ce80ff;
color: #ffffff;
font-size: 12px;
}
.shop_status {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: auto;
height: 18px;
border-radius: 8px;
background: #e6a23c;
color: #ffffff;
font-size: 10px;
font-weight: 400;
padding: 0 7.5px;
}
}
.address {
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
}
}
.edit_box {
width: 60px;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.edit {
width: 16px;
height: 20px;
}
.delete {
width: 16.5px;
height: 19px;
}
}
.floatRight {
justify-content: flex-end;
}
}
}
}
.empty {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
width: 100%;
// height: 100vh;
padding: 75px 0;
// background: #f8f8f8;
.icon {
width: 58.5px;
height: 55.5px;
}
.text {
font-size: 13px;
color: #999999;
margin-top: 7.5px;
}
}
}
.add_btn {
position: fixed;
bottom: 5%;
left: 50%;
margin: -18.5px 0 0 -146.5px;
background: #009944;
display: flex;
justify-content: center;
align-items: center;
width: 293px;
height: 37px;
color: #ffffff;
font-size: 15px;
border-radius: 20px;
}
}
</style>

546
src/views/badge/cropper.vue

@ -1,267 +1,329 @@
<template name="cropper"> <script lang="ts">
<view> import { defineComponent } from '@vue/runtime-dom'
<image :src="imgSrc.imgSrc" class="my-avatar" mode="aspectFill" @click="fSelect" :style="imgStyle"></image> import type { PropType } from '@vue/runtime-dom'
<!-- 上传图片 -->
<canvas canvas-id="avatar-canvas" id="avatar-canvas" class="my-canvas" :style="{top: styleTop, height: cvsStyleHeight}" interface Style {
disable-scroll="false"></canvas> width?: string
<!-- 截取边框 --> height?: string
<canvas canvas-id="oper-canvas" id="oper-canvas" class="oper-canvas" :style="{top: styleTop, height: cvsStyleHeight}" top?: string
disable-scroll="false" @touchstart="fStart" @touchmove="fMove" @touchend="fEnd"></canvas> left?: string
<view class="oper-wrapper" :style="{display: styleDisplay}"> [key: string]: any
<view class="btn-wrapper" v-if="showOper"> }
<view @click="fClose" hover-class="hover">取消</view>
<view @click="fUpload" hover-class="hover">选取</view> const tabHeight = 70
</view> export default defineComponent({
</view> name: 'Cropper',
</view> props: {
</template> avatarSrc: {
type: String as PropType<string>,
default: '',
},
avatarStyle: {
type: String as PropType<string>,
default: '',
},
selWidth: {
type: String as PropType<string>,
default: '',
},
selHeight: {
type: String as PropType<string>,
default: '',
},
expWidth: {
type: String as PropType<string>,
default: '',
},
expHeight: {
type: String as PropType<string>,
default: '',
},
minScale: {
type: String as PropType<string>,
default: '',
},
maxScale: {
type: String as PropType<string>,
default: '',
},
canScale: {
type: String as PropType<string>,
default: '',
},
noTab: {
type: String as PropType<string>,
default: '',
},
quality: {
type: String as PropType<string>,
default: '',
},
index: {
type: String as PropType<string>,
default: '',
},
},
data() {
return {
cvsStyleHeight: '0px',
styleDisplay: 'none',
styleTop: '-10000px',
prvTop: '-10000px',
imgStyle: {} as Style,
selStyle: {} as Style,
showOper: true,
imgSrc: {
imgSrc: '',
},
qlty: 0.9,
postWidthFirst: {},
}
},
watch: {
avatarSrc() {
this.imgSrc.imgSrc = this.avatarSrc
},
},
created() {
const canvas = document.getElementById('avatar-canvas')
const operCanvas = document.getElementById('oper-canvas')
this.ctxCanvas = canvas.getContext('2d')
this.ctxCanvasOper = operCanvas.getContext('2d')
<script> this.qlty = parseInt(this.quality) || 0.9
const tabHeight = 70; this.imgSrc.imgSrc = this.avatarSrc
export default { this.letScale = this.canScale === 'false' ? 0 : 1
name: "cropper", this.indx = this.index || undefined
data() { this.mnScale = this.minScale || 0.3
return { this.mxScale = this.maxScale || 4
cvsStyleHeight: '0px', this.noBar = this.noTab === 'true' ? 1 : 0
styleDisplay: 'none', if (this.noBar) {
styleTop: '-10000px', this.moreHeight = 0
prvTop: '-10000px', this.fWindowResize()
imgStyle: {}, } else {
selStyle: {}, this.moreHeight = 50
showOper: true, this.fWindowResize()
imgSrc: { }
imgSrc: '' },
}, methods: {
qlty: 0.9, fWindowResize() {
postWidthFirst: {}, const sysInfo = {
}; platform: navigator.platform,
}, pixelRatio: window.devicePixelRatio,
watch: { windowWidth: window.innerWidth,
avatarSrc() { windowHeight: window.innerHeight,
this.imgSrc.imgSrc = this.avatarSrc; windowTop: window.scrollY,
} windowBottom: 0,
}, statusBarHeight: 0,
props: { screenHeight: screen.height,
avatarSrc: '', }
avatarStyle: '',
selWidth: '',
selHeight: '',
expWidth: '',
expHeight: '',
minScale: '',
maxScale: '',
canScale: '',
noTab: '',
quality: '',
index: ''
},
created() {
const canvas = document.getElementById('avatar-canvas');
const operCanvas = document.getElementById('oper-canvas');
this.ctxCanvas = canvas.getContext('2d');
this.ctxCanvasOper = operCanvas.getContext('2d');
this.qlty = parseInt(this.quality) || 0.9; this.platform = sysInfo.platform
this.imgSrc.imgSrc = this.avatarSrc; this.pixelRatio = sysInfo.pixelRatio
this.letScale = this.canScale === 'false' ? 0 : 1; this.windowWidth = sysInfo.windowWidth
this.indx = this.index || undefined; this.drawTop = sysInfo.windowTop
this.mnScale = this.minScale || 0.3; this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom
this.mxScale = this.maxScale || 4; this.cvsStyleHeight = `${this.windowHeight - tabHeight}px`
this.noBar = this.noTab === 'true' ? 1 : 0;
if (this.noBar) {
this.moreHeight = 0;
this.fWindowResize();
} else {
this.moreHeight = 50;
this.fWindowResize();
}
},
methods: {
fWindowResize() {
const sysInfo = {
platform: navigator.platform,
pixelRatio: window.devicePixelRatio,
windowWidth: window.innerWidth,
windowHeight: window.innerHeight,
windowTop: window.scrollY,
windowBottom: 0,
statusBarHeight: 0,
screenHeight: screen.height
};
this.platform = sysInfo.platform; this.pxRatio = this.windowWidth / 750
this.pixelRatio = sysInfo.pixelRatio;
this.windowWidth = sysInfo.windowWidth;
this.drawTop = sysInfo.windowTop;
this.windowHeight = sysInfo.windowHeight + sysInfo.windowBottom;
this.cvsStyleHeight = this.windowHeight - tabHeight + 'px';
this.pxRatio = this.windowWidth / 750; const style = this.avatarStyle
console.log(style)
this.imgStyle = style
this.expWidth && (this.exportWidth = this.expWidth.includes('rpx')
? parseInt(this.expWidth) * this.pxRatio
: parseInt(this.expWidth))
this.expHeight && (this.exportHeight = this.expHeight.includes('rpx')
? parseInt(this.expHeight) * this.pxRatio
: parseInt(this.expHeight))
let style = this.avatarStyle; if (this.styleDisplay === 'flex')
console.log(style) this.fDrawInit(true)
this.imgStyle = style;
this.expWidth && (this.exportWidth = this.expWidth.indexOf('rpx') >= 0 ? parseInt(this.expWidth) * this.pxRatio :
parseInt(this.expWidth));
this.expHeight && (this.exportHeight = this.expHeight.indexOf('rpx') >= 0 ? parseInt(this.expHeight) * this.pxRatio :
parseInt(this.expHeight));
if (this.styleDisplay === 'flex') { this.fHideImg()
this.fDrawInit(true); },
} fSelect() {
this.fHideImg(); if (this.fSelecting)
}, return
fSelect() { this.fSelecting = true
if (this.fSelecting) return; setTimeout(() => {
this.fSelecting = true; this.fSelecting = false
setTimeout(() => { }, 500)
this.fSelecting = false;
}, 500);
const input = document.createElement('input'); const input = document.createElement('input')
input.type = 'file'; input.type = 'file'
input.accept = 'image/*'; input.accept = 'image/*'
input.onchange = (e) => { input.onchange = (e) => {
const file = e.target.files[0]; const file = e.target.files[0]
if(!file) return; if (!file)
return
const reader = new FileReader(); const reader = new FileReader()
reader.onload = (e) => { reader.onload = (e) => {
const path = e.target.result; const path = e.target.result
this.imgPath = path; this.imgPath = path
const img = new Image(); const img = new Image()
img.onload = () => { img.onload = () => {
this.imgWidth = img.width; this.imgWidth = img.width
this.imgHeight = img.height; this.imgHeight = img.height
this.path = path; this.path = path
if (!this.hasSel) { if (!this.hasSel) {
let style = this.selStyle || {}; const style = this.selStyle || {}
if (this.selWidth && this.selHeight) { if (this.selWidth && this.selHeight) {
let selWidth = this.selWidth.indexOf('rpx') >= 0 ? parseInt(this.selWidth) * this.pxRatio : const selWidth = this.selWidth.includes('rpx')
parseInt(this.selWidth), ? parseInt(this.selWidth) * this.pxRatio
selHeight = this.selHeight.indexOf('rpx') >= 0 ? parseInt(this.selHeight) * this.pxRatio : : parseInt(this.selWidth)
parseInt(this.selHeight); const selHeight = this.selHeight.includes('rpx')
style.width = parseInt(selWidth); ? parseInt(this.selHeight) * this.pxRatio
style.height = parseInt(selHeight); : parseInt(this.selHeight)
style.top = parseInt((this.windowHeight - style.height - tabHeight) / 2); style.width = `${parseInt(selWidth)}px`
style.left = parseInt((this.windowWidth - style.width) / 2); style.height = `${parseInt(selHeight)}px`
} else { style.top = `${parseInt((this.windowHeight - parseInt(style.height) - tabHeight) / 2)}px`
alert('裁剪框的宽或高没有设置'); style.left = `${parseInt((this.windowWidth - parseInt(style.width)) / 2)}px`
return; } else {
} alert('裁剪框的宽或高没有设置')
this.selStyle = style; return
} }
this.selStyle = style
}
this.fDrawInit(true); this.fDrawInit(true)
}; }
img.src = path; img.src = path
}; }
reader.readAsDataURL(file); reader.readAsDataURL(file)
}; }
input.click(); input.click()
}, },
fUpload() { fUpload() {
if (this.fUploading) return; if (this.fUploading)
this.fUploading = true; return
setTimeout(() => { this.fUploading = true
this.fUploading = false; setTimeout(() => {
}, 1000); this.fUploading = false
}, 1000)
let style = this.selStyle, const style = this.selStyle
x = parseInt(style.left), let x = parseInt(style.left)
y = parseInt(style.top), let y = parseInt(style.top)
width = parseInt(style.width), const width = parseInt(style.width)
height = parseInt(style.height), const height = parseInt(style.height)
expWidth = this.exportWidth || width, let expWidth = this.exportWidth || width
expHeight = this.exportHeight || height; let expHeight = this.exportHeight || height
x *= this.pixelRatio; x *= this.pixelRatio
y *= this.pixelRatio; y *= this.pixelRatio
expWidth = width; expWidth = width
expHeight = height; expHeight = height
this.styleDisplay = 'none'; this.styleDisplay = 'none'
this.styleTop = '-10000px'; this.styleTop = '-10000px'
this.hasSel = false; this.hasSel = false
this.fHideImg(); this.fHideImg()
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas')
canvas.width = width; canvas.width = width
canvas.height = height; canvas.height = height
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d')
ctx.drawImage(this.ctxCanvas.canvas, x, y, width, height, 0, 0, expWidth, expHeight); ctx.drawImage(this.ctxCanvas.canvas, x, y, width, height, 0, 0, expWidth, expHeight)
canvas.toBlob((blob) => { canvas.toBlob((blob) => {
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob)
this.$emit("upload", { this.$emit('upload', {
avatar: this.imgSrc, avatar: this.imgSrc,
path: url, path: url,
index: this.indx index: this.indx,
}); })
}, 'image/png', this.qlty); }, 'image/png', this.qlty)
}, },
// ... // ...
} },
} })
</script> </script>
<template name="cropper">
<view>
<image :src="imgSrc.imgSrc" class="my-avatar" mode="aspectFill" :style="imgStyle" @click="fSelect" />
<!-- 上传图片 -->
<canvas
id="avatar-canvas" canvas-id="avatar-canvas" class="my-canvas" :style="{ top: styleTop, height: cvsStyleHeight }"
disable-scroll="false"
/>
<!-- 截取边框 -->
<canvas
id="oper-canvas" canvas-id="oper-canvas" class="oper-canvas" :style="{ top: styleTop, height: cvsStyleHeight }"
disable-scroll="false" @touchstart="fStart" @touchmove="fMove" @touchend="fEnd"
/>
<view class="oper-wrapper" :style="{ display: styleDisplay }">
<view v-if="showOper" class="btn-wrapper">
<view hover-class="hover" @click="fClose">
取消
</view>
<view hover-class="hover" @click="fUpload">
选取
</view>
</view>
</view>
</view>
</template>
<style lang="less"> <style lang="less">
.my-canvas { .my-canvas {
display: flex; display: flex;
position: fixed !important; position: fixed !important;
background: #000000; background: #000000;
left: 0; left: 0;
z-index: 100; z-index: 100;
width: 100%; width: 100%;
} }
.my-avatar { .my-avatar {
width: 100vw; width: 100vw;
height: 100vw; height: 100vw;
} }
.oper-canvas { .oper-canvas {
display: flex; display: flex;
position: fixed !important; position: fixed !important;
left: 0; left: 0;
z-index: 101; z-index: 101;
width: 100%; width: 100%;
} }
.oper-wrapper { .oper-wrapper {
height: 71px; height: 71px;
position: fixed !important; position: fixed !important;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
left: 0; left: 0;
bottom: 0; bottom: 0;
z-index: 200; z-index: 200;
flex-direction: row; flex-direction: row;
} }
.btn-wrapper { .btn-wrapper {
background-color: #000000; background-color: #000000;
color: #ffffff; color: #ffffff;
display: flex; display: flex;
height: 100%; height: 100%;
width: 100%; width: 100%;
justify-content: space-around; justify-content: space-around;
align-items: center align-items: center;
} }
.btn-wrapper view { .btn-wrapper view {
width: 160rpx; width: 160rpx;
height: 80rpx; height: 80rpx;
line-height: 80rpx; line-height: 80rpx;
text-align: center; text-align: center;
font-size: 16px; font-size: 16px;
color: #ffffff; color: #ffffff;
z-index: 300; z-index: 300;
} }
.hover { .hover {
color: #f1f1f1; color: #f1f1f1;
} }
</style> </style>

269
src/views/badge/index.vue

@ -1,42 +1,100 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const show = ref(false)
const imgShow = ref(false)
const router = useRouter()
const imgurl = ref('') //
const fileInput = ref<HTMLInputElement | null>(null)
function onUploadClick() {
if (fileInput.value)
fileInput.value.click()
}
function myUpload(rsp) {
const self = this
self.imgurl = rsp.path //
}
function goToRecord() {
router.push('/badge/record')
}
function goToMyOrder() {
router.push('/badge/myOrder')
}
function goToPreview() {
router.push('/badge/preview')
}
function onFileChange
</script>
<template> <template>
<div class="photo-upload-page"> <div class="photo-upload-page">
<div class="badge-size"> <div class="badge-size">
<div class="size-title">剩余兑换数量</div> <div class="size-title">
剩余兑换数量
</div>
<div class="size-options"> <div class="size-options">
<div class="size-item"> <div class="size-item">
<div class="size-text">4cm</div> <div class="size-text">
<div class="size-count">剩余兑换1</div> 4cm
</div>
<div class="size-count">
剩余兑换1
</div>
</div> </div>
<div class="size-item"> <div class="size-item">
<div class="size-text">5cm</div> <div class="size-text">
<div class="size-count">剩余兑换2</div> 5cm
</div>
<div class="size-count">
剩余兑换2
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="badge-info"> <div class="badge-info">
<div class="badge-item" @click="goToRecord"> <div class="badge-item" @click="goToRecord">
<div class="badge-title">设计图集</div> <div class="badge-title">
<div class="badge-count">8</div> 设计图集
</div>
<div class="badge-count">
8
</div>
</div> </div>
<div class="badge-item" @click="goToMyOrder"> <div class="badge-item" @click="goToMyOrder">
<div class="badge-title">我的订单</div> <div class="badge-title">
<div class="badge-count">3</div> 我的订单
</div>
<div class="badge-count">
3
</div>
</div> </div>
</div> </div>
<div style="height: 8px;background: #F2F2F2;"></div> <div style="height: 8px;background: #F2F2F2;" />
<div class="step-container"> <div class="step-container">
<div class="step-item active"> <div class="step-item active">
<div class="step-num">1</div> <div class="step-num">
1
</div>
<div class="step-content"> <div class="step-content">
<div class="step-title">上传正面照片</div> <div class="step-title">
<div class="step-desc">1张五官清晰的正面照片</div> 上传正面照片
</div>
<div class="step-desc">
1张五官清晰的正面照片
</div>
</div> </div>
</div> </div>
<div class="step-item"> <div class="step-item">
<div class="step-num">2</div> <div class="step-num">
2
</div>
<div class="step-content"> <div class="step-content">
<div class="step-title">确认下单</div> <div class="step-title">
<div class="step-desc">选择一个你喜欢的设计</div> 确认下单
</div>
<div class="step-desc">
选择一个你喜欢的设计
</div>
</div> </div>
</div> </div>
</div> </div>
@ -46,70 +104,87 @@
<span class="photo-upload-guide-text">图片上传指南</span> <span class="photo-upload-guide-text">图片上传指南</span>
</div> </div>
<div class="photo-upload-area" @click="onUploadClick"> <div class="photo-upload-area" @click="onUploadClick">
<!-- <cropper selWidth="660rpx" selHeight="660rpx" @upload="myUpload" :avatarSrc="imgurl" avatarStyle="width:100vw;height:100vw;">
<img v-if="imgurl" :src="imgurl" class="photo-upload-image" alt="上传的照片" />
<div v-else class="photo-upload-placeholder">
<span class="photo-upload-plus">+</span>
<span class="photo-upload-text">点击上传照片</span>
</div>
</cropper> -->
<input <input
ref="fileInput" ref="fileInput"
type="file" type="file"
accept="image/*" accept="image/*"
style="display: none" style="display: none"
@change="onFileChange" @change="onFileChange"
/> >
<div class="photo-upload-plus">+</div> <div class="photo-upload-plus">
<div class="photo-upload-text">点击上传照片</div> +
<div class="photo-upload-tip">*上传照片时建议勾选[原图]</div> </div>
<div class="photo-upload-text">
点击上传照片
</div>
<div class="photo-upload-tip">
*上传照片时建议勾选[原图]
</div>
</div> </div>
<div class="photo-upload-footer"> <div class="photo-upload-footer">
请确定您对上传的照片拥有合法使用权利或已取得他人合法授权且同意本平台分析图片信息以提供生成服务 请确定您对上传的照片拥有合法使用权利或已取得他人合法授权且同意本平台分析图片信息以提供生成服务
</div> </div>
</div> </div>
<div class="style-section"> <div class="style-section">
<div class="style-title">风格样式</div> <div class="style-title">
风格样式
</div>
<div class="style-list"> <div class="style-list">
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒">
<div class="style-label">随机风格盲盒</div> <div class="style-label">
<span class="style-selected"></span> 随机风格盲盒
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫">
<div class="style-label">Q版国风动漫</div> <div class="style-label">
<span class="style-selected"></span> Q版国风动漫
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通">
<div class="style-label">Q版卡通</div> <div class="style-label">
<span class="style-selected"></span> Q版卡通
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风">
<div class="style-label">芭比风</div> <div class="style-label">
<span class="style-selected"></span> 芭比风
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="随机风格盲盒">
<div class="style-label">随机风格盲盒</div> <div class="style-label">
<span class="style-selected"></span> 随机风格盲盒
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="Q版国风动漫">
<div class="style-label">Q版国风动漫</div> <div class="style-label">
<span class="style-selected"></span> Q版国风动漫
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="Q版卡通">
<div class="style-label">Q版卡通</div> <div class="style-label">
<span class="style-selected"></span> Q版卡通
</div>
<span class="style-selected" />
</div> </div>
<div class="style-item"> <div class="style-item">
<img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风" /> <img class="style-img" src="@/assets/badge/suiji.png" alt="芭比风">
<div class="style-label">芭比风</div> <div class="style-label">
<span class="style-selected"></span> 芭比风
</div>
<span class="style-selected" />
</div> </div>
</div> </div>
</div> </div>
@ -149,7 +224,7 @@
</div> </div>
<div class="bg-photo-upload-area"> <div class="bg-photo-upload-area">
<label class="bg-photo-upload-label"> <label class="bg-photo-upload-label">
<input type="file" accept="image/*" style="display:none" /> <input type="file" accept="image/*" style="display:none">
<div class="bg-photo-upload-box"> <div class="bg-photo-upload-box">
<div class="bg-photo-upload-plus">+</div> <div class="bg-photo-upload-plus">+</div>
<div class="bg-photo-upload-text">上传照片</div> <div class="bg-photo-upload-text">上传照片</div>
@ -157,7 +232,7 @@
</label> </label>
</div> </div>
</div> </div>
<div style="height: 90px;"></div> <div style="height: 90px;" />
<div class="design-action-bar"> <div class="design-action-bar">
<div class="design-left"> <div class="design-left">
<img class="design-leaf-icon" width="18" height="18" src="@/assets/badge/leaf.png" alt=""> <img class="design-leaf-icon" width="18" height="18" src="@/assets/badge/leaf.png" alt="">
@ -171,33 +246,37 @@
</div> </div>
<van-action-sheet v-model:show="show" title="背景样式说明" :close-on-click-overlay="true" closeable> <van-action-sheet v-model:show="show" title="背景样式说明" :close-on-click-overlay="true" closeable>
<div style="padding: 24px 16px;"> <div style="padding: 24px 16px;">
<div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">照片自有背景</div> <div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">
照片自有背景
</div>
<div style="font-size: 12px; color: #888; margin-bottom: 12px;"> <div style="font-size: 12px; color: #888; margin-bottom: 12px;">
选择该选项设计的徽章会根据上传的人像照片背景进行生成效果 选择该选项设计的徽章会根据上传的人像照片背景进行生成效果
</div> </div>
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 24px;"> <div style="display: flex; align-items: center; justify-content: center; margin-bottom: 24px;">
<img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;" /> <img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;">
<span style="font-size: 24px; color: #bbb; margin-right: 12px;"> <span style="font-size: 24px; color: #bbb; margin-right: 12px;">
<van-icon name="arrow" /> <van-icon name="arrow" />
</span> </span>
<img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;">
</div>
<div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">
补充背景照片
</div> </div>
<div style="font-weight: bold; font-size: 15px; margin-bottom: 4px;">补充背景照片</div>
<div style="font-size: 12px; color: #888; margin-bottom: 12px;"> <div style="font-size: 12px; color: #888; margin-bottom: 12px;">
选择该选项需要额外上传一张照片作为背景 选择该选项需要额外上传一张照片作为背景
</div> </div>
<div style="display: flex; align-items: center; justify-content: center; margin-bottom: 12px;"> <div style="display: flex; align-items: center; justify-content: center; margin-bottom: 12px;">
<img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;" /> <img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover; margin-right: 12px;">
<span style="font-size: 24px; color: #bbb; margin-right: 12px;"> <span style="font-size: 24px; color: #bbb; margin-right: 12px;">
<van-icon name="plus" /> <van-icon name="plus" />
</span> </span>
<img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" style="width: 90px; height: 90px; border-radius: 12px; object-fit: cover;">
</div> </div>
<div style="font-size: 24px; color: #bbb;text-align: center;" > <div style="font-size: 24px; color: #bbb;text-align: center;">
<van-icon name="arrow-down" /> <van-icon name="arrow-down" />
</div> </div>
<div style="display: flex; align-items: center; justify-content: center; margin-top: 12px;"> <div style="display: flex; align-items: center; justify-content: center; margin-top: 12px;">
<img src="@/assets/badge/suiji.png" style="width: 120px; height: 120px; border-radius: 16px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" style="width: 120px; height: 120px; border-radius: 16px; object-fit: cover;">
</div> </div>
<div style="margin-top: 32px; text-align: center;"> <div style="margin-top: 32px; text-align: center;">
<button style="width: 90%; height: 44px; background: linear-gradient(90deg, #d6f5b7 0%, #50cf54 100%); border: none; border-radius: 22px; color: #222; font-size: 18px; font-weight: bold; cursor: pointer;" @click="show = false"> <button style="width: 90%; height: 44px; background: linear-gradient(90deg, #d6f5b7 0%, #50cf54 100%); border: none; border-radius: 22px; color: #222; font-size: 18px; font-weight: bold; cursor: pointer;" @click="show = false">
@ -206,11 +285,11 @@
</div> </div>
</div> </div>
</van-action-sheet> </van-action-sheet>
<van-action-sheet v-model:show="imgShow" title="图片上传指南" :close-on-click-overlay="true" closeable> <van-action-sheet v-model:show="imgShow" title="图片上传指南" :close-on-click-overlay="true" closeable>
<div style="padding: 0 16px 24px 16px;"> <div style="padding: 0 16px 24px 16px;">
<div style="text-align: center;"> <div style="text-align: center;">
<img src="@/assets/badge/suiji.png" alt="照片上传指南" style="width: 220px; border-radius: 16px; margin-bottom: 16px;" /> <img src="@/assets/badge/suiji.png" alt="照片上传指南" style="width: 220px; border-radius: 16px; margin-bottom: 16px;">
</div> </div>
<div style="display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: center; margin-bottom: 16px;"> <div style="display: flex; flex-wrap: wrap; gap: 8px 12px; justify-content: center; margin-bottom: 16px;">
<span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">光线均匀</span> <span style="background: #e6f7e6; color: #22c55e; border-radius: 8px; padding: 2px 10px; font-size: 13px;">光线均匀</span>
@ -221,26 +300,36 @@
</div> </div>
<div style="display: flex; justify-content: space-between; margin-bottom: 16px;"> <div style="display: flex; justify-content: space-between; margin-bottom: 16px;">
<div style="flex: 1; text-align: center;"> <div style="flex: 1; text-align: center;">
<img src="@/assets/badge/suiji.png" alt="多主体" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" alt="多主体" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;">
<div style="font-size: 13px; color: #888; margin-top: 4px;">多主体</div> <div style="font-size: 13px; color: #888; margin-top: 4px;">
多主体
</div>
</div> </div>
<div style="flex: 1; text-align: center;"> <div style="flex: 1; text-align: center;">
<img src="@/assets/badge/suiji.png" alt="光线昏暗" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" alt="光线昏暗" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;">
<div style="font-size: 13px; color: #888; margin-top: 4px;">光线昏暗</div> <div style="font-size: 13px; color: #888; margin-top: 4px;">
光线昏暗
</div>
</div> </div>
<div style="flex: 1; text-align: center;"> <div style="flex: 1; text-align: center;">
<img src="@/assets/badge/suiji.png" alt="后侧面及背影" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" alt="后侧面及背影" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;">
<div style="font-size: 13px; color: #888; margin-top: 4px;">后侧面及背影</div> <div style="font-size: 13px; color: #888; margin-top: 4px;">
后侧面及背影
</div>
</div> </div>
</div> </div>
<div style="display: flex; justify-content: space-between; margin-bottom: 24px;"> <div style="display: flex; justify-content: space-between; margin-bottom: 24px;">
<div style="flex: 1; text-align: center;"> <div style="flex: 1; text-align: center;">
<img src="@/assets/badge/suiji.png" alt="照片模糊" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" alt="照片模糊" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;">
<div style="font-size: 13px; color: #888; margin-top: 4px;">照片模糊</div> <div style="font-size: 13px; color: #888; margin-top: 4px;">
照片模糊
</div>
</div> </div>
<div style="flex: 1; text-align: center;"> <div style="flex: 1; text-align: center;">
<img src="@/assets/badge/suiji.png" alt="照片留白过少" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;" /> <img src="@/assets/badge/suiji.png" alt="照片留白过少" style="width: 25vw; height: 25vw; border-radius: 8px; object-fit: cover;">
<div style="font-size: 13px; color: #888; margin-top: 4px;">照片留白过少</div> <div style="font-size: 13px; color: #888; margin-top: 4px;">
照片留白过少
</div>
</div> </div>
</div> </div>
<div style="margin-top: 24px; text-align: center;"> <div style="margin-top: 24px; text-align: center;">
@ -251,34 +340,6 @@
</div> </div>
</van-action-sheet> </van-action-sheet>
</template> </template>
<script setup lang="ts">
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import cropper from "./cropper.vue";
const show = ref(false);
const imgShow = ref(false);
const router = useRouter();
const imgurl = ref(''); //
const fileInput = ref<HTMLInputElement | null>(null);
function onUploadClick() {
if (fileInput.value) {
fileInput.value.click();
}
}
function myUpload(rsp) {
const self = this;
self.imgurl = rsp.path; //
}
function goToRecord() {
router.push('/badge/record');
}
function goToMyOrder() {
router.push('/badge/myOrder');
}
function goToPreview() {
router.push('/badge/preview');
}
</script>
<style scoped> <style scoped>
.photo-upload-page { .photo-upload-page {
@ -704,4 +765,4 @@ function goToPreview() {
width: 18px; width: 18px;
height: 12px; height: 12px;
} }
</style> </style>

75
src/views/delivery/index.vue

@ -1,75 +0,0 @@
<template>
<div>
<div class="page">
<div class="section_2">
<div class="group_26">
<div class="image-text_35" v-if="symbol == 2">
<image src="/static/images/order/shunfeng.png" class="icon_1"></image>
<text lines="1" class="text-group_1">顺丰快递</text>
</div>
<div class="image-text_35" v-else>
<image src="/static/images/order/jingdong.png" class="icon_1"></image>
<text lines="1" class="text-group_1">京东快递</text>
</div>
<text lines="1" class="text_1">orderInfo.delivery_no</text>
<div @click="copyOrderId" data-text="{{orderInfo.delivery_no}}" class="button_1_copy">复制</div>
<!-- <div class="icon_5">
<image src="/static/images/order/tel.png" class="icon_6"></image>
</div> -->
</div>
<div class="list_7" v-if="routerInfo.length > 0">
<!-- acceptAddress: "深圳市"
acceptTime: "2023-04-03 19:39:40"
opCode: "50"
remark: "顺丰速运 已收取快件" -->
<div class="image-text_11-0" v-for="value, key in routerInfo" :key="value.delivery_id">
<div v-if="key==0">
<image class="gou_1" src="/static/images/order/gou_1.png"></image>
<div class="image_4-0" style="width:0rpx;border:1px solid #55B038;height:95%"></div>
<div class="text-group_51-1">
<text lines="1" class="text_23-1">{{value.remark}}</text>
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
</div>
</div>
<div v-else>
<image class="yuan_gou" src="/static/images/order/gray_yuan.png"></image>
<div class="image_4-0" style="width:0rpx;border:1px solid #DCDEE0;height:95%"></div>
<div class="text-group_51-1">
<text lines="1" class="text_23-1">{{value.remark}}</text>
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
</div>
</div>
</div>
<!-- <div class="image-text_11-1" v-for="{{routerInfo}}" v-key="delivery_id" v-for-index="key" v-for-item="value">
<image v-if="{{key == 0}}" src="/static/images/order/gou.png" class="thumbnail_3-1" style="width: 96rpx;height: 0rpx;opacity: 1;border: 4rpx solid #55B038;"></image>
<image src="/static/images/order/line.png" class="thumbnail_3-1"></image>
<div class="text-group_51-1">
<text lines="1" class="text_23-1">{{value.remark}}</text>
<text lines="1" decode="true" class="text_24-1">{{value.acceptTime}}</text>
</div>
</div> -->
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

173
src/views/multiPrint/detail.vue

@ -1,173 +0,0 @@
<template>
<div class="page">
<div class="page_wrap">
<div class="content">
<van-cell-group inset border>
<van-cell title="批次号" :value="id" />
<van-cell title="机器编号" :value="machine_id" />
<van-cell title="模型数量" :value="model_count" />
<van-cell title="批次详情" :value="order_count" is-link :to="{ name: 'orderDetail', query: { id: id } }" />
</van-cell-group>
<van-cell-group style="margin-top: 10px;" inset border>
<van-cell class="diy_cell" title="模型称重照片" label="需将模型和重量均拍入照片">
<van-uploader style="margin-top: 10px;" v-model="fileList" :after-read="beforeUpload" />
</van-cell>
<van-cell class="diy_cell" title="模型总重(克)">
<van-field placeholder="请输入" v-model="total_weight">
<template #button>g</template>
</van-field>
</van-cell>
</van-cell-group>
<div class="confirm-btn" @click="submitData">确认</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import dayjs from 'dayjs'
const route = useRoute();
const router = useRouter()
import { showSuccessToast, showToast } from "vant";
const id = route.query.id as string | number;
const machine_id = route.query.machine_id as string | number;
const model_count = route.query.model_count as string | number;
const order_count = route.query.order_count as string | number;
import * as api from '@/api/multiPrint'
const fileList = ref([
]);
const total_weight = ref('')
const imgList = ref()
//
function addWatermarkToImage(file, timestamp) {
return new Promise((resolve, reject) => {
const img = new Image();
const reader = new FileReader();
reader.onload = function(e) {
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = img.width;
const height = img.height;
canvas.width = width;
canvas.height = height;
// Canvas
ctx.drawImage(img, 0, 0, width, height);
//
ctx.font = '80px Arial';
ctx.fillStyle = '#ff0000';
ctx.textAlign = 'center';
ctx.textBaseline = 'top'; //
//
ctx.fillText(timestamp, width / 2, 100); //
//
canvas.toBlob((blob) => {
//
const newFile = new File([blob], file.name, {
type: file.type,
});
resolve(newFile);
}, file.type); // 使
};
img.src = e.target.result;
};
reader.readAsDataURL(file);
});
}
const beforeUpload = async () => {
try {
let file = fileList.value[0].file;
console.log("beforeUpload",fileList)
var timestamp = "时间:" + dayjs().format("YYYY-MM-DD HH:mm:ss");
let data = {
keyName: file.name,
}
let fileData = await addWatermarkToImage(file, timestamp)
console.log("addWatermarkToImage", fileData)
api.getPutSignURL(data).then(res => {
imgList.value = res.signedURL
api.uploadToOss(res.signedURL, fileData)
}).catch(err=>{
showToast('提交失败' + err.message)
})
}catch(err) {
}
}
const submitData = () => {
console.log("submitData",imgList.value)
if(imgList.value == '' && total_weight.value == '') {
return
}
let params = {
id: id,
model_weight_photo: imgList.value,
total_weight: total_weight.value
}
api.add({...params}).then((res: any) => {
showSuccessToast('提交成功, 请稍后在检查')
router.back()
}).catch((err: Error) => {
showToast('提交失败' + err.message)
})
}
</script>
<style scoped>
.page {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #F3F3F3;
padding-top: 10px;
.page_wrap {
position: relative;
width: 90%;
height: 100%;
margin: 0px auto;
.content {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
margin-top: 10px;
.diy_cell {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.confirm-btn {
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
background-color: #4281E3;
color: #FFFFFF;
border-radius: 10px;
margin-top: 20px;
}
}
}
}
:deep(.van-cell-group--inset) {
margin: 0;
}
:deep(.van-cell::after){
transform: scaleY(1.5);
}
</style>

273
src/views/multiPrint/index.vue

@ -1,273 +0,0 @@
<template>
<div>
<div class="page">
<div class="page_wrap">
<van-search
v-model="keyWord"
background="#F3F3F3"
shape="round"
clearable
@search="onSearch"
@clear="getPage"
input-align="center"
placeholder="机器编号"
/>
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<van-list
v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'" :finished-text="'没有更多了'"
:finished="finished" @load="onLoad"
>
<div class="content">
<div class="content_wrap">
<div class="content_item" v-for="item, index in list" :key="index">
<div class="left">
<div class="content_item_title">机器编号{{item.machine_id}}
<van-tag style="margin-left: 10px;" :type="getProgressStatusType(item.process_status)">
{{ renderProgressStatus(item) }}
</van-tag>
</div>
<div class="content_item_info">
<div class="time">提交打印时间: <span>{{ item.print_time }}</span></div>
<div class="count">模型数量: <span>{{ item.model_count }}</span></div>
<div class="reason" v-if="showReason(item)">原因: <span>
{{item.message}}
</span></div>
</div>
</div>
<div class="right">
<div class="icon_item" @click="goDetail(item)">
<img class="icon" :src="weight" alt="">
<div class="icon_text">称毛重</div>
</div>
</div>
</div>
</div>
</div>
</van-list>
</van-pull-refresh>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import * as api from '@/api/multiPrint'
import { useRoute, useRouter } from 'vue-router'
const router = useRouter();
import weight from '@/assets/common/weight.png';
const keyWord = ref('')
const loading = ref(false)
const error = ref(false)
const finished = ref(false)
const refreshing = ref(false)
let currentPage = ref(1)
let currentSize = ref(20)
const list = ref([])
const onLoad = () => {
if (refreshing.value) {
currentPage.value = 1;
list.value = [];
refreshing.value = false;
}
getPage()
};
const onRefresh = () => {
//
finished.value = false;
loading.value = true;
onLoad();
};
const onSearch = () => {
currentPage.value = 1;
list.value = [];
getPage()
}
//
const goDetail = (val: any) => {
console.log("goDetail",val)
router.push({
path: '/multiPrintDetail',
query: {
id: val.id,
machine_id: val.machine_id,
model_count: val.model_count,
order_count: val.order_count,
}
})
}
function getPage() {
api.page({
page: currentPage.value,
keyWord: keyWord.value,
size: currentSize.value
}).then(res => {
console.log("getPage",res)
let data = res.list || [];
list.value = list.value.concat(data)
if(data.length < currentSize.value) {
finished.value = true;
}
currentPage.value++
loading.value = false
}).catch(() => {
error.value = true
loading.value = false
})
}
function renderProgressStatus(item: any) {
switch (item.process_status) {
case 0:
return '待处理'
case 1:
return `处理中(${item.process_count}/${item.model_count})`
case 2:
return '处理完成'
default:
return '处理失败'
}
}
function getProgressStatusType(progressStatus) {
switch (progressStatus) {
case 0:
return 'default'
case 1:
return 'warning'
case 2:
return 'success'
case 3:
return 'danger'
default:
return 'danger'
}
}
function showReason(item) {
return item.process_status == 3;
}
</script>
<style lang="less" scoped>
.page {
width: 100%;
display: flex;
flex-direction: column;
background-color: #F3F3F3;
padding-top: 10px;
.page_wrap {
position: relative;
width: 90%;
height: 100%;
margin: 0px auto;
.content {
position: relative;
width: 100%;
height: 93vh;
margin: 10px 0;
.content_wrap {
display: flex;
flex-direction: column;
position: relative;
.content_item {
position: relative;
width: 100%;
// min-height: 100px;
display: flex;
justify-content: space-between;
background-color: #FFFFFF;
border-radius: 10px;
padding: 10px;
box-sizing: border-box;
margin-bottom: 10px;
.left {
position: relative;
width: 75%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
.content_item_title {
display: flex;
align-items: center;
font-size: 16px;
font-weight: bold;
color: #333333;
}
.content_item_info {
display: flex;
flex-direction: column;
margin-top: 10px;
.time {
font-size: 14px;
color: #666666;
}
.count {
font-size: 14px;
color: #666666;
span {
font-weight: bold;
color: #000;
}
}
.reason {
font-size: 14px;
color: #ec4444;
}
}
}
.right {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 25%;
.icon_item {
width: 60px;
height: 60px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.icon {
width: 20px;
height: 20px;
}
.icon_text {
font-size: 12px;
color: #1296db;
margin-top: 5px;
}
}
}
}
}
}
}
}
:deep(.van-search) {
padding: 0;
background: #ffffff!important;
border-radius: 30px;
}
:deep(.van-search__content) {
background: #ffffff!important;
}
.van-pull-refresh {
height: calc(95vh) !important; /* 计算高度(减去的高度自己调) */
overflow: auto !important; /* 滚动自适应 */
}
.van-list {
height: auto !important; /* 列表高度自适应 */
}
</style>

189
src/views/multiPrint/orderDetail.vue

@ -1,189 +0,0 @@
<template>
<div>
<div class="page">
<div class="page_wrap">
<van-search
v-model="keyWord"
background="#F3F3F3"
shape="round"
clearable
@search="onSearch"
@clear="getOrderList"
input-align="center"
placeholder="请输入订单号搜索"
/>
<van-list
v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'" :finished-text="'没有更多了'"
:finished="finished" @load="onLoad"
>
<div class="content">
<div class="content_wrap">
<div class="order_item" v-for="item, index in orderList" :key="index">
<div class="order_img">
<img :src="imgSrc(item.texture_cover_img)" >
</div>
<div class="order_info">
<div class="order_id">{{ item.pid }}</div>
<div class="order_size" >
<span v-for="el , elIndex in filterSize(item.model_size)" :key="elIndex">
{{ el }}
</span>
</div>
</div>
</div>
</div>
</div>
</van-list>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import * as api from '@/api/multiPrint'
import { useRoute } from 'vue-router'
import { onMounted } from 'vue';
const route = useRoute();
import {imgSrc} from "@/utils/utils"
const id = route.query.id as string | number;
const keyWord = ref('')
const loading = ref(false)
const error = ref(false)
const finished = ref(false)
const refreshing = ref(false)
let currentPage = ref(1)
let totalCount = ref(0)
const orderList = ref([])
// const test = ref('18cm_x2___15cm_x3___20cm_x1')
onMounted(() => {
})
const onLoad = () => {
if (refreshing.value) {
currentPage.value = 1;
orderList.value = [];
refreshing.value = false;
}
getOrderList(currentPage.value)
loading.value = false;
if (orderList.value.length >= totalCount.value) {
finished.value = true;
}
};
const filterSize = (input: any) => {
const items = input.split("___");
const result = items.map(item => {
const match = item.match(/(\d+)cm_x(\d+)/);
if (match) {
return `${match[1]}cm*${match[2]}`;
} else {
return item;
}
});
return result;
}
const getOrderList = (page: any) => {
api.detailPage({print_batch_id: id, keyWord: keyWord.value, page: page || 1}).then(res => {
console.log(res)
orderList.value = [...orderList.value, ...res.list]
totalCount.value = res.total
loading.value = false
}).catch(err => {
console.log(err)
loading.value = false
})
}
const onSearch = () => {
currentPage.value = 1
getOrderList(currentPage.value)
}
</script>
<style lang="less" scoped>
.page {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #F3F3F3;
padding-top: 10px;
.page_wrap {
position: relative;
width: 90%;
height: 100%;
margin: 0px auto;
.content {
position: relative;
width: 100%;
height: 93vh;
overflow: scroll;
margin: 10px 0;
.content_wrap {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.order_item {
display: flex;
flex-direction: column;
position: relative;
width: 48%;
min-height: 154px;
background-color: #fff;
border-radius: 10px;
margin-bottom: 10px;
overflow: hidden;
.order_img {
position: relative;
width: 163px;
height: 122px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.order_info {
display: flex;
position: relative;
width: 90%;
margin: 0 auto;
font-size: 12px;
font-weight: bold;
color: #333;
padding-top: 10px;
.order_id {
width: 100%;
}
.order_size {
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
width: 100%;
}
}
}
}
}
}
}
:deep(.van-search) {
padding: 0;
background: #ffffff!important;
border-radius: 30px;
}
:deep(.van-search__content) {
background: #ffffff!important;
}
</style>

768
src/views/my_order/detail.vue

@ -1,768 +0,0 @@
<script lang="tsx" setup>
import useClipboard from 'vue-clipboard3'
const { toClipboard } = useClipboard()
const router = useRouter()
import { orderStatus } from '@/utils/utils'
import { closeToast, showFailToast, showSuccessToast, showToast } from 'vant';
import * as myOrderApi from '@/api/my_order'
import { useStore } from '@/stores'
const store = useStore();
import { useTokenStore } from '@/stores/token'
const tokenStore = useTokenStore();
const {isWechat} = tokenStore;
const orderInfo = ref({})
const orderList = ref("")
const orderId = ref("")
const title = ref("")
const pid = ref("")
const userInfo = ref({})
const nums = ref(0)
const orderDetailInfo = ref({})
const dialogShow = ref(false)
const dialogShow2 = ref(false)
const actionShow = ref(false)
const actions = ref([
{
name: '删除订单'.$t,
},
])
onMounted(()=> {
userInfo.value = tokenStore.userInfo;
orderInfo.value = store.orderInfo;
console.log("orderInfo.value", orderInfo.value)
getOrderInfo(orderInfo.value.pid);
})
const returnClick = () => history.back();
//
const moreClick = () => {
actionShow.value = !actionShow.value
}
//
const onSelect = (e) => {
if(e.detail.name) {
dialogShow.value = true
}
}
const higher = computed(()=> {
return isWechat() ? 'higher' : '';
});
//
const tapDialogButton = (e) => {
// const u = wx.getStorageSync('userInfo');
let params = {
pid: orderInfo.value.pid,
// unionid: u.unionid
}
//
let status = orderInfo.value.status
let digital_order_id = orderInfo.value.digital_order_id;
let order_id = orderInfo.value.order_id;
let experience_status = orderInfo.value.remaining_experience.status;
let buyType = 0;
let undone_status = 0;
if(digital_order_id != order_id && digital_order_id && order_id) {
buyType = 1; //
if(status != 9000) {
undone_status = 1;
}
}else if(digital_order_id == order_id) {
buyType = 2; //
if(status < 7011) {
undone_status = 1;
}
}else if(digital_order_id == 0 && order_id !=0) {
buyType = 3; //
if(status != 9000) {
undone_status = 1;
}
}else if(experience_status == 1 && status < 4100) {
buyType = 4; // 3d
if(status < 4100) {
undone_status = 1;
}
}
if(undone_status!=0) {
dialogShow.value = false;
// dialogShow3.value = true;
return
}
// app.api.deleteOrder(params).then((res)=> {
// if(res.code == 1000) {
// showToast("".$t)
// setTimeout(()=> {
// router.push({
// path: "/myOrder",
// })
// }, 2000)
// dialogShow.value = false;
// }else if(res.code == -1) {
// showFailToast(res.message)
// }
// }).catch((err)=> {
// title.value = err;
// dialogShow.value = false;
// dialogShow2.value = true;
// })
closeToast();
}
const tapDialogButton2 = () => {
dialogShow2.value = false
contact();
}
const onClose = () => {
actionShow.value = false
}
//
const getOrderInfo = (pid) => {
if (pid) {
myOrderApi.detail(pid).then((res:any)=> {
let data = res;
data.forEach(element=> {
let arr = element.model_size.split(" ")
let obj = [];
arr.forEach(item => {
let index = item.lastIndexOf("*");
let num = item.substring(index+1, item.length)
let size = item.substring(0, index)
obj.push({size,num})
});
element.filterSize = obj
})
orderList.value = data;
})
// data = Object.assign(data, obj)
}
}
//
const copyOrderId = () => {
copy(orderInfo.value.pid.toString())
}
// 使
const copy = async (msg) => {
try {
//
console.log("msg", msg)
await toClipboard(msg)
showSuccessToast("复制成功".$t)
//
} catch (e) {
//
showFailToast("复制失败".$t)
}
}
const callShow = ref(false);
const callClick = () => {
callShow.value = true;
}
const contact = () => {
const a = document.createElement("a");
a.href = "tel:" + orderInfo.value.shop_tel
a.click();
callShow.value = false;
}
// 3D
// toAlbum(e) {
// //
// const u = wx.getStorageSync('userInfo');
// var pid = this.data.orderInfo.pid;
// var oid = this.data.orderInfo.order_id;
// var cn = this.data.orderInfo.customer_name;
// var cid = this.data.orderInfo.customer_id;
// var createTime = this.data.orderInfo.create_time;
// var status = this.data.orderInfo.status;
// var remainingExperienceStatus = this.data.orderInfo.remaining_experience.status;
// var expireTime = this.data.orderInfo.remaining_experience.day;
// var digitalOrderId = this.data.orderInfo.digital_order_id;
// var digitalType = this.data.orderInfo.digital_type;
// var titleCode = this.data.orderInfo.remaining_experience.title_code;
// //createTime2023-04-15 00:00:00
// wx.request({
// url: config.url + '/miniProgram/judgeP3dLogOrderTime',
// data: { photoTime: createTime, pid },
// header: { 'content-type': 'application/json' },
// success: (res) => {
// if(res.data.data.use_status!=1){
// wx.showToast({
// title: '3D',
// icon: 'none',
// duration: 2000
// })
// return
// }
// const url = `/package3D/pages/3d/3d?openid=${u.openid}`
// + `&unionid=${u.unionid}&id=${pid}&oid=${oid}`
// + `&cn=${cn}&cid=${cid}&expireTime=${expireTime}`
// + `&digitalType=${digitalType}`
// + `&status=${status}`
// + `&titleCode=${titleCode}`
// + `&remainingExperienceStatus=${remainingExperienceStatus}`;
// //3D
// if (digitalOrderId == 0) {
// wx.navigateTo({
// url: url
// });
// return
// }
// if(remainingExperienceStatus == 1) {
// if(status < 4100){
// wx.showToast({
// title: '3D',
// icon: 'none',
// duration: 2000
// })
// return
// }
// wx.navigateTo({
// url: url,
// });
// }
// wx.navigateTo({
// // webview
// // url: `/pages/webview/webview?nav=${navtitle}&url=${encodeURIComponent(url)}`,
// url: url,
// });
// }
// })
// },
//
const turnToDelivery = () => {
if(orderInfo.value.delivery_no) {
// wx.navigateTo({
// url: '/pages/delivery/delivery',
// success: function (res) {
// res.eventChannel.emit("orderInfo", that.data.orderInfo)
// }
// })
}else {
showToast("暂无快递信息".$t)
}
}
</script>
<template>
<van-dialog :title="'确认删除订单?'.$t" :message="'删除的订单将无法恢复'.$t" v-model:show="dialogShow" :confirmButtonText="'确认删除'.$t"
:cancelButtonText="'我再想想'.$t" @confirm="tapDialogButton" showCancelButton confirm-button-color="#AAAAAA"
cancel-button-color="#009944" round />
<van-dialog :title="'门店电话'.$t" :message="'确定拨打门店电话吗?'.$t" v-model:show="callShow" :confirmButtonText="'确定'.$t" :cancelButtonText="'取消'.$t"
@confirm="contact" showCancelButton confirm-button-color="#AAAAAA" cancel-button-color="#009944" round />
<van-dialog :title="title" v-model:show="dialogShow2" :confirmButtonText="'联系门店'.$t" :cancelButtonText="'我再想想'.$t"
@confirm="tapDialogButton2" showCancelButton confirm-button-color="#AAAAAA" cancel-button-color="#009944" round />
<!-- <van-dialog :title="'订单处于未完结状态'.$t,无法删除" v-model:show="dialogShow3" :confirmButtonText="'我已知晓'.$t" @confirm="tapDialogButton3"
confirm-button-color="#009944" round /> -->
<van-action-sheet round v-model:show="actionShow" :actions="actions" @close="onClose" @select="onSelect" @cancel="onClose"
:cancel-text="'取消'.$t" />
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" :left-text="'返回'.$t" left-arrow
@click-left="returnClick" safe-area-inset-top/>
<div class="page">
<div :class="['container', higher]">
<div class="order_info">
<div class="text-wrapper_43">
<div class="order-info">
<div class="text_31">{{ '订单信息'.$t }}</div>
<img src="@/assets/order/more.png" mode="widthFix" class="more" @click="moreClick"/>
</div>
</div>
<div class="text-wrapper_45">
<div class="order-id">
<div class="text_39">{{'订单ID'.$t}}</div>
<div class="text_40">{{orderInfo.pid}}</div>
</div>
<div @click="copyOrderId()" class="button_2">{{ '复制'.$t }}</div>
</div>
<div class="text-wrapper_44">
<div class="text_39">{{ '拍摄门店'.$t }}</div>
<div class="text_40">{{orderInfo.shop_name}}</div>
</div>
<div class="text-wrapper_44">
<div class="text_39">{{ '拍摄时间'.$t }}</div>
<div decode="true" class="text_40">{{orderInfo.takephoto_time}}</div>
</div>
<!-- 分割线 -->
<div class="line"></div>
<div class="group_13" @click="callClick">
<div class="image-text_12">
<div class="icon_2">
<img class="icon_4" src="@/assets/order/tel.png" />
</div>
<div class="text-order_record">{{ '联系门店'.$t }}</div>
</div>
</div>
</div>
<div class="order_record">
<!-- 订单明细数据 -->
<div class="section_2">
<div class="order-title">
<div class="title">{{ '订单记录'.$t }}</div>
</div>
<block v-for="item, index in orderList" :key="index">
<div class="order-box">
<div class="order-top">
<div class="header-text">
<div lines="1" class="order-name" v-if="item.digital_type == 0">{{ '手办'.$t }}</div>
<div lines="1" class="order-name" v-else-if="item.digital_type == 4">{{'体验3D相册'.$t}}</div>
<div lines="1" class="order-name" v-else-if="item.digital_type == 1">{{'3D相册'.$t}}</div>
<div class="order-status" v-if="item.print_type == 2 && item.digital_type == 0">{{ '重打'.$t }}</div>
<div class="order-status" v-else-if="item.print_type == 3 && item.digital_type == 0">{{ '加打'.$t }}</div>
</div>
<div class="text_13">{{item.create_time}}</div>
</div>
<!-- 遍历数组 -->
<div class="" v-if="item.digital_type == 0">
<div class="text-wrapper_37" v-for="fItem, fIndex in item.filterSize" :key="fIndex" v-for-item="fItem">
<div class="text_14">{{fItem.size}}</div>
<div class="text_15">x{{fItem.num}}</div>
</div>
</div>
<div class="text-wrapper_37">
<div class="text_38">
{{orderStatus(item.status,item.digital_type).$t}}
<van-icon v-if="item.status>=9000 && item.digital_type == 0" @click="turnToDelivery" data-delivery_no="{{item.delivery_no}}" name="arrow" size="18px" color="#767676"/>
</div>
<div class="text_38">{{item.update_time}}</div>
</div>
<div class="text-wrapper_37">
<div class="text_38">{{ '费用合计'.$t }}</div>
<div class="total">
<div class="text_29"></div>
<div class="text_30">{{ item.goods_amount / 100}}</div>
</div>
</div>
</div>
</block>
</div>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.page {
position: relative;
width: 375px;
height: 100vh;
display: flex;
background: rgba(245, 245, 245, 1.000000);
flex-direction: column;
.container {
position: relative;
width: 100%;
height: auto;
background: rgba(245, 245, 245, 1.000000);
padding-bottom: 60px;
box-sizing: border-box;
.order_info {
background-color: rgba(255, 255, 255, 1.000000);
border-radius: 8px;
width: 345px;
display: flex;
flex-direction: column;
margin: 7.5px auto 0 auto;
}
.order_record {
background-color: rgba(255, 255, 255, 1.000000);
border-radius: 8px;
width: 345px;
min-height: 200px;
display: flex;
flex-direction: column;
margin: 15px auto;
.section_2 {
position: relative;
width: 315px;
height: auto;
margin: 0 auto;
border-radius: 8px;
.order-title {
display: flex;
align-items: center;
width: 100%;
height: 24px;
margin-top: 24px;
padding-bottom: 6px;
margin-bottom: 11px;
border-bottom: 2px solid #F0F0F0;
.title {
color: #333333;
font-size: 16px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
}
}
.order-box {
display: flex;
flex-direction: column;
position: relative;
width: 100%;
margin-bottom: 15px;
background: #FAFDFB;
.order-top {
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(236, 244, 234, 1.000000);
border-radius: 10px 10px 0px 0px;
width: 315px;
height: 44px;
margin: 0 auto;
padding: 0 15px;
box-sizing: border-box;
.header-text {
display: flex;
justify-content: flex-start;
align-items: center;
position: relative;
height: 100%;
.order-name {
overflow-wrap: break-word;
color: #1A1A1A;
font-size: 14px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
text-align: left;
white-space: nowrap;
line-height: 14px;
margin-right: 8px;
}
.order-status {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 30px;
height: 24px;
background: #ffffff;
font-size: 11px;
color: #E6A23C;
font-weight: 500;
border-radius: 4px;
}
}
.text_13 {
height: 14px;
overflow-wrap: break-word;
color: #767676;
font-size: 14px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
text-align: left;
white-space: nowrap;
line-height: 14px;
}
}
}
}
}
}
.higher {
padding-bottom: 110px;
}
}
.text-group_9 {
width: 234px;
height: 180px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.text-wrapper_37 {
width: 285px;
height: 44px;
display: flex;
justify-content: space-between;
align-items: center;
background: #FAFDFB;
border-bottom: 2px solid #F0F0F0;
margin: 0 auto;
&:last-child {
border-bottom: none;
}
.total {
display: flex;
align-items: center;
position: relative;
height: 100%;
.text_29 {
width: 12px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 12px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
text-align: right;
white-space: nowrap;
line-height: 12px;
}
.text_30 {
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 16px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
}
.button_3 {
display: flex;
justify-content: center;
align-items: center;
height: 30px;
background-color: #009944;
border-radius: 6px;
font-size: 14px;
margin: 0;
&::after {
display: none;
}
}
}
.line {
margin: 0 auto;
width: 95%;
height: 1px;
background-color: #F0F0F0;
border-bottom: 1px solid #F0F0F0;
}
.text_4 {
width: 48px;
height: 16px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 16px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
.text_14 {
height: 12px;
overflow-wrap: break-word;
color: rgba(102, 102, 102, 1.000000);
font-size: 14px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 12px;
}
.text_15 {
height: 12px;
overflow-wrap: break-word;
color: rgba(102, 102, 102, 1.000000);
font-size: 12px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 12px;
}
.text-wrapper_43 {
position: relative;
width: 315px;
height: 24px;
margin: 14px auto 11px auto;
padding-bottom: 6px;
border-bottom: 1px solid #F0F0F0;
.order-info {
display: flex;
justify-content: space-between;
align-items: center;
width: 315px;
height: 100%;
margin: 0 auto;
.more {
position: relative;
width: 16px;
height: 16px;
}
}
}
.text_31 {
width: 64px;
height: 16px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 16px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
.text-wrapper_44 {
display: flex;
justify-content: flex-start;
align-items: center;
width: 315px;
height: 20px;
margin: 0 auto 10px auto;
}
.text_38 {
display: flex;
align-items: center;
color: #1A1A1A;
font-size: 14px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
white-space: nowrap;
}
.text-wrapper_45 {
display: flex;
justify-content: space-between;
align-items: center;
width: 315px;
margin: 0 auto 10px auto;
.order-id {
display: flex;
}
}
.text_39 {
// width: 52px;
height: 15px;
overflow-wrap: break-word;
color: rgba(153, 153, 153, 1.000000);
font-size: 14px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
margin-right: 15px;
}
.text_40 {
height: 15px;
overflow-wrap: break-word;
color: rgba(51, 51, 51, 1.000000);
font-size: 14px;
font-family: Source Han Sans CN-Regular;
font-weight: normal;
text-align: left;
white-space: nowrap;
line-height: 15px;
margin-top: 2px;
}
.button_2 {
width: 36px;
height: 20px;
color: #AAAAAA;
border: 1px solid #AAAAAA;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
border-radius: 5px;
margin-left: 10px;
}
.button_2::after {
display: none;
}
.group_13 {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 42px;
}
.image-text_12 {
height: 16px;
flex-direction: row;
display: flex;
justify-content: space-between;
}
.icon_2 {
width: 16px;
height: 16px;
display: flex;
justify-content: center;
flex-direction: column;
.icon_4 {
width: 14px;
height: 14px;
}
}
.text-order_record {
height: 16px;
overflow-wrap: break-word;
color: #009944;
font-size: 16px;
font-family: Source Han Sans CN-Medium;
font-weight: 500;
text-align: left;
white-space: nowrap;
line-height: 16px;
}
.group_9 {
background-color: rgba(255, 255, 255, 1.000000);
height: 72px;
display: flex;
flex-direction: column;
width: 375px;
}
</style>

543
src/views/my_order/index.vue

@ -1,543 +0,0 @@
<script lang="tsx" setup>
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
import { normalizeStatus, getURLParameters } from '@/utils/utils'
import * as myOrderApi from '@/api/my_order'
import * as configApi from '@/api/config'
import { imgSrc } from "@/utils/utils"
import { useStore } from '@/stores'
import { useRoute, useRouter } from 'vue-router'
const store = useStore();
import { useTokenStore } from '@/stores/token'
import { showFailToast } from 'vant';
const tokenStore = useTokenStore();
const router = useRouter();
const route = useRoute()
const userInfo = ref(null)
const refreshing = ref(false)
const finished = ref(false)
const loading = ref(false)
const error = ref(false)
const list = ref([])
let page = 1
const size = 6
const { isWechat } = tokenStore;
const brandId = ref();
onMounted(() => {
userInfo.value = tokenStore.userInfo;
brandId.value = instance.proxy.$brandId;
getBrand(brandId.value);
})
function onLoad() {
if (refreshing.value) {
list.value = []
page = 1
refreshing.value = false
}
getPage();
}
//
const getPage = () => {
myOrderApi.page({
page,
brand_id: brandId.value || "",
size,
}).then((res: any) => {
const data = res || []
list.value = list.value.concat(normalizeStatus(data))
if (data.length < size)
finished.value = true
page++
}).catch(() => {
error.value = true
}).finally(() => {
loading.value = false
})
}
//
const getBrand = (val) => {
configApi.brand(val).then((res: any) => {
store.setBrandInfo(res); //
setIcon(res)
}).catch((err) => {
console.log("configErr", err)
}).finally(() => {
})
}
const setIcon = (res) => {
const favicon = res.favicon
if (favicon) {
const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'icon';
link.href = favicon;
document.head.appendChild(link);
}
}
const onRefresh = () => {
//
finished.value = false
//
loading.value = true
onLoad()
}
// 3D
const toAlbum = (data) => {
store.updateOrderInfo(data)
if (data.has_experience || data.status >= 4100) {
// web
router.push({
path: data.is_gsplat == 1 ? '/photo3d/gsplat' : '/photo3d',
})
}else {
showFailToast('3D相册制作中'.$t)
return
}
console.log("toAlbum", data)
// const u = wx.getStorageSync('userInfo');
// var pid = e.currentTarget.dataset.pid;
// var cn = e.currentTarget.dataset.cn;
// var oid = e.currentTarget.dataset.oid;
// var cid = e.currentTarget.dataset.cid;
// var status = e.currentTarget.dataset.status;
// var remainingExperienceStatus = e.currentTarget.dataset.remain_status;
// var expireTime = e.currentTarget.dataset.expire_time;
// var digitalOrderId = e.currentTarget.dataset.digital_order_id;
// var digitalType = e.currentTarget.dataset.digital_type;
// var createTime = e.currentTarget.dataset.create_time;
// var titleCode = e.currentTarget.dataset.title_code;
// console.log(e.currentTarget.dataset)
// //createTime2023-04-15 00:00:00
// wx.request({
// url: config.url + '/miniProgram/judgeP3dLogOrderTime',
// data: {photoTime: createTime, pid},
// header: {'content-type': 'application/json'},
// success: (res) => {
// if (res.data.data.use_status != 1) {
// wx.showToast({
// title: '3D',
// icon: 'none',
// duration: 2000
// })
// return
// }
// const url = `/package3D/pages/3d/3d?openid=${u.openid}`
// + `&unionid=${u.unionid}&id=${pid}&oid=${oid}`
// + `&cn=${cn}&cid=${cid}&expireTime=${expireTime}`
// + `&digitalType=${digitalType}`
// + `&status=${status}`
// + `&titleCode=${titleCode}`
// + `&remainingExperienceStatus=${remainingExperienceStatus}`
// console.log("url", url);
// if (digitalOrderId == 0) {
// wx.navigateTo({
// url: url,
// });
// return
// }
// if (status < 4100) {
// wx.showToast({
// title: '3D',
// icon: 'none',
// duration: 2000
// })
// return
// }
// //
// // const timestamp = Date.parse(new Date());
// // const url = `http://172.16.20.5:3000/?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}&expireTime=${expireTime}&remainingExperienceStatus=${remainingExperienceStatus}`
// // const url = `https://wechat.suwa3d.com/3d/index.html?t=${Date.now()}#/model?openid=${u.openid}&unionid=${u.unionid}&id=${pid}&oid=${oid}&cn=${cn}&cid=${cid}`
// // const navtitle = '3D'; //
// wx.navigateTo({
// // webview
// // url: `/pages/webview/webview?nav=${navtitle}&url=${encodeURIComponent(url)}`,
// url: url,
// });
// },
// fail: (err) => {
// console.log(err);
// }
// })
}
function getExpeienceText(item: any) {
switch (item.remaining_experience?.title_code) {
case 1:
return '3D相册体验中'.$t
case 2:
return '3D相册体验结束'.$t
case 3:
return '您购买的3D相册正在精修中!'.$t
}
}
function showExperience(item: any) {
return item.remaining_experience?.status !== 0
}
const detailClick = (data: any) => {
store.updateOrderInfo(data)
router.push({
path: '/myOrder/detail',
})
}
</script>
<template>
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" safe-area-inset-top />
<div class="page">
<div class="container">
<div class="box-wrap">
<van-pull-refresh v-model="refreshing" @refresh="onRefresh">
<Brand />
<van-list v-model:loading="loading" v-model:error="error" :error-text="'请求失败,点击重新加载'.$t"
:finished-text="'没有更多了'.$t" :finished="finished" @load="onLoad">
<van-card v-for="item in list" :key="item.pid">
<template #title>
<van-cell :title="item.pid" is-link :value="'详情'.$t" class="title" @click="detailClick(item)" />
</template>
<template #thumb>
<img v-if="item.texture_cover_img" :src="imgSrc(item.texture_cover_img)" alt="" @click="toAlbum(item)">
<div v-else class="empty_img" @click="toAlbum(item)" ></div>
</template>
<template #tags>
{{ item.head_count }}{{ '人'.$t }}/{{ item.model_json.$t }}
</template>
<template #footer>
<div class="van-wrap">
<div class="van-status">
<div :class="['status', item.statusColor == 0 ? 'undone' : '']">{{ item.statusName.$t }}</div>
<div class="created_time">{{ item.update_time }}</div>
</div>
<div class="btns">
<div class="check_btn" v-if="item.status >= 4100 || item.has_experience" @click="toAlbum(item)">{{ '查看3D相册'.$t }}</div>
<div class="check_btn disabled" v-else>{{ '查看3D相册'.$t }}</div>
</div>
</div>
<div :class="['photograph-box', { expire: item.remaining_experience?.status === 2 }]"
v-if="showExperience(item)">
<div class="box-wrap">
<div class="experience">{{ getExpeienceText(item) }}</div>
<div class="right" v-if="item.remaining_experience.day > 0">
<div class="countdown">{{ '倒计时'.$t }}<div class="bold">{{ item.remaining_experience?.day }}</div>
{{ '天'.$t }}</div>
</div>
</div>
</div>
</template>
</van-card>
</van-list>
</van-pull-refresh>
</div>
</div>
<Tabbar></Tabbar>
</div>
</template>
<style lang="less" scoped>
.page {
box-sizing: border-box;
// padding-bottom: calc(env(safe-area-inset-bottom) + 96px);
background-color: #F3F3F3;
}
.container {
display: block;
padding: 5px 15px 0 15px;
>.box-wrap {
overflow-y: scroll;
height: 100vh;
padding-bottom: 100px;
// height: calc(100vh - 96px);
}
}
.text-group {
display: flex;
flex-direction: column;
align-items: center;
}
.cover {
position: absolute;
width: 100%;
height: 100vh;
background: #ffffff;
z-index: 9;
}
.button {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
font-size: 16px;
background-color: #1aad19;
color: #fff;
border-radius: 5px;
padding-left: 14px;
padding-right: 14px;
height: 40px;
}
:deep(.van-card) {
background: #ffffff;
margin-top: 10px;
border: 3px solid #F0F2F5;
border-radius: 8px;
padding: 0;
.van-card__header {
display: flex;
justify-content: space-between;
width: 315px;
height: 90px;
flex-direction: row;
margin: 15px auto;
}
.van-card__thumb {
width: 120px;
height: 90px;
border-radius: 16px;
margin-right: 0;
img {
width: 100%;
height: 100%;
}
}
.empty_img {
width: 120px;
height: 90px;
background: #fff;
}
.van-card__content {
display: flex;
flex: unset;
flex-direction: column;
justify-content: space-between;
width: 180px;
height: 90px;
overflow-wrap: break-word;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
color: #666666;
font-size: 14px;
font-weight: normal;
white-space: nowrap;
}
}
:deep(.van-cell__title) {
flex: unset;
overflow-wrap: break-word;
word-break: break-all;
text-overflow: ellipsis;
overflow: hidden;
color: #333333;
font-size: 17px;
font-family: Source Han Sans CN-Bold;
font-weight: 700;
white-space: nowrap;
}
:deep(.van-cell__value),
:deep(.van-icon) {
// width: 56px;
color: #767676;
font-size: 14px;
font-weight: 400;
}
:deep(.van-cell) {
padding: 0;
display: flex;
justify-content: space-between;
align-items: flex-start;
position: relative;
width: 180px;
height: 32px;
}
:deep(.van-card__footer) .van-cell {
margin-top: 0.4rem;
background: #FAFAFA;
}
:deep(.van-card__footer) .van-wrap {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 315px;
margin: 0 auto;
.van-status {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
width: 315px;
height: 46px;
background-color: #FAFAFA;
margin: 0 auto;
border-radius: 8px;
padding: 5px;
margin-bottom: 5px;
.status {
color: #009944;
font-size: 14px;
}
.created_time {
color: #AAAAAA;
font-size: 14px;
}
.undone {
color: #E6A23C;
}
}
}
:deep(.van-card__footer) .van-cell__title {
text-align: left;
color: #009944;
}
.btns {
display: flex;
justify-content: flex-end;
width: 100%;
height: 34px;
margin-bottom: 10px;
.check_btn {
font-size: 14px;
font-weight: 400;
border-radius: 4px;
height: 34px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
color: #009944;
border: 1px solid#009944;
padding: 0 12.5px;
box-sizing: border-box;
}
.disabled {
opacity: .3;
}
}
.photograph-box {
display: flex;
position: relative;
width: 100%;
height: 48px;
background: #FCF5EB;
overflow: hidden;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
border: .5px solid #FDE2E2;
box-sizing: border-box;
.box-wrap {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
width: 315px;
height: 100%;
margin: 0 auto;
.experience {
font-size: 15px;
color: #E6A23C;
font-weight: 700;
font-family: Source Han Sans CN-Bold;
}
.right {
display: flex;
justify-content: flex-start;
align-items: center;
color: #E6A23C;
position: relative;
font-family: Source Han Sans CN-Regular;
.countdown,
.hint {
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
font-weight: 400;
.bold {
font-weight: 700;
}
}
.buy-btn {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 106px;
height: 17px;
background: #E6A23C;
font-weight: 400;
color: #FFFFFF;
font-size: 14px;
border-radius: 5px;
}
}
}
}
.expire {
border: .5px solid #FDE2E2;
background: #FDF0F0;
.box-wrap {
.experience {
color: #F56C6C;
}
.right {
color: #F56C6C;
.buy-btn {
background: #F56C6C;
}
}
}
}
</style>

161
src/views/photo_3d/ar.vue

@ -1,161 +0,0 @@
<template>
<arMode :pid="pid" :modelFile="modelFile" @handleProgress="handleProgress"
@handleLoaded="handleLoaded"></arMode>
<!-- <arFrame :pid="pid" :modelFile="modelFile" @handleProgress="handleProgress"
@handleLoaded="handleLoaded" @closeHint="closeHint"></arFrame> -->
<div class="popup" v-if="showProcess">
<div class="pcenter">
<div class="text">{{ '渲染中...'.$t }}</div>
<van-progress class="progress" :percentage="percent" stroke-width="8px" :show-pivot="false"/>
</div>
</div>
<!-- <div class="hint_cover" v-if="hintVisible">
<div class="hint">将设备</div>
<div class="hint">向前和向后移动</div>
</div> -->
<div class="exit" @click="backTo">
<img class="exit_img" :src="exit" />
<div>{{'退出AR'.$t}}</div>
</div>
</template>
<script setup lang="ts">
import exit from "@/assets/photo3D/icon_exit.png";
import * as api from '@/api/photo_3d'
const router = useRouter()
import { showFailToast } from "vant";
import { useStore } from '@/stores'
const store = useStore();
const backTo = () => router.back()
const modelFile = ref()
const percent = ref(0)
const orderInfo = ref()
const pid = ref();
const showProcess = ref(false)
const hintVisible = ref(true)
onMounted(()=> {
orderInfo.value = store.orderInfo;
pid.value = store.orderInfo.pid
getModel(pid.value)
})
const closeHint = () => hintVisible.value = false;
//
const getModel = (pid: any) => {
api.glb(pid).then((data: any) => {
if (data && data.s) {
// let _data = {
// iShare: data.s,
// id: data.id,
// }
//
// if (data.isShare) {
// _data.expireTime = data.expireTime || '';
// _data.remainingExperienceStatus = data.remainingExperienceStatus || '';
// _data.digitalType = data.digitalType || '';
// _data.titleCode = data.titleCode || '';
// _data.oid = data.oid || '';
// }
// that.setData(_data)
}
modelFile.value = data.url;
}).catch(err=> {
console.log("loaded failed", err);
showFailToast(err && err.message);
})
}
//
const handleProgress = (detail) => {
showProcess.value = true
if (detail < percent.value) return;
//
if (detail == 1) {
setTimeout(() => {
if (showProcess.value) {
//
showProcess.value = false
}
}, 10000);
}
percent.value = detail
}
//
const handleLoaded = (detail) => {
setTimeout(() => {
showProcess.value = false;
}, 1000)
}
</script>
<style lang="less" scoped>
.exit {
position: absolute;
left: 30px;
bottom: 30px;
font-size: 14px;
color: #fff;
text-align: center;
.exit_img {
width: 38px;
height: 39px;
display: block;
margin: 0 auto 6px;
}
}
.popup {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
text-align: center;
}
.text {
font-size: 15px;
color: #fff;
}
.progress {
width: 80%;
margin: 0 auto;
margin-top: 5px;
}
.pcenter {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100%;
}
.hint_cover {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: 2;
.hint {
width: 200px;
height: 30px;
font-size: 20px;
color: #ffffff;
}
}
</style>

1190
src/views/photo_3d/gsplat.vue

File diff suppressed because it is too large Load Diff

1124
src/views/photo_3d/index.vue

File diff suppressed because it is too large Load Diff

1071
src/views/photo_3d/threejs.vue

File diff suppressed because it is too large Load Diff

610
src/views/queue/index.vue

@ -1,610 +0,0 @@
<script setup lang="ts">
import { getCurrentInstance } from 'vue'
const instance = getCurrentInstance();
import { contractMap } from '@/dict/status_dict'
import dayjs from 'dayjs'
import { showDialog, showFailToast } from 'vant'
import { useRoute } from 'vue-router'
import * as queueApi from '@/api/queue'
import * as configApi from '@/api/config'
import router from '@/router'
import {getTreeData} from "@/utils/utils"
// import {AttrResponse} from './utils/type'
// import { AxiosResponse } from 'axios'
import { useStore } from '@/stores'
const store = useStore();
const isProd = process.env.mode === 'production' || process.env.mode === 'gray'
const hintShow = ref(false)
const isAll = ref(true)
const loading = ref(false)
const choseManyType = ref([2, 4, 5])
const name = ref(isProd ? '' : '测试')
const mobile = ref(isProd ? '' : '13695004676')
const birthday = ref(isProd ? '' : '1990-10-10')
const attrBuyTypes = ref([])
const buyTypes = ref([])
const attrList = ref([])
const goodsList = ref([])
const choseList = ref({})
const choseAttrsIds = ref([])
const choseGoodsIds = ref([])
const totalPrice = ref(0)
const goodsTotalPrice = ref(0)
const shopId = ref(0)
const brandId = ref()
const logo = ref('')
const currency = ref('')
const useLogo = ref(false)
const v = ref('')
const shopName = ref('')
// const checkboxRefs = ref([])
const agree = ref(false)
const showPicker = ref(false)
const showAgree = ref(false)
const agreePage = ref('')
const agreeTitle = ref('')
const current = ref();
const route = useRoute()
const cate_map = ref({
1: '数字模型',
2: '手办尺寸',
3: '额外携带',
4: '',
})
const minDate = new Date(1900, 0, 1)
const maxDate = new Date()
const ignore = ref()
const currentDate = ref(['1990', '10', '10'])
// const toggle = (index) => {
// checkboxRefs.value[index].toggle();
// };
onMounted(() => {
shopId.value = parseInt(String(route.query.shop_id), 10)
brandId.value = parseInt(String(route.query.shop_id), 10)
ignore.value = parseInt(String(route.query.ignore), 10)
shopName.value = String(route.query.shop_name)
currency.value = String(route.query.currency)
useLogo.value = Boolean(route.query.use_logo)
v.value = String(route.query.v)
logo.value = String(route.query.logo)
if (!logo.value) {
// logo
logo.value = `/resource/img/logo/${shopId.value}.png?t=${new Date().getTime()}`
}
brandId.value = instance.proxy.$brandId;
// isShowHint();
getBrand(brandId.value);
// init()
})
const isShowHint = ()=> {
isAll.value = ignore.value == 0 ? false : true;
if(ignore.value == 0) {
hintShow.value = false
}else {
hintShow.value = true
}
}
const closeHint = () => {
hintShow.value = false;
}
const checkChange = (val) => {
console.log('123', val)
agree.value = val;
}
//
const getBrand = (val) => {
configApi.brand(val).then((res: any) => {
store.setBrandInfo(res); //
setIcon(res)
}).catch((err) => {
console.log("configErr", err)
}).finally(() => {
})
}
function onViewAgree(name: string, val: number) {
let url;
let sid = brandId.value;
let timeStamp = Date.now();
// TODO: /v1/en
//
if(store.brandInfo.agrees) {
store.brandInfo.agrees.filter((el: any)=> {
if(el.agree_type == val) {
url = el.url
agreeTitle.value = el.title
}
})
}else {
if(sid == 130 || sid == 134) {
url = `/pages/agreement/v1/cn/${sid}/${name}.html?` + timeStamp
}else {
url = `/pages/agreement/v1/${name}.html?` + timeStamp;
}
}
agreeTitle.value = contractMap[val]
showAgree.value = true
agreePage.value = url
}
const setIcon = (res) => {
const favicon = res.favicon
if (favicon) {
const link = document.querySelector("link[rel*='icon']") || document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'icon';
link.href = favicon;
document.head.appendChild(link);
}
}
const hidden = ref(false)
const init = () => {
nextTick(()=> {
loading.value = true
queueApi.attr({
shop_id: shopId.value,
brand_id: brandId.value || "",
}).then((res: any) => {
goodsList.value = res.goods;
hidden.value = !!res.hidden;
// setAttrList(res.attrs);
// setGoodsList(res.goods);
//
attrBuyTypes.value = res.attrBuyTypes || [];
if (attrBuyTypes.value.length) buyTypes.value = [attrBuyTypes[0]?.value.id];
//
defaultSelected();
})
.catch((error) => {
console.log('err', error)
showDialog({ message: error.message }).then(() => {
router.replace('/')
})
}).finally(() => {
loading.value = false
})
})
}
const selectedGoodsMap = ref({})
const selectedGoodsAttrMap = ref({})
const attributeMap = ref({})
const setGoodsList = (data) => {
let _data = data || [];
let list = [];
let cateMap = {};
_data.forEach((el) => {
let cate = cateMap[el.cate_id];
if (!cate) {
cate = {
id: el.cate_id,
cate_name: el.cate_name,
children: [],
attrs: []
};
cateMap[el.cate_id] = cate;
list.push(cate);
selectedGoodsMap.value[el.cate_id] = [];
selectedGoodsAttrMap.value[el.cate_id] = [];
if (el.attr_ids != "") {
JSON.parse(el.attr_ids).forEach((el) => {
let c = attributeMap.value[el];
if (c) {
cate.attrs.push(c);
}
});
}
}
cate.children.push(el);
cate.children.sort((a, b) => a.sort - b.sort);
});
list.sort((a, b) => {
return a.sort - b.sort;
});
attrList.value = list;
}
const selectedData = ref({})
const attributeList = ref([])
const setAttrList = (data) => {
let _data = data || [];
_data.map((e) => {
e.parentId = e.parent_id;
e.orderNum = e.id;
attributeMap.value[e.id] = e;
});
let __data = getTreeData(_data);
__data.forEach((e) => {
selectedData.value[e.id] = [];
});
attributeList.value = __data;
}
const selectBuyType = (buyType) => {
buyTypes.value = buyType;
getGoodsPrice();
}
const cate_map_list = ref({
1: [],
2: [],
3: [],
4: []
})
const currentGood = ref(null)
const selectGoods = (cateId, goodsId) => {
//
current.value = cateId;
currentGood.value = goodsId;
}
const goodsChange = (e) => {
//
// if (index >= 0) {
// cate_map_list.value[currentData]?.splice(index, 1)
// } else {
// cate_map_list.value[currentData]?.push(goodData);
// }
getGoodsPrice();
}
const selectGoodsAttr = (cateId, attrId) => {
selectedGoodsAttrMap.value[cateId] = attrId;
getGoodsPrice();
}
const calculated = ref(false)
watch(() => totalPrice.value, (val, preVal) => {
totalPrice.value = calculated.value ? totalPrice.value : 0
},{immediate: true})
//
function getGoodsPrice() {
//
const attrIds = []
const goodsIds = []
Object.values(selectedGoodsMap.value).forEach((cl: any)=> {
Object.values(cl).forEach((item)=> {
goodsIds.push(item)
})
})
Object.values(selectedGoodsAttrMap.value).forEach((dl: any) => {
if(!Array.isArray(dl)) {
attrIds.push(dl)
}
});
choseAttrsIds.value = attrIds
choseGoodsIds.value = goodsIds
queueApi.calc({
buy_types: filterBuyTypes(),
attr_ids: attrIds,
goods_ids: goodsIds,
shop_id: shopId.value,
})
.then((res: any) => {
console.log('获取到价格', res)
totalPrice.value = res.totalPrice * 100 || 0
goodsTotalPrice.value = res.goodsTotalPrice * 100 || 0
calculated.value = true
})
.catch((err) => {
console.log('err', err)
totalPrice.value = 0
goodsTotalPrice.value = 0
calculated.value = false
})
}
function filterBuyTypes() {
return (buyTypes.value || []).filter((item) => item > 0)
}
// const onGoodsChange = (data) => {
// totalPrice.value = data.total_amount;
// goodsTotalPrice.value = data.total_goods_amount;
// choseAttrsIds.value = data.attr_ids
// choseGoodsIds.value = data.goods_ids
// calculated.value = data.calculated;
// }
//
function onSubmit() {
loading.value = true
// if (totalPrice.value === 0) {
// if (choseGoodsIds.value.length === 0) {
// showDialog({ message: ''.$t })
// loading.value = false
// return
// }
// if (choseAttrsIds.value.length === 0) {
// showDialog({ message: '姿'.$t })
// loading.value = false
// return
// }
// showDialog({ message: ''.$t })
// loading.value = false
// return
// }
if (agree.value === false && isAll.value) {
hintShow.value = true
loading.value = false
return
}
submitQueue().finally(() => {
loading.value = false
})
}
function submitQueue() {
const params = {
// attr_ids: choseAttrsIds.value,
// goods_ids: choseGoodsIds.value,
shop_id: shopId.value,
applyTime: dayjs(currentDate.value.join('-')).format('YYYY-MM-DD'),
customer_mobile: mobile.value,
customer_name: name.value,
// buy_types: filterBuyTypes(),
}
return queueApi.queueAdd(params)
.then((res: any) => {
// showDialog({ message: '' })
// const path = `/queue/succeed?shop_id=${shopId.value}&shop_name=${shopName.value}&currency=${currency.value}&use_logo=${useLogo.value ? 1 : ''
// }&v=${v.value}&index=${res.index}`
const path = `/queue/succeed?shop_id=${shopId.value}&shop_name=${shopName.value}&use_logo=${useLogo.value ? 1 : ''
}&v=${v.value}&index=${res.index}`
router.push(path)
})
.catch((err: Error) => {
showDialog({ message: err.message })
})
}
const goodsHidden = () => {
return hidden.value;
// return this.shop_id == 86;
}
//
const defaultSelected = () => {
if(!goodsHidden()) {
return;
}
attrList.value.forEach((el) => {
if (el.id == 2) {
el.children.forEach(child => {
if (child.goods_name == '18cm') {
selectGoods(el.id, child.id)
}
})
}
if (el.attrs.length) {
el.attrs.forEach(child => {
if (child.attr_name == '站姿') {
selectGoodsAttr(el.id, child.id)
}
})
}
// console.log(JSON.stringify(el))
})
}
function onConfirm({ selectedValues }) {
currentDate.value = selectedValues
console.log('currentDate', currentDate.value);
birthday.value = selectedValues.join('-')
showPicker.value = false
}
</script>
<template>
<div class="page" :class="[{'goods-hidden': goodsHidden()}]">
<Hint :hintShow="hintShow" @onViewAgree="onViewAgree" @check="checkChange" @close="closeHint"></Hint>
<van-form @submit="onSubmit">
<img v-if="useLogo" :src="logo" class="logo">
<van-cell-group inset>
<van-field
v-model="shopName" disabled readonly name="shopName" label-width="65px" :label="'门店'.$t"
/>
<van-field
v-model="name" name="name" :label="'姓名'.$t" label-width="65px" :placeholder="'姓名'.$t"
:rules="[{ required: true, message: '请填写姓名'.$t }]"
/>
<van-field
v-model="mobile" name="mobile" :label="'手机'.$t" label-width="65px" :placeholder="'手机'.$t"
:rules="[{ required: true, message: '请填写手机'.$t }]"
/>
<van-field
v-model="birthday" is-link readonly name="birthday" label-width="65px" :label="'生日'.$t" :placeholder="'生日'.$t"
:rules="[{ required: true, message: '请填写生日'.$t }]" @click="showPicker = true"
/>
<!-- <van-field :label="'购买类型'.$t" label-width="65px" v-if="attrBuyTypes.length > 0">
<template #input>
<el-checkbox-group v-model="buyTypes" size="small" @change="selectBuyType">
<el-checkbox-button v-for="al in attrBuyTypes" :key="al.id" :label="al.id">
{{ al.name.$t }}
</el-checkbox-button>
</el-checkbox-group>
</template>
</van-field> -->
<!-- <template v-for="item in attrList">
<template
v-if="item.children && item.children.length && item.children.length > 0"
>
<van-field :label="cate_map[item.id].$t" label-width="65px">
<template #input>
<el-checkbox-group v-model="selectedGoodsMap[item.id]" size="small" @change="goodsChange">
<el-checkbox-button v-for="cl in item.children" :key="cl.id" :label="cl.id" @click="selectGoods(item.id, cl.id)">
{{ item.id == 1 ? '选购'.$t : cl.goods_name.$t }}
</el-checkbox-button>
</el-checkbox-group>
</template>
</van-field>
<template v-if="item.attrs.length">
<van-field :label="'拍摄姿势'.$t" label-width="65px">
<template #input>
<el-radio-group v-model="selectedGoodsAttrMap[item.id]" size="small">
<el-radio-button v-for="rl in item.attrs" :key="rl.id" :label="rl.id" @click="selectGoodsAttr(item.id, rl.id)" >
{{ rl.attr_name.$t }}
</el-radio-button>
</el-radio-group>
</template>
</van-field>
</template>
</template>
</template> -->
<!-- <van-field>
<template #input>
<div class="warning-box">
<img class="image" src="@/assets/common/warning.png" alt="" />
<div class="tip">{{'以上为单人拍照参考价格,详细可与店员咨询'.$t}}</div>
</div>
</template>
</van-field> -->
</van-cell-group>
<div class="empty-footer" />
<!-- <van-submit-bar
v-if="!loading" :loading="loading" :currency="currency.$t" :price="totalPrice" :button-text="'提交'.$t"
:label="'合计:'.$t"
@submit="onSubmit"
> -->
<van-submit-bar
v-if="!loading" :loading="loading" :button-text="'提交'.$t"
@submit="onSubmit"
>
<!-- <van-checkbox v-model="checked">全选</van-checkbox> -->
<template #tip v-if="isAll">
<van-checkbox icon-size="18px" v-model="agree" checked-color="#07c160">
<span style="font-size: 14px;">{{'我已阅读并同意'.$t}}</span>
<a
href="javascript:;" class="agreement"
@click.stop="onViewAgree('user_service', 1)"
>{{'用户服务协议'.$t}}</a>
<a
href="javascript:;" class="agreement"
@click.stop="onViewAgree('user_privacy', 2)"
>{{'用户隐私政策'.$t}}</a>
<a v-if="store.brandInfo.agrees?.length > 2"
href="javascript:;" class="agreement"
@click.stop="onViewAgree('child_privacy', 3)"
>{{'儿童隐私政策'.$t}}</a>
</van-checkbox>
</template>
</van-submit-bar>
<van-popup v-model:show="showPicker" position="bottom">
<van-date-picker
v-model="currentDate" :min-date="minDate" :max-date="maxDate" @confirm="onConfirm"
@cancel="showPicker = false"
/>
</van-popup>
</van-form>
<van-overlay :show="loading">
<div class="loading-wrapper" @click.stop>
<van-loading size="24px">
{{'加载中'.$t}}...
</van-loading>
</div>
</van-overlay>
<van-dialog v-model:show="showAgree" :title="agreeTitle.$t" :confirm-button-text="'我已知晓'.$t" width="100vw" class="agree-dialog">
<iframe :src="agreePage" class="agree-iframe" />
</van-dialog>
</div>
</template>
<style lang="less" scoped>
:deep(.el-checkbox-button) {
--el-checkbox-button-checked-bg-color: #1aad19;
--el-checkbox-button-checked-border-color: #1aad19;
--el-checkbox-button-checked-color: #1aad19;
}
:deep(.el-radio-button) {
--el-radio-button-checked-bg-color: #1aad19;
--el-radio-button-checked-border-color: #1aad19;
}
:deep(.el-checkbox-button__inner:hover) {
color: #000;
}
:deep(.el-radio-button__inner:hover) {
color: #fff;
}
:deep(.van-submit-bar__button--danger) {
background: #1aad19;
}
.goods-hidden{
display: none;
}
.page {
background-color: #f5f5f5;
height: 100vh;
position: relative;
padding-top: 15px;
}
.logo {
width: 96%;
margin: 0.5rem auto;
/* min-height:10rem; */
text-align: center;
}
.empty-footer {
height: 10rem
}
.loading-wrapper {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.agree-iframe {
height: 80vh;
width: 100vw;
}
.warning-box {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
.image {
margin-right: 5px;
width: 12px;
height: 12px;
}
.tip {
font-size: 12px;
color: #666666;
}
}
.agreement {
color: #1aad19;
font-size: 14px;
}
</style>

57
src/views/queue/succeed.vue

@ -1,57 +0,0 @@
<script setup lang="tsx">
import { useRoute } from 'vue-router'
import router from '@/router'
const index = ref('0')
const route = useRoute()
onMounted(() => {
index.value = route.query.index as string
})
function goBack() {
router.back()
}
</script>
<template>
<div class="container">
<van-empty :description="'排队成功'.$t" image="/resource/img/succeed.png">
<div class="footer">
<p class="text">
{{"您前面还有".$t}} <span class="num">{{ index }}</span> {{"人请等待叫号".$t}}
</p>
<van-button @click="goBack">
{{"返回".$t}}
</van-button>
</div>
</van-empty>
<div class="empty" />
</div>
</template>
<style scoped lang="less">
.container{
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: #ffffff;
}
.footer{
display: flex;
flex-direction: column;
align-items: center;
.text{
font-size: 14px;
color: #aaaaaa;
}
.num{
color: #009944;
}
}
.empty{
height: 10vh;
}
</style>

52
src/views/queue/utils/type.ts

@ -1,52 +0,0 @@
export interface AttrResponse {
attrBuyTypes: AttrBuyType[]
attrs: Attr[]
goods: Good[]
hidden: boolean
}
export interface AttrBuyType {
id: number
name: string
}
export interface Attr {
id: number
attr_name: string
parent_id: number
attr_ratio: number
version_id: number
type_id: number
model_repair_cost: number
attr_level: number
attr_desc: string
attr_price: number
digital_price: number
createTime: string
updateTime: string
}
export interface Good {
id: number
version_id: number
status: number
cate_id: number
base_attr_id: number
goods_name: string
goods_desc: string
attr_ids: string
attr_ids_list?: number[]
with_attr_ids: string
with_attr_ids_list: any
shop_ids: any
with_attr_discount: number
goods_type: number
goods_price: number
createTime: string
updateTime: string
cate_name: string
price: number
src_price: number
goods_count: number
attr_id: number
}

62
src/views/short_url/actions.vue

@ -1,62 +0,0 @@
<script lang="tsx" setup>
import { useRoute } from 'vue-router'
import * as Dict from './dict'
import { actions as actionsApi } from '@/api/short_url'
import router from '@/router'
import Loading from '@/components/loading/index.vue'
const code = ref('')
const actions = ref([])
const loading = ref(false)
const route = useRoute()
onMounted(() => {
code.value = route.query.code as string
getActions()
})
function onAction(action: any) {
switch (action.value) {
case Dict.OperationWebsiteId:
window.location.href = action.jump_url
break
case Dict.OperationMiniProgramId:
window.location.href = action.jump_url
break
case Dict.OrderHistoryId:
router.push(`/shortUrl/orderTrack?code=${code.value}&action=orderTrack`)
break
case Dict.OrderInfoId:
router.push(`/shortUrl/orderInfo?code=${code.value}&action=orderInfo`)
break
case Dict.PrintOrderInfoId:
router.push(`/shortUrl/printOrderInfo?code=${code.value}&action=printOrderInfo`)
break
}
}
function getActions() {
loading.value = true
actionsApi(code.value).then((res: any) => {
actions.value = res || []
}).finally(() => {
loading.value = false
})
}
</script>
<template>
<van-cell-group>
<van-cell
v-for="action in actions"
:key="action.value"
:title="action.label"
:clickable="true"
@click="onAction(action)"
>
点击查看
</van-cell>
</van-cell-group>
<Loading :loading="loading" />
</template>
<style lang="less" scoped></style>

54
src/views/short_url/components/orderTrackItem.vue

@ -1,54 +0,0 @@
<script setup lang="tsx">
defineProps({
activity: {
type: Object,
default: () => ({}),
},
})
function sortByTimeDesc(bjectInfo: any[]) {
//
const tempRes = (bjectInfo || []).filter((el: any) => el?.routes?.length > 0).sort((a, b) => {
return new Date(b.acceptTime).getTime() - new Date(a.acceptTime).getTime()
})
return tempRes
}
function getAcceptTime(item) {
if (item && item.routes && item.routes[0])
return item.routes[0].acceptTime
return ''
}
// function hasExpressRouter(routerList?: any[]) {
// if (!routerList)
// return false
// return routerList.some((item) => {
// return item.routes && item.routes.length > 0
// })
// }
</script>
<template>
<van-step
v-for="(item, index1) in sortByTimeDesc(
activity.routerInfo,
)" :key="index1"
>
<h3>
{{ item.routes[0] ? item.routes[0].acceptAddress : '' }}
({{ item.routes[0] ? item.routes[0].remark : '' }})
</h3>
<p>{{ getAcceptTime(item) }}</p>
</van-step>
<van-step>
<h3>
{{ activity.msg }} {{ activity.express_no
}}
</h3>
<p>{{ activity.time }}</p>
</van-step>
</template>
<style></style>

28
src/views/short_url/dict.ts

@ -1,28 +0,0 @@
export const View3DPhotoAlbumCode = 'view_3d_photo_album'
export const View3DPhotoAlbumName = '查看3D相册'
export const View3DPhotoAlbumId = 1
// 运营网址
export const OperationWebsiteCode = 'operation_website'
export const OperationWebsiteName = '运营网址'
export const OperationWebsiteId = 2
// 运营小程序
export const OperationMiniProgramCode = 'operation_mini_program'
export const OperationMiniProgramName = '运营小程序'
export const OperationMiniProgramId = 3
// 订单履历
export const OrderHistoryCode = 'order_history'
export const OrderHistoryName = '订单履历'
export const OrderHistoryId = 4
// 订单信息
export const OrderInfoCode = 'order_info'
export const OrderInfoName = '订单信息'
export const OrderInfoId = 5
// 打印订单信息
export const PrintOrderInfoCode = 'print_order_info'
export const PrintOrderInfoName = '打印订单信息'
export const PrintOrderInfoId = 6

171
src/views/short_url/orderInfo.vue

@ -1,171 +0,0 @@
<script lang="tsx" setup>
import { useRoute } from 'vue-router'
import type { Ref } from 'vue'
import { modelSize as _modelSize, printType } from './utils'
import { orderInfo as orderInfoApi } from '@/api/short_url'
import Loading from '@/components/loading/index.vue'
import { filterMsgButton } from '@/dict/status_dict'
const code = ref('')
const src = ref('')
const data: Ref<any> = ref({})
const tags = ref([])
const loading = ref(false)
const modelSize = _modelSize
const route = useRoute()
onMounted(() => {
code.value = route.query.code as string
getInfo()
})
function getImage() {
src.value = ''
if (data.value.info && data.value.info.texture_cover_img)
src.value = `https://3dview.suwa3d.com/${data.value.info.texture_cover_img}`
}
function getTags() {
//
if (!data.value.info || !data.value.info.pid)
return
//
const arrTags = [];
//
[data.value].forEach((item: any) => {
const arrTag = []
//
if (item.is_expedited) {
//
arrTag.push('加急')
}
//
if (item.is_expires)
arrTag.push('超时')
const msg = printType(item.info.print_type)
if (msg !== '' && msg !== '正常')
arrTag.push(msg)
arrTags.push(arrTag)
})
tags.value = arrTags
}
function isSample() {
return data.value.order_tag_type === 'sample'
}
function getPrintTypeText() {
switch (data.value?.info?.print_type) {
case 1:
return '首次打印'
case 2:
return '重打'
case 3:
return '加打'
}
}
function getStatusText() {
return filterMsgButton(data.value?.info?.status, 'text')
}
function getInfo() {
loading.value = true
orderInfoApi(code.value).then((res: any) => {
data.value = res || {}
getImage()
getTags()
}).finally(() => {
loading.value = false
})
}
</script>
<template>
<van-cell-group title="基本信息">
<van-cell title="拍照订单">
<span>
{{ data?.info?.pid }}
</span>
</van-cell>
<van-cell title="尺寸*数量">
<van-tag v-for="(item, key) in modelSize(data?.info?.model_size)" :key="key" type="success" plain>
{{ item }}
</van-tag>
</van-cell>
<van-cell title="提交建模时间" :value="data.submit_model_time" />
<van-cell title="订单状态">
<van-tag type="success">
{{ loading ? '' : getStatusText() }}
</van-tag>
</van-cell>
<van-cell title="打印类型">
<van-tag v-if="isSample()" type="success">
样品
</van-tag>
<van-tag type="success">
{{ getPrintTypeText() }}
</van-tag>
</van-cell>
</van-cell-group>
<van-cell-group title=" ">
<van-cell title="商品金额">
<span>{{ data.goods_amount / 100 }} {{ data.currency }}</span>
</van-cell>
<van-cell v-if="data.other_fee_amount > 0 && data.other_fee_name !== ''" :title="`优惠金额(${data.other_fee_name})`">
<span>{{ data.other_fee_amount / 100 }} {{ data.currency }}</span>
</van-cell>
<van-cell title="总计">
<span>{{ data.total_amount / 100 }} {{ data.currency }}</span>
</van-cell>
</van-cell-group>
<van-cell-group title="门店客户信息">
<van-cell title="门店" :value="data?.info?.shop_name" />
<van-cell title="客户">
{{ data?.info?.customer_name }} (TEL:{{ data?.info?.customer_mobile }})
</van-cell>
<van-cell title="寄送地址">
<span>
{{ data?.info?.province_name }}
{{ data?.info?.city_name }}
{{ data?.info?.country_name }}
{{ data?.info?.address }}
</span>
</van-cell>
</van-cell-group>
<van-cell-group title="重量">
<van-cell title="毛重">
<span>{{ data?.info?.model_gross_weight }}g</span>
</van-cell>
<van-cell title="净重">
<span>{{ data?.info?.model_weight }}g</span>
</van-cell>
</van-cell-group>
<van-cell-group v-if="data.motherList && data.motherList.length > 0" title="其他">
<van-cell title="子母单">
<van-tag
v-for="(item, key) in data.motherList" :key="key" type="success"
class="mother-tag"
plain
>
{{ item.pid }}
</van-tag>
</van-cell>
</van-cell-group>
<Loading :loading="loading" />
</template>
<style lang="less" scoped>
.mother-tag{
margin-right: 0.4rem;
}
</style>

72
src/views/short_url/orderTrack.vue

@ -1,72 +0,0 @@
<script lang="tsx" setup>
import { useRoute } from 'vue-router'
import type { Ref } from 'vue'
import OrderTrackItem from './components/orderTrackItem.vue'
import { orderTrack as orderTrackApi } from '@/api/short_url'
const code = ref('')
const data: Ref<any> = ref({})
const activities = ref([])
const route = useRoute()
const loading = ref(false)
onMounted(() => {
code.value = route.query.code as string
getInfo()
})
function getInfo() {
loading.value = true
orderTrackApi(code.value).then((res: any) => {
data.value = res || {}
formatData(data.value)
}).finally(() => {
loading.value = false
})
}
function formatData(res: any) {
const tempData = res
//
const tempRes = tempData.sort((a, b) => {
return new Date(b.time).getTime() - new Date(a.time).getTime()
})
const tempNewRes = []
for (const i in tempRes) {
//
//
const tempv1 = tempRes[i]
const tempv2 = tempRes[parseInt(i) + 1]
if (tempv1?.status === 5000) {
// id
if (
tempv2?.status === 5000
&& tempv2?.order_id === tempv1?.order_id
)
continue
}
const msg = tempRes[i]
if (msg.msg.includes('已称完净重') && msg.msg.includes('等待打包')) {
const pattern = /已称完净重\(([\d\.?]+)g\),等待打包/
const matches = msg.msg.match(pattern)
if (matches)
msg.msg = `${'已称完净重'}(${matches[1]}g),${'等待打包'}`
}
tempNewRes.push(msg)
}
activities.value = tempNewRes
}
</script>
<template>
<van-steps direction="vertical" :active="0">
<OrderTrackItem v-for="(activity, index) in activities" :key="index" :activity="activity" />
</van-steps>
<Loading :loading="loading" />
</template>
<style lang="less" scoped></style>

170
src/views/short_url/printOrderInfo.vue

@ -1,170 +0,0 @@
<script lang="tsx" setup>
import { useRoute } from 'vue-router'
import type { Ref } from 'vue'
import { modelSize as _modelSize, printType } from './utils'
import { printOrderInfo as printOrderInfoApi } from '@/api/short_url'
import { filterMsgButton } from '@/dict/status_dict'
const code = ref('')
const src = ref('')
const data: Ref<any> = ref({})
const tags = ref([])
const loading = ref(false)
const modelSize = _modelSize
const route = useRoute()
onMounted(() => {
code.value = route.query.code as string
getInfo()
})
function getImage() {
src.value = ''
if (data.value.info && data.value.info.texture_cover_img)
src.value = `https://3dview.suwa3d.com/${data.value.info.texture_cover_img}`
}
function getTags() {
//
if (!data.value.info || !data.value.info.pid)
return
//
const arrTags = [];
//
[data.value].forEach((item: any) => {
const arrTag = []
//
if (item.is_expedited) {
//
arrTag.push('加急')
}
//
if (item.is_expires)
arrTag.push('超时')
const msg = printType(item.info.print_type)
if (!!msg && msg !== '正常')
arrTag.push(msg)
arrTags.push(arrTag)
})
tags.value = arrTags
}
function isSample() {
return data.value.order_tag_type === 'sample'
}
function getPrintTypeText() {
switch (data.value?.info?.print_type) {
case 1:
return '首次打印'
case 2:
return '重打'
case 3:
return '加打'
}
}
function getStatusText() {
return filterMsgButton(data.value?.info?.status, 'text')
}
function getInfo() {
loading.value = true
printOrderInfoApi(code.value).then((res: any) => {
data.value = res || {}
getImage()
getTags()
}).finally(() => {
loading.value = false
})
}
</script>
<template>
<van-cell-group title="基本信息">
<van-cell title="拍照订单">
<span>
{{ data?.info?.pid }}
</span>
</van-cell>
<van-cell title="尺寸*数量">
<van-tag v-for="(item, key) in modelSize(data?.info?.model_size)" :key="key" type="success" plain>
{{ item }}
</van-tag>
</van-cell>
<van-cell title="提交建模时间" :value="data.submit_model_time" />
<van-cell title="订单状态">
<van-tag type="success">
{{ loading ? '' : getStatusText() }}
</van-tag>
</van-cell>
<van-cell title="打印类型">
<van-tag v-if="isSample()" type="success">
样品
</van-tag>
<van-tag type="success">
{{ getPrintTypeText() }}
</van-tag>
</van-cell>
</van-cell-group>
<van-cell-group title=" ">
<van-cell title="商品金额">
<span>{{ data.goods_amount / 100 }} {{ data.currency }}</span>
</van-cell>
<van-cell v-if="data.other_fee_amount > 0 && data.other_fee_name" :title="`优惠金额(${data.other_fee_name})`">
<span>{{ data.other_fee_amount / 100 }} {{ data.currency }}</span>
</van-cell>
<van-cell title="总计">
<span>{{ data.total_amount / 100 }} {{ data.currency }}</span>
</van-cell>
</van-cell-group>
<van-cell-group title="门店客户信息">
<van-cell title="门店" :value="data?.info?.shop_name" />
<van-cell title="客户">
{{ data?.info?.customer_name }} (TEL:{{ data?.info?.customer_mobile }})
</van-cell>
<van-cell title="寄送地址">
<span>
{{ data?.info?.province_name }}
{{ data?.info?.city_name }}
{{ data?.info?.country_name }}
{{ data?.info?.address }}
</span>
</van-cell>
</van-cell-group>
<van-cell-group title="重量">
<van-cell title="毛重">
<span>{{ data?.info?.model_gross_weight }}g</span>
</van-cell>
<van-cell title="净重">
<span>{{ data?.info?.model_weight }}g</span>
</van-cell>
</van-cell-group>
<van-cell-group v-if="data.motherList && data.motherList.length > 0" title="其他">
<van-cell title="子母单">
<van-tag
v-for="(item, key) in data.motherList" :key="key" type="success"
class="mother-tag"
plain
>
{{ item.pid }}
</van-tag>
</van-cell>
</van-cell-group>
<Loading :loading="loading" />
</template>
<style lang="less" scoped>
.mother-tag{
margin-right: 0.4rem;
}
</style>

34
src/views/short_url/utils.ts

@ -1,34 +0,0 @@
export function printType(val: number) {
let type = ''
switch (val) {
case 1:
type = '正常打印'
break
case 2:
type = '重打'
break
case 3:
type = '加打'
break
case 4:
type = '样品'
break
default:
break
}
return type
}
export function modelSize(val: string) {
if (!val)
return ''
// 分割字符串
const arrV = val.split('__')
const data = []
arrV.forEach((item) => {
const temp = item.replace(/_x/g, '*').replace(/_/g, '')
data.push(temp)
})
return data
}

377
src/views/user/index.vue

@ -1,377 +0,0 @@
<template>
<van-popup v-model:show="actionShow" round position="bottom">
<van-picker
:columns="actions"
@cancel="actionShow = false"
@confirm="onSelect"
/>
</van-popup>
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" safe-area-inset-top/>
<div class="personalContainer">
<div class="user-section">
<div class="user-info-box" @click="toPerson">
<div class="portrait-box">
<img
class="portrait"
:src="headimgUrl"
/>
</div>
<div class="info-box" v-if="userInfo">
<div class="username">{{ nickname }}</div>
<van-icon class="arrow" name="arrow" size="18px" color="#767676" />
</div>
<div class="info-box" v-else>
<div @click="login" class="username">{{'请登录'.$t}}</div>
</div>
</div>
</div>
<!-- <div v-if="shootPerms" class="my_item" @click="takephoto" data-method="2">
<div class="item_wrap">
拍照
<div class="right_arrow" ></div>
</div>
</div>
<div class="my_item" @click="login" data-method="2">
<div class="item_wrap">
领取订单
<div class="right_arrow" ></div>
</div>
</div> -->
<!-- <div class="my_item" @click="toAddress" data-method="1">
<div class="item_wrap">
我的地址
<div class="right_arrow" ></div>
</div>
</div> -->
<!-- <div class="my_item">
<div class="item_wrap">
<button class="feedback" open-type="feedback">反馈意见</button>
<div class="right_arrow" ></div>
</div>
</div>
<div class="my_item">
<div class="item_wrap">
<button class="feedback" open-type="contact">在线客服</button>
<div class="right_arrow" ></div>
</div>
</div> -->
<!-- <div class="my_item" @click="toAbout">
<van-field
is-link
readonly
:label="'关于我们'.$t"
/>
</div> -->
<div class="my_item" @click="languageChange">
<van-field
v-model="fieldValue"
is-link
readonly
:label="'语言'.$t"
/>
</div>
<div class="version">
<div class="version_wrap">
<div>v1.0.0</div>
</div>
</div>
</div>
<Tabbar></Tabbar>
</template>
<script setup lang="ts">
import { useTranslation } from "i18next-vue";
// import { showFailToast, showToast, FormInstance } from 'vant'
import { localStorage } from '@/utils/local-storage'
import {useStore} from '@/stores'
import { useTokenStore } from '@/stores/token'
import {headimgurl, nickname as fNickname} from './utils';
import {set as setLang} from '@/lang/i18n';
import {toValueWithout} from '@/lang/utils';
const { i18next } = useTranslation();
// const { t, locale } = useI18n();
const userInfo = ref({})
const store = useStore();
const tokenStore = useTokenStore();
const {isWechat} = tokenStore;
const showAvaModal = ref(false)
const version = ref('')
const fieldValue = ref('简体中文');
const actionShow = ref(false);
const actions = ref([
{
id: 1,
value: "zh-CN",
text: "简体中文".$t,
},
{
id: 2,
value: "en",
text: '英文'.$t,
},
{
id: 3,
value: "zh-TW",
text: '繁体中文'.$t,
},
{
id: 4,
value: "ko",
text: '韩文'.$t,
},
]);
const nickname = computed(() => {
return fNickname();
});
const initLang = actions.value.find((e: any) => e.value == i18next.language) || actions.value[0];
fieldValue.value = initLang?.text;
const shootPerms = ref(false)
const router = useRouter()
const headimgUrl = computed(() => {
return headimgurl();
});
onMounted(()=> {
userInfo.value = tokenStore.userInfo;
shootPerms.value = tokenStore.userInfo.shootPerms;
// const accountInfo = wx.getAccountInfoSync();
// this.setData({ version: accountInfo.miniProgram.version || accountInfo.miniProgram.envVersion })
// this.setData({
// userInfo: userInfo,
// shootPerms: userInfo?.shootPerms == true,
// })
})
//
const languageChange = () => {
actionShow.value = !actionShow.value
}
//
const onSelect = ({selectedOptions}) => {
const lang = selectedOptions[0].value;
// locale.value = selectedOptions[0].value;
localStorage.set("i18nextLng", lang);
actionShow.value = false;
fieldValue.value = selectedOptions[0].text
console.log("fieldValue.value", fieldValue.value)
//
setLang(lang).then((data) => {
console.log('switch lang succeed', data)
store.updateTitle("个人中心".$t)
}).catch((e) => {
console.log('switch lang faield', e);
});
}
const login = (e) => {
//
// WxLogin(this)
// if (!IsLogin()) {
// this.setData({
// shootPerms: false
// });
// wx.navigateTo({
// url: '/pages/login/login',
// })
// return
// } else {
// let method = e.currentTarget.dataset.method;
// if (method == 1) {
// wx.navigateTo({
// url: "/packageAddress/pages/address/address?select=true"
// })
// } else if (method == 2) {
// wx.navigateTo({
// url: "/pages/receive/receive"
// })
// }
// }
}
//
const takephoto = () => {
// router.push({
// path: "/packageTakePhoto/pages/takePhoto/takePhoto"
// })
}
//
const toPerson = () => {
// if (IsLogin()) {
router.push({
path: '/person'
})
// } else {
// showToast("");
// setTimeout(() => {
// router.push({
// path: '/pages/login/login',
// })
// }, 1500)
// return
// }
}
const toAddress = () => {
router.push({
path: '/address'
})
}
const toAbout = () => {
router.push({
path: "/about"
})
}
</script>
<style lang="less" scoped>
.container {
/* height: 100%; */
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
/* padding: 200px 0; */
box-sizing: border-box;
background-color: rgba(245, 245, 245, 1.000000);
padding: 50px 0;
}
.feedback {
margin: 0;
padding: 0;
background-color: transparent;
width: 100%;
height: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
font-size: 16px;
font-weight: 400;
flex-grow: 1;
}
.userinfo {
display: flex;
/* flex-direction: column;
align-items: center; */
}
.personalContainer {
width: 100%;
height: 100%;
background-color: rgba(245, 245, 245, 1.000000);
}
.personalContainer .user-section {
height: 150px;
position: relative;
padding: 50px 15px 0;
}
.user-info-box {
height: 60px;
display: flex;
align-items: center;
position: relative;
z-index: 1;
.portrait {
width: 65px;
height: 65px;
border: 2.5px solid #fff;
border-radius: 50%;
}
.username {
font-size: 20px;
color: #333333;
margin-left: 10px;
font-weight: 700;
}
.info-box {
display: flex;
justify-content: center;
align-items: center;
.arrow {
margin-left: 10px;
}
}
}
.right_arrow {
border: solid gray;
border-width: 0 3px 3px 0;
padding: 3px;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.my_item {
width: 100%;
height: 50px;
display: flex;
background: #ffffff;
align-items: center;
border-bottom: 1px solid gainsboro;
.item_wrap {
display: flex;
justify-content: space-between;
align-items: center;
width: 90%;
margin: 0 auto;
}
}
.my_item button{line-height: 1.1;}
.my_item button::after{display: none;}
.button {
width: 100%;
background: white;
border: none;
text-align: left;
padding: 0px;
margin: 0 !important;
line-height: 1.3;
font-size: 16px;
font-weight: 400;
}
.button::after {
border: none;
border-radius: 0
}
.version {
display: flex;
width: 100%;
height: 50px;
color: #606266;
background: #ffffff;
.version_wrap {
display: flex;
justify-content: flex-start;
align-items: center;
width: 90%;
margin: 0 auto;
}
}
</style>

191
src/views/user/person.vue

@ -1,191 +0,0 @@
<template>
<van-nav-bar v-if="!isWechat()" :title="store.navTitle" left-text="返回" left-arrow
@click-left="returnClick" safe-area-inset-top/>
<div class="page">
<van-dialog
:title="'确认退出登录?'.$t"
v-model:show="dialogShow"
:confirmButtonText="'确认退出'.$t"
:cancelButtonText="'我再想想'.$t"
@confirm="onLogout"
showCancelButton
confirm-button-color="#AAAAAA"
cancel-button-color="#009944"
round
/>
<div class="container">
<div class="person-box">
<div class="column">
<div class="text">{{'头像'.$t}}</div>
<div class="avatar-box">
<img :src="headimgUrl" class="avatar"/>
</div>
</div>
<div class="column">
<div class="text">{{'账号'.$t}}</div>
<div class="nickname">{{ nickname }}</div>
<!-- <div class="input_box">
<input type="nickname" class="nickname" :value="userInfo.nickname"/>
</div> -->
</div>
<!-- <div class="column">
<div class="text">{{'性别'.$t}}</div>
<div class="sex">{{sex}}</div>
</div> -->
</div>
<div class="logout">
<div class="logout-btn" @click="showLogout">{{'退出登录'.$t}}</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useStore } from '@/stores';
import { useTokenStore } from '@/stores/token';
import { closeToast, showLoadingToast, showToast } from 'vant';
import {headimgurl, logout, nickname as fNickname} from './utils';
const store = useStore()
const tokenStore = useTokenStore()
const router = useRouter()
const {isWechat} = tokenStore;
const userInfo = ref("")
const dialogShow = ref(false)
const sex = ref("")
const headimgUrl = computed(() => {
return headimgurl();
});
const nickname = computed(() => {
return fNickname();
})
onMounted(()=> {
userInfo.value = tokenStore.userInfo;
let sexId = userInfo.value.sex;
switch(sexId) {
case 1: sex.value = "男";break;
case 2: sex.value = "女";break;
default: sex.value = "未知";break;
}
})
const returnClick = () => history.back();
// 退
const showLogout = () => {
dialogShow.value = true
}
// 退
const onLogout = () => {
showLoadingToast({message: "退出登录中...".$t, forbidClick: true,});
setTimeout(()=> {
// TODO: 退
tokenStore.logout();
logout();
// wx.removeStorage({
// key: 'authorization',
// })
router.push({
path: '/myOrder',
})
closeToast();
}, 1500)
}
</script>
<style lang="less" scoped>
.page {
width: 100vw;
min-height: 100vh;
box-sizing: border-box;
background-color: #F5F5F5;
/* 利用新增的 env() 和 constant() 特性,自动计算底部安全距离 */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* 可计算 */
// padding-bottom: calc(124px + env(safe-area-inset-bottom));
}
.container {
width: 100%;
padding: 15px 0;
height: auto;
.person-box {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
position: relative;
width: 345px;
height: 175px;
margin: 0 auto;
padding: 12px 0;
background: #ffffff;
border-radius: 8px;
.column {
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
width: 100%;
height: 56px;
padding: 9px 16px;
box-sizing: border-box;
.text {
color: #767676;
font-size: 16px;
font-weight: 400;
font-family: Source Han Sans CN-Regular;
}
.avatar-box {
position: relative;
width: 38px;
height: 38px;
border-radius: 16px;
overflow: hidden;
margin: 0;
padding: 0;
.avatar {
position: relative;
width: 100%;
height: 100%;
}
}
.input_box {
display: flex;
align-items: center;
min-width: 90px;
.nickname {
text-align: right;
appearance: none;
border: none;
}
}
}
}
.logout {
position: absolute;
bottom: 0%;
left: 50%;
width: 345px;
height: 192px;
margin-left: -172.5px;
.logout-btn {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 100%;
height: 42px;
background: #ffffff;
color: #F56C6C;
font-size: 16px;
font-family: Source Han Sans CN-Regular;
font-weight: 400;
border-radius: 8px;
}
}
}
</style>

34
src/views/user/utils.ts

@ -1,34 +0,0 @@
import defaultHeadimgUrl from '@/assets/common/avatar.png'
import { useTokenStore } from '@/stores/token'
import hello from 'hellojs'
export function headimgurl() {
const tokenStore = useTokenStore();
const user = tokenStore.userInfo;
if (user?.headimgurl) {
return user?.headimgurl;
}
return defaultHeadimgUrl;
}
export function nickname() {
const tokenStore = useTokenStore();
const user = tokenStore.userInfo;
console.log("tokenStore.userInfo", tokenStore.userInfo)
if (user.nickname) {
return user.nickname;
} else {
return user.social_type + user.id;
}
}
export function logout() {
const tokenStore = useTokenStore();
const user = tokenStore.userInfo;
const socialType = user.social_type;
if (!socialType) {
return Promise.reject('未知的登录方式');
}
return hello(socialType).logout();
}
Loading…
Cancel
Save