修复已知问题
This commit is contained in:
40
package.json
40
package.json
@@ -37,9 +37,9 @@
|
|||||||
],
|
],
|
||||||
"author": "",
|
"author": "",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.21.5",
|
"@babel/runtime": "^7.26.0",
|
||||||
"@nutui/icons-react-taro": "^2.0.1",
|
"@nutui/icons-react-taro": "^2.0.1",
|
||||||
"@nutui/nutui-react-taro": "^2.6.14",
|
"@nutui/nutui-react-taro": "^2.7.4",
|
||||||
"@tarojs/components": "4.0.8",
|
"@tarojs/components": "4.0.8",
|
||||||
"@tarojs/helper": "4.0.8",
|
"@tarojs/helper": "4.0.8",
|
||||||
"@tarojs/plugin-framework-react": "4.0.8",
|
"@tarojs/plugin-framework-react": "4.0.8",
|
||||||
@@ -59,39 +59,39 @@
|
|||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts-taro3-react": "^1.0.13",
|
"echarts-taro3-react": "^1.0.13",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"react": "^18.0.0",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.0.0",
|
"react-dom": "^18.3.1",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-router-dom": "^7.1.1"
|
"react-router-dom": "^7.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.8.0",
|
"@babel/core": "^7.26.0",
|
||||||
"@babel/plugin-proposal-class-properties": "7.14.5",
|
"@babel/plugin-proposal-class-properties": "7.14.5",
|
||||||
"@babel/preset-react": "^7.24.1",
|
"@babel/preset-react": "^7.26.3",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.15",
|
||||||
"@tarojs/cli": "4.0.8",
|
"@tarojs/cli": "4.0.8",
|
||||||
"@tarojs/taro-loader": "4.0.8",
|
"@tarojs/taro-loader": "4.0.8",
|
||||||
"@tarojs/webpack5-runner": "4.0.8",
|
"@tarojs/webpack5-runner": "4.0.8",
|
||||||
"@types/node": "^18.15.11",
|
"@types/node": "^18.19.68",
|
||||||
"@types/react": "^18.0.0",
|
"@types/react": "^18.3.18",
|
||||||
"@types/webpack-env": "^1.13.6",
|
"@types/webpack-env": "^1.18.5",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||||
"@typescript-eslint/parser": "^6.2.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"babel-plugin-import": "^1.13.8",
|
"babel-plugin-import": "^1.13.8",
|
||||||
"babel-preset-taro": "4.0.8",
|
"babel-preset-taro": "4.0.8",
|
||||||
"eslint": "^8.12.0",
|
"eslint": "^8.57.1",
|
||||||
"eslint-config-taro": "4.0.8",
|
"eslint-config-taro": "4.0.8",
|
||||||
"eslint-plugin-import": "^2.12.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
"eslint-plugin-react": "^7.8.2",
|
"eslint-plugin-react": "^7.37.3",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.6.2",
|
||||||
"postcss": "^8.4.49",
|
"postcss": "^8.4.49",
|
||||||
"react-refresh": "^0.11.0",
|
"react-refresh": "^0.11.0",
|
||||||
"stylelint": "^14.4.0",
|
"stylelint": "^14.16.1",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.2",
|
||||||
"tsconfig-paths-webpack-plugin": "^4.0.1",
|
"tsconfig-paths-webpack-plugin": "^4.2.0",
|
||||||
"typescript": "^5.1.0",
|
"typescript": "^5.7.2",
|
||||||
"webpack": "5.78.0"
|
"webpack": "5.78.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
144
pnpm-lock.yaml
generated
144
pnpm-lock.yaml
generated
@@ -9,13 +9,13 @@ importers:
|
|||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime':
|
'@babel/runtime':
|
||||||
specifier: ^7.21.5
|
specifier: ^7.26.0
|
||||||
version: 7.26.0
|
version: 7.26.0
|
||||||
'@nutui/icons-react-taro':
|
'@nutui/icons-react-taro':
|
||||||
specifier: ^2.0.1
|
specifier: ^2.0.1
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
'@nutui/nutui-react-taro':
|
'@nutui/nutui-react-taro':
|
||||||
specifier: ^2.6.14
|
specifier: ^2.7.4
|
||||||
version: 2.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@tarojs/components':
|
'@tarojs/components':
|
||||||
specifier: 4.0.8
|
specifier: 4.0.8
|
||||||
@@ -75,10 +75,10 @@ importers:
|
|||||||
specifier: ^3.7.7
|
specifier: ^3.7.7
|
||||||
version: 3.7.7
|
version: 3.7.7
|
||||||
react:
|
react:
|
||||||
specifier: ^18.0.0
|
specifier: ^18.3.1
|
||||||
version: 18.3.1
|
version: 18.3.1
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18.0.0
|
specifier: ^18.3.1
|
||||||
version: 18.3.1(react@18.3.1)
|
version: 18.3.1(react@18.3.1)
|
||||||
react-markdown:
|
react-markdown:
|
||||||
specifier: ^10.1.0
|
specifier: ^10.1.0
|
||||||
@@ -88,16 +88,16 @@ importers:
|
|||||||
version: 7.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 7.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@babel/core':
|
'@babel/core':
|
||||||
specifier: ^7.8.0
|
specifier: ^7.26.0
|
||||||
version: 7.26.0
|
version: 7.26.0
|
||||||
'@babel/plugin-proposal-class-properties':
|
'@babel/plugin-proposal-class-properties':
|
||||||
specifier: 7.14.5
|
specifier: 7.14.5
|
||||||
version: 7.14.5(@babel/core@7.26.0)
|
version: 7.14.5(@babel/core@7.26.0)
|
||||||
'@babel/preset-react':
|
'@babel/preset-react':
|
||||||
specifier: ^7.24.1
|
specifier: ^7.26.3
|
||||||
version: 7.26.3(@babel/core@7.26.0)
|
version: 7.26.3(@babel/core@7.26.0)
|
||||||
'@pmmmwh/react-refresh-webpack-plugin':
|
'@pmmmwh/react-refresh-webpack-plugin':
|
||||||
specifier: ^0.5.5
|
specifier: ^0.5.15
|
||||||
version: 0.5.15(react-refresh@0.11.0)(type-fest@2.19.0)(webpack-dev-server@4.15.2(webpack@5.78.0(@swc/core@1.3.96)))(webpack@5.78.0(@swc/core@1.3.96))
|
version: 0.5.15(react-refresh@0.11.0)(type-fest@2.19.0)(webpack-dev-server@4.15.2(webpack@5.78.0(@swc/core@1.3.96)))(webpack@5.78.0(@swc/core@1.3.96))
|
||||||
'@tarojs/cli':
|
'@tarojs/cli':
|
||||||
specifier: 4.0.8
|
specifier: 4.0.8
|
||||||
@@ -109,19 +109,19 @@ importers:
|
|||||||
specifier: 4.0.8
|
specifier: 4.0.8
|
||||||
version: 4.0.8(@babel/core@7.26.0)(@swc/core@1.3.96)(@tarojs/runtime@4.0.8)(less@3.13.1)(postcss@8.4.49)(sass@1.83.0)(stylus@0.64.0)(typescript@5.7.2)(webpack@5.78.0(@swc/core@1.3.96))
|
version: 4.0.8(@babel/core@7.26.0)(@swc/core@1.3.96)(@tarojs/runtime@4.0.8)(less@3.13.1)(postcss@8.4.49)(sass@1.83.0)(stylus@0.64.0)(typescript@5.7.2)(webpack@5.78.0(@swc/core@1.3.96))
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^18.15.11
|
specifier: ^18.19.68
|
||||||
version: 18.19.68
|
version: 18.19.68
|
||||||
'@types/react':
|
'@types/react':
|
||||||
specifier: ^18.0.0
|
specifier: ^18.3.18
|
||||||
version: 18.3.18
|
version: 18.3.18
|
||||||
'@types/webpack-env':
|
'@types/webpack-env':
|
||||||
specifier: ^1.13.6
|
specifier: ^1.18.5
|
||||||
version: 1.18.5
|
version: 1.18.5
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^6.2.0
|
specifier: ^6.21.0
|
||||||
version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2)
|
version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)(typescript@5.7.2)
|
||||||
'@typescript-eslint/parser':
|
'@typescript-eslint/parser':
|
||||||
specifier: ^6.2.0
|
specifier: ^6.21.0
|
||||||
version: 6.21.0(eslint@8.57.1)(typescript@5.7.2)
|
version: 6.21.0(eslint@8.57.1)(typescript@5.7.2)
|
||||||
autoprefixer:
|
autoprefixer:
|
||||||
specifier: ^10.4.20
|
specifier: ^10.4.20
|
||||||
@@ -133,19 +133,19 @@ importers:
|
|||||||
specifier: 4.0.8
|
specifier: 4.0.8
|
||||||
version: 4.0.8(@babel/core@7.26.0)(@babel/plugin-transform-typescript@7.26.3(@babel/core@7.26.0))(@babel/preset-react@7.26.3(@babel/core@7.26.0))(react-refresh@0.11.0)
|
version: 4.0.8(@babel/core@7.26.0)(@babel/plugin-transform-typescript@7.26.3(@babel/core@7.26.0))(@babel/preset-react@7.26.3(@babel/core@7.26.0))(react-refresh@0.11.0)
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^8.12.0
|
specifier: ^8.57.1
|
||||||
version: 8.57.1
|
version: 8.57.1
|
||||||
eslint-config-taro:
|
eslint-config-taro:
|
||||||
specifier: 4.0.8
|
specifier: 4.0.8
|
||||||
version: 4.0.8(@babel/core@7.26.0)(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.3(eslint@8.57.1))(eslint@8.57.1)(typescript@5.7.2)
|
version: 4.0.8(@babel/core@7.26.0)(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.3(eslint@8.57.1))(eslint@8.57.1)(typescript@5.7.2)
|
||||||
eslint-plugin-import:
|
eslint-plugin-import:
|
||||||
specifier: ^2.12.0
|
specifier: ^2.31.0
|
||||||
version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)
|
version: 2.31.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.2))(eslint@8.57.1)
|
||||||
eslint-plugin-react:
|
eslint-plugin-react:
|
||||||
specifier: ^7.8.2
|
specifier: ^7.37.3
|
||||||
version: 7.37.3(eslint@8.57.1)
|
version: 7.37.3(eslint@8.57.1)
|
||||||
eslint-plugin-react-hooks:
|
eslint-plugin-react-hooks:
|
||||||
specifier: ^4.2.0
|
specifier: ^4.6.2
|
||||||
version: 4.6.2(eslint@8.57.1)
|
version: 4.6.2(eslint@8.57.1)
|
||||||
postcss:
|
postcss:
|
||||||
specifier: ^8.4.49
|
specifier: ^8.4.49
|
||||||
@@ -154,19 +154,19 @@ importers:
|
|||||||
specifier: ^0.11.0
|
specifier: ^0.11.0
|
||||||
version: 0.11.0
|
version: 0.11.0
|
||||||
stylelint:
|
stylelint:
|
||||||
specifier: ^14.4.0
|
specifier: ^14.16.1
|
||||||
version: 14.16.1
|
version: 14.16.1
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^3.4.17
|
specifier: ^3.4.17
|
||||||
version: 3.4.17(ts-node@10.9.2(@swc/core@1.3.96)(@types/node@18.19.68)(typescript@5.7.2))
|
version: 3.4.17(ts-node@10.9.2(@swc/core@1.3.96)(@types/node@18.19.68)(typescript@5.7.2))
|
||||||
ts-node:
|
ts-node:
|
||||||
specifier: ^10.9.1
|
specifier: ^10.9.2
|
||||||
version: 10.9.2(@swc/core@1.3.96)(@types/node@18.19.68)(typescript@5.7.2)
|
version: 10.9.2(@swc/core@1.3.96)(@types/node@18.19.68)(typescript@5.7.2)
|
||||||
tsconfig-paths-webpack-plugin:
|
tsconfig-paths-webpack-plugin:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.2.0
|
||||||
version: 4.2.0
|
version: 4.2.0
|
||||||
typescript:
|
typescript:
|
||||||
specifier: ^5.1.0
|
specifier: ^5.7.2
|
||||||
version: 5.7.2
|
version: 5.7.2
|
||||||
webpack:
|
webpack:
|
||||||
specifier: 5.78.0
|
specifier: 5.78.0
|
||||||
@@ -279,10 +279,18 @@ packages:
|
|||||||
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz}
|
resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==, tarball: https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz}
|
||||||
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==, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz}
|
resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==, tarball: https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz}
|
||||||
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==, tarball: https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz}
|
resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==, tarball: https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -300,6 +308,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==, tarball: https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz}
|
resolution: {integrity: sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==, tarball: https://registry.npmmirror.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@@ -764,6 +777,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz}
|
resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==, tarball: https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/types@7.27.6':
|
||||||
|
resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, tarball: https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz}
|
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, tarball: https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -2367,8 +2384,8 @@ packages:
|
|||||||
caniuse-api@3.0.0:
|
caniuse-api@3.0.0:
|
||||||
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==, tarball: https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz}
|
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==, tarball: https://registry.npmmirror.com/caniuse-api/-/caniuse-api-3.0.0.tgz}
|
||||||
|
|
||||||
caniuse-lite@1.0.30001690:
|
caniuse-lite@1.0.30001721:
|
||||||
resolution: {integrity: sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==, tarball: https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz}
|
resolution: {integrity: sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==}
|
||||||
|
|
||||||
capital-case@1.0.4:
|
capital-case@1.0.4:
|
||||||
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==, tarball: https://registry.npmmirror.com/capital-case/-/capital-case-1.0.4.tgz}
|
resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==, tarball: https://registry.npmmirror.com/capital-case/-/capital-case-1.0.4.tgz}
|
||||||
@@ -2758,6 +2775,15 @@ packages:
|
|||||||
supports-color:
|
supports-color:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
debug@4.4.1:
|
||||||
|
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
|
||||||
decamelize-keys@1.1.1:
|
decamelize-keys@1.1.1:
|
||||||
resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, tarball: https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz}
|
resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, tarball: https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4592,6 +4618,11 @@ packages:
|
|||||||
mz@2.7.0:
|
mz@2.7.0:
|
||||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, tarball: https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz}
|
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, tarball: https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz}
|
||||||
|
|
||||||
|
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==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz}
|
resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
@@ -5224,6 +5255,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz}
|
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==, tarball: https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz}
|
||||||
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==, tarball: https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, tarball: https://registry.npmmirror.com/prelude-ls/-/prelude-ls-1.2.1.tgz}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
@@ -5678,14 +5713,14 @@ packages:
|
|||||||
serialize-javascript@6.0.2:
|
serialize-javascript@6.0.2:
|
||||||
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, tarball: https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz}
|
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, tarball: https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz}
|
||||||
|
|
||||||
seroval-plugins@1.1.1:
|
seroval-plugins@1.3.2:
|
||||||
resolution: {integrity: sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==}
|
resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
seroval: ^1.0
|
seroval: ^1.0
|
||||||
|
|
||||||
seroval@1.1.1:
|
seroval@1.3.2:
|
||||||
resolution: {integrity: sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==}
|
resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
serve-index@1.9.1:
|
serve-index@1.9.1:
|
||||||
@@ -6767,8 +6802,14 @@ snapshots:
|
|||||||
|
|
||||||
'@babel/helper-string-parser@7.25.9': {}
|
'@babel/helper-string-parser@7.25.9': {}
|
||||||
|
|
||||||
|
'@babel/helper-string-parser@7.27.1':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@babel/helper-validator-identifier@7.25.9': {}
|
'@babel/helper-validator-identifier@7.25.9': {}
|
||||||
|
|
||||||
|
'@babel/helper-validator-identifier@7.27.1':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@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':
|
||||||
@@ -6788,6 +6829,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@babel/types': 7.26.3
|
'@babel/types': 7.26.3
|
||||||
|
|
||||||
|
'@babel/parser@7.27.5':
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.27.6
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)':
|
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.26.0
|
'@babel/core': 7.26.0
|
||||||
@@ -7383,6 +7429,12 @@ 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.6':
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-string-parser': 7.27.1
|
||||||
|
'@babel/helper-validator-identifier': 7.27.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@cspotcode/source-map-support@0.8.1':
|
'@cspotcode/source-map-support@0.8.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jridgewell/trace-mapping': 0.3.9
|
'@jridgewell/trace-mapping': 0.3.9
|
||||||
@@ -8632,7 +8684,7 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/compiler-core@3.5.13':
|
'@vue/compiler-core@3.5.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.26.3
|
'@babel/parser': 7.27.5
|
||||||
'@vue/shared': 3.5.13
|
'@vue/shared': 3.5.13
|
||||||
entities: 4.5.0
|
entities: 4.5.0
|
||||||
estree-walker: 2.0.2
|
estree-walker: 2.0.2
|
||||||
@@ -8647,14 +8699,14 @@ snapshots:
|
|||||||
|
|
||||||
'@vue/compiler-sfc@3.5.13':
|
'@vue/compiler-sfc@3.5.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.26.3
|
'@babel/parser': 7.27.5
|
||||||
'@vue/compiler-core': 3.5.13
|
'@vue/compiler-core': 3.5.13
|
||||||
'@vue/compiler-dom': 3.5.13
|
'@vue/compiler-dom': 3.5.13
|
||||||
'@vue/compiler-ssr': 3.5.13
|
'@vue/compiler-ssr': 3.5.13
|
||||||
'@vue/shared': 3.5.13
|
'@vue/shared': 3.5.13
|
||||||
estree-walker: 2.0.2
|
estree-walker: 2.0.2
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
postcss: 8.4.49
|
postcss: 8.5.4
|
||||||
source-map-js: 1.2.1
|
source-map-js: 1.2.1
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -8948,7 +9000,7 @@ snapshots:
|
|||||||
autoprefixer@10.4.20(postcss@8.4.49):
|
autoprefixer@10.4.20(postcss@8.4.49):
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.24.3
|
browserslist: 4.24.3
|
||||||
caniuse-lite: 1.0.30001690
|
caniuse-lite: 1.0.30001721
|
||||||
fraction.js: 4.3.7
|
fraction.js: 4.3.7
|
||||||
normalize-range: 0.1.2
|
normalize-range: 0.1.2
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
@@ -9128,7 +9180,7 @@ snapshots:
|
|||||||
|
|
||||||
browserslist@4.24.3:
|
browserslist@4.24.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: 1.0.30001690
|
caniuse-lite: 1.0.30001721
|
||||||
electron-to-chromium: 1.5.76
|
electron-to-chromium: 1.5.76
|
||||||
node-releases: 2.0.19
|
node-releases: 2.0.19
|
||||||
update-browserslist-db: 1.1.1(browserslist@4.24.3)
|
update-browserslist-db: 1.1.1(browserslist@4.24.3)
|
||||||
@@ -9215,11 +9267,11 @@ snapshots:
|
|||||||
caniuse-api@3.0.0:
|
caniuse-api@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: 4.24.3
|
browserslist: 4.24.3
|
||||||
caniuse-lite: 1.0.30001690
|
caniuse-lite: 1.0.30001721
|
||||||
lodash.memoize: 4.1.2
|
lodash.memoize: 4.1.2
|
||||||
lodash.uniq: 4.5.0
|
lodash.uniq: 4.5.0
|
||||||
|
|
||||||
caniuse-lite@1.0.30001690: {}
|
caniuse-lite@1.0.30001721: {}
|
||||||
|
|
||||||
capital-case@1.0.4:
|
capital-case@1.0.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -9634,6 +9686,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.3
|
ms: 2.1.3
|
||||||
|
|
||||||
|
debug@4.4.1:
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.3
|
||||||
|
|
||||||
decamelize-keys@1.1.1:
|
decamelize-keys@1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
decamelize: 1.2.0
|
decamelize: 1.2.0
|
||||||
@@ -11861,6 +11917,9 @@ snapshots:
|
|||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
thenify-all: 1.6.0
|
thenify-all: 1.6.0
|
||||||
|
|
||||||
|
nanoid@3.3.11:
|
||||||
|
optional: true
|
||||||
|
|
||||||
nanoid@3.3.8: {}
|
nanoid@3.3.8: {}
|
||||||
|
|
||||||
native-request@1.1.2:
|
native-request@1.1.2:
|
||||||
@@ -12452,6 +12511,13 @@ 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
|
||||||
|
optional: true
|
||||||
|
|
||||||
prelude-ls@1.2.1: {}
|
prelude-ls@1.2.1: {}
|
||||||
|
|
||||||
prepend-http@2.0.0: {}
|
prepend-http@2.0.0: {}
|
||||||
@@ -12986,11 +13052,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
randombytes: 2.1.0
|
randombytes: 2.1.0
|
||||||
|
|
||||||
seroval-plugins@1.1.1(seroval@1.1.1):
|
seroval-plugins@1.3.2(seroval@1.3.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
seroval: 1.1.1
|
seroval: 1.3.2
|
||||||
|
|
||||||
seroval@1.1.1: {}
|
seroval@1.3.2: {}
|
||||||
|
|
||||||
serve-index@1.9.1:
|
serve-index@1.9.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -13103,8 +13169,8 @@ snapshots:
|
|||||||
solid-js@1.9.3:
|
solid-js@1.9.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
seroval: 1.1.1
|
seroval: 1.3.2
|
||||||
seroval-plugins: 1.1.1(seroval@1.1.1)
|
seroval-plugins: 1.3.2(seroval@1.3.2)
|
||||||
|
|
||||||
sort-keys-length@1.0.1:
|
sort-keys-length@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -13355,7 +13421,7 @@ snapshots:
|
|||||||
stylus@0.64.0:
|
stylus@0.64.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@adobe/css-tools': 4.3.3
|
'@adobe/css-tools': 4.3.3
|
||||||
debug: 4.4.0
|
debug: 4.4.1
|
||||||
glob: 10.4.5
|
glob: 10.4.5
|
||||||
sax: 1.4.1
|
sax: 1.4.1
|
||||||
source-map: 0.7.4
|
source-map: 0.7.4
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ export interface CmsWebsite {
|
|||||||
topNavs?: CmsNavigation[];
|
topNavs?: CmsNavigation[];
|
||||||
bottomNavs?: CmsNavigation[];
|
bottomNavs?: CmsNavigation[];
|
||||||
loginUser?: any;
|
loginUser?: any;
|
||||||
|
search?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
101
src/api/hjm/hjmBxLog/index.ts
Normal file
101
src/api/hjm/hjmBxLog/index.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api/index';
|
||||||
|
import type { HjmBxLog, HjmBxLogParam } from './model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function pageHjmBxLog(params: HjmBxLogParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<HjmBxLog>>>(
|
||||||
|
'/hjm/hjm-bx-log/page',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询黄家明_保险记录列表
|
||||||
|
*/
|
||||||
|
export async function listHjmBxLog(params?: HjmBxLogParam) {
|
||||||
|
const res = await request.get<ApiResult<HjmBxLog[]>>(
|
||||||
|
'/hjm/hjm-bx-log',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function addHjmBxLog(data: HjmBxLog) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-bx-log',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function updateHjmBxLog(data: HjmBxLog) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-bx-log',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function removeHjmBxLog(id?: number) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-bx-log/' + id
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function removeBatchHjmBxLog(data: (number | undefined)[]) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-bx-log/batch',
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id查询黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export async function getHjmBxLog(id: number) {
|
||||||
|
const res = await request.get<ApiResult<HjmBxLog>>(
|
||||||
|
'/hjm/hjm-bx-log/' + id
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
39
src/api/hjm/hjmBxLog/model/index.ts
Normal file
39
src/api/hjm/hjmBxLog/model/index.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import type { PageParam } from '@/api/index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黄家明_保险记录
|
||||||
|
*/
|
||||||
|
export interface HjmBxLog {
|
||||||
|
// 自增ID
|
||||||
|
id?: number;
|
||||||
|
// 用户ID
|
||||||
|
userId?: number;
|
||||||
|
// 事故类型
|
||||||
|
accidentType?: string;
|
||||||
|
// 车辆ID
|
||||||
|
carId?: number;
|
||||||
|
// 保险图片
|
||||||
|
image?: string;
|
||||||
|
// 排序(数字越小越靠前)
|
||||||
|
sortNumber?: number;
|
||||||
|
// 备注
|
||||||
|
comments?: string;
|
||||||
|
// 状态, 0正常, 1冻结
|
||||||
|
status?: number;
|
||||||
|
// 是否删除, 0否, 1是
|
||||||
|
deleted?: number;
|
||||||
|
// 租户id
|
||||||
|
tenantId?: number;
|
||||||
|
// 创建时间
|
||||||
|
createTime?: string;
|
||||||
|
// 修改时间
|
||||||
|
updateTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黄家明_保险记录搜索条件
|
||||||
|
*/
|
||||||
|
export interface HjmBxLogParam extends PageParam {
|
||||||
|
id?: number;
|
||||||
|
keywords?: string;
|
||||||
|
}
|
||||||
115
src/api/hjm/hjmExamLog/index.ts
Normal file
115
src/api/hjm/hjmExamLog/index.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import request from '@/utils/request';
|
||||||
|
import type { ApiResult, PageResult } from '@/api/index';
|
||||||
|
import type { HjmExamLog, HjmExamLogParam } from './model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function pageHjmExamLog(params: HjmExamLogParam) {
|
||||||
|
const res = await request.get<ApiResult<PageResult<HjmExamLog>>>(
|
||||||
|
'/hjm/hjm-exam-log/page',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询黄家明_学习记录列表
|
||||||
|
*/
|
||||||
|
export async function listHjmExamLog(params?: HjmExamLogParam) {
|
||||||
|
const res = await request.get<ApiResult<HjmExamLog[]>>(
|
||||||
|
'/hjm/hjm-exam-log',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function addHjmExamLog(data: HjmExamLog) {
|
||||||
|
const res = await request.post<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-exam-log',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function updateHjmExamLog(data: HjmExamLog) {
|
||||||
|
const res = await request.put<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-exam-log',
|
||||||
|
data
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function removeHjmExamLog(id?: number) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-exam-log/' + id
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function removeBatchHjmExamLog(data: (number | undefined)[]) {
|
||||||
|
const res = await request.del<ApiResult<unknown>>(
|
||||||
|
'/hjm/hjm-exam-log/batch',
|
||||||
|
{
|
||||||
|
data
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.message;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id查询黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export async function getHjmExamLog(id: number) {
|
||||||
|
const res = await request.get<ApiResult<HjmExamLog>>(
|
||||||
|
'/hjm/hjm-exam-log/' + id
|
||||||
|
);
|
||||||
|
if (res.code === 0 && res.data) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function checkMonthTaskCompleted() {
|
||||||
|
const res = await request.get<ApiResult<HjmExamLog>>(
|
||||||
|
'/hjm/hjm-exam-log/checkMonthTaskCompleted'
|
||||||
|
);
|
||||||
|
console.log(res,'1231231123123123')
|
||||||
|
if (res.code === 0) {
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
39
src/api/hjm/hjmExamLog/model/index.ts
Normal file
39
src/api/hjm/hjmExamLog/model/index.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import type { PageParam } from '@/api/index';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黄家明_学习记录
|
||||||
|
*/
|
||||||
|
export interface HjmExamLog {
|
||||||
|
// 自增ID
|
||||||
|
id?: number;
|
||||||
|
// 用户ID
|
||||||
|
userId?: number;
|
||||||
|
// 得分
|
||||||
|
total?: string;
|
||||||
|
// 用时
|
||||||
|
useTime?: string;
|
||||||
|
// 排序(数字越小越靠前)
|
||||||
|
sortNumber?: number;
|
||||||
|
// 备注
|
||||||
|
comments?: string;
|
||||||
|
// 状态, 0正常, 1冻结
|
||||||
|
status?: number;
|
||||||
|
// 是否删除, 0否, 1是
|
||||||
|
deleted?: number;
|
||||||
|
// 租户id
|
||||||
|
tenantId?: number;
|
||||||
|
// 创建时间
|
||||||
|
createTime?: string;
|
||||||
|
// 修改时间
|
||||||
|
updateTime?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黄家明_学习记录搜索条件
|
||||||
|
*/
|
||||||
|
export interface HjmExamLogParam extends PageParam {
|
||||||
|
id?: number;
|
||||||
|
userId?: number;
|
||||||
|
status?: number;
|
||||||
|
keywords?: string;
|
||||||
|
}
|
||||||
@@ -8,9 +8,7 @@ import type { HjmQuestions, HjmQuestionsParam } from './model';
|
|||||||
export async function pageHjmQuestions(params: HjmQuestionsParam) {
|
export async function pageHjmQuestions(params: HjmQuestionsParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<HjmQuestions>>>(
|
const res = await request.get<ApiResult<PageResult<HjmQuestions>>>(
|
||||||
'/hjm/hjm-questions/page',
|
'/hjm/hjm-questions/page',
|
||||||
{
|
params
|
||||||
params
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -24,9 +22,7 @@ export async function pageHjmQuestions(params: HjmQuestionsParam) {
|
|||||||
export async function listHjmQuestions(params?: HjmQuestionsParam) {
|
export async function listHjmQuestions(params?: HjmQuestionsParam) {
|
||||||
const res = await request.get<ApiResult<HjmQuestions[]>>(
|
const res = await request.get<ApiResult<HjmQuestions[]>>(
|
||||||
'/hjm/hjm-questions',
|
'/hjm/hjm-questions',
|
||||||
{
|
params
|
||||||
params
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
if (res.code === 0 && res.data) {
|
if (res.code === 0 && res.data) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ export interface PageParam {
|
|||||||
// 搜素关键词
|
// 搜素关键词
|
||||||
keywords?: string;
|
keywords?: string;
|
||||||
// 起始时间
|
// 起始时间
|
||||||
createTimeStart?: number;
|
createTimeStart?: string;
|
||||||
// 结束时间
|
// 结束时间
|
||||||
createTimeEnd?: number;
|
createTimeEnd?: string;
|
||||||
timeStart?: number;
|
timeStart?: number;
|
||||||
timeEnd?: number;
|
timeEnd?: number;
|
||||||
isExpireTime?: number;
|
isExpireTime?: number;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ export default defineAppConfig({
|
|||||||
'pages/order/order',
|
'pages/order/order',
|
||||||
'pages/kefu/kefu',
|
'pages/kefu/kefu',
|
||||||
'pages/user/user',
|
'pages/user/user',
|
||||||
'pages/article/article'
|
'pages/article/article',
|
||||||
|
'pages/study/study'
|
||||||
],
|
],
|
||||||
"subpackages": [
|
"subpackages": [
|
||||||
{
|
{
|
||||||
@@ -30,7 +31,6 @@ export default defineAppConfig({
|
|||||||
"root": "user",
|
"root": "user",
|
||||||
"pages": [
|
"pages": [
|
||||||
"car/index",
|
"car/index",
|
||||||
"bx/index",
|
|
||||||
"company/company",
|
"company/company",
|
||||||
"profile/profile",
|
"profile/profile",
|
||||||
"setting/setting",
|
"setting/setting",
|
||||||
@@ -44,7 +44,10 @@ export default defineAppConfig({
|
|||||||
"location",
|
"location",
|
||||||
"query",
|
"query",
|
||||||
"fence",
|
"fence",
|
||||||
"baoxiu"
|
"video/video",
|
||||||
|
"exam/exam",
|
||||||
|
"bx/bx",
|
||||||
|
"bx/bx-add"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
@@ -85,7 +88,7 @@ export default defineAppConfig({
|
|||||||
text: "首页",
|
text: "首页",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pagePath: "pages/article/article",
|
pagePath: "pages/study/study",
|
||||||
iconPath: "assets/tabbar/order.png",
|
iconPath: "assets/tabbar/order.png",
|
||||||
selectedIconPath: "assets/tabbar/order-active.png",
|
selectedIconPath: "assets/tabbar/order-active.png",
|
||||||
text: "学习",
|
text: "学习",
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
export default definePageConfig({
|
|
||||||
navigationBarTitleText: '一键报修'
|
|
||||||
})
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {useRouter} from '@tarojs/taro'
|
|
||||||
import {getHjmCar, pageHjmCar} from "@/api/hjm/hjmCar";
|
|
||||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
|
||||||
import {Image,Cell} from '@nutui/nutui-react-taro'
|
|
||||||
import './location.scss'
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 电子围栏
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
const Fence = () => {
|
|
||||||
const {params} = useRouter();
|
|
||||||
const [keywords, setKeywords] = useState<string>()
|
|
||||||
const [item, setItem] = useState<HjmCar>()
|
|
||||||
|
|
||||||
// 打开地图选择位置
|
|
||||||
// const chooseLocation = async () => {
|
|
||||||
// try {
|
|
||||||
// const res = await Taro.chooseLocation({
|
|
||||||
// latitude, // 默认纬度
|
|
||||||
// longitude // 默认经度
|
|
||||||
// })
|
|
||||||
// console.log('选择的位置:', res);
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error('选择位置失败:', err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
const reload = () => {
|
|
||||||
const id = Number(params.id);
|
|
||||||
// 执行搜索
|
|
||||||
if (keywords) {
|
|
||||||
pageHjmCar({keywords}).then(res => {
|
|
||||||
if (res?.list && res?.list?.length > 0) {
|
|
||||||
const data = res?.list[0];
|
|
||||||
setItem(data)
|
|
||||||
setKeywords(data.code)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 获取车辆信息
|
|
||||||
if (id) {
|
|
||||||
getHjmCar(id).then(data => {
|
|
||||||
setItem(data)
|
|
||||||
setKeywords(data.code)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{/*<div className={'fixed z-20 top-5 left-0 w-full'}>*/}
|
|
||||||
{/* <div className={'px-4'}>*/}
|
|
||||||
{/* <div*/}
|
|
||||||
{/* style={{*/}
|
|
||||||
{/* display: 'flex',*/}
|
|
||||||
{/* alignItems: 'center',*/}
|
|
||||||
{/* background: '#fff',*/}
|
|
||||||
{/* padding: '0 10px',*/}
|
|
||||||
{/* borderRadius: '20px'*/}
|
|
||||||
{/* }}*/}
|
|
||||||
{/* >*/}
|
|
||||||
{/* <Search/>*/}
|
|
||||||
{/* <Input*/}
|
|
||||||
{/* placeholder="车辆编号"*/}
|
|
||||||
{/* value={keywords}*/}
|
|
||||||
{/* onChange={onKeywords}*/}
|
|
||||||
{/* />*/}
|
|
||||||
{/* <div*/}
|
|
||||||
{/* className={'flex items-center'}*/}
|
|
||||||
{/* >*/}
|
|
||||||
{/* <Button type="warning" onClick={reload}>*/}
|
|
||||||
{/* 查询*/}
|
|
||||||
{/* </Button>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/* </div>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
{item ? (
|
|
||||||
<div className={'car-info w-full bg-white'}>
|
|
||||||
<Image src={item?.image} mode={'widthFix'} width={'100%'} className={'bg-gray-50'}/>
|
|
||||||
<div className={'px-2'}>
|
|
||||||
<Cell className={'car-info-item-title'}>
|
|
||||||
车辆编号:{item?.code}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-title'}>
|
|
||||||
快递公司:{item?.kuaidi}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-title'}>
|
|
||||||
管理负责人:{item?.kuaidiAdmin}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-content'}>
|
|
||||||
操作员:{item?.driver}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-content'}>
|
|
||||||
保险状态:{item?.insuranceStatus}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-content'}>
|
|
||||||
GPS编号:{item?.gpsNo}
|
|
||||||
</Cell>
|
|
||||||
<Cell className={'car-info-item-content'}>
|
|
||||||
电子围栏:{item?.fenceName}
|
|
||||||
</Cell>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : ''}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Fence
|
|
||||||
202
src/hjm/bx/BestSellers.tsx
Normal file
202
src/hjm/bx/BestSellers.tsx
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Image, Space, Tag, Button} from '@nutui/nutui-react-taro'
|
||||||
|
import {Truck, User, Shield, Location} from '@nutui/icons-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||||
|
|
||||||
|
interface BestSellersProps {
|
||||||
|
data: HjmCar[]
|
||||||
|
onRefresh?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆列表组件
|
||||||
|
*/
|
||||||
|
const BestSellers: React.FC<BestSellersProps> = ({data, onRefresh}) => {
|
||||||
|
|
||||||
|
// 获取保险状态显示
|
||||||
|
const getInsuranceStatusDisplay = (status?: number) => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return {text: '未投保', color: '#ff4d4f', bgColor: '#fff2f0'}
|
||||||
|
case 1:
|
||||||
|
return {text: '已投保', color: '#52c41a', bgColor: '#f6ffed'}
|
||||||
|
case 2:
|
||||||
|
return {text: '即将到期', color: '#faad14', bgColor: '#fffbe6'}
|
||||||
|
default:
|
||||||
|
return {text: '未知', color: '#8c8c8c', bgColor: '#f5f5f5'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到车辆详情
|
||||||
|
const navigateToDetail = (item: HjmCar) => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/hjm/query?id=${item.id}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 快速报险
|
||||||
|
const quickInsurance = (item: HjmCar, event: any) => {
|
||||||
|
event.stopPropagation()
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/hjm/bx/bx-add?carId=${item.id}&carCode=${item.code}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data || data.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{padding: '0 16px', marginBottom: '16px'}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '12px'
|
||||||
|
}}>
|
||||||
|
{data.map((item, index) => {
|
||||||
|
const insuranceStatus = getInsuranceStatusDisplay(item.insuranceStatus)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px',
|
||||||
|
boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
|
||||||
|
border: '1px solid #f0f0f0'
|
||||||
|
}}
|
||||||
|
onClick={() => navigateToDetail(item)}
|
||||||
|
>
|
||||||
|
<div style={{display: 'flex', gap: '12px'}}>
|
||||||
|
{/* 车辆图片 */}
|
||||||
|
<div style={{flexShrink: 0}}>
|
||||||
|
<Image
|
||||||
|
src={item.image || 'https://via.placeholder.com/80x80?text=车辆'}
|
||||||
|
mode="aspectFill"
|
||||||
|
radius="8px"
|
||||||
|
width="80"
|
||||||
|
height="80"
|
||||||
|
style={{
|
||||||
|
border: '1px solid #f0f0f0'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 车辆信息 */}
|
||||||
|
<div style={{flex: 1, minWidth: 0}}>
|
||||||
|
<Space direction="vertical" size={8}>
|
||||||
|
{/* 车辆编号 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<Truck size={16} color="#1890ff"/>
|
||||||
|
<span style={{
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#262626'
|
||||||
|
}}>
|
||||||
|
{item.code || '未知编号'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 快递公司 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<Location size={14} color="#8c8c8c"/>
|
||||||
|
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||||
|
快递公司:
|
||||||
|
</span>
|
||||||
|
<span style={{fontSize: '13px', color: '#595959'}}>
|
||||||
|
{item.parentOrganization || '未知'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 保险状态 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<Shield size={14} color="#8c8c8c"/>
|
||||||
|
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||||
|
保险状态:
|
||||||
|
</span>
|
||||||
|
<Tag
|
||||||
|
color={insuranceStatus.color}
|
||||||
|
style={{
|
||||||
|
backgroundColor: insuranceStatus.bgColor,
|
||||||
|
border: `1px solid ${insuranceStatus.color}`,
|
||||||
|
fontSize: '12px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{insuranceStatus.text}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 操作员 */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<User size={14} color="#8c8c8c"/>
|
||||||
|
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||||
|
操作员:
|
||||||
|
</span>
|
||||||
|
<span style={{fontSize: '13px', color: '#595959'}}>
|
||||||
|
{item.driver || '未绑定'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 操作按钮 */}
|
||||||
|
<div style={{
|
||||||
|
marginTop: '12px',
|
||||||
|
paddingTop: '12px',
|
||||||
|
borderTop: '1px solid #f0f0f0',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={(e) => quickInsurance(item, e)}
|
||||||
|
style={{
|
||||||
|
borderRadius: '16px',
|
||||||
|
fontSize: '12px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
一键报险
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
size="small"
|
||||||
|
onClick={() => navigateToDetail(item)}
|
||||||
|
style={{
|
||||||
|
borderRadius: '16px',
|
||||||
|
fontSize: '12px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
查看详情
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BestSellers
|
||||||
3
src/hjm/bx/bx-add.config.ts
Normal file
3
src/hjm/bx/bx-add.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '一键报险'
|
||||||
|
})
|
||||||
366
src/hjm/bx/bx-add.tsx
Normal file
366
src/hjm/bx/bx-add.tsx
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {
|
||||||
|
Image,
|
||||||
|
Button,
|
||||||
|
TextArea,
|
||||||
|
Cell,
|
||||||
|
Loading,
|
||||||
|
Space
|
||||||
|
} from '@nutui/nutui-react-taro'
|
||||||
|
import {Camera, Truck} from '@nutui/icons-react-taro'
|
||||||
|
import {addHjmBxLog} from "@/api/hjm/hjmBxLog";
|
||||||
|
import {pageHjmCar} from "@/api/hjm/hjmCar";
|
||||||
|
import {uploadFile} from "@/api/system/file";
|
||||||
|
import {HjmBxLog} from "@/api/hjm/hjmBxLog/model";
|
||||||
|
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键报险 - 添加报险记录页面
|
||||||
|
*/
|
||||||
|
function BxAdd() {
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [uploading, setUploading] = useState<boolean>(false)
|
||||||
|
const [carInfo, setCarInfo] = useState<HjmCar | null>(null)
|
||||||
|
const [formData, setFormData] = useState<HjmBxLog>({
|
||||||
|
carId: undefined,
|
||||||
|
image: '',
|
||||||
|
comments: '',
|
||||||
|
status: 0 // 0: 待审核, 1: 已通过, 2: 已驳回
|
||||||
|
})
|
||||||
|
|
||||||
|
// 事故类型选项
|
||||||
|
const accidentTypes = [
|
||||||
|
{text: '轻微刮擦', value: '轻微刮擦'},
|
||||||
|
{text: '碰撞事故', value: '碰撞事故'},
|
||||||
|
{text: '追尾事故', value: '追尾事故'},
|
||||||
|
{text: '侧翻事故', value: '侧翻事故'},
|
||||||
|
{text: '其他事故', value: '其他事故'}
|
||||||
|
]
|
||||||
|
|
||||||
|
const [accidentType, setAccidentType] = useState<string>('')
|
||||||
|
const [accidentDescription, setAccidentDescription] = useState<string>('')
|
||||||
|
|
||||||
|
// 初始化页面数据
|
||||||
|
const initPageData = async () => {
|
||||||
|
try {
|
||||||
|
pageHjmCar({driverId: Taro.getStorageSync('UserId')}).then(res => {
|
||||||
|
const car = res?.list[0];
|
||||||
|
setLoading(true)
|
||||||
|
if (car) {
|
||||||
|
setCarInfo(car)
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
carId: car.id
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '获取车辆信息失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.navigateBack()
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取车辆信息失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '获取车辆信息失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拍照上传
|
||||||
|
const takePhoto = () => {
|
||||||
|
Taro.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
sizeType: ['compressed'],
|
||||||
|
sourceType: ['camera'],
|
||||||
|
success: async () => {
|
||||||
|
try {
|
||||||
|
setUploading(true)
|
||||||
|
// 这里应该调用实际的上传接口
|
||||||
|
uploadFile().then(data => {
|
||||||
|
setFormData({
|
||||||
|
...formData,
|
||||||
|
image: data.url
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
setUploading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
// 表单验证
|
||||||
|
if (!formData.carId) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择车辆',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accidentType) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择事故类型',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.image) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请上传事故现场照片',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
setLoading(true)
|
||||||
|
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData: HjmBxLog = {
|
||||||
|
...formData,
|
||||||
|
comments: `事故类型:${accidentType}\n事故描述:${accidentDescription || '无'}`
|
||||||
|
}
|
||||||
|
|
||||||
|
await addHjmBxLog(submitData)
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: '报险提交成功',
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
Taro.navigateBack()
|
||||||
|
}, 1500)
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '提交失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
initPageData()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (loading && !carInfo) {
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '100vh'
|
||||||
|
}}>
|
||||||
|
<Loading type="spinner">加载中...</Loading>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#f5f5f5',
|
||||||
|
minHeight: '100vh',
|
||||||
|
paddingBottom: '80px'
|
||||||
|
}}>
|
||||||
|
{/* 车辆信息卡片 */}
|
||||||
|
{carInfo && (
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
margin: '16px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px',
|
||||||
|
boxShadow: '0 2px 8px rgba(0,0,0,0.06)'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px',
|
||||||
|
marginBottom: '12px'
|
||||||
|
}}>
|
||||||
|
<Truck size={18} color="#1890ff"/>
|
||||||
|
<span style={{fontSize: '16px', fontWeight: 'bold'}}>车辆信息</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Space direction="vertical" size={8}>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<span style={{color: '#8c8c8c'}}>车辆编号:</span>
|
||||||
|
<span style={{fontWeight: 'bold'}}>{carInfo.code}</span>
|
||||||
|
</div>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<span style={{color: '#8c8c8c'}}>快递公司:</span>
|
||||||
|
<span>{carInfo.parentOrganization}</span>
|
||||||
|
</div>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<span style={{color: '#8c8c8c'}}>操作员:</span>
|
||||||
|
<span>{carInfo.driver || '未绑定'}</span>
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 事故信息表单 */}
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
margin: '16px 16px 16px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
padding: '16px',
|
||||||
|
borderBottom: '1px solid #f0f0f0'
|
||||||
|
}}>
|
||||||
|
<span style={{fontSize: '16px', fontWeight: 'bold'}}>事故信息</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Cell.Group>
|
||||||
|
{/* 事故类型 */}
|
||||||
|
<Cell
|
||||||
|
title="事故类型"
|
||||||
|
description={accidentType || '请选择事故类型'}
|
||||||
|
onClick={() => {
|
||||||
|
Taro.showActionSheet({
|
||||||
|
itemList: accidentTypes.map(item => item.text),
|
||||||
|
success: (res) => {
|
||||||
|
setAccidentType(accidentTypes[res.tapIndex].value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 事故时间 */}
|
||||||
|
{/*<Cell*/}
|
||||||
|
{/* title="事故时间"*/}
|
||||||
|
{/* description={accidentTime ? new Date(accidentTime).toLocaleString() : '请选择事故时间'}*/}
|
||||||
|
{/* onClick={() => {*/}
|
||||||
|
{/* const now = new Date()*/}
|
||||||
|
{/* setAccidentTime(now.toISOString().slice(0, 16))*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
</Cell.Group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 事故描述 */}
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
margin: '0 16px 16px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px'
|
||||||
|
}}>
|
||||||
|
<div style={{marginBottom: '12px'}}>
|
||||||
|
<span style={{fontSize: '16px', fontWeight: 'bold'}}>事故描述</span>
|
||||||
|
<span style={{color: '#8c8c8c', fontSize: '12px', marginLeft: '8px'}}>(选填)</span>
|
||||||
|
</div>
|
||||||
|
<TextArea
|
||||||
|
placeholder={'请详细描述事故经过、损失情况等...'}
|
||||||
|
value={accidentDescription}
|
||||||
|
onChange={setAccidentDescription}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 现场照片 */}
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
margin: '0 16px 16px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px'
|
||||||
|
}}>
|
||||||
|
<div style={{marginBottom: '12px'}}>
|
||||||
|
<span style={{fontSize: '16px', fontWeight: 'bold'}}>现场照片</span>
|
||||||
|
<span style={{color: '#ff4d4f', fontSize: '12px', marginLeft: '8px'}}>*必填</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: '12px'
|
||||||
|
}}>
|
||||||
|
{formData.image && (
|
||||||
|
<div style={{position: 'relative'}}>
|
||||||
|
<Image
|
||||||
|
src={formData.image}
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
radius="8px"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="default"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '-8px',
|
||||||
|
right: '-8px',
|
||||||
|
width: '24px',
|
||||||
|
height: '24px',
|
||||||
|
borderRadius: '12px',
|
||||||
|
fontSize: '12px'
|
||||||
|
}}
|
||||||
|
onClick={() => setFormData(prev => ({...prev, image: ''}))}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!formData.image && (
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
loading={uploading}
|
||||||
|
onClick={takePhoto}
|
||||||
|
style={{
|
||||||
|
width: '100px',
|
||||||
|
height: '100px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
border: '2px dashed #d9d9d9'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Camera size={24}/>
|
||||||
|
<span style={{fontSize: '12px', marginTop: '4px'}}>拍照</span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 提交按钮 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: '16px',
|
||||||
|
borderTop: '1px solid #f0f0f0'
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
block
|
||||||
|
onClick={handleSubmit}
|
||||||
|
>
|
||||||
|
提交报险申请
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BxAdd
|
||||||
291
src/hjm/bx/bx-list.tsx
Normal file
291
src/hjm/bx/bx-list.tsx
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {
|
||||||
|
InfiniteLoading,
|
||||||
|
Loading,
|
||||||
|
Empty,
|
||||||
|
Button,
|
||||||
|
Input,
|
||||||
|
Tag,
|
||||||
|
Image,
|
||||||
|
Space,
|
||||||
|
Cell
|
||||||
|
} from '@nutui/nutui-react-taro'
|
||||||
|
import {Search, Calendar, Truck, File} from '@nutui/icons-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {pageHjmBxLog} from "@/api/hjm/hjmBxLog";
|
||||||
|
import {HjmBxLog} from "@/api/hjm/hjmBxLog/model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 报险记录列表页面
|
||||||
|
*/
|
||||||
|
const BxList: React.FC = () => {
|
||||||
|
const [list, setList] = useState<HjmBxLog[]>([])
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [keywords, setKeywords] = useState<string>('')
|
||||||
|
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||||
|
|
||||||
|
// 获取状态显示
|
||||||
|
const getStatusDisplay = (status?: number) => {
|
||||||
|
switch (status) {
|
||||||
|
case 0:
|
||||||
|
return {text: '待审核', color: '#faad14', bgColor: '#fffbe6'}
|
||||||
|
case 1:
|
||||||
|
return {text: '已通过', color: '#52c41a', bgColor: '#f6ffed'}
|
||||||
|
case 2:
|
||||||
|
return {text: '已驳回', color: '#ff4d4f', bgColor: '#fff2f0'}
|
||||||
|
default:
|
||||||
|
return {text: '未知', color: '#8c8c8c', bgColor: '#f5f5f5'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const reload = async (showLoading = true) => {
|
||||||
|
try {
|
||||||
|
if (showLoading) setLoading(true)
|
||||||
|
setRefreshing(true)
|
||||||
|
|
||||||
|
const res = await pageHjmBxLog({
|
||||||
|
keywords: keywords.trim() || undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
setList(res?.list || [])
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取报险记录失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '获取报险记录失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
setRefreshing(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSearch = () => {
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKeywordsChange = (value: string) => {
|
||||||
|
setKeywords(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAddInsurance = () => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/hjm/bx/bx-add'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewDetail = (item: HjmBxLog) => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: `/hjm/bx/bx-detail?id=${item.id}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
reload()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* 搜索栏 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: '20px',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
zIndex: 20,
|
||||||
|
padding: '0 16px',
|
||||||
|
backgroundColor: '#f5f5f5'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: '8px 12px',
|
||||||
|
borderRadius: '20px',
|
||||||
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||||
|
}}>
|
||||||
|
<Search size={16} color="#999"/>
|
||||||
|
<Input
|
||||||
|
placeholder="搜索报险记录"
|
||||||
|
value={keywords}
|
||||||
|
onChange={onKeywordsChange}
|
||||||
|
onConfirm={onSearch}
|
||||||
|
style={{
|
||||||
|
border: 'none',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: '8px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={onSearch}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 报险记录列表 */}
|
||||||
|
<div style={{
|
||||||
|
marginTop: '80px',
|
||||||
|
paddingBottom: '80px'
|
||||||
|
}}>
|
||||||
|
{loading && list.length === 0 ? (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '200px'
|
||||||
|
}}>
|
||||||
|
<Loading type="spinner">加载中...</Loading>
|
||||||
|
</div>
|
||||||
|
) : list.length === 0 ? (
|
||||||
|
<Empty description="暂无报险记录">
|
||||||
|
<Button type="primary" onClick={onAddInsurance}>
|
||||||
|
立即报险
|
||||||
|
</Button>
|
||||||
|
</Empty>
|
||||||
|
) : (
|
||||||
|
<div style={{padding: '0 16px'}}>
|
||||||
|
{list.map((item, index) => {
|
||||||
|
const statusDisplay = getStatusDisplay(item.status)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '16px',
|
||||||
|
marginBottom: '12px',
|
||||||
|
boxShadow: '0 2px 8px rgba(0,0,0,0.06)',
|
||||||
|
border: '1px solid #f0f0f0'
|
||||||
|
}}
|
||||||
|
onClick={() => viewDetail(item)}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
marginBottom: '12px'
|
||||||
|
}}>
|
||||||
|
<div style={{flex: 1}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px',
|
||||||
|
marginBottom: '8px'
|
||||||
|
}}>
|
||||||
|
<File size={16} color="#1890ff"/>
|
||||||
|
<span style={{
|
||||||
|
fontSize: '16px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: '#262626'
|
||||||
|
}}>
|
||||||
|
报险记录 #{item.id}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Space direction="vertical" size={4}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<Truck size={14} color="#8c8c8c"/>
|
||||||
|
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||||
|
车辆ID:{item.carId}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '8px'
|
||||||
|
}}>
|
||||||
|
<Calendar size={14} color="#8c8c8c"/>
|
||||||
|
<span style={{fontSize: '13px', color: '#8c8c8c'}}>
|
||||||
|
提交时间:{item.createTime}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Space>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Tag
|
||||||
|
color={statusDisplay.color}
|
||||||
|
style={{
|
||||||
|
backgroundColor: statusDisplay.bgColor,
|
||||||
|
border: `1px solid ${statusDisplay.color}`,
|
||||||
|
fontSize: '12px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{statusDisplay.text}
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 事故照片预览 */}
|
||||||
|
{item.image && (
|
||||||
|
<div style={{marginBottom: '12px'}}>
|
||||||
|
<Image
|
||||||
|
src={item.image}
|
||||||
|
width="60"
|
||||||
|
height="60"
|
||||||
|
radius="6px"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 备注信息 */}
|
||||||
|
{item.comments && (
|
||||||
|
<div style={{
|
||||||
|
backgroundColor: '#f8f9fa',
|
||||||
|
padding: '8px 12px',
|
||||||
|
borderRadius: '6px',
|
||||||
|
fontSize: '13px',
|
||||||
|
color: '#595959',
|
||||||
|
lineHeight: '1.4'
|
||||||
|
}}>
|
||||||
|
{item.comments.length > 50
|
||||||
|
? `${item.comments.substring(0, 50)}...`
|
||||||
|
: item.comments
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 浮动添加按钮 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: '20px',
|
||||||
|
right: '20px',
|
||||||
|
zIndex: 30
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
shape="round"
|
||||||
|
size="large"
|
||||||
|
onClick={onAddInsurance}
|
||||||
|
style={{
|
||||||
|
width: '56px',
|
||||||
|
height: '56px',
|
||||||
|
borderRadius: '28px',
|
||||||
|
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BxList
|
||||||
3
src/hjm/bx/bx.config.ts
Normal file
3
src/hjm/bx/bx.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '报险记录'
|
||||||
|
})
|
||||||
162
src/hjm/bx/bx.tsx
Normal file
162
src/hjm/bx/bx.tsx
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {InfiniteLoading, Loading, Empty, Button, Input} from '@nutui/nutui-react-taro'
|
||||||
|
import {Search, Plus} from '@nutui/icons-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {pageHjmCar} from "@/api/hjm/hjmCar";
|
||||||
|
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||||
|
import BestSellers from "./BestSellers";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一键报险 - 车辆列表页面
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const InsuranceList = () => {
|
||||||
|
const [list, setList] = useState<HjmCar[]>([])
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [keywords, setKeywords] = useState<string>('')
|
||||||
|
const [refreshing, setRefreshing] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const reload = async (showLoading = true) => {
|
||||||
|
try {
|
||||||
|
if (showLoading) setLoading(true)
|
||||||
|
setRefreshing(true)
|
||||||
|
|
||||||
|
// 获取车辆列表 - 只获取正常状态的车辆
|
||||||
|
const res = await pageHjmCar({
|
||||||
|
status: 1,
|
||||||
|
keywords: keywords.trim() || undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
setList(res?.list || [])
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取车辆列表失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '获取车辆列表失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setLoading(false)
|
||||||
|
setRefreshing(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSearch = () => {
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onKeywordsChange = (value: string) => {
|
||||||
|
setKeywords(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onAddInsurance = () => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/hjm/bx/bx-add'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
reload()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* 搜索栏 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
top: '20px',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
zIndex: 20,
|
||||||
|
padding: '0 16px',
|
||||||
|
backgroundColor: '#f5f5f5'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: '#fff',
|
||||||
|
padding: '8px 12px',
|
||||||
|
borderRadius: '20px',
|
||||||
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
||||||
|
}}>
|
||||||
|
<Search size={16} color="#999"/>
|
||||||
|
<Input
|
||||||
|
placeholder="搜索车辆编号或快递公司"
|
||||||
|
value={keywords}
|
||||||
|
onChange={onKeywordsChange}
|
||||||
|
onConfirm={onSearch}
|
||||||
|
style={{
|
||||||
|
border: 'none',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: '8px'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={onSearch}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
搜索
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 车辆列表 */}
|
||||||
|
<div style={{
|
||||||
|
marginTop: '80px',
|
||||||
|
paddingBottom: '80px'
|
||||||
|
}}>
|
||||||
|
{loading && list.length === 0 ? (
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
height: '200px'
|
||||||
|
}}>
|
||||||
|
<Loading type="spinner">加载中...</Loading>
|
||||||
|
</div>
|
||||||
|
) : list.length === 0 ? (
|
||||||
|
<Empty description="暂无车辆数据">
|
||||||
|
<Button type="primary" onClick={() => reload()}>
|
||||||
|
重新加载
|
||||||
|
</Button>
|
||||||
|
</Empty>
|
||||||
|
) : (
|
||||||
|
<InfiniteLoading
|
||||||
|
style={{width: '100%'}}
|
||||||
|
hasMore={false}
|
||||||
|
onLoadMore={() => {}}
|
||||||
|
>
|
||||||
|
<BestSellers data={list} onRefresh={() => reload(false)}/>
|
||||||
|
</InfiniteLoading>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 浮动添加按钮 */}
|
||||||
|
<div style={{
|
||||||
|
position: 'fixed',
|
||||||
|
bottom: '20px',
|
||||||
|
right: '20px',
|
||||||
|
zIndex: 30
|
||||||
|
}}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
shape="round"
|
||||||
|
size="large"
|
||||||
|
onClick={onAddInsurance}
|
||||||
|
style={{
|
||||||
|
width: '56px',
|
||||||
|
height: '56px',
|
||||||
|
borderRadius: '28px',
|
||||||
|
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus size={24}/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InsuranceList
|
||||||
131
src/hjm/exam/exam-simple.tsx
Normal file
131
src/hjm/exam/exam-simple.tsx
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {Button} from '@nutui/nutui-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {pageHjmQuestions} from "@/api/hjm/hjmQuestions";
|
||||||
|
import {HjmQuestions} from "@/api/hjm/hjmQuestions/model";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简化版考试系统 - 用于测试
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const ExamSimple = () => {
|
||||||
|
const [questions, setQuestions] = useState<HjmQuestions[]>([])
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
|
||||||
|
// 加载题目
|
||||||
|
const loadQuestions = () => {
|
||||||
|
setLoading(true)
|
||||||
|
console.log('开始加载题目...')
|
||||||
|
|
||||||
|
pageHjmQuestions({}).then(data => {
|
||||||
|
console.log('API返回数据:', data)
|
||||||
|
const questionList = data?.list || []
|
||||||
|
setQuestions(questionList)
|
||||||
|
console.log('加载题目成功:', questionList)
|
||||||
|
|
||||||
|
Taro.showToast({
|
||||||
|
title: `加载成功,共${questionList.length}道题`,
|
||||||
|
icon: 'success'
|
||||||
|
})
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('加载题目失败:', error)
|
||||||
|
Taro.showToast({
|
||||||
|
title: '加载题目失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadQuestions()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '16px' }}>
|
||||||
|
<h1 style={{ fontSize: '20px', fontWeight: 'bold', marginBottom: '16px' }}>
|
||||||
|
考试系统测试页面
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '16px' }}>
|
||||||
|
<p>题目数量:{questions.length} 道</p>
|
||||||
|
<p>加载状态:{loading ? '加载中...' : '加载完成'}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ marginBottom: '16px' }}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={loadQuestions}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
重新加载题目
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{questions.length > 0 && (
|
||||||
|
<div style={{ backgroundColor: 'white', padding: '16px', borderRadius: '8px' }}>
|
||||||
|
<h3 style={{ marginBottom: '12px' }}>题目列表:</h3>
|
||||||
|
{questions.slice(0, 5).map((question, index) => (
|
||||||
|
<div key={index} style={{ marginBottom: '12px', padding: '8px', backgroundColor: '#f5f5f5', borderRadius: '4px' }}>
|
||||||
|
<div style={{ fontWeight: 'bold', marginBottom: '4px' }}>
|
||||||
|
第{index + 1}题:{question.question}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: '12px', color: '#666' }}>
|
||||||
|
类型:{question.type === 0 ? '选择题' : question.type === 1 ? '填空题' : '问答题'} |
|
||||||
|
难度:{question.difficulty === 0 ? '简单' : question.difficulty === 1 ? '中等' : '困难'}
|
||||||
|
</div>
|
||||||
|
{question.type === 0 && (
|
||||||
|
<div style={{ fontSize: '12px', marginTop: '4px' }}>
|
||||||
|
{question.choicesList && question.choicesList.length > 0 ? (
|
||||||
|
// 使用 choicesList 显示选项
|
||||||
|
<>
|
||||||
|
{question.choicesList.map((choice, index) => {
|
||||||
|
const optionLabel = String.fromCharCode(65 + index); // A, B, C, D
|
||||||
|
return (
|
||||||
|
<div key={index} style={{ color: choice.isCorrect ? '#52c41a' : '#333' }}>
|
||||||
|
{optionLabel}: {choice.content} {choice.isCorrect && '✓'}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
// 备用方案:使用传统字段
|
||||||
|
<>
|
||||||
|
A: {question.choicesA}<br/>
|
||||||
|
B: {question.choicesB}<br/>
|
||||||
|
C: {question.choicesC}<br/>
|
||||||
|
D: {question.choicesD}<br/>
|
||||||
|
正确答案: {question.correctAnswer}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
{questions.length > 5 && (
|
||||||
|
<div style={{ textAlign: 'center', color: '#666', fontSize: '14px' }}>
|
||||||
|
还有 {questions.length - 5} 道题目...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div style={{ marginTop: '16px' }}>
|
||||||
|
<Button
|
||||||
|
type="success"
|
||||||
|
onClick={() => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/hjm/exam/exam'
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
disabled={questions.length === 0}
|
||||||
|
>
|
||||||
|
进入完整考试系统
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ExamSimple
|
||||||
3
src/hjm/exam/exam.config.ts
Normal file
3
src/hjm/exam/exam.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '开始考试'
|
||||||
|
})
|
||||||
608
src/hjm/exam/exam.tsx
Normal file
608
src/hjm/exam/exam.tsx
Normal file
@@ -0,0 +1,608 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {ArrowLeft, ArrowRight} from '@nutui/icons-react-taro'
|
||||||
|
import {Button, Radio, Input, Progress} from '@nutui/nutui-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import { TextArea } from '@nutui/nutui-react-taro'
|
||||||
|
import {pageHjmQuestions} from "@/api/hjm/hjmQuestions";
|
||||||
|
import {HjmQuestions} from "@/api/hjm/hjmQuestions/model";
|
||||||
|
import {addHjmExamLog} from "@/api/hjm/hjmExamLog";
|
||||||
|
|
||||||
|
// 用户答案接口
|
||||||
|
interface UserAnswer {
|
||||||
|
questionId: number;
|
||||||
|
answer: string;
|
||||||
|
isCorrect: boolean;
|
||||||
|
score: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 考试状态枚举
|
||||||
|
enum ExamStatus {
|
||||||
|
NOT_STARTED = 'not_started',
|
||||||
|
IN_PROGRESS = 'in_progress',
|
||||||
|
COMPLETED = 'completed'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 考试系统
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const Exam = () => {
|
||||||
|
const [questions, setQuestions] = useState<HjmQuestions[]>([])
|
||||||
|
const [currentQuestionIndex, setCurrentQuestionIndex] = useState<number>(0)
|
||||||
|
const [userAnswers, setUserAnswers] = useState<UserAnswer[]>([])
|
||||||
|
const [currentAnswer, setCurrentAnswer] = useState<any>('')
|
||||||
|
const [examStatus, setExamStatus] = useState<ExamStatus>(ExamStatus.NOT_STARTED)
|
||||||
|
const [totalScore, setTotalScore] = useState<number>(0)
|
||||||
|
const [timeRemaining, setTimeRemaining] = useState<number>(600) // 10分钟考试时间
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [error, setError] = useState<string>('')
|
||||||
|
|
||||||
|
// 加载题目
|
||||||
|
const loadQuestions = () => {
|
||||||
|
setLoading(true)
|
||||||
|
setError('')
|
||||||
|
console.log('开始加载题目...')
|
||||||
|
|
||||||
|
pageHjmQuestions({}).then(data => {
|
||||||
|
console.log('API返回数据:', data)
|
||||||
|
const questionList = data?.list || []
|
||||||
|
// 限制为10道题目
|
||||||
|
const limitedQuestions = questionList.slice(0, 10)
|
||||||
|
setQuestions(limitedQuestions)
|
||||||
|
console.log('加载题目成功:', limitedQuestions)
|
||||||
|
|
||||||
|
// 调试:检查选择题的 choicesList 数据
|
||||||
|
limitedQuestions.forEach((question, index) => {
|
||||||
|
if (question.type === 0) {
|
||||||
|
console.log(`第${index + 1}题 (选择题):`, {
|
||||||
|
question: question.question,
|
||||||
|
choicesList: question.choicesList,
|
||||||
|
correctAnswer: question.correctAnswer
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (limitedQuestions.length === 0) {
|
||||||
|
setError('没有找到题目数据')
|
||||||
|
}
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('加载题目失败:', error)
|
||||||
|
setError('加载题目失败: ' + (error.message || '未知错误'))
|
||||||
|
Taro.showToast({
|
||||||
|
title: '加载题目失败',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开始考试
|
||||||
|
const startExam = () => {
|
||||||
|
if (questions.length === 0) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '没有题目数据',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('开始考试,题目数量:', questions.length)
|
||||||
|
setExamStatus(ExamStatus.IN_PROGRESS)
|
||||||
|
setCurrentQuestionIndex(0)
|
||||||
|
setUserAnswers([])
|
||||||
|
setCurrentAnswer('')
|
||||||
|
setTotalScore(0)
|
||||||
|
setTimeRemaining(600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前题目
|
||||||
|
const getCurrentQuestion = (): HjmQuestions | null => {
|
||||||
|
try {
|
||||||
|
if (questions && questions.length > 0 &&
|
||||||
|
currentQuestionIndex >= 0 &&
|
||||||
|
currentQuestionIndex < questions.length) {
|
||||||
|
return questions[currentQuestionIndex]
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取当前题目时出错:', error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交当前题目答案
|
||||||
|
const submitCurrentAnswer = () => {
|
||||||
|
const currentQuestion = getCurrentQuestion()
|
||||||
|
if (!currentQuestion || !currentAnswer.trim()) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择或填写答案',
|
||||||
|
icon: 'error'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算得分
|
||||||
|
const isCorrect = checkAnswer(currentQuestion, currentAnswer)
|
||||||
|
const score = isCorrect ? 10 : 0 // 每题10分
|
||||||
|
|
||||||
|
const userAnswer: UserAnswer = {
|
||||||
|
questionId: currentQuestion.id!,
|
||||||
|
answer: currentAnswer,
|
||||||
|
isCorrect,
|
||||||
|
score
|
||||||
|
}
|
||||||
|
|
||||||
|
const newUserAnswers = [...userAnswers, userAnswer]
|
||||||
|
setUserAnswers(newUserAnswers)
|
||||||
|
|
||||||
|
// 显示答题反馈
|
||||||
|
const currentScore = userAnswers.reduce((sum, answer) => sum + answer.score, 0) + score
|
||||||
|
Taro.showToast({
|
||||||
|
title: isCorrect ? `回答正确!+10分 (总分:${currentScore})` : `回答错误!(总分:${currentScore})`,
|
||||||
|
icon: isCorrect ? 'success' : 'none',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
|
||||||
|
// 清空当前答案
|
||||||
|
setCurrentAnswer('')
|
||||||
|
|
||||||
|
// 延迟跳转,让用户看到反馈
|
||||||
|
setTimeout(() => {
|
||||||
|
// 检查是否是最后一题
|
||||||
|
if (currentQuestionIndex === questions.length - 1) {
|
||||||
|
// 考试结束
|
||||||
|
finishExam(newUserAnswers)
|
||||||
|
} else {
|
||||||
|
// 下一题
|
||||||
|
setCurrentQuestionIndex(currentQuestionIndex + 1)
|
||||||
|
}
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查答案是否正确
|
||||||
|
const checkAnswer = (question: HjmQuestions, answer: string): boolean => {
|
||||||
|
try {
|
||||||
|
if (question.type === 0) { // 选择题
|
||||||
|
// 使用 choicesList 来检查答案
|
||||||
|
if (question.choicesList && question.choicesList.length > 0) {
|
||||||
|
// 找到用户选择的选项索引
|
||||||
|
let selectedIndex = -1;
|
||||||
|
|
||||||
|
// 如果答案是字母格式(A, B, C, D)
|
||||||
|
if (answer.length === 1 && answer >= 'A' && answer <= 'D') {
|
||||||
|
selectedIndex = answer.charCodeAt(0) - 65; // A=0, B=1, C=2, D=3
|
||||||
|
}
|
||||||
|
// 如果答案是数字格式(0, 1, 2, 3)
|
||||||
|
else if (!isNaN(Number(answer))) {
|
||||||
|
selectedIndex = Number(answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查索引是否有效
|
||||||
|
if (selectedIndex >= 0 && selectedIndex < question.choicesList.length) {
|
||||||
|
return question.choicesList[selectedIndex]?.isCorrect || false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 备用方案:使用 correctAnswer 字段
|
||||||
|
return answer === question.correctAnswer
|
||||||
|
} else if (question.type === 1) { // 填空题
|
||||||
|
// 简单的字符串匹配,可以根据需要改进
|
||||||
|
return answer.trim().toLowerCase() === question.correctAnswer?.trim().toLowerCase()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} catch (error) {
|
||||||
|
console.error('检查答案时出错:', error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成考试
|
||||||
|
const finishExam = (answers: UserAnswer[]) => {
|
||||||
|
const total = answers.reduce((sum, answer) => sum + answer.score, 0)
|
||||||
|
setTotalScore(total)
|
||||||
|
setExamStatus(ExamStatus.COMPLETED)
|
||||||
|
Taro.showToast({
|
||||||
|
title: `考试完成!得分:${total}分`,
|
||||||
|
icon: 'success',
|
||||||
|
duration: 3000
|
||||||
|
})
|
||||||
|
// 考试得满分完成本月学习任务
|
||||||
|
addHjmExamLog({total: total.toString(), status: total == 100 ? 1 : 0, useTime: formatTime(600 - timeRemaining)}).then(() => {})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新开始考试
|
||||||
|
const restartExam = () => {
|
||||||
|
setExamStatus(ExamStatus.NOT_STARTED)
|
||||||
|
setCurrentQuestionIndex(0)
|
||||||
|
setUserAnswers([])
|
||||||
|
setCurrentAnswer('')
|
||||||
|
setTotalScore(0)
|
||||||
|
setTimeRemaining(600)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算进度百分比
|
||||||
|
const getProgress = (): number => {
|
||||||
|
if (questions.length === 0) return 0
|
||||||
|
return Math.round(((currentQuestionIndex + 1) / questions.length) * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化时间显示
|
||||||
|
const formatTime = (seconds: number): string => {
|
||||||
|
const minutes = Math.floor(seconds / 60)
|
||||||
|
const remainingSeconds = seconds % 60
|
||||||
|
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取成绩等级
|
||||||
|
const getGradeLevel = (score: number, totalScore: number): { level: string, color: string, description: string } => {
|
||||||
|
const percentage = (score / totalScore) * 100
|
||||||
|
if (percentage >= 90) {
|
||||||
|
return {level: '优秀', color: '#52c41a', description: '恭喜您!成绩优异!'}
|
||||||
|
} else if (percentage >= 80) {
|
||||||
|
return {level: '良好', color: '#1890ff', description: '成绩良好,继续努力!'}
|
||||||
|
} else if (percentage >= 70) {
|
||||||
|
return {level: '中等', color: '#faad14', description: '成绩中等,还有提升空间!'}
|
||||||
|
} else if (percentage >= 60) {
|
||||||
|
return {level: '及格', color: '#fa8c16', description: '刚好及格,需要加强学习!'}
|
||||||
|
} else {
|
||||||
|
return {level: '不及格', color: '#f5222d', description: '成绩不理想,建议重新学习!'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取答题统计
|
||||||
|
const getAnswerStats = () => {
|
||||||
|
const correctCount = userAnswers.filter(answer => answer.isCorrect).length
|
||||||
|
const wrongCount = userAnswers.length - correctCount
|
||||||
|
const totalTime = 600 - timeRemaining
|
||||||
|
return {
|
||||||
|
correctCount,
|
||||||
|
wrongCount,
|
||||||
|
totalTime: formatTime(totalTime),
|
||||||
|
accuracy: userAnswers.length > 0 ? Math.round((correctCount / userAnswers.length) * 100) : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
loadQuestions()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 倒计时效果
|
||||||
|
useEffect(() => {
|
||||||
|
let timer: NodeJS.Timeout
|
||||||
|
if (examStatus === ExamStatus.IN_PROGRESS && timeRemaining > 0) {
|
||||||
|
timer = setTimeout(() => {
|
||||||
|
setTimeRemaining(prev => prev - 1)
|
||||||
|
}, 1000)
|
||||||
|
} else if (timeRemaining === 0 && examStatus === ExamStatus.IN_PROGRESS) {
|
||||||
|
// 时间到,自动提交
|
||||||
|
finishExam(userAnswers)
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
if (timer) {
|
||||||
|
clearTimeout(timer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [examStatus, timeRemaining]) // 移除 userAnswers 依赖,避免无限循环
|
||||||
|
|
||||||
|
const currentQuestion = getCurrentQuestion()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{padding: '16px', minHeight: '100vh', backgroundColor: '#f5f5f5'}}>
|
||||||
|
{/* 加载状态 */}
|
||||||
|
{loading && (
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '24px', textAlign: 'center'}}>
|
||||||
|
<h1 style={{fontSize: '20px', fontWeight: 'bold', marginBottom: '16px'}}>正在加载题目...</h1>
|
||||||
|
<div style={{color: '#666'}}>请稍候</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 错误状态 */}
|
||||||
|
{error && !loading && (
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '24px', textAlign: 'center'}}>
|
||||||
|
<h1 style={{fontSize: '20px', fontWeight: 'bold', marginBottom: '16px', color: '#f5222d'}}>加载失败</h1>
|
||||||
|
<div style={{marginBottom: '16px', color: '#666'}}>{error}</div>
|
||||||
|
<Button type="primary" onClick={loadQuestions}>
|
||||||
|
重新加载
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 考试未开始 */}
|
||||||
|
{!loading && !error && examStatus === ExamStatus.NOT_STARTED && (
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '24px', textAlign: 'center'}}>
|
||||||
|
<h1 style={{fontSize: '20px', fontWeight: 'bold', marginBottom: '16px'}}>在线考试系统</h1>
|
||||||
|
<div style={{marginBottom: '16px', color: '#666'}}>
|
||||||
|
<p>题目数量:{questions.length} 道</p>
|
||||||
|
<p>考试时间:10 分钟</p>
|
||||||
|
<p>每题分值:10 分</p>
|
||||||
|
<p>总分:{questions.length * 10} 分</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
onClick={startExam}
|
||||||
|
disabled={questions.length === 0}
|
||||||
|
>
|
||||||
|
开始考试
|
||||||
|
</Button>
|
||||||
|
{questions.length === 0 && (
|
||||||
|
<div style={{marginTop: '8px', fontSize: '14px', color: '#f5222d'}}>
|
||||||
|
暂无题目数据,请联系管理员
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 考试进行中 */}
|
||||||
|
{examStatus === ExamStatus.IN_PROGRESS && currentQuestion && (
|
||||||
|
<div>
|
||||||
|
{/* 顶部信息栏 */}
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '16px', marginBottom: '16px'}}>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px'}}>
|
||||||
|
<span style={{fontSize: '14px', color: '#666'}}>
|
||||||
|
第 {currentQuestionIndex + 1} 题 / 共 {questions.length} 题
|
||||||
|
</span>
|
||||||
|
<span style={{fontSize: '14px', fontWeight: 'bold', color: '#f5222d'}}>
|
||||||
|
剩余时间:{formatTime(timeRemaining)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '8px'}}>
|
||||||
|
<span style={{fontSize: '14px', color: '#1890ff'}}>
|
||||||
|
当前得分:{userAnswers.reduce((sum, answer) => sum + answer.score, 0)} 分
|
||||||
|
</span>
|
||||||
|
<span style={{fontSize: '14px', color: '#666'}}>
|
||||||
|
已答:{userAnswers.length} 题
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Progress percent={getProgress()} color="#1890ff"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 题目内容 */}
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '16px', marginBottom: '16px'}}>
|
||||||
|
<div style={{marginBottom: '16px'}}>
|
||||||
|
<h2 style={{fontSize: '18px', fontWeight: 'bold', marginBottom: '8px'}}>
|
||||||
|
{currentQuestionIndex + 1}. {currentQuestion.question}
|
||||||
|
</h2>
|
||||||
|
<div style={{fontSize: '14px', color: '#999'}}>
|
||||||
|
{currentQuestion.type === 0 ? '选择题' : currentQuestion.type === 1 ? '填空题' : '问答题'}
|
||||||
|
({currentQuestion.difficulty === 0 ? '简单' : currentQuestion.difficulty === 1 ? '中等' : '困难'})
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 选择题选项 */}
|
||||||
|
{currentQuestion.type === 0 && (
|
||||||
|
<div>
|
||||||
|
<Radio.Group
|
||||||
|
value={currentAnswer}
|
||||||
|
onChange={(value) => setCurrentAnswer(value)}
|
||||||
|
>
|
||||||
|
{currentQuestion.choicesList && currentQuestion.choicesList.length > 0 ? (
|
||||||
|
// 使用 choicesList 显示选项
|
||||||
|
currentQuestion.choicesList.map((choice, index) => {
|
||||||
|
const optionLabel = String.fromCharCode(65 + index); // A, B, C, D
|
||||||
|
return (
|
||||||
|
<div key={index} style={{marginBottom: '8px'}}>
|
||||||
|
<Radio value={optionLabel}>
|
||||||
|
{optionLabel}. {choice.content}
|
||||||
|
</Radio>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
// 备用方案:使用传统的 choicesA, choicesB 等字段
|
||||||
|
<>
|
||||||
|
{currentQuestion.choicesA && (
|
||||||
|
<div style={{marginBottom: '8px'}}>
|
||||||
|
<Radio value="A">A. {currentQuestion.choicesA}</Radio>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{currentQuestion.choicesB && (
|
||||||
|
<div style={{marginBottom: '8px'}}>
|
||||||
|
<Radio value="B">B. {currentQuestion.choicesB}</Radio>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{currentQuestion.choicesC && (
|
||||||
|
<div style={{marginBottom: '8px'}}>
|
||||||
|
<Radio value="C">C. {currentQuestion.choicesC}</Radio>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{currentQuestion.choicesD && (
|
||||||
|
<div style={{marginBottom: '8px'}}>
|
||||||
|
<Radio value="D">D. {currentQuestion.choicesD}</Radio>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Radio.Group>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 填空题输入 */}
|
||||||
|
{currentQuestion.type === 1 && (
|
||||||
|
<div style={{marginBottom: '16px'}}>
|
||||||
|
<Input
|
||||||
|
placeholder="请输入答案"
|
||||||
|
value={currentAnswer}
|
||||||
|
onChange={(value) => setCurrentAnswer(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 问答题输入 */}
|
||||||
|
{currentQuestion.type === 2 && (
|
||||||
|
<div style={{marginBottom: '16px'}}>
|
||||||
|
<TextArea
|
||||||
|
placeholder={'个性签名'}
|
||||||
|
value={currentAnswer}
|
||||||
|
onChange={(value) => setCurrentAnswer(value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 操作按钮 */}
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '16px'}}>
|
||||||
|
<div style={{display: 'flex', justifyContent: 'space-between'}}>
|
||||||
|
<Button
|
||||||
|
type="default"
|
||||||
|
disabled={currentQuestionIndex === 0}
|
||||||
|
onClick={() => setCurrentQuestionIndex(currentQuestionIndex - 1)}
|
||||||
|
>
|
||||||
|
<ArrowLeft size={16}/> 上一题
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={submitCurrentAnswer}
|
||||||
|
disabled={!currentAnswer.trim()}
|
||||||
|
>
|
||||||
|
{currentQuestionIndex === questions.length - 1 ? '提交试卷' : '下一题'}
|
||||||
|
<ArrowRight size={16}/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 考试完成 */}
|
||||||
|
{examStatus === ExamStatus.COMPLETED && (
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '24px', textAlign: 'center'}}>
|
||||||
|
<h1 style={{fontSize: '24px', fontWeight: 'bold', marginBottom: '16px', color: '#52c41a'}}>🎉
|
||||||
|
考试完成!</h1>
|
||||||
|
|
||||||
|
{/* 成绩展示 */}
|
||||||
|
<div style={{marginBottom: '24px'}}>
|
||||||
|
<div style={{fontSize: '36px', fontWeight: 'bold', color: '#1890ff', marginBottom: '8px'}}>{totalScore} 分
|
||||||
|
</div>
|
||||||
|
<div style={{color: '#666', marginBottom: '8px'}}>总分:{questions.length * 10} 分</div>
|
||||||
|
|
||||||
|
{/* 成绩等级 */}
|
||||||
|
{(() => {
|
||||||
|
const gradeInfo = getGradeLevel(totalScore, questions.length * 10)
|
||||||
|
return (
|
||||||
|
<div style={{marginBottom: '16px'}}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
display: 'inline-block',
|
||||||
|
padding: '8px 16px',
|
||||||
|
borderRadius: '20px',
|
||||||
|
color: 'white',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '8px',
|
||||||
|
backgroundColor: gradeInfo.color
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{gradeInfo.level}
|
||||||
|
</div>
|
||||||
|
<div style={{fontSize: '14px', color: '#666'}}>{gradeInfo.description}</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 答题统计 */}
|
||||||
|
<div style={{marginBottom: '24px', backgroundColor: '#f5f5f5', borderRadius: '8px', padding: '16px'}}>
|
||||||
|
<h3 style={{fontWeight: 'bold', marginBottom: '12px', textAlign: 'left'}}>📊 答题统计</h3>
|
||||||
|
{(() => {
|
||||||
|
const stats = getAnswerStats()
|
||||||
|
return (
|
||||||
|
<div style={{display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '16px', fontSize: '14px'}}>
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<div style={{color: '#52c41a', fontWeight: 'bold', fontSize: '18px'}}>{stats.correctCount}</div>
|
||||||
|
<div style={{color: '#666'}}>答对题数</div>
|
||||||
|
</div>
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<div style={{color: '#f5222d', fontWeight: 'bold', fontSize: '18px'}}>{stats.wrongCount}</div>
|
||||||
|
<div style={{color: '#666'}}>答错题数</div>
|
||||||
|
</div>
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<div style={{color: '#1890ff', fontWeight: 'bold', fontSize: '18px'}}>{stats.accuracy}%</div>
|
||||||
|
<div style={{color: '#666'}}>正确率</div>
|
||||||
|
</div>
|
||||||
|
<div style={{textAlign: 'center'}}>
|
||||||
|
<div style={{color: '#722ed1', fontWeight: 'bold', fontSize: '18px'}}>{stats.totalTime}</div>
|
||||||
|
<div style={{color: '#666'}}>用时</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 答题详情 */}
|
||||||
|
<div style={{marginBottom: '24px', textAlign: 'left'}}>
|
||||||
|
<h3 style={{fontWeight: 'bold', marginBottom: '12px'}}>📝 答题详情</h3>
|
||||||
|
<div style={{maxHeight: '320px', overflowY: 'auto'}}>
|
||||||
|
{userAnswers.map((answer, index) => {
|
||||||
|
const question = questions.find(q => q.id === answer.questionId)
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
padding: '12px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
borderLeft: `4px solid ${answer.isCorrect ? '#52c41a' : '#f5222d'}`,
|
||||||
|
backgroundColor: answer.isCorrect ? '#f6ffed' : '#fff2f0',
|
||||||
|
marginBottom: '12px'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'flex-start',
|
||||||
|
marginBottom: '8px'
|
||||||
|
}}>
|
||||||
|
<span style={{fontWeight: '500', fontSize: '14px'}}>第{index + 1}题</span>
|
||||||
|
<span style={{
|
||||||
|
fontSize: '14px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: answer.isCorrect ? '#52c41a' : '#f5222d'
|
||||||
|
}}>
|
||||||
|
{answer.isCorrect ? '✓ 正确' : '✗ 错误'} ({answer.score}分)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div style={{fontSize: '14px', color: '#333', marginBottom: '8px'}}>
|
||||||
|
<strong>题目:</strong>{question?.question}
|
||||||
|
</div>
|
||||||
|
<div style={{fontSize: '14px'}}>
|
||||||
|
<span style={{color: '#666'}}>您的答案:</span>
|
||||||
|
<span style={{color: answer.isCorrect ? '#52c41a' : '#f5222d'}}>{answer.answer}</span>
|
||||||
|
</div>
|
||||||
|
{!answer.isCorrect && (
|
||||||
|
<div style={{fontSize: '14px', marginTop: '4px'}}>
|
||||||
|
<span style={{color: '#666'}}>正确答案:</span>
|
||||||
|
<span style={{color: '#52c41a'}}>
|
||||||
|
{(() => {
|
||||||
|
// 如果是选择题,显示正确选项的内容
|
||||||
|
if (question?.type === 0 && question.choicesList) {
|
||||||
|
const correctChoice = question.choicesList.find(choice => choice.isCorrect);
|
||||||
|
if (correctChoice) {
|
||||||
|
const correctIndex = question.choicesList.indexOf(correctChoice);
|
||||||
|
const correctLabel = String.fromCharCode(65 + correctIndex);
|
||||||
|
return `${correctLabel}. ${correctChoice.content}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 备用方案:使用 correctAnswer 字段
|
||||||
|
return question?.correctAnswer || '未知';
|
||||||
|
})()}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{display: 'flex', flexDirection: 'column', gap: '8px'}}>
|
||||||
|
<Button type="primary" size="large" onClick={restartExam}>
|
||||||
|
重新考试
|
||||||
|
</Button>
|
||||||
|
<Button type="default" size="large" onClick={() => Taro.navigateBack()}>
|
||||||
|
返回
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Exam
|
||||||
@@ -163,8 +163,7 @@ const Location = () => {
|
|||||||
{
|
{
|
||||||
points: points,
|
points: points,
|
||||||
color: '#ff0000',
|
color: '#ff0000',
|
||||||
fillColor: '#ffcccc',
|
strokeWidth: 3
|
||||||
strokeWidth: 2
|
|
||||||
}
|
}
|
||||||
] : []}
|
] : []}
|
||||||
onTap={() => {
|
onTap={() => {
|
||||||
|
|||||||
3
src/hjm/video/video.config.ts
Normal file
3
src/hjm/video/video.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '观看视频'
|
||||||
|
})
|
||||||
69
src/hjm/video/video.tsx
Normal file
69
src/hjm/video/video.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {Video} from '@nutui/nutui-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {useRouter} from '@tarojs/taro'
|
||||||
|
import {getCmsArticle} from "@/api/cms/cmsArticle";
|
||||||
|
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||||
|
import {View} from '@tarojs/components'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章终极列表
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const VideoForm = () => {
|
||||||
|
const {params} = useRouter();
|
||||||
|
const [item, setItem] = useState<CmsArticle>()
|
||||||
|
const [source, setSource] = useState({
|
||||||
|
src: '',
|
||||||
|
type: 'video/mp4',
|
||||||
|
})
|
||||||
|
const options = {
|
||||||
|
autoplay: true,
|
||||||
|
muted: true,
|
||||||
|
controls: true,
|
||||||
|
}
|
||||||
|
const play = (elm: any) => console.log('play', elm)
|
||||||
|
const pause = (elm: any) => console.log('pause', elm)
|
||||||
|
const playend = () => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/hjm/exam/exam',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
getCmsArticle(Number(params.id)).then(data => {
|
||||||
|
setItem(data)
|
||||||
|
Taro.setNavigationBarTitle({
|
||||||
|
title: `${data.title}`
|
||||||
|
})
|
||||||
|
console.log(item)
|
||||||
|
setSource({
|
||||||
|
src: `${data.pdfUrl || 'https://oss.wsdns.cn/20250605/9e88d2100425471288d4115cc48660ed.mp4'}`,
|
||||||
|
type: 'video/mp4',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
reload()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'px-3 mt-4 mb-10'}>
|
||||||
|
<div className={'flex flex-col justify-between items-center bg-white rounded-lg p-2'}>
|
||||||
|
<Video
|
||||||
|
source={source}
|
||||||
|
options={options}
|
||||||
|
onPlay={play}
|
||||||
|
onPause={pause}
|
||||||
|
onPlayEnd={playend}
|
||||||
|
style={{ height: '163px' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<View className={'content text-gray-700 text-sm py-4 text-center'}>
|
||||||
|
观看完视频后开始考试!
|
||||||
|
</View>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default VideoForm
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { Swiper } from '@nutui/nutui-react-taro'
|
|
||||||
import {CmsAd} from "@/api/cms/cmsAd/model";
|
|
||||||
import {getCmsAd} from "@/api/cms/cmsAd";
|
|
||||||
|
|
||||||
const MyPage = () => {
|
|
||||||
const [item, setItem] = useState<CmsAd>()
|
|
||||||
const reload = () => {
|
|
||||||
getCmsAd(366).then(data => {
|
|
||||||
setItem(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Swiper defaultValue={0} height={279} indicator style={{ height: '280px' }}>
|
|
||||||
{item?.imageList?.map((item) => (
|
|
||||||
<Swiper.Item key={item}>
|
|
||||||
<img width="100%" height="100%" src={item.url} alt="" style={{ height: '280px' }} />
|
|
||||||
</Swiper.Item>
|
|
||||||
))}
|
|
||||||
</Swiper>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default MyPage
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import {useEffect} from "react";
|
|
||||||
import {Image, Space} from '@nutui/nutui-react-taro'
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
|
|
||||||
const BestSellers = (props: any) => {
|
|
||||||
const reload = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'px-2 mb-4'}>
|
|
||||||
<div className={'flex flex-col justify-between items-center rounded-lg p-3'}>
|
|
||||||
{props.data?.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div key={index} className={'flex bg-white rounded-lg w-full p-3 mb-2'}
|
|
||||||
onClick={() => Taro.navigateTo({url: '/hjm/location?id=' + item.id})}>
|
|
||||||
<Image src={item.image} mode={'scaleToFill'}
|
|
||||||
radius="10%" width="80" height="80"/>
|
|
||||||
<div className={'mx-3 flex flex-col'}>
|
|
||||||
<Space direction={'vertical'}>
|
|
||||||
<div className={'car-no text-lg font-bold'}>{item.code}</div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>快递公司:<span
|
|
||||||
className={'text-gray-700'}>{item.parentOrganization}</span></div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>保险状态:<span className={'text-green-600'}>{item.insuranceStatus}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>绑定操作员:<span
|
|
||||||
className={'text-gray-700'}>{item.driver}</span></div>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<div style={{height: '170px'}}></div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default BestSellers
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {Tabs, TabPane} from '@nutui/nutui-react-taro'
|
|
||||||
|
|
||||||
const list = [
|
|
||||||
{
|
|
||||||
title: '今天',
|
|
||||||
id: 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '昨天',
|
|
||||||
id: 2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '过去7天',
|
|
||||||
id: 3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '过去30天',
|
|
||||||
id: 4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
const Chart = () => {
|
|
||||||
const [tapIndex, setTapIndex] = useState<string | number>('0')
|
|
||||||
const reload = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Tabs
|
|
||||||
align={'left'}
|
|
||||||
tabStyle={{position: 'sticky', top: '0px'}}
|
|
||||||
value={tapIndex}
|
|
||||||
onChange={(paneKey) => {
|
|
||||||
setTapIndex(paneKey)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
list?.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<TabPane key={index} title={item.title}/>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</Tabs>
|
|
||||||
{
|
|
||||||
list?.map((item, index) => {
|
|
||||||
console.log(item.title)
|
|
||||||
return (
|
|
||||||
<div key={index} className={'px-3'}>
|
|
||||||
{
|
|
||||||
tapIndex != index ? null :
|
|
||||||
<div className={'bg-white rounded-lg p-4 flex justify-center items-center text-center text-gray-300'} style={{height: '200px'}}>
|
|
||||||
线状图
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</>
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Chart
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {Button} from '@nutui/nutui-react-taro'
|
|
||||||
import {Target, Scan} from '@nutui/icons-react-taro'
|
|
||||||
import {getUserInfo} from "@/api/layout";
|
|
||||||
|
|
||||||
const ExpirationTime = () => {
|
|
||||||
const [roleName, setRoleName] = useState<string>()
|
|
||||||
const onScanCode = () => {
|
|
||||||
Taro.scanCode({
|
|
||||||
onlyFromCamera: true,
|
|
||||||
scanType: ['qrCode'],
|
|
||||||
success: (res) => {
|
|
||||||
console.log(res,'qrcode...')
|
|
||||||
Taro.navigateTo({ url: '/hjm/query?id=' + res.result })
|
|
||||||
},
|
|
||||||
fail: (res) => {
|
|
||||||
console.log(res,'扫码失败')
|
|
||||||
Taro.showToast({
|
|
||||||
title: '扫码失败',
|
|
||||||
icon: 'none',
|
|
||||||
duration: 2000
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getUserInfo().then((data) => {
|
|
||||||
if (data) {
|
|
||||||
data.roles?.map((item,index) => {
|
|
||||||
if(index == 0){
|
|
||||||
setRoleName(item.roleCode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'mb-3 w-full fixed'} style={{ marginTop: '90px'}}>
|
|
||||||
<div className={'w-full flex justify-around items-center py-3 rounded-lg'}>
|
|
||||||
<Button size={'large'} style={{ background: 'linear-gradient(to right, #f3f2f7, #805de1)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/location' })}>定位查询</Button>
|
|
||||||
<Button size={'large'} style={{ background: 'linear-gradient(to right, #fffbe6, #ffc53d)',borderColor:'#f3f2f7'}} icon={<Scan />} onClick={onScanCode}>车辆查询</Button>
|
|
||||||
{
|
|
||||||
roleName == 'youzheng' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #eaff8f, #7cb305)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/fence' })}>电子围栏</Button>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
roleName == 'kuaidiyuan' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #ffa39e, #ff4d4f)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/baoxiu' })}>一键报修</Button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default ExpirationTime
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import Taro from '@tarojs/taro';
|
|
||||||
import {TriangleDown} from '@nutui/icons-react-taro'
|
|
||||||
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
|
||||||
|
|
||||||
const Header = (props: any) => {
|
|
||||||
const [showBasic, setShowBasic] = useState(false)
|
|
||||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
Taro.getSystemInfo({
|
|
||||||
success: (res) => {
|
|
||||||
setStatusBarHeight(res.statusBarHeight)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<NavBar
|
|
||||||
fixed={true}
|
|
||||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
|
||||||
onBackClick={() => {
|
|
||||||
}}
|
|
||||||
left={
|
|
||||||
<div className={'flex items-center gap-2'} onClick={() => setShowBasic(true)}>
|
|
||||||
<Avatar
|
|
||||||
size="22"
|
|
||||||
shape="square"
|
|
||||||
src={props.user?.avatar}
|
|
||||||
/>
|
|
||||||
{props.user?.nickname}
|
|
||||||
<TriangleDown size={9}/>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
</NavBar>
|
|
||||||
<Popup
|
|
||||||
visible={showBasic}
|
|
||||||
position="bottom"
|
|
||||||
className={'w-full h-full'}
|
|
||||||
onClose={() => {
|
|
||||||
setShowBasic(false)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className={'py-3 font-bold text-center'}>车辆信息</div>
|
|
||||||
|
|
||||||
</Popup>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Header
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {ArrowRight} from '@nutui/icons-react-taro'
|
|
||||||
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {useRouter} from '@tarojs/taro'
|
|
||||||
import {BaseUrl} from "@/utils/config";
|
|
||||||
import {TEMPLATE_ID} from "@/utils/server";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 帮助中心
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
const Help = () => {
|
|
||||||
const {params} = useRouter();
|
|
||||||
const [categoryId, setCategoryId] = useState<number>(3494)
|
|
||||||
const [list, setList] = useState<CmsArticle[]>([])
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
if (params.id) {
|
|
||||||
setCategoryId(Number(params.id))
|
|
||||||
}
|
|
||||||
Taro.request({
|
|
||||||
url: BaseUrl + '/cms/cms-article/page',
|
|
||||||
method: 'GET',
|
|
||||||
data: {
|
|
||||||
categoryId
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
TenantId: TEMPLATE_ID
|
|
||||||
},
|
|
||||||
success: function (res) {
|
|
||||||
const data = res.data.data;
|
|
||||||
if (data?.list) {
|
|
||||||
setList(data?.list)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'px-3 mb-10'}>
|
|
||||||
<div className={'flex flex-col justify-between items-center bg-white rounded-lg p-4'}>
|
|
||||||
<div className={'title-bar flex justify-between items-center w-full mb-2'}>
|
|
||||||
<div className={'font-bold text-lg flex text-gray-800 justify-center items-center'}>帮助中心</div>
|
|
||||||
<a className={'text-gray-400 text-sm'} onClick={() => Taro.navigateTo({url: `/cms/article?id=${categoryId}`})}>查看全部</a>
|
|
||||||
</div>
|
|
||||||
<div className={'bg-white min-h-36 w-full'}>
|
|
||||||
{
|
|
||||||
list.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div key={index} className={'flex justify-between items-center py-2'} onClick={() => Taro.navigateTo({url: `/cms/help?id=${item.articleId}`}) }>
|
|
||||||
<div className={'text-sm'}>{item.title}</div>
|
|
||||||
<ArrowRight color={'#cccccc'} size={18} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Help
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {Input, Radio, Button} from '@nutui/nutui-react-taro'
|
|
||||||
import {TenantId} from "@/utils/config";
|
|
||||||
import './login.scss';
|
|
||||||
import {saveStorageByLoginUser} from "@/utils/server";
|
|
||||||
|
|
||||||
const Login = (props:any) => {
|
|
||||||
const [isAgree, setIsAgree] = useState(false)
|
|
||||||
const [env, setEnv] = useState<string>()
|
|
||||||
|
|
||||||
/* 获取用户手机号 */
|
|
||||||
const handleGetPhoneNumber = ({detail}) => {
|
|
||||||
const {code, encryptedData, iv} = detail
|
|
||||||
Taro.login({
|
|
||||||
success: function () {
|
|
||||||
if (code) {
|
|
||||||
Taro.request({
|
|
||||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
|
||||||
method: 'POST',
|
|
||||||
data: {
|
|
||||||
code,
|
|
||||||
encryptedData,
|
|
||||||
iv,
|
|
||||||
notVerifyPhone: true,
|
|
||||||
refereeId: 0,
|
|
||||||
sceneType: 'save_referee',
|
|
||||||
tenantId: TenantId
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
TenantId
|
|
||||||
},
|
|
||||||
success: function (res) {
|
|
||||||
saveStorageByLoginUser(res.data.data.access_token,res.data.data.user)
|
|
||||||
props.done(res.data.data.user);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log('登录失败!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
Taro.hideTabBar()
|
|
||||||
setEnv(Taro.getEnv())
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div style={{height: '80vh'}} className={'flex flex-col justify-center px-5'}>
|
|
||||||
<div className={'text-3xl text-center py-5 font-normal mb-10 '}>登录</div>
|
|
||||||
{
|
|
||||||
env === 'WEAPP' && (
|
|
||||||
<>
|
|
||||||
<div className={'flex flex-col w-full text-white rounded-full justify-between items-center my-2'} style={{ background: 'linear-gradient(to right, #7e22ce, #9333ea)'}}>
|
|
||||||
<Button open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
|
||||||
授权手机号登录
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
{
|
|
||||||
env === 'WEB' && (
|
|
||||||
<>
|
|
||||||
<div className={'flex flex-col justify-between items-center my-2'}>
|
|
||||||
<Input type="text" placeholder="手机号" maxLength={11}
|
|
||||||
style={{backgroundColor: '#ffffff', borderRadius: '8px'}}/>
|
|
||||||
</div>
|
|
||||||
<div className={'flex flex-col justify-between items-center my-2'}>
|
|
||||||
<Input type="password" placeholder="密码" style={{backgroundColor: '#ffffff', borderRadius: '8px'}}/>
|
|
||||||
</div>
|
|
||||||
<div className={'flex justify-between my-2 text-left px-1'}>
|
|
||||||
<a href={'#'} className={'text-blue-600 text-sm'}
|
|
||||||
onClick={() => Taro.navigateTo({url: '/passport/forget'})}>忘记密码</a>
|
|
||||||
<a href={'#'} className={'text-blue-600 text-sm'}
|
|
||||||
onClick={() => Taro.navigateTo({url: '/passport/setting'})}>服务配置</a>
|
|
||||||
</div>
|
|
||||||
<div className={'flex justify-center my-5'}>
|
|
||||||
<Button type="info" size={'large'} className={'w-full rounded-lg p-2'} disabled={!isAgree}>登录</Button>
|
|
||||||
</div>
|
|
||||||
<div className={'w-full bottom-20 my-2 flex justify-center text-sm items-center text-center'}>
|
|
||||||
没有账号?<a href={''} onClick={() => Taro.navigateTo({url: '/passport/register'})}
|
|
||||||
className={'text-blue-600'}>立即注册</a>
|
|
||||||
</div>
|
|
||||||
<div className={'my-2 flex fixed bottom-20 text-sm items-center px-1'}>
|
|
||||||
<Radio style={{color: '#333333'}} checked={isAgree} onClick={() => setIsAgree(!isAgree)}></Radio>
|
|
||||||
<span className={'text-gray-400'} onClick={() => setIsAgree(!isAgree)}>登录表示您已阅读并同意</span><a
|
|
||||||
onClick={() => Taro.navigateTo({url: '/passport/agreement'})}
|
|
||||||
className={'text-blue-600'}>《服务协议及隐私政策》</a>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Login
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
import {useEffect, useState} from 'react'
|
|
||||||
import {navigateTo} from '@tarojs/taro'
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {Button} from '@tarojs/components';
|
|
||||||
import {Image} from '@nutui/nutui-react-taro'
|
|
||||||
import {getUserInfo, getWxOpenId} from "@/api/layout";
|
|
||||||
import {TenantId} from "@/utils/config";
|
|
||||||
import {User} from "@/api/system/user/model";
|
|
||||||
// import News from "./News";
|
|
||||||
import {myPageBszxBm} from "@/api/bszx/bszxBm";
|
|
||||||
import {listCmsNavigation} from "@/api/cms/cmsNavigation";
|
|
||||||
|
|
||||||
const Page = () => {
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true)
|
|
||||||
const [isLogin, setIsLogin] = useState<boolean>(false)
|
|
||||||
const [userInfo, setUserInfo] = useState<User>()
|
|
||||||
const [bmLogs, setBmLogs] = useState<any>()
|
|
||||||
const [navItems, setNavItems] = useState<any>([])
|
|
||||||
|
|
||||||
/* 获取用户手机号 */
|
|
||||||
const handleGetPhoneNumber = ({detail}) => {
|
|
||||||
const {code, encryptedData, iv} = detail
|
|
||||||
Taro.login({
|
|
||||||
success: function () {
|
|
||||||
if (code) {
|
|
||||||
Taro.request({
|
|
||||||
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
|
||||||
method: 'POST',
|
|
||||||
data: {
|
|
||||||
code,
|
|
||||||
encryptedData,
|
|
||||||
iv,
|
|
||||||
notVerifyPhone: true,
|
|
||||||
refereeId: 0,
|
|
||||||
sceneType: 'save_referee',
|
|
||||||
tenantId: TenantId
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
TenantId
|
|
||||||
},
|
|
||||||
success: function (res) {
|
|
||||||
Taro.setStorageSync('access_token', res.data.data.access_token)
|
|
||||||
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
|
||||||
setUserInfo(res.data.data.user)
|
|
||||||
Taro.setStorageSync('Phone', res.data.data.user.phone)
|
|
||||||
setIsLogin(true)
|
|
||||||
Taro.showToast({
|
|
||||||
title: '登录成功',
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log('登录失败!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onLogin = (item: any, index: number) => {
|
|
||||||
if(!isLogin){
|
|
||||||
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
|
|
||||||
}else {
|
|
||||||
// 报名链接
|
|
||||||
if(index == 0){
|
|
||||||
console.log(bmLogs,'bmLogs')
|
|
||||||
if(bmLogs && bmLogs.length > 0){
|
|
||||||
return navigateTo({url: `/bszx/bm-cert/bm-cert?id=${bmLogs[0].id}`})
|
|
||||||
}else {
|
|
||||||
navigateTo({url: `/user/profile/profile`})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 善款明细
|
|
||||||
if(item.navigationId == 4119){
|
|
||||||
return navigateTo({url: `/bszx/pay-record/pay-record`})
|
|
||||||
}
|
|
||||||
return navigateTo({url: `/pages/category/category?id=${item.navigationId}`})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
// 读取栏目
|
|
||||||
listCmsNavigation({parentId: 2828,hide: 0}).then(res => {
|
|
||||||
console.log(res,'9999')
|
|
||||||
setNavItems(res);
|
|
||||||
})
|
|
||||||
Taro.getUserInfo({
|
|
||||||
success: (res) => {
|
|
||||||
const avatar = res.userInfo.avatarUrl;
|
|
||||||
setUserInfo({
|
|
||||||
avatar,
|
|
||||||
nickname: res.userInfo.nickName,
|
|
||||||
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
|
||||||
})
|
|
||||||
getUserInfo().then((data) => {
|
|
||||||
if (data) {
|
|
||||||
setUserInfo(data)
|
|
||||||
setIsLogin(true);
|
|
||||||
console.log(userInfo, 'userInfo...')
|
|
||||||
Taro.setStorageSync('UserId', data.userId)
|
|
||||||
// 获取openId
|
|
||||||
if (!data.openid) {
|
|
||||||
Taro.login({
|
|
||||||
success: (res) => {
|
|
||||||
getWxOpenId({code: res.code}).then(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
console.log('未登录')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 报名日志
|
|
||||||
myPageBszxBm({limit: 1}).then(res => {
|
|
||||||
if (res.list) {
|
|
||||||
setBmLogs(res.list);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
setLoading(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const showAuthModal = () => {
|
|
||||||
Taro.showModal({
|
|
||||||
title: '授权提示',
|
|
||||||
content: '需要获取您的用户信息',
|
|
||||||
confirmText: '去授权',
|
|
||||||
cancelText: '取消',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// 用户点击确认,打开授权设置页面
|
|
||||||
openSetting();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const openSetting = () => {
|
|
||||||
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
|
||||||
Taro.openSetting({
|
|
||||||
success: (res) => {
|
|
||||||
if (res.authSetting['scope.userInfo']) {
|
|
||||||
// 用户授权成功,可以获取用户信息
|
|
||||||
reload();
|
|
||||||
} else {
|
|
||||||
// 用户拒绝授权,提示授权失败
|
|
||||||
Taro.showToast({
|
|
||||||
title: '授权失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Taro.getSetting({
|
|
||||||
success: (res) => {
|
|
||||||
if (res.authSetting['scope.userInfo']) {
|
|
||||||
// 用户已经授权过,可以直接获取用户信息
|
|
||||||
console.log('用户已经授权过,可以直接获取用户信息')
|
|
||||||
reload();
|
|
||||||
} else {
|
|
||||||
// 用户未授权,需要弹出授权窗口
|
|
||||||
console.log('用户未授权,需要弹出授权窗口')
|
|
||||||
showAuthModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
reload();
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'my-3'}>
|
|
||||||
<div className={'pt-4 bg-yellow-50 rounded-2xl'}
|
|
||||||
style={{background: 'linear-gradient(to bottom, #ffffff, #ffffcc)'}}>
|
|
||||||
<div className={'flex justify-between pb-2 px-1'}>
|
|
||||||
{
|
|
||||||
navItems.map((item, index) => (
|
|
||||||
<div key={index} className={'text-center'}>
|
|
||||||
{
|
|
||||||
isLogin && !loading ?
|
|
||||||
<div className={'flex flex-col justify-center items-center'} onClick={() => {
|
|
||||||
onLogin(item, index)
|
|
||||||
}}>
|
|
||||||
<Image src={item.icon} height={28} width={28}/>
|
|
||||||
<div className={'mt-2'} style={{fontSize: '15px'}}>{item?.title}</div>
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<Button className={'text-white'} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
|
||||||
<div className={'flex flex-col justify-center items-center'}>
|
|
||||||
<Image src={item.icon} height={28} width={28}/>
|
|
||||||
<div className={'mt-2 text-gray-700'} style={{fontSize: '15px'}}>{item?.title}</div>
|
|
||||||
</div>
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/*<image src={'https://oss.wsdns.cn/20250224/18a2f3b807c94aac8a67af34e95534d6.jpeg'} className={'book'}>倡议书</image>*/}
|
|
||||||
{/*<News id={categoryId}/>*/}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Page
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import {Input, Button} from '@nutui/nutui-react-taro'
|
|
||||||
import {copyText} from "@/utils/common";
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
|
|
||||||
const SiteUrl = (props: any) => {
|
|
||||||
const [siteUrl, setSiteUrl] = useState<string>('')
|
|
||||||
const reload = () => {
|
|
||||||
if(props.tenantId){
|
|
||||||
setSiteUrl(`https://${props.tenantId}.shoplnk.cn`)
|
|
||||||
}else {
|
|
||||||
setSiteUrl(`https://${Taro.getStorageSync('TenantId')}.shoplnk.cn`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [props])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'px-3 mt-1 mb-4'}>
|
|
||||||
<div className={'flex justify-between items-center bg-gray-300 rounded-lg pr-2'}>
|
|
||||||
<Input type="text" value={siteUrl} disabled style={{backgroundColor: '#d1d5db', borderRadius: '8px'}}/>
|
|
||||||
<Button type={'info'} onClick={() => copyText(siteUrl)}>复制</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default SiteUrl
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
import { useRef, useEffect } from 'react'
|
|
||||||
import { View } from '@tarojs/components'
|
|
||||||
import { EChart } from "echarts-taro3-react";
|
|
||||||
import './index.scss'
|
|
||||||
|
|
||||||
export default function Index() {
|
|
||||||
const refBarChart = useRef<any>()
|
|
||||||
const defautOption = {
|
|
||||||
xAxis: {
|
|
||||||
type: "category",
|
|
||||||
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: "value",
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
data: [120, 200, 150, 80, 70, 110, 130],
|
|
||||||
type: "line",
|
|
||||||
showBackground: true,
|
|
||||||
backgroundStyle: {
|
|
||||||
color: "rgba(220, 220, 220, 0.8)",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
useEffect(() => {
|
|
||||||
if(refBarChart.current) {
|
|
||||||
refBarChart.current?.refresh(defautOption);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View className='index'>
|
|
||||||
<EChart ref={refBarChart} canvasId='line-canvas' />
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
.index {
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
background-color: #F3F3F3;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 100%;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
export default definePageConfig({
|
|
||||||
navigationBarTitleText: 'shopLnk.cn - 数灵云店',
|
|
||||||
navigationBarTextStyle: 'black',
|
|
||||||
navigationStyle: 'custom'
|
|
||||||
})
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
page {
|
|
||||||
background: url("https://oss.wsdns.cn/20250414/5bed65bff2f8434995e6c22d67271c77.png");
|
|
||||||
background-size: cover;
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
import Header from './Header'
|
|
||||||
import BestSellers from "./BestSellers";
|
|
||||||
import './index.scss'
|
|
||||||
import Taro from '@tarojs/taro';
|
|
||||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
|
||||||
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
|
||||||
import {useEffect, useState} from "react";
|
|
||||||
import ExpirationTime from "./ExpirationTime";
|
|
||||||
import {User} from "@/api/system/user/model";
|
|
||||||
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
|
||||||
import Login from "./Login";
|
|
||||||
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
|
|
||||||
import {pageHjmCar} from "@/api/hjm/hjmCar";
|
|
||||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
|
||||||
|
|
||||||
function Home() {
|
|
||||||
const [website, setWebsite] = useState<CmsWebsite>()
|
|
||||||
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
|
||||||
const [userInfo, setUserInfo] = useState<User>()
|
|
||||||
const [list, setList] = useState<HjmCar[]>([])
|
|
||||||
console.log(userInfo?.nickname)
|
|
||||||
console.log(website?.websiteName)
|
|
||||||
// const [hasMore, setHasMore] = useState(true)
|
|
||||||
// const [list, setList] = useState<BszxPay[]>([])
|
|
||||||
// const [page, setPage] = useState(1)
|
|
||||||
|
|
||||||
useShareTimeline(() => {
|
|
||||||
return {
|
|
||||||
title: '注册即可开通 - webSoft云应用',
|
|
||||||
path: `/pages/index/index`
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
useShareAppMessage(() => {
|
|
||||||
return {
|
|
||||||
title: '注册即可开通 - webSoft云应用',
|
|
||||||
path: `/pages/index/index`,
|
|
||||||
success: function (res) {
|
|
||||||
console.log('分享成功', res);
|
|
||||||
},
|
|
||||||
fail: function (res) {
|
|
||||||
console.log('分享失败', res);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// const reloadMore = async () => {
|
|
||||||
// setPage(page + 1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
const showAuthModal = () => {
|
|
||||||
Taro.showModal({
|
|
||||||
title: '授权提示',
|
|
||||||
content: '需要获取您的用户信息',
|
|
||||||
confirmText: '去授权',
|
|
||||||
cancelText: '取消',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// 用户点击确认,打开授权设置页面
|
|
||||||
openSetting();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const openSetting = () => {
|
|
||||||
// Taro.openSetting:调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。
|
|
||||||
Taro.openSetting({
|
|
||||||
success: (res) => {
|
|
||||||
if (res.authSetting['scope.userInfo']) {
|
|
||||||
// 用户授权成功,可以获取用户信息
|
|
||||||
reload();
|
|
||||||
} else {
|
|
||||||
// 用户拒绝授权,提示授权失败
|
|
||||||
Taro.showToast({
|
|
||||||
title: '授权失败',
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 登录成功后回调
|
|
||||||
const handleLogin = (data: User) => {
|
|
||||||
setIsLogin(true)
|
|
||||||
setUserInfo(data)
|
|
||||||
Taro.showTabBar()
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
Taro.hideTabBar()
|
|
||||||
// 获取站点信息
|
|
||||||
getSiteInfo().then((data) => {
|
|
||||||
console.log(data,'siteInfo')
|
|
||||||
setWebsite(data)
|
|
||||||
})
|
|
||||||
// 获取用户信息
|
|
||||||
Taro.getUserInfo({
|
|
||||||
success: (res) => {
|
|
||||||
const avatar = res.userInfo.avatarUrl;
|
|
||||||
setUserInfo({
|
|
||||||
avatar,
|
|
||||||
nickname: res.userInfo.nickName,
|
|
||||||
sexName: res.userInfo.gender == 1 ? '男' : '女'
|
|
||||||
})
|
|
||||||
getUserInfo().then((data) => {
|
|
||||||
if (data) {
|
|
||||||
setUserInfo(data)
|
|
||||||
setIsLogin(true);
|
|
||||||
Taro.setStorageSync('UserId', data.userId)
|
|
||||||
// 获取openId
|
|
||||||
if (!data.openid) {
|
|
||||||
Taro.login({
|
|
||||||
success: (res) => {
|
|
||||||
getWxOpenId({code: res.code}).then(() => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).catch(() => {
|
|
||||||
setIsLogin(false);
|
|
||||||
console.log('未登录')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
pageHjmCar({}).then(res => {
|
|
||||||
setList(res?.list || [])
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
|
||||||
Taro.getSetting({
|
|
||||||
success: (res) => {
|
|
||||||
if (res.authSetting['scope.userInfo']) {
|
|
||||||
// 用户已经授权过,可以直接获取用户信息
|
|
||||||
console.log('用户已经授权过,可以直接获取用户信息')
|
|
||||||
reload();
|
|
||||||
} else {
|
|
||||||
// 用户未授权,需要弹出授权窗口
|
|
||||||
console.log('用户未授权,需要弹出授权窗口')
|
|
||||||
showAuthModal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{!IsLogin ? (<Login done={handleLogin}/>) : (<>
|
|
||||||
<Header user={userInfo}/>
|
|
||||||
<ExpirationTime />
|
|
||||||
<InfiniteLoading
|
|
||||||
className={'w-full fixed left-0 top-40'}
|
|
||||||
>
|
|
||||||
<BestSellers data={list}/>
|
|
||||||
</InfiniteLoading>
|
|
||||||
</>)}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Home
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// 微信授权按钮的特殊样式
|
|
||||||
button[open-type="getPhoneNumber"] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 0 !important;
|
|
||||||
height: 80px;
|
|
||||||
color: #ffffff !important;
|
|
||||||
margin: 0 !important;
|
|
||||||
border: none !important;
|
|
||||||
border-radius: 50px !important;
|
|
||||||
}
|
|
||||||
@@ -39,7 +39,7 @@ const ExpirationTime = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'mb-3 fixed top-36 z-20'} style={{ width: '94%', marginLeft: '3%'}}>
|
<div className={'mb-3 fixed top-36 z-20'} style={{ width: '96%', marginLeft: '3%'}}>
|
||||||
<div className={'w-full flex justify-around items-center py-3 rounded-lg'}>
|
<div className={'w-full flex justify-around items-center py-3 rounded-lg'}>
|
||||||
<Button size={'large'} style={{ background: 'linear-gradient(to right, #f3f2f7, #805de1)',borderColor:'#f3f2f7'}} icon={<Truck />} onClick={() => Taro.navigateTo({ url: '/hjm/list' })}>车辆列表</Button>
|
<Button size={'large'} style={{ background: 'linear-gradient(to right, #f3f2f7, #805de1)',borderColor:'#f3f2f7'}} icon={<Truck />} onClick={() => Taro.navigateTo({ url: '/hjm/list' })}>车辆列表</Button>
|
||||||
<Button size={'large'} style={{ background: 'linear-gradient(to right, #fffbe6, #ffc53d)',borderColor:'#f3f2f7'}} icon={<Scan />} onClick={onScanCode}>扫一扫</Button>
|
<Button size={'large'} style={{ background: 'linear-gradient(to right, #fffbe6, #ffc53d)',borderColor:'#f3f2f7'}} icon={<Scan />} onClick={onScanCode}>扫一扫</Button>
|
||||||
@@ -47,7 +47,7 @@ const ExpirationTime = () => {
|
|||||||
roleName == 'youzheng' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #eaff8f, #7cb305)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/fence' })}>电子围栏</Button>
|
roleName == 'youzheng' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #eaff8f, #7cb305)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/fence' })}>电子围栏</Button>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
roleName == 'kuaidiyuan' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #ffa39e, #ff4d4f)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/baoxiu' })}>一键报修</Button>
|
roleName == 'kuaidiyuan' && <Button size={'large'} style={{ background: 'linear-gradient(to right, #ffa39e, #ff4d4f)',borderColor:'#f3f2f7'}} icon={<Target />} onClick={() => Taro.navigateTo({ url: '/hjm/bx/bx-add' })}>一键报险</Button>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
|
import {Button, Space} from '@nutui/nutui-react-taro'
|
||||||
import {TriangleDown} from '@nutui/icons-react-taro'
|
import {TriangleDown} from '@nutui/icons-react-taro'
|
||||||
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
||||||
|
import {getUserInfo} from "@/api/layout";
|
||||||
|
import {TenantId} from "@/utils/config";
|
||||||
|
|
||||||
const Header = (props: any) => {
|
const Header = (props: any) => {
|
||||||
|
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
||||||
const [showBasic, setShowBasic] = useState(false)
|
const [showBasic, setShowBasic] = useState(false)
|
||||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
||||||
|
const [roleName, setRoleName] = useState<string>()
|
||||||
|
|
||||||
const onNav = () => {
|
const onNav = () => {
|
||||||
Taro.navigateTo({
|
if (!IsLogin) {
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Taro.switchTab({
|
||||||
url: '/pages/user/user',
|
url: '/pages/user/user',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -18,6 +27,96 @@ const Header = (props: any) => {
|
|||||||
setStatusBarHeight(res.statusBarHeight)
|
setStatusBarHeight(res.statusBarHeight)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
getUserInfo().then((data) => {
|
||||||
|
if (data) {
|
||||||
|
setIsLogin(true);
|
||||||
|
Taro.setStorageSync('UserId', data.userId)
|
||||||
|
// 安装人员
|
||||||
|
const isKdy = data.roles?.findIndex(item => item.roleCode == 'admin')
|
||||||
|
if(isKdy != -1){
|
||||||
|
setRoleName('安装人员')
|
||||||
|
Taro.setStorageSync('RoleName', '安装人员')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 交警
|
||||||
|
const isJj = data.roles?.findIndex(item => item.roleCode == 'jiaojing')
|
||||||
|
if(isJj != -1){
|
||||||
|
setRoleName('交警')
|
||||||
|
Taro.setStorageSync('RoleName', '交警')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 邮政协会/管局
|
||||||
|
const isYz = data.roles?.findIndex(item => item.roleCode == 'youzheng')
|
||||||
|
if(isYz != -1){
|
||||||
|
setRoleName('邮政协会/管局')
|
||||||
|
Taro.setStorageSync('RoleName', '邮政协会/管局')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 快递公司
|
||||||
|
const isKd = data.roles?.findIndex(item => item.roleCode == 'kuaidi')
|
||||||
|
if(isKd != -1){
|
||||||
|
setRoleName('快递公司')
|
||||||
|
Taro.setStorageSync('RoleName', '快递公司')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 快递员
|
||||||
|
const isKdyy = data.roles?.findIndex(item => item.roleCode == 'kuaidiyuan')
|
||||||
|
if(isKdyy != -1){
|
||||||
|
setRoleName('快递员')
|
||||||
|
Taro.setStorageSync('RoleName', '快递员')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 注册用户
|
||||||
|
const isUser = data.roles?.findIndex(item => item.roleCode == 'user')
|
||||||
|
if(isUser != -1){
|
||||||
|
setRoleName('注册用户')
|
||||||
|
Taro.setStorageSync('RoleName', '注册用户')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
setIsLogin(false);
|
||||||
|
console.log('未登录')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 获取用户手机号 */
|
||||||
|
const handleGetPhoneNumber = ({detail}) => {
|
||||||
|
const {code, encryptedData, iv} = detail
|
||||||
|
Taro.login({
|
||||||
|
success: function () {
|
||||||
|
if (code) {
|
||||||
|
Taro.request({
|
||||||
|
url: 'https://server.gxwebsoft.com/api/wx-login/loginByMpWxPhone',
|
||||||
|
method: 'POST',
|
||||||
|
data: {
|
||||||
|
code,
|
||||||
|
encryptedData,
|
||||||
|
iv,
|
||||||
|
notVerifyPhone: true,
|
||||||
|
refereeId: 0,
|
||||||
|
sceneType: 'save_referee',
|
||||||
|
tenantId: TenantId
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
TenantId
|
||||||
|
},
|
||||||
|
success: function (res) {
|
||||||
|
Taro.setStorageSync('access_token', res.data.data.access_token)
|
||||||
|
Taro.setStorageSync('UserId', res.data.data.user.userId)
|
||||||
|
setIsLogin(true)
|
||||||
|
// 重新加载小程序
|
||||||
|
Taro.reLaunch({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log('登录失败!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -32,27 +131,39 @@ const Header = (props: any) => {
|
|||||||
onBackClick={() => {
|
onBackClick={() => {
|
||||||
}}
|
}}
|
||||||
left={
|
left={
|
||||||
<div className={'flex items-center gap-2'} onClick={onNav}>
|
!IsLogin ? (
|
||||||
<Avatar
|
<div style={{display: 'flex', alignItems: 'center'}}>
|
||||||
size="22"
|
<Button style={{color: '#000'}} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
|
||||||
src={props.user?.avatar}
|
<Space>
|
||||||
/>
|
<Avatar
|
||||||
{props.user?.nickname}
|
size="22"
|
||||||
<TriangleDown size={9}/>
|
src={props.user?.avatar}
|
||||||
</div>
|
/>
|
||||||
}
|
<span style={{color: '#000'}}>{props.user?.nickname}</span>
|
||||||
>
|
</Space>
|
||||||
|
</Button>
|
||||||
|
<TriangleDown size={9}/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div style={{display: 'flex', alignItems: 'center', gap: '8px'}} onClick={onNav}>
|
||||||
|
<Avatar
|
||||||
|
size="22"
|
||||||
|
src={props.user?.avatar}
|
||||||
|
/>
|
||||||
|
{props.user?.nickname}{roleName && <span>({roleName})</span>}
|
||||||
|
<TriangleDown size={9}/>
|
||||||
|
</div>
|
||||||
|
)}>
|
||||||
</NavBar>
|
</NavBar>
|
||||||
<Popup
|
<Popup
|
||||||
visible={showBasic}
|
visible={showBasic}
|
||||||
position="bottom"
|
position="bottom"
|
||||||
className={'w-full h-full'}
|
style={{width: '100%', height: '100%'}}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setShowBasic(false)
|
setShowBasic(false)
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={'py-3 font-bold text-center'}>车辆信息</div>
|
<div style={{padding: '12px 0', fontWeight: 'bold', textAlign: 'center'}}>车辆信息</div>
|
||||||
|
|
||||||
</Popup>
|
</Popup>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,18 +1,15 @@
|
|||||||
import Header from './Header'
|
import Header from './Header'
|
||||||
// import BestSellers from "./BestSellers";
|
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import {Map} from '@tarojs/components'
|
import {Map} from '@tarojs/components'
|
||||||
import {Search} from '@nutui/icons-react-taro'
|
import {Search} from '@nutui/icons-react-taro'
|
||||||
import {Button, Input} from '@nutui/nutui-react-taro'
|
import {Button, Input} from '@nutui/nutui-react-taro'
|
||||||
// import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
|
||||||
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
import {useShareAppMessage, useShareTimeline} from "@tarojs/taro"
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import ExpirationTime from "./ExpirationTime";
|
import ExpirationTime from "./ExpirationTime";
|
||||||
import {User} from "@/api/system/user/model";
|
import {User} from "@/api/system/user/model";
|
||||||
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
||||||
import Login from "./Login";
|
import Login from "./Login";
|
||||||
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
|
|
||||||
import {pageByQQMap, pageHjmCar} from "@/api/hjm/hjmCar";
|
import {pageByQQMap, pageHjmCar} from "@/api/hjm/hjmCar";
|
||||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
||||||
|
|
||||||
@@ -26,8 +23,8 @@ export interface Market {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Home() {
|
function Home() {
|
||||||
const [website, setWebsite] = useState<CmsWebsite>()
|
|
||||||
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
const [IsLogin, setIsLogin] = useState<boolean>(true)
|
||||||
|
const [search, setSearch] = useState(false)
|
||||||
const [userInfo, setUserInfo] = useState<User>()
|
const [userInfo, setUserInfo] = useState<User>()
|
||||||
const [longitude, setLongitude] = useState<any>(108.374959)
|
const [longitude, setLongitude] = useState<any>(108.374959)
|
||||||
const [latitude, setLatitude] = useState<any>(22.767024)
|
const [latitude, setLatitude] = useState<any>(22.767024)
|
||||||
@@ -35,12 +32,6 @@ function Home() {
|
|||||||
const [scale, setScale] = useState<any>(16)
|
const [scale, setScale] = useState<any>(16)
|
||||||
const [keywords, setKeywords] = useState<string>('')
|
const [keywords, setKeywords] = useState<string>('')
|
||||||
const [list, setList] = useState<HjmCar[]>([])
|
const [list, setList] = useState<HjmCar[]>([])
|
||||||
console.log(userInfo?.nickname)
|
|
||||||
console.log(website?.websiteName)
|
|
||||||
console.log(list.length)
|
|
||||||
// const [hasMore, setHasMore] = useState(true)
|
|
||||||
// const [list, setList] = useState<BszxPay[]>([])
|
|
||||||
// const [page, setPage] = useState(1)
|
|
||||||
|
|
||||||
useShareTimeline(() => {
|
useShareTimeline(() => {
|
||||||
return {
|
return {
|
||||||
@@ -168,6 +159,7 @@ function Home() {
|
|||||||
name: `${data.organization}`
|
name: `${data.organization}`
|
||||||
}])
|
}])
|
||||||
}
|
}
|
||||||
|
console.log(list.length,'carList.length')
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,7 +170,9 @@ function Home() {
|
|||||||
// 获取站点信息
|
// 获取站点信息
|
||||||
getSiteInfo().then((data) => {
|
getSiteInfo().then((data) => {
|
||||||
console.log(data, 'siteInfo')
|
console.log(data, 'siteInfo')
|
||||||
setWebsite(data)
|
if (data.search) {
|
||||||
|
setSearch(false);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
// Taro.getSetting:获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。
|
||||||
Taro.getSetting({
|
Taro.getSetting({
|
||||||
@@ -228,21 +222,21 @@ function Home() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{!IsLogin ? (<Login done={handleLogin}/>) : (<>
|
{!IsLogin && search ? (<Login done={handleLogin}/>) : (<>
|
||||||
<Header user={userInfo}/>
|
<Header user={userInfo}/>
|
||||||
<ExpirationTime/>
|
<ExpirationTime/>
|
||||||
<div className={'fixed z-20 top-24 left-0 w-full'}>
|
<div className={'fixed z-20 top-24 left-0 w-full'}>
|
||||||
<div className={'px-4'}>
|
<div className={'px-2'}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
background: '#fff',
|
background: '#fff',
|
||||||
padding: '0 10px',
|
padding: '0 7px',
|
||||||
borderRadius: '20px'
|
borderRadius: '20px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Search/>
|
<Search className={'mx-2'}/>
|
||||||
<Input
|
<Input
|
||||||
placeholder="车辆编号"
|
placeholder="车辆编号"
|
||||||
value={keywords}
|
value={keywords}
|
||||||
@@ -259,23 +253,20 @@ function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Map
|
{markers.length > 0 && (
|
||||||
id="map"
|
<Map
|
||||||
longitude={longitude}
|
id="map"
|
||||||
latitude={latitude}
|
longitude={longitude}
|
||||||
scale={scale}
|
latitude={latitude}
|
||||||
// @ts-ignore
|
scale={scale}
|
||||||
markers={markers}
|
// @ts-ignore
|
||||||
onTap={(map) => {
|
markers={markers}
|
||||||
console.log('map tap',map)
|
onTap={(map) => {
|
||||||
}}
|
console.log('map tap', map)
|
||||||
style={{width: '100%', height: '100vh'}}
|
}}
|
||||||
/>
|
style={{width: '100%', height: '100vh'}}
|
||||||
{/*<InfiniteLoading*/}
|
/>
|
||||||
{/* className={'w-full fixed left-0 top-40'}*/}
|
)}
|
||||||
{/*>*/}
|
|
||||||
{/* <BestSellers data={list}/>*/}
|
|
||||||
{/*</InfiniteLoading>*/}
|
|
||||||
</>)}
|
</>)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
3
src/pages/study/study.config.ts
Normal file
3
src/pages/study/study.config.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '学习'
|
||||||
|
})
|
||||||
59
src/pages/study/study.tsx
Normal file
59
src/pages/study/study.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {Image} from '@nutui/nutui-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import {pageCmsArticle} from "@/api/cms/cmsArticle";
|
||||||
|
import {CmsArticle} from "@/api/cms/cmsArticle/model";
|
||||||
|
import {checkMonthTaskCompleted} from "@/api/hjm/hjmExamLog";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文章终极列表
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
const Study = () => {
|
||||||
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
|
const [list, setList] = useState<CmsArticle[]>()
|
||||||
|
const [monthTaskCompleted, setMonthTaskCompleted] = useState<boolean>(false)
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
setLoading(true)
|
||||||
|
checkMonthTaskCompleted().then(res => {
|
||||||
|
if(res){
|
||||||
|
setMonthTaskCompleted(true)
|
||||||
|
}
|
||||||
|
pageCmsArticle({categoryId: 4289, status: 0}).then(data => {
|
||||||
|
setList(data?.list)
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
setLoading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
reload()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={'px-3 mt-4 mb-10'}>
|
||||||
|
{/* 已完成任务 */}
|
||||||
|
{monthTaskCompleted && !loading && (
|
||||||
|
<div style={{backgroundColor: 'white', borderRadius: '8px', padding: '24px', textAlign: 'center'}}>
|
||||||
|
<h1 style={{fontSize: '20px', fontWeight: 'bold', marginBottom: '16px', color: '#52c41a'}}>🎉
|
||||||
|
本月学习任务已完成!</h1>
|
||||||
|
<div style={{marginBottom: '16px', color: '#666'}}>
|
||||||
|
您已经完成了本月的学习任务,无需再进行考试。
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{
|
||||||
|
!monthTaskCompleted && list?.map((item, index) => {
|
||||||
|
return (
|
||||||
|
<div key={index} className={'flex flex-col justify-between items-center bg-white rounded-lg p-2'} onClick={() => Taro.navigateTo({url: `/hjm/video/video?id=${item.articleId}`})}>
|
||||||
|
<Image src={item.image} height={200}/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Study
|
||||||
@@ -10,6 +10,7 @@ import {TenantId} from "@/utils/config";
|
|||||||
function UserCard() {
|
function UserCard() {
|
||||||
const [IsLogin, setIsLogin] = useState<boolean>(false)
|
const [IsLogin, setIsLogin] = useState<boolean>(false)
|
||||||
const [userInfo, setUserInfo] = useState<User>()
|
const [userInfo, setUserInfo] = useState<User>()
|
||||||
|
const [roleName, setRoleName] = useState<string>('注册用户')
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -52,6 +53,11 @@ function UserCard() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 判断身份
|
||||||
|
const roleName = Taro.getStorageSync('RoleName');
|
||||||
|
if(roleName){
|
||||||
|
setRoleName(roleName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
console.log('未登录')
|
console.log('未登录')
|
||||||
@@ -159,7 +165,7 @@ function UserCard() {
|
|||||||
{IsLogin ? (
|
{IsLogin ? (
|
||||||
<div className={'grade text-xs py-1'}>
|
<div className={'grade text-xs py-1'}>
|
||||||
<Tag type="success" round>
|
<Tag type="success" round>
|
||||||
<div className={'p-1'}>{userInfo?.realName || '注册用户'}</div>
|
<div className={'p-1'}>{roleName || '注册用户'}</div>
|
||||||
</Tag>
|
</Tag>
|
||||||
</div>
|
</div>
|
||||||
) : ''}
|
) : ''}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ const UserCell = () => {
|
|||||||
align="center"
|
align="center"
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navTo('/user/bx/index', true)
|
navTo('/hjm/bx/bx', true)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Cell.Group>
|
</Cell.Group>
|
||||||
@@ -171,15 +171,8 @@ const UserCell = () => {
|
|||||||
title="账号安全"
|
title="账号安全"
|
||||||
align="center"
|
align="center"
|
||||||
extra={<ArrowRight color="#cccccc" size={18}/>}
|
extra={<ArrowRight color="#cccccc" size={18}/>}
|
||||||
onClick={() => Taro.navigateTo({url: '/user/profile/profile'})}
|
onClick={() => navTo('/user/profile/profile',true)}
|
||||||
/>
|
/>
|
||||||
{/*<Cell*/}
|
|
||||||
{/* className="nutui-cell-clickable"*/}
|
|
||||||
{/* title="切换账户"*/}
|
|
||||||
{/* align="center"*/}
|
|
||||||
{/* extra={<ArrowRight color="#cccccc" size={18}/>}*/}
|
|
||||||
{/* onClick={() => Taro.navigateTo({url: '/user/profile/profile'})}*/}
|
|
||||||
{/*/>*/}
|
|
||||||
<Cell
|
<Cell
|
||||||
className="nutui-cell-clickable"
|
className="nutui-cell-clickable"
|
||||||
title="退出登录"
|
title="退出登录"
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import {useEffect} from "react";
|
|
||||||
import {Image, Space} from '@nutui/nutui-react-taro'
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
|
|
||||||
const BestSellers = (props: any) => {
|
|
||||||
const reload = () => {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={'px-2 mb-4'}>
|
|
||||||
<div className={'flex flex-col justify-between items-center rounded-lg px-3'}>
|
|
||||||
{props.data?.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div key={index} className={'flex bg-white rounded-lg w-full p-3 mb-3'}
|
|
||||||
onClick={() => Taro.navigateTo({url: '/hjm/query?id=' + item.id})}>
|
|
||||||
<Image src={item.image} mode={'scaleToFill'}
|
|
||||||
radius="10%" width="80" height="80"/>
|
|
||||||
<div className={'mx-3 flex flex-col'}>
|
|
||||||
<Space direction={'vertical'}>
|
|
||||||
<div className={'car-no text-lg font-bold'}>{item.code}</div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>快递公司:<span
|
|
||||||
className={'text-gray-700'}>{item.parentOrganization}</span></div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>保险状态:<span className={'text-green-600'}>{item.insuranceStatus}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex text-xs text-gray-500'}>绑定操作员:<span
|
|
||||||
className={'text-gray-700'}>{item.driver}</span></div>
|
|
||||||
</Space>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
<div style={{height: '170px'}}></div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default BestSellers
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export default definePageConfig({
|
|
||||||
navigationBarTitleText: '报险记录',
|
|
||||||
navigationStyle: 'custom'
|
|
||||||
})
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import {useEffect, useState} from "react";
|
|
||||||
import Taro from '@tarojs/taro'
|
|
||||||
import {ArrowLeft} from '@nutui/icons-react-taro'
|
|
||||||
import {NavBar, InfiniteLoading} from '@nutui/nutui-react-taro'
|
|
||||||
import {HjmCar} from "@/api/hjm/hjmCar/model";
|
|
||||||
import BestSellers from "./BestSellers";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文章终极列表
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
const Index = () => {
|
|
||||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
|
||||||
const [list, setList] = useState<HjmCar[]>([])
|
|
||||||
|
|
||||||
const reload = () => {
|
|
||||||
// 获取车辆列表
|
|
||||||
setList([])
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Taro.getSystemInfo({
|
|
||||||
success: (res) => {
|
|
||||||
setStatusBarHeight(res.statusBarHeight)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
reload()
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<NavBar
|
|
||||||
fixed={true}
|
|
||||||
style={{marginTop: `${statusBarHeight}px`}}
|
|
||||||
onBackClick={() => {
|
|
||||||
}}
|
|
||||||
left={
|
|
||||||
<>
|
|
||||||
<ArrowLeft size={18} onClick={() => {Taro.navigateBack()}} />
|
|
||||||
{/*<SearchBar shape="round" maxLength={5} style={{paddingLeft: '1px'}}/>*/}
|
|
||||||
{/*<div className={'flex flex-col text-center justify-center items-center'}>*/}
|
|
||||||
{/* <Filter size={14}/>*/}
|
|
||||||
{/* <div className={'text-xs text-gray-600 whitespace-nowrap'}>筛选</div>*/}
|
|
||||||
{/*</div>*/}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<span>报险记录</span>
|
|
||||||
</NavBar>
|
|
||||||
<InfiniteLoading
|
|
||||||
className={'w-full fixed left-0 top-24'}
|
|
||||||
>
|
|
||||||
<BestSellers data={list}/>
|
|
||||||
</InfiniteLoading>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
export default Index
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {Image, Tag} from '@nutui/nutui-react-taro'
|
import {Image} from '@nutui/nutui-react-taro'
|
||||||
import {ConfigProvider} from '@nutui/nutui-react-taro'
|
import {ConfigProvider} from '@nutui/nutui-react-taro'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ import {uploadFile} from "@/api/system/file";
|
|||||||
|
|
||||||
function Index() {
|
function Index() {
|
||||||
const [isUpdate, setIsUpdate] = useState<boolean>(false)
|
const [isUpdate, setIsUpdate] = useState<boolean>(false)
|
||||||
|
const [submitText, setSubmitText] = useState<string>('提交')
|
||||||
|
|
||||||
const [FormData, setFormData] = useState<UserVerify>({
|
const [FormData, setFormData] = useState<UserVerify>({
|
||||||
userId: undefined,
|
userId: undefined,
|
||||||
@@ -37,6 +38,9 @@ function Index() {
|
|||||||
if (data) {
|
if (data) {
|
||||||
setIsUpdate(true);
|
setIsUpdate(true);
|
||||||
setFormData(data)
|
setFormData(data)
|
||||||
|
if(data.status == 2){
|
||||||
|
setSubmitText('重新提交')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setFormData({
|
setFormData({
|
||||||
type: 0
|
type: 0
|
||||||
@@ -146,7 +150,7 @@ function Index() {
|
|||||||
onFinish={(values) => submitSucceed(values)}
|
onFinish={(values) => submitSucceed(values)}
|
||||||
onFinishFailed={(errors) => submitFailed(errors)}
|
onFinishFailed={(errors) => submitFailed(errors)}
|
||||||
footer={
|
footer={
|
||||||
FormData.status != 1 && (
|
FormData.status != 1 && FormData.status != 0 && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -156,7 +160,7 @@ function Index() {
|
|||||||
>
|
>
|
||||||
<Button nativeType="submit" block type={'info'}
|
<Button nativeType="submit" block type={'info'}
|
||||||
disabled={FormData.status != 2 && FormData.status != undefined}>
|
disabled={FormData.status != 2 && FormData.status != undefined}>
|
||||||
提交
|
{submitText}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -288,7 +292,7 @@ function Index() {
|
|||||||
label={'审核状态'}
|
label={'审核状态'}
|
||||||
name="status"
|
name="status"
|
||||||
>
|
>
|
||||||
<Tag plain>{FormData.statusText}</Tag>
|
<span className={'text-gray-500'}>{FormData.statusText}</span>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {BaseUrl, TenantId} from "@/utils/config";
|
|||||||
let baseUrl = BaseUrl
|
let baseUrl = BaseUrl
|
||||||
|
|
||||||
if(process.env.NODE_ENV === 'development'){
|
if(process.env.NODE_ENV === 'development'){
|
||||||
// baseUrl = 'http://localhost:9000/api'
|
baseUrl = 'http://localhost:9000/api'
|
||||||
}
|
}
|
||||||
export function request<T>(options:any) {
|
export function request<T>(options:any) {
|
||||||
const token = Taro.getStorageSync('access_token');
|
const token = Taro.getStorageSync('access_token');
|
||||||
|
|||||||
Reference in New Issue
Block a user