提交 3c8294ee authored 作者: lihuihui's avatar lihuihui
...@@ -12,20 +12,23 @@ ...@@ -12,20 +12,23 @@
"deploy": "node ./deploy.js" "deploy": "node ./deploy.js"
}, },
"dependencies": { "dependencies": {
"@vueuse/core": "^8.2.6",
"axios": "^0.26.1", "axios": "^0.26.1",
"blueimp-md5": "^2.19.0", "blueimp-md5": "^2.19.0",
"lodash-es": "^4.17.21",
"pinia": "^2.0.13", "pinia": "^2.0.13",
"qs": "^6.10.3", "qs": "^6.10.3",
"sass": "^1.50.0", "sass": "^1.50.0",
"swiper": "^8.1.0", "swiper": "^8.1.0",
"vant": "^3.4.7", "vant": "^3.4.7",
"vue": "^3.2.32", "vue": "^3.2.33",
"vue-router": "^4.0.14" "vue-router": "^4.0.14"
}, },
"devDependencies": { "devDependencies": {
"@rushstack/eslint-patch": "^1.1.2", "@rushstack/eslint-patch": "^1.1.3",
"@types/blueimp-md5": "^2.18.0", "@types/blueimp-md5": "^2.18.0",
"@types/node": "^17.0.23", "@types/lodash-es": "^4.17.6",
"@types/node": "^17.0.24",
"@types/qs": "^6.9.7", "@types/qs": "^6.9.7",
"@vitejs/plugin-vue": "^2.3.1", "@vitejs/plugin-vue": "^2.3.1",
"@vue/eslint-config-typescript": "^10.0.0", "@vue/eslint-config-typescript": "^10.0.0",
...@@ -33,8 +36,8 @@ ...@@ -33,8 +36,8 @@
"eslint": "^8.13.0", "eslint": "^8.13.0",
"eslint-plugin-vue": "^8.6.0", "eslint-plugin-vue": "^8.6.0",
"typescript": "~4.6.3", "typescript": "~4.6.3",
"vite": "^2.9.4", "vite": "^2.9.5",
"vite-plugin-checker": "^0.4.5", "vite-plugin-checker": "^0.4.6",
"vue-tsc": "^0.34.6" "vue-tsc": "^0.34.6"
} }
} }
lockfileVersion: 5.3 lockfileVersion: 5.3
specifiers: specifiers:
'@rushstack/eslint-patch': ^1.1.2 '@rushstack/eslint-patch': ^1.1.3
'@types/blueimp-md5': ^2.18.0 '@types/blueimp-md5': ^2.18.0
'@types/node': ^17.0.23 '@types/lodash-es': ^4.17.6
'@types/node': ^17.0.24
'@types/qs': ^6.9.7 '@types/qs': ^6.9.7
'@vitejs/plugin-vue': ^2.3.1 '@vitejs/plugin-vue': ^2.3.1
'@vue/eslint-config-typescript': ^10.0.0 '@vue/eslint-config-typescript': ^10.0.0
'@vue/tsconfig': ^0.1.3 '@vue/tsconfig': ^0.1.3
'@vueuse/core': ^8.2.6
axios: ^0.26.1 axios: ^0.26.1
blueimp-md5: ^2.19.0 blueimp-md5: ^2.19.0
eslint: ^8.13.0 eslint: ^8.13.0
eslint-plugin-vue: ^8.6.0 eslint-plugin-vue: ^8.6.0
lodash-es: ^4.17.21
pinia: ^2.0.13 pinia: ^2.0.13
qs: ^6.10.3 qs: ^6.10.3
sass: ^1.50.0 sass: ^1.50.0
swiper: ^8.1.0 swiper: ^8.1.0
typescript: ~4.6.3 typescript: ~4.6.3
vant: ^3.4.7 vant: ^3.4.7
vite: ^2.9.4 vite: ^2.9.5
vite-plugin-checker: ^0.4.5 vite-plugin-checker: ^0.4.6
vue: ^3.2.32 vue: ^3.2.33
vue-router: ^4.0.14 vue-router: ^4.0.14
vue-tsc: ^0.34.6 vue-tsc: ^0.34.6
dependencies: dependencies:
'@vueuse/core': 8.2.6_vue@3.2.33
axios: 0.26.1 axios: 0.26.1
blueimp-md5: 2.19.0 blueimp-md5: 2.19.0
pinia: 2.0.13_typescript@4.6.3+vue@3.2.32 lodash-es: 4.17.21
pinia: 2.0.13_typescript@4.6.3+vue@3.2.33
qs: 6.10.3 qs: 6.10.3
sass: 1.50.0 sass: 1.50.0
swiper: 8.1.0 swiper: 8.1.0
vant: 3.4.7_vue@3.2.32 vant: 3.4.7_vue@3.2.33
vue: 3.2.32 vue: 3.2.33
vue-router: 4.0.14_vue@3.2.32 vue-router: 4.0.14_vue@3.2.33
devDependencies: devDependencies:
'@rushstack/eslint-patch': 1.1.2 '@rushstack/eslint-patch': 1.1.3
'@types/blueimp-md5': 2.18.0 '@types/blueimp-md5': 2.18.0
'@types/node': 17.0.23 '@types/lodash-es': 4.17.6
'@types/node': 17.0.24
'@types/qs': 6.9.7 '@types/qs': 6.9.7
'@vitejs/plugin-vue': 2.3.1_vite@2.9.4+vue@3.2.32 '@vitejs/plugin-vue': 2.3.1_vite@2.9.5+vue@3.2.33
'@vue/eslint-config-typescript': 10.0.0_a62cbc2f4797496d74696b1f6538012a '@vue/eslint-config-typescript': 10.0.0_a62cbc2f4797496d74696b1f6538012a
'@vue/tsconfig': 0.1.3_@types+node@17.0.23 '@vue/tsconfig': 0.1.3_@types+node@17.0.24
eslint: 8.13.0 eslint: 8.13.0
eslint-plugin-vue: 8.6.0_eslint@8.13.0 eslint-plugin-vue: 8.6.0_eslint@8.13.0
typescript: 4.6.3 typescript: 4.6.3
vite: 2.9.4_sass@1.50.0 vite: 2.9.5_sass@1.50.0
vite-plugin-checker: 0.4.5_vite@2.9.4 vite-plugin-checker: 0.4.6_vite@2.9.5
vue-tsc: 0.34.6_typescript@4.6.3 vue-tsc: 0.34.6_typescript@4.6.3
packages: packages:
...@@ -135,8 +141,8 @@ packages: ...@@ -135,8 +141,8 @@ packages:
resolution: {integrity: sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==} resolution: {integrity: sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==}
dev: false dev: false
/@rushstack/eslint-patch/1.1.2: /@rushstack/eslint-patch/1.1.3:
resolution: {integrity: sha512-oe5WJEDaVsW8fBlGT7udrSCgOwWfoYHQOmSpnh8X+0GXpqqcRCP8k4y+Dxb0taWJDPpB+rdDUtumIiBwkY9qGA==} resolution: {integrity: sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw==}
dev: true dev: true
/@types/blueimp-md5/2.18.0: /@types/blueimp-md5/2.18.0:
...@@ -147,8 +153,18 @@ packages: ...@@ -147,8 +153,18 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true dev: true
/@types/node/17.0.23: /@types/lodash-es/4.17.6:
resolution: {integrity: sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==} resolution: {integrity: sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==}
dependencies:
'@types/lodash': 4.14.181
dev: true
/@types/lodash/4.14.181:
resolution: {integrity: sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==}
dev: true
/@types/node/17.0.24:
resolution: {integrity: sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==}
dev: true dev: true
/@types/qs/6.9.7: /@types/qs/6.9.7:
...@@ -295,15 +311,15 @@ packages: ...@@ -295,15 +311,15 @@ packages:
resolution: {integrity: sha512-3z+nywPaV2F5BdJO7RQxWlgfzJeEOmViD2yHMb7Tg+R4NR/7iQskqW8v2Cnv9FWSJgTOSHlcr7UzeLpiTAP4HA==} resolution: {integrity: sha512-3z+nywPaV2F5BdJO7RQxWlgfzJeEOmViD2yHMb7Tg+R4NR/7iQskqW8v2Cnv9FWSJgTOSHlcr7UzeLpiTAP4HA==}
dev: false dev: false
/@vitejs/plugin-vue/2.3.1_vite@2.9.4+vue@3.2.32: /@vitejs/plugin-vue/2.3.1_vite@2.9.5+vue@3.2.33:
resolution: {integrity: sha512-YNzBt8+jt6bSwpt7LP890U1UcTOIZZxfpE5WOJ638PNxSEKOqAi0+FSKS0nVeukfdZ0Ai/H7AFd6k3hayfGZqQ==} resolution: {integrity: sha512-YNzBt8+jt6bSwpt7LP890U1UcTOIZZxfpE5WOJ638PNxSEKOqAi0+FSKS0nVeukfdZ0Ai/H7AFd6k3hayfGZqQ==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
peerDependencies: peerDependencies:
vite: ^2.5.10 vite: ^2.5.10
vue: ^3.2.25 vue: ^3.2.25
dependencies: dependencies:
vite: 2.9.4_sass@1.50.0 vite: 2.9.5_sass@1.50.0
vue: 3.2.32 vue: 3.2.33
dev: true dev: true
/@volar/code-gen/0.34.6: /@volar/code-gen/0.34.6:
...@@ -352,6 +368,16 @@ packages: ...@@ -352,6 +368,16 @@ packages:
'@vue/shared': 3.2.32 '@vue/shared': 3.2.32
estree-walker: 2.0.2 estree-walker: 2.0.2
source-map: 0.6.1 source-map: 0.6.1
dev: true
/@vue/compiler-core/3.2.33:
resolution: {integrity: sha512-AAmr52ji3Zhk7IKIuigX2osWWsb2nQE5xsdFYjdnmtQ4gymmqXbjLvkSE174+fF3A3kstYrTgGkqgOEbsdLDpw==}
dependencies:
'@babel/parser': 7.17.9
'@vue/shared': 3.2.33
estree-walker: 2.0.2
source-map: 0.6.1
dev: false
/@vue/compiler-dom/3.2.31: /@vue/compiler-dom/3.2.31:
resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==} resolution: {integrity: sha512-60zIlFfzIDf3u91cqfqy9KhCKIJgPeqxgveH2L+87RcGU/alT6BRrk5JtUso0OibH3O7NXuNOQ0cDc9beT0wrg==}
...@@ -365,6 +391,14 @@ packages: ...@@ -365,6 +391,14 @@ packages:
dependencies: dependencies:
'@vue/compiler-core': 3.2.32 '@vue/compiler-core': 3.2.32
'@vue/shared': 3.2.32 '@vue/shared': 3.2.32
dev: true
/@vue/compiler-dom/3.2.33:
resolution: {integrity: sha512-GhiG1C8X98Xz9QUX/RlA6/kgPBWJkjq0Rq6//5XTAGSYrTMBgcLpP9+CnlUg1TFxnnCVughAG+KZl28XJqw8uQ==}
dependencies:
'@vue/compiler-core': 3.2.33
'@vue/shared': 3.2.33
dev: false
/@vue/compiler-sfc/3.2.31: /@vue/compiler-sfc/3.2.31:
resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==} resolution: {integrity: sha512-748adc9msSPGzXgibHiO6T7RWgfnDcVQD+VVwYgSsyyY8Ans64tALHZANrKtOzvkwznV/F4H7OAod/jIlp/dkQ==}
...@@ -381,15 +415,15 @@ packages: ...@@ -381,15 +415,15 @@ packages:
source-map: 0.6.1 source-map: 0.6.1
dev: true dev: true
/@vue/compiler-sfc/3.2.32: /@vue/compiler-sfc/3.2.33:
resolution: {integrity: sha512-uO6+Gh3AVdWm72lRRCjMr8nMOEqc6ezT9lWs5dPzh1E9TNaJkMYPaRtdY9flUv/fyVQotkfjY/ponjfR+trPSg==} resolution: {integrity: sha512-H8D0WqagCr295pQjUYyO8P3IejM3vEzeCO1apzByAEaAR/WimhMYczHfZVvlCE/9yBaEu/eu9RdiWr0kF8b71Q==}
dependencies: dependencies:
'@babel/parser': 7.17.9 '@babel/parser': 7.17.9
'@vue/compiler-core': 3.2.32 '@vue/compiler-core': 3.2.33
'@vue/compiler-dom': 3.2.32 '@vue/compiler-dom': 3.2.33
'@vue/compiler-ssr': 3.2.32 '@vue/compiler-ssr': 3.2.33
'@vue/reactivity-transform': 3.2.32 '@vue/reactivity-transform': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
estree-walker: 2.0.2 estree-walker: 2.0.2
magic-string: 0.25.9 magic-string: 0.25.9
postcss: 8.4.12 postcss: 8.4.12
...@@ -403,11 +437,11 @@ packages: ...@@ -403,11 +437,11 @@ packages:
'@vue/shared': 3.2.31 '@vue/shared': 3.2.31
dev: true dev: true
/@vue/compiler-ssr/3.2.32: /@vue/compiler-ssr/3.2.33:
resolution: {integrity: sha512-ZklVUF/SgTx6yrDUkaTaBL/JMVOtSocP+z5Xz/qIqqLdW/hWL90P+ob/jOQ0Xc/om57892Q7sRSrex0wujOL2Q==} resolution: {integrity: sha512-XQh1Xdk3VquDpXsnoCd7JnMoWec9CfAzQDQsaMcSU79OrrO2PNR0ErlIjm/mGq3GmBfkQjzZACV+7GhfRB8xMQ==}
dependencies: dependencies:
'@vue/compiler-dom': 3.2.32 '@vue/compiler-dom': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
dev: false dev: false
/@vue/devtools-api/6.1.4: /@vue/devtools-api/6.1.4:
...@@ -441,12 +475,12 @@ packages: ...@@ -441,12 +475,12 @@ packages:
magic-string: 0.25.9 magic-string: 0.25.9
dev: true dev: true
/@vue/reactivity-transform/3.2.32: /@vue/reactivity-transform/3.2.33:
resolution: {integrity: sha512-CW1W9zaJtE275tZSWIfQKiPG0iHpdtSlmTqYBu7Y62qvtMgKG5yOxtvBs4RlrZHlaqFSE26avLAgQiTp4YHozw==} resolution: {integrity: sha512-4UL5KOIvSQb254aqenW4q34qMXbfZcmEsV/yVidLUgvwYQQ/D21bGX3DlgPUGI3c4C+iOnNmDCkIxkILoX/Pyw==}
dependencies: dependencies:
'@babel/parser': 7.17.9 '@babel/parser': 7.17.9
'@vue/compiler-core': 3.2.32 '@vue/compiler-core': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
estree-walker: 2.0.2 estree-walker: 2.0.2
magic-string: 0.25.9 magic-string: 0.25.9
dev: false dev: false
...@@ -457,35 +491,35 @@ packages: ...@@ -457,35 +491,35 @@ packages:
'@vue/shared': 3.2.31 '@vue/shared': 3.2.31
dev: true dev: true
/@vue/reactivity/3.2.32: /@vue/reactivity/3.2.33:
resolution: {integrity: sha512-4zaDumuyDqkuhbb63hRd+YHFGopW7srFIWesLUQ2su/rJfWrSq3YUvoKAJE8Eu1EhZ2Q4c1NuwnEreKj1FkDxA==} resolution: {integrity: sha512-62Sq0mp9/0bLmDuxuLD5CIaMG2susFAGARLuZ/5jkU1FCf9EDbwUuF+BO8Ub3Rbodx0ziIecM/NsmyjardBxfQ==}
dependencies: dependencies:
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
dev: false dev: false
/@vue/runtime-core/3.2.32: /@vue/runtime-core/3.2.33:
resolution: {integrity: sha512-uKKzK6LaCnbCJ7rcHvsK0azHLGpqs+Vi9B28CV1mfWVq1F3Bj8Okk3cX+5DtD06aUh4V2bYhS2UjjWiUUKUF0w==} resolution: {integrity: sha512-N2D2vfaXsBPhzCV3JsXQa2NECjxP3eXgZlFqKh4tgakp3iX6LCGv76DLlc+IfFZq+TW10Y8QUfeihXOupJ1dGw==}
dependencies: dependencies:
'@vue/reactivity': 3.2.32 '@vue/reactivity': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
dev: false dev: false
/@vue/runtime-dom/3.2.32: /@vue/runtime-dom/3.2.33:
resolution: {integrity: sha512-AmlIg+GPqjkNoADLjHojEX5RGcAg+TsgXOOcUrtDHwKvA8mO26EnLQLB8nylDjU6AMJh2CIYn8NEgyOV5ZIScQ==} resolution: {integrity: sha512-LSrJ6W7CZTSUygX5s8aFkraDWlO6K4geOwA3quFF2O+hC3QuAMZt/0Xb7JKE3C4JD4pFwCSO7oCrZmZ0BIJUnw==}
dependencies: dependencies:
'@vue/runtime-core': 3.2.32 '@vue/runtime-core': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
csstype: 2.6.20 csstype: 2.6.20
dev: false dev: false
/@vue/server-renderer/3.2.32_vue@3.2.32: /@vue/server-renderer/3.2.33_vue@3.2.33:
resolution: {integrity: sha512-TYKpZZfRJpGTTiy/s6bVYwQJpAUx3G03z4G7/3O18M11oacrMTVHaHjiPuPqf3xQtY8R4LKmQ3EOT/DRCA/7Wg==} resolution: {integrity: sha512-4jpJHRD4ORv8PlbYi+/MfP8ec1okz6rybe36MdpkDrGIdEItHEUyaHSKvz+ptNEyQpALmmVfRteHkU9F8vxOew==}
peerDependencies: peerDependencies:
vue: 3.2.32 vue: 3.2.33
dependencies: dependencies:
'@vue/compiler-ssr': 3.2.32 '@vue/compiler-ssr': 3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
vue: 3.2.32 vue: 3.2.33
dev: false dev: false
/@vue/shared/3.2.31: /@vue/shared/3.2.31:
...@@ -494,8 +528,13 @@ packages: ...@@ -494,8 +528,13 @@ packages:
/@vue/shared/3.2.32: /@vue/shared/3.2.32:
resolution: {integrity: sha512-bjcixPErUsAnTQRQX4Z5IQnICYjIfNCyCl8p29v1M6kfVzvwOICPw+dz48nNuWlTOOx2RHhzHdazJibE8GSnsw==} resolution: {integrity: sha512-bjcixPErUsAnTQRQX4Z5IQnICYjIfNCyCl8p29v1M6kfVzvwOICPw+dz48nNuWlTOOx2RHhzHdazJibE8GSnsw==}
dev: true
/@vue/shared/3.2.33:
resolution: {integrity: sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg==}
dev: false
/@vue/tsconfig/0.1.3_@types+node@17.0.23: /@vue/tsconfig/0.1.3_@types+node@17.0.24:
resolution: {integrity: sha512-kQVsh8yyWPvHpb8gIc9l/HIDiiVUy1amynLNpCy8p+FoCiZXCo6fQos5/097MmnNZc9AtseDsCrfkhqCrJ8Olg==} resolution: {integrity: sha512-kQVsh8yyWPvHpb8gIc9l/HIDiiVUy1amynLNpCy8p+FoCiZXCo6fQos5/097MmnNZc9AtseDsCrfkhqCrJ8Olg==}
peerDependencies: peerDependencies:
'@types/node': '*' '@types/node': '*'
...@@ -503,9 +542,45 @@ packages: ...@@ -503,9 +542,45 @@ packages:
'@types/node': '@types/node':
optional: true optional: true
dependencies: dependencies:
'@types/node': 17.0.23 '@types/node': 17.0.24
dev: true dev: true
/@vueuse/core/8.2.6_vue@3.2.33:
resolution: {integrity: sha512-fzlpM3B5oVe+UhCT1mXlhG1Zxdq2lq1Z2AvddSB8+RxrsSFzII7DKfsQEz8Vop7Lzc++4m8drTNbhPovYoFqHw==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue:
optional: true
dependencies:
'@vueuse/metadata': 8.2.6
'@vueuse/shared': 8.2.6_vue@3.2.33
vue: 3.2.33
vue-demi: 0.12.5_vue@3.2.33
dev: false
/@vueuse/metadata/8.2.6:
resolution: {integrity: sha512-OBKtafCt+4RcEJlYDCjp1vl65pBCL2g4TmipEtdZ8/qphKlW6nakJbkY7XRN5grPmjqU99/ahJGtyGk5NHS2hw==}
dev: false
/@vueuse/shared/8.2.6_vue@3.2.33:
resolution: {integrity: sha512-J/W4CMfdL8TahELuSOgtfVO4eQXTjhigp7dVWIBsLUVFCeY9d49gvHUcQN3y5xYLZ6iNP57TjTQjMMT/zhklkw==}
peerDependencies:
'@vue/composition-api': ^1.1.0
vue: ^2.6.0 || ^3.2.0
peerDependenciesMeta:
'@vue/composition-api':
optional: true
vue:
optional: true
dependencies:
vue: 3.2.33
vue-demi: 0.12.5_vue@3.2.33
dev: false
/acorn-jsx/5.3.2_acorn@8.7.0: /acorn-jsx/5.3.2_acorn@8.7.0:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies: peerDependencies:
...@@ -1324,6 +1399,10 @@ packages: ...@@ -1324,6 +1399,10 @@ packages:
type-check: 0.4.0 type-check: 0.4.0
dev: true dev: true
/lodash-es/4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
dev: false
/lodash.debounce/4.0.8: /lodash.debounce/4.0.8:
resolution: {integrity: sha1-gteb/zCmfEAF/9XiUVMArZyk168=} resolution: {integrity: sha1-gteb/zCmfEAF/9XiUVMArZyk168=}
dev: true dev: true
...@@ -1448,7 +1527,7 @@ packages: ...@@ -1448,7 +1527,7 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
/pinia/2.0.13_typescript@4.6.3+vue@3.2.32: /pinia/2.0.13_typescript@4.6.3+vue@3.2.33:
resolution: {integrity: sha512-B7rSqm1xNpwcPMnqns8/gVBfbbi7lWTByzS6aPZ4JOXSJD4Y531rZHDCoYWBwLyHY/8hWnXljgiXp6rRyrofcw==} resolution: {integrity: sha512-B7rSqm1xNpwcPMnqns8/gVBfbbi7lWTByzS6aPZ4JOXSJD4Y531rZHDCoYWBwLyHY/8hWnXljgiXp6rRyrofcw==}
peerDependencies: peerDependencies:
'@vue/composition-api': ^1.4.0 '@vue/composition-api': ^1.4.0
...@@ -1462,8 +1541,8 @@ packages: ...@@ -1462,8 +1541,8 @@ packages:
dependencies: dependencies:
'@vue/devtools-api': 6.1.4 '@vue/devtools-api': 6.1.4
typescript: 4.6.3 typescript: 4.6.3
vue: 3.2.32 vue: 3.2.33
vue-demi: 0.12.5_vue@3.2.32 vue-demi: 0.12.5_vue@3.2.33
dev: false dev: false
/postcss/8.4.12: /postcss/8.4.12:
...@@ -1705,7 +1784,7 @@ packages: ...@@ -1705,7 +1784,7 @@ packages:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
dev: true dev: true
/vant/3.4.7_vue@3.2.32: /vant/3.4.7_vue@3.2.33:
resolution: {integrity: sha512-/iafbNF3VPcDevIun8DMj84V9sGMcBZ2LW8j20uqthW6NpFmkMpDFJxMINQFIZ0myEogqVSDVhS6XFAwlx3nkQ==} resolution: {integrity: sha512-/iafbNF3VPcDevIun8DMj84V9sGMcBZ2LW8j20uqthW6NpFmkMpDFJxMINQFIZ0myEogqVSDVhS6XFAwlx3nkQ==}
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
...@@ -1713,11 +1792,11 @@ packages: ...@@ -1713,11 +1792,11 @@ packages:
'@vant/icons': 1.8.0 '@vant/icons': 1.8.0
'@vant/popperjs': 1.1.0 '@vant/popperjs': 1.1.0
'@vant/use': 1.3.6 '@vant/use': 1.3.6
vue: 3.2.32 vue: 3.2.33
dev: false dev: false
/vite-plugin-checker/0.4.5_vite@2.9.4: /vite-plugin-checker/0.4.6_vite@2.9.5:
resolution: {integrity: sha512-kCfVzfGzK4D/G6vGPpAffpg9e57AlxUFOjMTr4qEiZpqHyy4ejBNi6OD1UzKn+ZIrWryLKMhjxjQ8hkwns45xA==} resolution: {integrity: sha512-oFel33hlsc8aUspfq0ThQRpWsfrG772fmZ5qPHKUhmew6ieejd2viITlwXHIRBY6hE3U0kirXoTWwft3DdbK+g==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
vite: ^2.0.0 vite: ^2.0.0
...@@ -1733,15 +1812,15 @@ packages: ...@@ -1733,15 +1812,15 @@ packages:
npm-run-path: 4.0.1 npm-run-path: 4.0.1
strip-ansi: 6.0.1 strip-ansi: 6.0.1
tiny-invariant: 1.2.0 tiny-invariant: 1.2.0
vite: 2.9.4_sass@1.50.0 vite: 2.9.5_sass@1.50.0
vscode-languageclient: 7.0.0 vscode-languageclient: 7.0.0
vscode-languageserver: 7.0.0 vscode-languageserver: 7.0.0
vscode-languageserver-textdocument: 1.0.4 vscode-languageserver-textdocument: 1.0.4
vscode-uri: 3.0.3 vscode-uri: 3.0.3
dev: true dev: true
/vite/2.9.4_sass@1.50.0: /vite/2.9.5_sass@1.50.0:
resolution: {integrity: sha512-7pO6ruZMsyTpaPB7kGtW+yj15Ze5g+E4w4Ramk1sAJLIuI4uPd5sauqubmZNpq0Yc1vLVxoXRf2Uj+qWxk5aXw==} resolution: {integrity: sha512-dvMN64X2YEQgSXF1lYabKXw3BbN6e+BL67+P3Vy4MacnY+UzT1AfkHiioFSi9+uiDUiaDy7Ax/LQqivk6orilg==}
engines: {node: '>=12.2.0'} engines: {node: '>=12.2.0'}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
...@@ -1805,7 +1884,7 @@ packages: ...@@ -1805,7 +1884,7 @@ packages:
resolution: {integrity: sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==} resolution: {integrity: sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==}
dev: true dev: true
/vue-demi/0.12.5_vue@3.2.32: /vue-demi/0.12.5_vue@3.2.33:
resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==} resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==}
engines: {node: '>=12'} engines: {node: '>=12'}
hasBin: true hasBin: true
...@@ -1817,7 +1896,7 @@ packages: ...@@ -1817,7 +1896,7 @@ packages:
'@vue/composition-api': '@vue/composition-api':
optional: true optional: true
dependencies: dependencies:
vue: 3.2.32 vue: 3.2.33
dev: false dev: false
/vue-eslint-parser/8.3.0_eslint@8.13.0: /vue-eslint-parser/8.3.0_eslint@8.13.0:
...@@ -1838,13 +1917,13 @@ packages: ...@@ -1838,13 +1917,13 @@ packages:
- supports-color - supports-color
dev: true dev: true
/vue-router/4.0.14_vue@3.2.32: /vue-router/4.0.14_vue@3.2.33:
resolution: {integrity: sha512-wAO6zF9zxA3u+7AkMPqw9LjoUCjSxfFvINQj3E/DceTt6uEz1XZLraDhdg2EYmvVwTBSGlLYsUw8bDmx0754Mw==} resolution: {integrity: sha512-wAO6zF9zxA3u+7AkMPqw9LjoUCjSxfFvINQj3E/DceTt6uEz1XZLraDhdg2EYmvVwTBSGlLYsUw8bDmx0754Mw==}
peerDependencies: peerDependencies:
vue: ^3.2.0 vue: ^3.2.0
dependencies: dependencies:
'@vue/devtools-api': 6.1.4 '@vue/devtools-api': 6.1.4
vue: 3.2.32 vue: 3.2.33
dev: false dev: false
/vue-tsc/0.34.6_typescript@4.6.3: /vue-tsc/0.34.6_typescript@4.6.3:
...@@ -1857,14 +1936,14 @@ packages: ...@@ -1857,14 +1936,14 @@ packages:
typescript: 4.6.3 typescript: 4.6.3
dev: true dev: true
/vue/3.2.32: /vue/3.2.33:
resolution: {integrity: sha512-6L3jKZApF042OgbCkh+HcFeAkiYi3Lovi8wNhWqIK98Pi5efAMLZzRHgi91v+60oIRxdJsGS9sTMsb+yDpY8Eg==} resolution: {integrity: sha512-si1ExAlDUrLSIg/V7D/GgA4twJwfsfgG+t9w10z38HhL/HA07132pUQ2KuwAo8qbCyMJ9e6OqrmWrOCr+jW7ZQ==}
dependencies: dependencies:
'@vue/compiler-dom': 3.2.32 '@vue/compiler-dom': 3.2.33
'@vue/compiler-sfc': 3.2.32 '@vue/compiler-sfc': 3.2.33
'@vue/runtime-dom': 3.2.32 '@vue/runtime-dom': 3.2.33
'@vue/server-renderer': 3.2.32_vue@3.2.32 '@vue/server-renderer': 3.2.33_vue@3.2.33
'@vue/shared': 3.2.32 '@vue/shared': 3.2.33
dev: false dev: false
/which/2.0.2: /which/2.0.2:
......
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { ref, computed, nextTick } from 'vue'
import { ImagePreview } from 'vant' import { ImagePreview } from 'vant'
const props = defineProps<{ data: any }>() const props = defineProps<{ data: any }>()
const emit = defineEmits(['submitComment', 'load'])
const imageList = computed<string[]>(() => { const imageList = computed<string[]>(() => {
try { try {
...@@ -10,9 +11,41 @@ const imageList = computed<string[]>(() => { ...@@ -10,9 +11,41 @@ const imageList = computed<string[]>(() => {
return [] return []
} }
}) })
const onImagePreview = function (index: number) { // 图片预览
const onImagePreview = (index: number) => {
ImagePreview({ images: imageList.value, startPosition: index }) ImagePreview({ images: imageList.value, startPosition: index })
} }
// 评论
const commentInput = ref<HTMLElement | null>(null)
const commentVisible = ref<boolean>(false)
const commentValue = ref<string>()
const commentActive = ref<any>()
const commentPlaceholder = computed(() => {
return commentActive.value ? `回复${commentActive.value?.user_info?.name}:` : '评论'
})
// 显示评论输入框
const showComment = (data?: any) => {
commentActive.value = data
commentVisible.value = true
nextTick(() => {
commentInput.value?.focus()
})
}
const hideComment = () => {
commentVisible.value = false
commentValue.value = ''
}
// 提交评论
const onSubmitComment = (data: any) => {
data.comment = commentActive.value ? commentPlaceholder.value + data.comment : data.comment
emit(
'submitComment',
Object.assign({}, commentActive.value || props.data, data),
commentActive.value ? 'reply' : 'comment'
)
hideComment()
}
</script> </script>
<template> <template>
...@@ -30,18 +63,32 @@ const onImagePreview = function (index: number) { ...@@ -30,18 +63,32 @@ const onImagePreview = function (index: number) {
</ul> </ul>
<div class="publish-tools"> <div class="publish-tools">
<p class="t1">{{ data.created_time }}</p> <p class="t1">{{ data.created_time }}</p>
<p class="t2">评论</p> <p class="t2" @click="showComment()">评论</p>
</div> </div>
<!-- 评论 --> <!-- 评论 -->
<div class="publish-comments" v-if="data.comments.total"> <div class="publish-comments" v-if="data.comments.total">
<div class="comment-item" v-for="item in data.comments.list" :key="item.id"> <div class="comment-item" v-for="item in data.comments.list" :key="item.id" @click="showComment(item)">
<div class="comment-item-hd">{{ item.user_name }}</div> <div class="comment-item-hd">{{ item.user_name }}</div>
<div class="comment-item-bd">{{ item.content }}</div> <div class="comment-item-bd">{{ item.content }}</div>
</div> </div>
<div class="comment-more">查看{{ data.comments.total }}条评论 <van-icon name="arrow" /></div> <div class="comment-more" v-if="data.comments.total > data.comments.list.length" @click="$emit('load')">
查看{{ data.comments.total }}条评论 <van-icon name="arrow" />
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="comment" v-if="commentVisible">
<van-form @submit="onSubmitComment">
<van-field
v-model="commentValue"
name="comment"
:placeholder="commentPlaceholder"
autosize
ref="commentInput"
@blur="hideComment"
/>
</van-form>
</div>
</template> </template>
<style lang="scss"> <style lang="scss">
...@@ -103,9 +150,13 @@ const onImagePreview = function (index: number) { ...@@ -103,9 +150,13 @@ const onImagePreview = function (index: number) {
color: #999999; color: #999999;
} }
.t2 { .t2 {
padding-left: 0.38rem;
font-size: 0.24rem; font-size: 0.24rem;
color: #999999; color: #999999;
line-height: 0.36rem; line-height: 0.36rem;
background: url('https://webapp-pub.ezijing.com/project/prp-h5/icon_comment.png') no-repeat left center;
background-size: 0.26rem;
cursor: pointer;
} }
} }
.publish-comments { .publish-comments {
...@@ -136,4 +187,12 @@ const onImagePreview = function (index: number) { ...@@ -136,4 +187,12 @@ const onImagePreview = function (index: number) {
border-top: 0.01rem solid #d3d3d3; border-top: 0.01rem solid #d3d3d3;
cursor: pointer; cursor: pointer;
} }
.comment {
position: fixed;
left: 0;
right: 0;
bottom: 0;
box-shadow: 0 0 29px #0000001a;
z-index: 1000;
}
</style> </style>
...@@ -10,6 +10,7 @@ import AppContainer from '@/components/base/AppContainer.vue' ...@@ -10,6 +10,7 @@ import AppContainer from '@/components/base/AppContainer.vue'
import Avatar from '@/components/Avatar.vue' import Avatar from '@/components/Avatar.vue'
import modules from './modules' import modules from './modules'
import { useUserStore } from '@/stores/user'
const app = createApp(App) const app = createApp(App)
// 注册公共组件 // 注册公共组件
...@@ -22,3 +23,6 @@ app.use(router) ...@@ -22,3 +23,6 @@ app.use(router)
app.use(Vant) app.use(Vant)
app.mount('#app') app.mount('#app')
// 初始化用户信息,判断是否登录
useUserStore().getUser()
import httpRequest from '@/utils/axios' import httpRequest from '@/utils/axios'
// 获取课程列表 // 获取课程列表
export function getCourseList(params: { page_size: number; page: number }) { export function getCourseList(params?: { page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/learning/course-list', { params }) return httpRequest.get('/api/psp/v1/learning/course-list', { params })
} }
...@@ -14,13 +14,24 @@ export function getCourseView(params: { id: string }) { ...@@ -14,13 +14,24 @@ export function getCourseView(params: { id: string }) {
export function getChapterView(params: { chapter_id: string; page_size?: number; page?: number }) { export function getChapterView(params: { chapter_id: string; page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/learning/chapter-view', { params }) return httpRequest.get('/api/psp/v1/learning/chapter-view', { params })
} }
// 打卡
export function coursePublish(data: { // 课程章节打卡
export function createCourseRecord(data: {
chapter_id: string chapter_id: string
course_id: string course_id: string
content: string content: string
title?: string picture?: string
file?: string file?: string
}) { }) {
return httpRequest.post('/api/psp/v1/learning/upload', data) return httpRequest.post('/api/psp/v1/learning/upload', data)
} }
// 打卡记录评论
export function createCourseComment(data: { entity_id: string; to_comment_id?: string; content: string }) {
return httpRequest.post('/api/psp/v1/learning/comment', data)
}
// 获取打卡记录评论
export function getRecordComment(params: { id: string; page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/learning/record-comments', { params })
}
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { useInfiniteScroll } from '@vueuse/core'
import ChapterItemRecord from './ChapterItemRecord.vue'
import { getChapterView } from '../api'
interface Info {
loading: boolean
page: number
total: number
list: any[]
}
const props = defineProps<{ courseId: string; data: any }>()
// 章节详情
const chapterVisible = ref<boolean>(false)
const dataset = reactive<Info>({ loading: false, page: 1, total: 0, list: [] })
// 查看本章所有打卡记录
const showChapterRecord = () => {
chapterVisible.value = true
dataset.page = 1
dataset.list = []
getChapterRecord()
}
// 获取章节打卡记录
const getChapterRecord = () => {
dataset.loading = true
getChapterView({ chapter_id: props.data.id, page: dataset.page, page_size: 10 })
.then(res => {
const { total, list } = res.data
dataset.total = total
dataset.list = dataset.list.concat(list)
if (dataset.list.length <= total) {
dataset.page++
}
})
.finally(() => {
dataset.loading = false
})
}
// 滚动加载
const el = ref<HTMLElement>()
useInfiniteScroll(
el,
() => {
!dataset.loading && getChapterRecord()
},
{ distance: 10 }
)
</script>
<template>
<div class="course-chapter-item">
<h2 class="chapter-title">{{ data.chapter_name }}</h2>
<ChapterItemRecord v-for="publish in data.records.list" :data="publish" :key="publish.id"></ChapterItemRecord>
<div class="chapter-view" @click="showChapterRecord">查看本章所有打卡记录</div>
</div>
<van-popup v-model:show="chapterVisible" round position="bottom" :style="{ height: '80%' }">
<div class="course-chapter" ref="el">
<ChapterItemRecord v-for="publish in dataset.list" :data="publish" :key="publish.id"></ChapterItemRecord>
<van-button
block
round
class="my-button button-fixed"
:to="{ path: '/course/publish', query: { course_id: courseId, chapter_id: data.id } }"
>我也要拍照得星星</van-button
>
</div>
</van-popup>
</template>
<style lang="scss">
.chapter-title {
margin-bottom: 0.22rem;
font-size: 0.28rem;
font-weight: bold;
color: #333333;
line-height: 0.28rem;
}
.chapter-view {
padding: 0.36rem 0;
font-size: 0.24rem;
color: #033974;
line-height: 0.36rem;
text-align: center;
border-top: 0.01rem solid #d3d3d3;
cursor: pointer;
}
.course-chapter {
height: 100%;
overflow-y: auto;
padding: 0.38rem 0.24rem 1rem;
box-sizing: border-box;
}
.button-fixed {
position: fixed;
bottom: 0.2rem;
left: 0.2rem;
right: 0.2rem;
width: auto;
}
</style>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { uniqWith } from 'lodash-es'
import PublishItem from '@/components/PublishItem.vue'
import { getRecordComment, createCourseComment } from '../api'
const props = defineProps<{ data: any }>()
const page = ref<number>(1)
const dataset = reactive(props.data)
// 数据合并
const mergeList = (arr: any[], arr2: any[]) => {
return uniqWith(arr.concat(arr2), (a, b) => a.id === b.id)
}
// 获取打卡评论
const getRecordCommentList = () => {
getRecordComment({ id: props.data.id, page: page.value, page_size: 5 }).then(res => {
const { total, list } = res.data.comments
dataset.comments.total = total
dataset.comments.list = page.value === 1 ? list : mergeList(dataset.comments.list, list)
})
}
// 评论
const onSubmitComment = (data: any, action: string) => {
const params =
action === 'comment'
? { entity_id: data.id, content: data.comment } // 评论
: { entity_id: data.entity_id, content: data.comment, to_comment_id: data.id } // 回复
createCourseComment(params).then(() => {
page.value = 1
getRecordCommentList()
})
}
const onLoadMore = () => {
page.value++
getRecordCommentList()
}
</script>
<template>
<PublishItem :data="dataset" :key="dataset.id" @submitComment="onSubmitComment" @load="onLoadMore"></PublishItem>
</template>
...@@ -8,7 +8,7 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -8,7 +8,7 @@ export const routes: Array<RouteRecordRaw> = [
children: [ children: [
{ path: '', component: () => import('./views/Index.vue') }, { path: '', component: () => import('./views/Index.vue') },
{ name: 'courseView', path: 'view/:id', component: () => import('./views/View.vue'), props: true }, { name: 'courseView', path: 'view/:id', component: () => import('./views/View.vue'), props: true },
{ path: 'publish', component: () => import('./views/Publish.vue') } { path: 'publish', component: () => import('./views/Publish.vue'), meta: { requireLogin: true } }
] ]
} }
] ]
<script setup lang="ts"> <script setup lang="ts">
import { reactive } from 'vue' import { reactive } from 'vue'
import { useRouter, useRoute } from 'vue-router' import { useRouter, useRoute } from 'vue-router'
import { coursePublish } from '../api' import { createCourseRecord } from '../api'
import UploadImageList from '@/components/UploadImageList.vue' import UploadImageList from '@/components/UploadImageList.vue'
import { Toast } from 'vant' import { Toast } from 'vant'
const router = useRouter() const router = useRouter()
...@@ -12,7 +12,7 @@ const form = reactive({ ...{ chapter_id: '', course_id: '', content: '', picture ...@@ -12,7 +12,7 @@ const form = reactive({ ...{ chapter_id: '', course_id: '', content: '', picture
const pictureValidator = () => !!form.picture.length const pictureValidator = () => !!form.picture.length
function onSubmit() { function onSubmit() {
const params = Object.assign({}, form, { picture: JSON.stringify(form.picture) }) const params = Object.assign({}, form, { picture: JSON.stringify(form.picture) })
coursePublish(params).then(() => { createCourseRecord(params).then(() => {
Toast.success('发布成功') Toast.success('发布成功')
router.push({ name: 'courseView', params: { id: form.course_id } }) router.push({ name: 'courseView', params: { id: form.course_id } })
}) })
...@@ -40,7 +40,7 @@ function onSubmit() { ...@@ -40,7 +40,7 @@ function onSubmit() {
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .van-cell { :deep(.van-cell) {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
&::after { &::after {
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { Toast } from 'vant' import { Toast } from 'vant'
import PublishItem from '@/components/PublishItem.vue' import ChapterItem from '../components/ChapterItem.vue'
import { getCourseView, getChapterView } from '../api' import { getCourseView } from '../api'
const props = defineProps<{ id: string }>() const props = defineProps<{ id: string }>()
// 课程 // 课程
const data = ref() const data = ref()
function getCourse() { const getCourse = () => {
const toast = Toast.loading({ message: '加载中...', forbidClick: true }) const toast = Toast.loading({ message: '加载中...', forbidClick: true })
getCourseView({ id: props.id }).then(res => { getCourseView({ id: props.id }).then(res => {
data.value = res.data.course data.value = res.data.course
toast.clear() toast.clear()
}) })
} }
onMounted(getCourse) onMounted(() => {
getCourse()
// 章节 })
const show = ref<boolean>(false)
// 当前选中的章节
const activeChapter = ref()
// 打卡记录
const chapterRecord = ref<{ total: number; list: any[] }>({ total: 0, list: [] })
// 获取章节打卡记录
const getChapterRecord = function () {
const toast = Toast.loading({ message: '加载中...', forbidClick: true })
const params = {
chapter_id: activeChapter.value.id
}
getChapterView(params).then(res => {
chapterRecord.value = res.data
toast.clear()
})
}
const showChapterRecord = function (data: any) {
activeChapter.value = data
show.value = true
getChapterRecord()
}
</script> </script>
<template> <template>
...@@ -53,8 +33,8 @@ const showChapterRecord = function (data: any) { ...@@ -53,8 +33,8 @@ const showChapterRecord = function (data: any) {
<span>{{ data.course_chapters.small_total }}课时</span> <span>{{ data.course_chapters.small_total }}课时</span>
</li> </li>
<li class="l2"> <li class="l2">
<span>{{ data.course_chapters.big_total }}人看过</span> <span>{{ data.pv }}人看过</span>
<span>{{ data.course_chapters.small_total }}人评论</span> <span>{{ data.records_total }}人评论</span>
</li> </li>
</ul> </ul>
<div class="star"> <div class="star">
...@@ -75,26 +55,10 @@ const showChapterRecord = function (data: any) { ...@@ -75,26 +55,10 @@ const showChapterRecord = function (data: any) {
<div class="course-bottom"> <div class="course-bottom">
<div class="course-tips">如果你也是知识获得者,请晒出你的海报、说出你的感想,得到你的星星。</div> <div class="course-tips">如果你也是知识获得者,请晒出你的海报、说出你的感想,得到你的星星。</div>
<div class="course-chapters"> <div class="course-chapters">
<div class="course-chapter-item" v-for="item in data.course_chapters.list" :key="item.id"> <ChapterItem v-for="item in data.course_chapters.list" :courseId="id" :data="item" :key="item.id"></ChapterItem>
<h2 class="chapter-title">{{ item.chapter_name }}</h2>
<PublishItem v-for="publish in item.records.list" :data="publish" :key="publish.id"></PublishItem>
<div class="chapter-view" @click="showChapterRecord(item)">查看本章所有打卡记录</div>
</div>
</div>
</div> </div>
</div> </div>
<van-popup v-model:show="show" round position="bottom" :style="{ height: '80%' }">
<div class="course-chapter">
<PublishItem v-for="publish in chapterRecord.list" :data="publish" :key="publish.id"></PublishItem>
<van-button
block
round
class="my-button"
:to="{ path: '/course/publish', query: { course_id: id, chapter_id: activeChapter.id } }"
>我也要拍照得星星</van-button
>
</div> </div>
</van-popup>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -140,12 +104,14 @@ const showChapterRecord = function (data: any) { ...@@ -140,12 +104,14 @@ const showChapterRecord = function (data: any) {
margin: 0.07rem 0; margin: 0.07rem 0;
p { p {
display: inline-block; display: inline-block;
padding: 0 0.15rem; padding: 0 0.15rem 0 0.38rem;
height: 0.3rem; height: 0.3rem;
font-size: 0.2rem; font-size: 0.2rem;
line-height: 0.3rem; line-height: 0.3rem;
border-radius: 0.15rem; border-radius: 0.15rem;
border: 0.01rem solid #80b0e5; border: 0.01rem solid #80b0e5;
background: url('https://webapp-pub.ezijing.com/project/prp-h5/icon_star.png') no-repeat 0.1rem center;
background-size: 0.22rem;
b { b {
color: #033974; color: #033974;
} }
...@@ -193,25 +159,5 @@ const showChapterRecord = function (data: any) { ...@@ -193,25 +159,5 @@ const showChapterRecord = function (data: any) {
background-color: #fff; background-color: #fff;
border-top-left-radius: 0.2rem; border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem; border-top-right-radius: 0.2rem;
.chapter-title {
margin-bottom: 0.22rem;
font-size: 0.28rem;
font-weight: bold;
color: #333333;
line-height: 0.28rem;
}
}
.chapter-view {
margin-bottom: 0.56rem;
padding: 0.16rem 0;
font-size: 0.24rem;
color: #033974;
line-height: 0.36rem;
text-align: center;
border-top: 0.01rem solid #d3d3d3;
cursor: pointer;
}
.course-chapter {
padding: 0.38rem 0.24rem;
} }
</style> </style>
...@@ -5,11 +5,21 @@ export function getHomeData() { ...@@ -5,11 +5,21 @@ export function getHomeData() {
return httpRequest.get('/api/psp/v1/index/index') return httpRequest.get('/api/psp/v1/index/index')
} }
// 获取导学视频列表 // 获取导学视频列表
export function getVideoList(params?: { page_size: number; page: number }) { export function getVideoList(params?: { page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/learning/video-list', { params }) return httpRequest.get('/api/psp/v1/learning/video-list', { params })
} }
// 获取导学视频详情
export function getVideoView(params: { id: string }) {
return httpRequest.get('/api/psp/v1/learning/video-view', { params })
}
// 获取课程列表 // 获取课程列表
export function getCourseList(params?: { page_size: number; page: number }) { export function getCourseList(params?: { page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/learning/course-list', { params }) return httpRequest.get('/api/psp/v1/learning/course-list', { params })
} }
// 陪伴问答评论
export function createQuestionComment(data: { question_id: string; to_comment_id?: string; content: string }) {
return httpRequest.post('/api/psp/v1/question/create-comment', data)
}
...@@ -3,31 +3,16 @@ import { Swiper, SwiperSlide } from 'swiper/vue' ...@@ -3,31 +3,16 @@ import { Swiper, SwiperSlide } from 'swiper/vue'
import { Pagination } from 'swiper' import { Pagination } from 'swiper'
import 'swiper/css' import 'swiper/css'
import 'swiper/css/pagination' import 'swiper/css/pagination'
import type { IBanner } from '../types'
const list: Array<{ defineProps<{ list: IBanner[] }>()
url: string
imageUrl: string
}> = [
{
url: '/',
imageUrl: 'https://webapp-pub.ezijing.com/project/prp-h5/banner.png'
},
{
url: '/',
imageUrl: 'https://webapp-pub.ezijing.com/project/prp-h5/banner.png'
},
{
url: '/',
imageUrl: 'https://webapp-pub.ezijing.com/project/prp-h5/banner.png'
}
]
</script> </script>
<template> <template>
<nav class="home-banner"> <nav class="home-banner">
<Swiper pagination :modules="[Pagination]"> <Swiper pagination :modules="[Pagination]">
<SwiperSlide v-for="(item, index) in list" :key="index"> <SwiperSlide v-for="(item, index) in list" :key="index">
<img :src="item.imageUrl" /> <img :src="item.cover_page" />
</SwiperSlide> </SwiperSlide>
</Swiper> </Swiper>
</nav> </nav>
......
...@@ -7,12 +7,12 @@ import { getCourseList } from '../api' ...@@ -7,12 +7,12 @@ import { getCourseList } from '../api'
// 学习进度 // 学习进度
const dataset = ref<{ total: number; list: ICourseItem[] }>({ total: 0, list: [] }) const dataset = ref<{ total: number; list: ICourseItem[] }>({ total: 0, list: [] })
function fetchCourseList() { const fetchCourseList = () => {
getCourseList().then(res => { getCourseList({ page_size: 100 }).then(res => {
dataset.value = res.data dataset.value = res.data
}) })
} }
const studyStatus = function (progress: number) { const studyStatus = (progress: number) => {
if (progress === 100) { if (progress === 100) {
return '已完成' return '已完成'
} else if (progress > 0) { } else if (progress > 0) {
...@@ -72,6 +72,7 @@ onMounted(() => { ...@@ -72,6 +72,7 @@ onMounted(() => {
flex: 1; flex: 1;
margin-left: 0.26rem; margin-left: 0.26rem;
line-height: 0.33rem; line-height: 0.33rem;
overflow: hidden;
h5 { h5 {
font-size: 0.24rem; font-size: 0.24rem;
font-weight: 500; font-weight: 500;
......
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, computed, onMounted } from 'vue'
import { Swiper, SwiperSlide } from 'swiper/vue' import { Swiper, SwiperSlide } from 'swiper/vue'
import 'swiper/css' import 'swiper/css'
import type { IVideoItem } from '../types' import type { IVideoItem } from '../types'
import { getVideoList } from '../api' import { getVideoList, getVideoView } from '../api'
// 课程导学 // 课程导学
const dataset = ref<{ total: number; list: IVideoItem[] }>({ total: 0, list: [] }) const dataset = ref<{ total: number; list: IVideoItem[] }>({ total: 0, list: [] })
function fetchVideoList() { const fetchVideoList = () => {
getVideoList().then(res => { getVideoList({ page_size: 100 }).then(res => {
dataset.value = res.data dataset.value = res.data
}) })
} }
onMounted(() => { onMounted(() => {
fetchVideoList() fetchVideoList()
}) })
// 查看详情
const dialogVisible = ref<boolean>(false)
const videoInfo = ref<IVideoItem>()
const videoUrl = computed(() => {
if (videoInfo.value) {
// 优先取mp4
const [first = {}] = videoInfo.value.play_info.filter(item => item.Format === 'mp4')
return first.PlayURL
}
return ''
})
const fetchVideoView = (id: string) => {
getVideoView({ id }).then(res => {
videoInfo.value = res.data
})
}
const onClick = (data: IVideoItem) => {
fetchVideoView(data.id)
dialogVisible.value = true
}
</script> </script>
<template> <template>
<swiper slides-per-view="auto" :space-between="10"> <swiper slides-per-view="auto" :space-between="10">
<swiper-slide v-for="(item, index) in dataset.list" :key="index" class="video-item"> <swiper-slide v-for="(item, index) in dataset.list" :key="index" class="video-item" @click="onClick(item)">
<img :src="item.cover_page" /> <img :src="item.cover_page" />
<h5>{{ item.course_name }}</h5> <h5>{{ item.course_name }}</h5>
<p>{{ item.pv }}播放</p> <p>{{ item.pv }}播放</p>
</swiper-slide> </swiper-slide>
</swiper> </swiper>
<van-popup v-model:show="dialogVisible" round>
<div class="video-wrap" v-if="dialogVisible">
<video controls autoplay :src="videoUrl"></video>
</div>
</van-popup>
</template> </template>
<style lang="scss"> <style lang="scss">
...@@ -54,4 +80,12 @@ onMounted(() => { ...@@ -54,4 +80,12 @@ onMounted(() => {
color: #999999; color: #999999;
} }
} }
.video-wrap {
width: 80vw;
margin: 0.2rem;
video {
width: 100%;
max-height: 80vh;
}
}
</style> </style>
<script setup lang="ts"> <script setup lang="ts">
import { Toast } from 'vant'
import PublishItem from '@/components/PublishItem.vue' import PublishItem from '@/components/PublishItem.vue'
import { createQuestionComment } from '../api'
defineProps<{ data: any }>() defineProps<{ data: any }>()
// 评论
const onSubmitComment = (data: any, action: string) => {
if (action === 'comment') {
// 评论
createQuestionComment({
question_id: data.id,
content: data.comment
}).then(() => {
Toast.success('评论成功')
})
} else {
// 回复
createQuestionComment({
question_id: data.entity_id,
content: data.comment,
to_comment_id: data.id
}).then(() => {
Toast.success('回复成功')
})
}
}
</script> </script>
<template> <template>
<AppCard title="陪伴问答" id="qa"> <AppCard title="陪伴问答" id="qa">
<template #header-aside> <template #header-aside>
<div class="button">发表问答</div> <div class="button"><router-link to="/qa/publish">发表问答</router-link></div>
</template> </template>
<PublishItem v-for="item in data.list" :data="item" :key="item.id"></PublishItem> <PublishItem v-for="item in data.list" :data="item" :key="item.id" @submitComment="onSubmitComment"></PublishItem>
</AppCard> </AppCard>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .publish-item { :deep(.publish-item) {
padding: 0.24rem; padding: 0.24rem;
margin-bottom: 0.2rem; margin-bottom: 0.2rem;
background: #fff; background: #fff;
......
...@@ -12,6 +12,7 @@ export interface IBanner { ...@@ -12,6 +12,7 @@ export interface IBanner {
id: string id: string
title: string title: string
pv: string pv: string
cover_page: string
} }
export interface IDocItem { export interface IDocItem {
......
...@@ -18,7 +18,7 @@ const data = ref<HomeInfo>({ ...@@ -18,7 +18,7 @@ const data = ref<HomeInfo>({
questions: {} questions: {}
}) })
// 获取首页数据 // 获取首页数据
function fetchHomeData() { const fetchHomeData = () => {
api.getHomeData().then(res => { api.getHomeData().then(res => {
data.value = res.data data.value = res.data
}) })
......
...@@ -5,6 +5,7 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -5,6 +5,7 @@ export const routes: Array<RouteRecordRaw> = [
{ {
path: '/my', path: '/my',
component: AppLayout, component: AppLayout,
meta: { requireLogin: true },
children: [{ path: '', component: () => import('./views/Index.vue') }] children: [{ path: '', component: () => import('./views/Index.vue') }]
} }
] ]
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { getMyInfo } from '../api' import { getMyInfo } from '../api'
import { logout } from '@/api/base'
const info = ref() const info = ref()
const teamInfo = ref() const teamInfo = ref()
function fetchMyInfo() { const fetchMyInfo = () => {
getMyInfo().then(res => { getMyInfo().then(res => {
info.value = res.data.info || {} info.value = res.data.info || {}
teamInfo.value = res.data.team_info || { star: 0 } teamInfo.value = res.data.team_info || { star: 0 }
...@@ -50,6 +50,13 @@ const menus: Array<{ ...@@ -50,6 +50,13 @@ const menus: Array<{
icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_6.png' icon: 'https://webapp-pub.ezijing.com/project/prp-h5/my_menu_6.png'
} }
] ]
// 退出登录
const onLogout = () => {
logout().then(() => {
window.location.href = '/'
})
}
</script> </script>
<template> <template>
<div class="my" v-if="info"> <div class="my" v-if="info">
...@@ -79,7 +86,7 @@ const menus: Array<{ ...@@ -79,7 +86,7 @@ const menus: Array<{
</ul> </ul>
</nav> </nav>
</div> </div>
<div class="logout">退出登录</div> <div class="logout" @click="onLogout">退出登录</div>
</div> </div>
</template> </template>
......
import httpRequest from '@/utils/axios'
// 获取问答列表
export function getQuestionList(params?: { page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/question/list', { params })
}
// 获取问答详情
export function getQuestionView(params: { id: string; page_size?: number; page?: number }) {
return httpRequest.get('/api/psp/v1/question/view', { params })
}
// 发布问答
export function createQuestion(data: { title: string; desc: string; picture?: string; file?: string }) {
return httpRequest.post('/api/psp/v1/question/create-question', data)
}
// 发布问答评论
export function createQuestionComment(data: { question_id: string; to_comment_id?: string; content: string }) {
return httpRequest.post('/api/psp/v1/question/create-comment', data)
}
...@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [ ...@@ -5,6 +5,9 @@ export const routes: Array<RouteRecordRaw> = [
{ {
path: '/qa', path: '/qa',
component: AppLayout, component: AppLayout,
children: [{ path: '', component: () => import('./views/Index.vue') }] children: [
{ path: '', component: () => import('./views/Index.vue') },
{ path: 'publish', component: () => import('./views/Publish.vue'), meta: { requireLogin: true } }
]
} }
] ]
<script setup lang="ts">
import { reactive } from 'vue'
import { useRouter } from 'vue-router'
import { createQuestion } from '../api'
import UploadImageList from '@/components/UploadImageList.vue'
import { Toast } from 'vant'
const router = useRouter()
const form = reactive({ title: '', desc: '', picture: [] })
function onSubmit() {
const params = Object.assign({}, form, { picture: JSON.stringify(form.picture) })
createQuestion(params).then(() => {
Toast.success('发布成功')
router.push({ path: '/#qa' })
})
}
</script>
<template>
<AppContainer title="发布问题" backgroundColor="#fff" headerAlign="center">
<van-form @submit="onSubmit">
<van-field
v-model="form.title"
placeholder="请输入问题标题"
:rules="[{ required: true, message: '请输入问题标题' }]"
/>
<van-field
v-model="form.desc"
type="textarea"
placeholder="请输入问题内容"
:autosize="{ minHeight: 200 }"
:rules="[{ required: true, message: '请输入问题内容' }]"
/>
<van-field>
<template #input>
<UploadImageList v-model="form.picture"></UploadImageList>
</template>
</van-field>
<van-button block round native-type="submit" class="my-button">发布</van-button>
</van-form>
</AppContainer>
</template>
<style lang="scss" scoped>
:deep(.van-cell) {
padding-left: 0;
padding-right: 0;
&::after {
left: 0;
right: 0;
}
}
.my-button {
margin: 1rem 0;
}
</style>
import httpRequest from '@/utils/axios'
// 查询名片
export function getBussinessCard(params: unknown) {
return httpRequest.get('/api/psp/v1/welfare/get-card',{params})
}
// 获取验证码
export function getPhoneCode(params: unknown) {
return httpRequest.get('/api/psp/v1/welfare/send-code',{params})
}
// 查询证书
export function getCertificate(params: unknown) {
return httpRequest.get('/api/psp/v1/welfare/get-certificate',{params})
}
// 持证人权益-持证人列表
export function getLicenseList() {
return httpRequest.post('/api/psp/v1/welfare/avatar-list')
}
// 获取用户信息
export function getUserInfo() {
return httpRequest.post('/api/psp/v1/my/info')
}
<script setup lang="ts">
import * as api from '../api'
import { reactive, onMounted } from 'vue'
const FormInfo = reactive({
email: '',
address: ''
})
const userInfo = reactive({
name: '',
mobile: '',
certificate_number: ''
})
onMounted(() => {
getUserInfo()
})
// 获取用户信息
function getUserInfo() {
api.getUserInfo().then(res => {
userInfo.name = res.data.info.name
userInfo.mobile = res.data.info.mobile
userInfo.certificate_number = res.data.info.certificate_number
})
}
// 查询名片
function handleSubmit() {
const params: unknown = {
email: FormInfo.email,
address: FormInfo.address
}
api.getBussinessCard(params).then(res => {
console.log(res, '0000')
})
}
</script>
<template>
<div class="main_content">
<van-form>
<van-cell-group inset>
<van-field
v-model="userInfo.name"
name="姓名"
label="姓名"
placeholder="请输入姓名"
:rules="[{ required: true, message: '请输入姓名' }]"
disabled
/>
<van-field
v-model="userInfo.mobile"
name="手机号"
label="手机号"
placeholder="请输入手机号"
:rules="[{ required: true, message: '请输入手机号' }]"
disabled
/>
<van-field
v-model="userInfo.certificate_number"
name="证书号"
label="证书号"
placeholder="请输入证书号"
:rules="[{ required: true, message: '请输入证书号' }]"
disabled
/>
<van-field
v-model="FormInfo.email"
name="邮箱"
label="邮箱"
placeholder="请输入邮箱"
:rules="[{ required: true, message: '请输入邮箱' }]"
/>
<van-field
v-model="FormInfo.address"
name="地址"
label="地址"
placeholder="请输入地址"
:rules="[{ required: true, message: '请输入地址' }]"
/>
</van-cell-group>
<div style="margin-top: 0.93rem">
<van-button
round
block
native-type="submit"
style="background: linear-gradient(149deg, #f7c988 0%, #e5a448 100%)"
@click="handleSubmit"
:disabled="FormInfo.email === '' || FormInfo.address === ''"
>
确认信息正确,查询名片
</van-button>
</div>
</van-form>
<template>
<div class="main_content_card"></div>
<div class="main_content_bottom"></div>
</template>
</div>
</template>
<style lang="scss" scoped>
.main_content {
height: 8.02rem;
padding: 0.23rem 0.3rem 0 0.3rem;
background: #ffffff;
border-radius: 0.2rem;
.main_content_card {
margin: 0.83rem 0.38rem 0 0.34rem;
height: 3.22rem;
background-color: red;
}
.main_content_bottom {
height: 3.28rem;
margin-top: 0.66rem;
// background-color: red;
background: url(https://webapp-pub.oss-cn-beijing.aliyuncs.com/prp_h5/card_img.png) no-repeat;
background-size: 100% 100%;
}
}
::v-deep .van-button {
font-size: 0.28rem;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #ffffff;
}
</style>
<script setup lang="ts">
// import type { FormInfo } from '../types'
import { Toast } from 'vant'
import * as api from '../api'
import { ref, reactive } from 'vue'
const FormInfo = reactive({
phone: '',
code: ''
})
const url = ref('')
const time = ref(60)
const isDisposed = ref(false)
const isShowForm = ref(false)
function getCode() {
console.log('00000', FormInfo.phone)
if (FormInfo.phone === '') {
console.log('1111')
Toast('请输入手机号')
console.log('2222')
return
}
const params: unknown = {
phone: FormInfo.phone
}
api.getPhoneCode(params).then(res => {
console.log('获取验证码结果', res)
console.log('验证码发送成功!')
isDisposed.value = true
handleTimeChange()
})
}
// 倒计时
const handleTimeChange = () => {
if (time.value <= 0) {
isDisposed.value = false
time.value = 60
} else {
setTimeout(() => {
time.value--
handleTimeChange()
}, 1000)
}
}
// 查询名片
function handleQuery() {
const params: unknown = {
phone: FormInfo.phone,
code: FormInfo.code
}
api.getCertificate(params).then(res => {
url.value = res.data.url
console.log(res.data.url, 'res.data.url')
})
}
// 他人代查
function handleOther() {
isShowForm.value = true
}
</script>
<template>
<div class="main_content">
<van-form v-if="url === '' || isShowForm">
<van-cell-group inset>
<van-field
v-model="FormInfo.phone"
name="手机号"
label="手机号"
placeholder="请输入手机号"
:rules="[{ required: true, message: '请输入手机号' }]"
/>
<!-- <van-field
v-model="FormInfo.code"
name="验证码"
label="验证码"
placeholder="请输入验证码"
/> -->
<van-field
v-model="FormInfo.code"
center
clearable
label="验证码"
placeholder="请输入验证码"
:rules="[{ required: true, message: '请输入验证码' }]"
>
<template #button>
<van-button size="small" type="primary" round block @click="getCode" :disabled="isDisposed">{{
isDisposed ? `${time}s后重新获取` : '获取验证码'
}}</van-button>
</template>
</van-field>
</van-cell-group>
<div style="margin-top: 0.93rem">
<van-button
round
block
native-type="submit"
style="background: linear-gradient(149deg, #f7c988 0%, #e5a448 100%)"
@click="handleQuery"
:disabled="FormInfo.code === '' || FormInfo.code === ''"
>
确认信息正确,查询名片
</van-button>
</div>
</van-form>
<div class="main_content_card" v-else-if="url !== '' || !isShowForm">
<img :src="url" alt="" class="main_content_card_img" />
<div class="main_content_card_btn" @click="handleOther">他人代查</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.main_content {
// width: 6.9rem;
height: 8.02rem;
padding: 0.23rem 0.3rem 0 0.3rem;
background: #ffffff;
border-radius: 0.2rem;
.main_content_card {
.main_content_card_img {
width: 100%;
display: block;
}
.main_content_card_btn {
width: 1.18rem;
height: 0.4rem;
background: linear-gradient(164deg, #f7c988 0%, #e5a448 100%);
border-radius: 0.2rem;
opacity: 1;
font-size: 0.22rem;
font-weight: 400;
color: #ffffff;
line-height: 0.4rem;
text-align: center;
float: right;
margin-top: 0.34rem;
}
}
}
::v-deep {
.van-button {
font-size: 0.28rem;
font-family: PingFang SC-Regular, PingFang SC;
font-weight: 400;
color: #ffffff;
}
.van-field__control {
margin-left: -0.4rem !important;
}
// .van-cell {
// padding: var(--van-cell-horizontal-padding);
// }
// :root {
// --van-cell-horizontal-padding: var(--van-padding-md);
// }
// :root {
// --van-padding-md: 7px !important;
// }
}
</style>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import * as api from '../api'
import type { licenseeList } from '../types'
const data = ref<licenseeList>({
list: []
})
onMounted(() => {
// 获取持证人列表
handleLicenseList()
})
// 获取持证人列表
const handleLicenseList = () => {
api.getLicenseList().then(res => {
data.value = res.data
})
}
</script>
<template>
<div class="main_content">
<div v-if="data.list.length > 0">
<div class="main_content_list" v-for="(item, index) in data.list" :key="index">
<img class="img_top" :src="item.avatar" />
<div class="img_bottom">
<div class="img_bottom_people">{{ item.batch_name }}</div>
<div class="img_bottom_name">{{ item.name }}</div>
<div class="img_bottom_cardnum">证书编号</div>
<div class="img_bottom_num">{{ item.certificate_number }}</div>
</div>
</div>
</div>
<van-empty v-else description="暂无持证人" />
</div>
</template>
<style lang="scss" scoped>
.main_content {
height: 8.02rem;
padding: 0.23rem 0.31rem 0 0.31rem;
background: #ffffff;
border-radius: 0.2rem;
display: flex;
justify-content: space-around;
// align-items: center;
flex-wrap: wrap;
.main_content_list {
width: 45%;
height: 4.54rem;
margin-top: 0.2rem;
border-radius: 0.2rem;
box-sizing: border-box;
.img_top {
width: 100%;
height: 2.6rem;
background: red;
border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem;
}
.img_bottom {
height: 1.94rem;
border-bottom-left-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
padding-left: 0.21rem;
padding-top: 0.15rem;
background: url(https://webapp-pub.ezijing.com/prp_h5/license_bg.png) no-repeat;
background-size: contain;
.img_bottom_people {
font-size: 0.24rem;
font-weight: 400;
color: #ffffff;
}
.img_bottom_name {
font-size: 0.32rem;
font-weight: 500;
color: #cfb181;
margin-top: 0.1rem;
}
.img_bottom_cardnum {
font-size: 0.24rem;
font-weight: 400;
color: #ffffff;
margin-top: 0.2rem;
}
.img_bottom_num {
font-size: 0.28rem;
font-weight: 400;
color: #cfb181;
margin-top: 0.1rem;
}
}
}
}
</style>
export interface FormInfo {
name: string
mobile: string
cardNumber: string
email: string
address: string
}
export interface Ilist {
avatar: string
name: string
batch_name:string
certificate_number: string
}
export interface licenseeList {
list: Ilist[]
}
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import BusinessBusinessCardQuery from '../components/BusinessCardQuery.vue'
import CertificateQuery from '../components/CertificateQuery.vue'
import LicenseeView from '../components/LicenseeView.vue'
const active = ref<number>(0) const active = ref<number>(0)
</script> </script>
...@@ -13,9 +17,17 @@ const active = ref<number>(0) ...@@ -13,9 +17,17 @@ const active = ref<number>(0)
title-inactive-color="#4E4E4E" title-inactive-color="#4E4E4E"
line-height="0" line-height="0"
> >
<van-tab title="名片查询"> </van-tab> <van-tab title="名片查询&nbsp;&nbsp;&nbsp;|"><BusinessBusinessCardQuery /> </van-tab>
<van-tab title="证书查询"> </van-tab> <van-tab title="证书查询&nbsp;&nbsp;&nbsp;|"> <CertificateQuery /></van-tab>
<van-tab title="持证人查看"> </van-tab>
<van-tab title="&nbsp;持证人查看"><LicenseeView /> </van-tab>
</van-tabs> </van-tabs>
</AppContainer> </AppContainer>
</template> </template>
<style lang="scss" scoped>
.van-tab {
font-size: 0.26rem;
font-weight: 400;
color: #868686;
}
</style>
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
// import { useUserStore } from '@/stores/user' import { useUserStore } from '@/stores/user'
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes: [{ path: '/:pathMatch(.*)*', redirect: '/' }] routes: [{ path: '/:pathMatch(.*)*', redirect: '/' }]
}) })
// router.beforeEach((to, from, next) => { router.beforeEach(async (to, from, next) => {
// const user = useUserStore() const user = useUserStore()
// user.getUser() if (to.meta.requireLogin && !user.isLogin) {
// next() location.href = `${import.meta.env.VITE_LOGIN_URL}?rd=${encodeURIComponent(location.href)}`
// }) }
next()
})
export default router export default router
...@@ -7,7 +7,7 @@ export interface IVideoItem { ...@@ -7,7 +7,7 @@ export interface IVideoItem {
course_name: string course_name: string
aliyun_video_id: string aliyun_video_id: string
pv: string pv: string
play_info: object play_info: any[]
} }
// 课程 // 课程
...@@ -30,7 +30,7 @@ export interface ICourseItem { ...@@ -30,7 +30,7 @@ export interface ICourseItem {
export interface ICourseChapters { export interface ICourseChapters {
big_total: string big_total: string
small_total: string small_total: string
list: [] list: any[]
} }
// 课程老师 // 课程老师
......
...@@ -2,7 +2,7 @@ import axios from 'axios' ...@@ -2,7 +2,7 @@ import axios from 'axios'
import qs from 'qs' import qs from 'qs'
const httpRequest = axios.create({ const httpRequest = axios.create({
// baseURL: 'https://learn-api.ezijing.com', baseURL: 'https://project-api.ezijing.com',
timeout: 60000, timeout: 60000,
withCredentials: true, withCredentials: true,
headers: { headers: {
......
...@@ -23,7 +23,7 @@ export default defineConfig(({ mode }) => { ...@@ -23,7 +23,7 @@ export default defineConfig(({ mode }) => {
changeOrigin: true, changeOrigin: true,
rewrite: path => path.replace('/api/psp/', '/') rewrite: path => path.replace('/api/psp/', '/')
}, },
'/api': 'https://learn-api.ezijing.com' '/api': 'https://project-api.ezijing.com'
} }
}, },
resolve: { resolve: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论