Compare commits

42 Commits

Author SHA1 Message Date
beb97a0762 kpi总览界面,隐藏两个平安的指标 2025-09-17 15:33:11 +08:00
425c4c2043 实名认证接口加参数ump:1 2025-09-15 13:18:53 +08:00
2e9f2a6fa1 VConsole调试删除 2025-09-15 09:23:33 +08:00
93aaaacd06 实名认证链接decode测试 2025-09-15 09:23:32 +08:00
4fd27cfa0e 实名认证调整 2025-09-15 09:23:03 +08:00
f4a2c6d6fa 认证页的返回都调转列表页 2025-09-15 09:22:09 +08:00
5592ad773e 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:20 +08:00
ff53323c3f 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:18 +08:00
1df54434c9 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:16 +08:00
210eb41ca6 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:13 +08:00
436a35ddb5 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:11 +08:00
b33522708e 实名认证页,认证结果esignFlag做缓存,添加打印 2025-09-15 09:14:09 +08:00
a9938d03fa 实名认证页,认证结果esignFlag做缓存 2025-09-15 09:14:06 +08:00
e7ce0721ca 实名认证页返回都到列表页 2025-09-15 09:14:03 +08:00
3cab49c0d4 实名认证页代码优化 2025-09-15 09:14:01 +08:00
0d14a9add6 实名认证页代码优化 2025-09-15 09:13:58 +08:00
6bc78f76ad 认证页增加双击不放大功能,滚动条丝滑滚动优化 2025-09-15 09:13:55 +08:00
fe5e85b8d5 认证页下一步添加接口 2025-09-15 09:13:49 +08:00
d799cf7b93 实名认证esignFlag缓存添加 2025-09-15 09:13:46 +08:00
64240414b5 实名认证操作成功后返回到认证列表页 2025-09-15 09:13:43 +08:00
0aac318448 实名认证界面加缓存数据 2025-09-15 09:13:40 +08:00
121435ff3e 实名认证界面加缓存数据 2025-09-15 09:13:36 +08:00
2dbf353113 实名认证接口加token参数 2025-09-15 09:13:33 +08:00
728063ca86 实名认证加token参数 2025-09-15 09:13:29 +08:00
ad548db437 实名认证加token参数 2025-09-15 09:13:26 +08:00
ad5f16acc9 story#7189,跳转加token参数 2025-09-15 09:13:24 +08:00
39921aa2bb story#7189,高度调整 2025-09-15 09:13:21 +08:00
3d56f91575 story#7189,type默认'full' 2025-09-15 09:13:19 +08:00
fda0139a06 story#7189,认证页radio回显处理 2025-09-15 09:13:17 +08:00
620e6b5ad4 story#7189,回程车小程序司机端-迁移认证,跳转新的url 2025-09-15 09:13:14 +08:00
4c0ad71e89 story#7189,回程车小程序司机端-迁移认证,添加调试 2025-09-15 09:13:11 +08:00
7f8c482df1 story#7189,回程车小程序司机端-迁移认证 2025-09-15 09:13:08 +08:00
ceff5e008c story#7189,回程车小程序司机端-迁移认证页面 2025-09-15 09:13:03 +08:00
16924fb22e story#7189,回程车小程序司机端-迁移认证页面 2025-09-15 09:13:02 +08:00
6a8b6b7730 司机端培训资料,关键字接受字段更换,切换优化加loading 2025-09-09 13:34:39 +08:00
bdc78351e4 司机端培训资料,关键字接受字段更换,切换优化加loading 2025-09-09 13:34:38 +08:00
25cc195f1e 三分钟联系客户率 2025-09-09 10:55:23 +08:00
97ba1500ff 好评率好评量删除 2025-09-09 10:55:23 +08:00
93f0e9317c kpi率乘以一百 2025-09-08 10:18:33 +08:00
2c83b1ea60 kpi字段替换 2025-09-08 09:41:42 +08:00
872021eca5 平安聚合时效 2025-09-05 11:44:00 +08:00
6beda9f6f1 服务商KPI 2025-09-04 10:01:16 +08:00
69 changed files with 458 additions and 138822 deletions

332
package-lock.json generated
View File

@@ -15,10 +15,9 @@
"dayjs": "^1.8.14",
"decimal.js": "^10.4.3",
"echarts": "^5.2.2",
"element-ui": "^2.15.13",
"element-ui": "^2.15.9",
"less": "^4.1.3",
"less-loader": "^11.1.3",
"qrcode": "^1.5.4",
"qs": "^6.11.2",
"sass": "^1.65.1",
"sass-loader": "^13.3.2",
@@ -3351,6 +3350,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"engines": {
"node": ">=8"
}
@@ -4801,15 +4801,6 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"node_modules/decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/decimal.js": {
"version": "10.4.3",
"resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz",
@@ -5029,12 +5020,6 @@
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
"node_modules/dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
"license": "MIT"
},
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -5225,7 +5210,8 @@
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"node_modules/emojis-list": {
"version": "3.0.0",
@@ -6229,6 +6215,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"dependencies": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -6383,6 +6370,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
@@ -7004,6 +6992,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"engines": {
"node": ">=8"
}
@@ -7419,6 +7408,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"dependencies": {
"p-locate": "^4.1.0"
},
@@ -8455,6 +8445,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"dependencies": {
"p-try": "^2.0.0"
},
@@ -8469,6 +8460,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"dependencies": {
"p-limit": "^2.2.0"
},
@@ -8493,6 +8485,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true,
"engines": {
"node": ">=6"
}
@@ -8589,6 +8582,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
"engines": {
"node": ">=8"
}
@@ -8669,15 +8663,6 @@
"node": ">=8"
}
},
"node_modules/pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
"license": "MIT",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/portfinder": {
"version": "1.0.32",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
@@ -9409,131 +9394,6 @@
"node": ">=6"
}
},
"node_modules/qrcode": {
"version": "1.5.4",
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz",
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
"license": "MIT",
"dependencies": {
"dijkstrajs": "^1.0.1",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"bin": {
"qrcode": "bin/qrcode"
},
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/qrcode/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/qrcode/node_modules/camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/qrcode/node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"node_modules/qrcode/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/qrcode/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/qrcode/node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
"license": "ISC"
},
"node_modules/qrcode/node_modules/yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"license": "MIT",
"dependencies": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/qrcode/node_modules/yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"license": "ISC",
"dependencies": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
@@ -9783,6 +9643,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -9796,12 +9657,6 @@
"node": ">=0.10.0"
}
},
"node_modules/require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"license": "ISC"
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -10178,12 +10033,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
"license": "ISC"
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -10475,6 +10324,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -10488,6 +10338,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
@@ -11851,12 +11702,6 @@
"which": "bin/which"
}
},
"node_modules/which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
"license": "ISC"
},
"node_modules/wildcard": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",
@@ -14573,7 +14418,8 @@
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
@@ -15627,11 +15473,6 @@
}
}
},
"decamelize": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
},
"decimal.js": {
"version": "10.4.3",
"resolved": "https://registry.npmmirror.com/decimal.js/-/decimal.js-10.4.3.tgz",
@@ -15786,11 +15627,6 @@
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"dev": true
},
"dijkstrajs": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
},
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -15947,7 +15783,8 @@
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"emojis-list": {
"version": "3.0.0",
@@ -16708,6 +16545,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -16812,7 +16650,8 @@
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-intrinsic": {
"version": "1.2.1",
@@ -17249,7 +17088,8 @@
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"is-glob": {
"version": "4.0.3",
@@ -17559,6 +17399,7 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
@@ -18343,6 +18184,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
@@ -18351,6 +18193,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
@@ -18368,7 +18211,8 @@
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"param-case": {
"version": "3.0.4",
@@ -18448,7 +18292,8 @@
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"path-is-absolute": {
"version": "1.0.1",
@@ -18505,11 +18350,6 @@
"find-up": "^4.0.0"
}
},
"pngjs": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/pngjs/-/pngjs-5.0.0.tgz",
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
},
"portfinder": {
"version": "1.0.32",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
@@ -18995,96 +18835,6 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
"qrcode": {
"version": "1.5.4",
"resolved": "https://registry.npmmirror.com/qrcode/-/qrcode-1.5.4.tgz",
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
"requires": {
"dijkstrajs": "^1.0.1",
"pngjs": "^5.0.0",
"yargs": "^15.3.1"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-5.3.1.tgz",
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
},
"cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-6.0.0.tgz",
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^6.2.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
}
},
"y18n": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-4.0.3.tgz",
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
},
"yargs": {
"version": "15.4.1",
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": {
"cliui": "^6.0.0",
"decamelize": "^1.2.0",
"find-up": "^4.1.0",
"get-caller-file": "^2.0.1",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^4.2.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^18.1.2"
}
},
"yargs-parser": {
"version": "18.1.3",
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-18.1.3.tgz",
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
}
},
"qs": {
"version": "6.11.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
@@ -19271,7 +19021,8 @@
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true
},
"require-from-string": {
"version": "2.0.2",
@@ -19279,11 +19030,6 @@
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true
},
"require-main-filename": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-2.0.0.tgz",
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -19547,11 +19293,6 @@
"send": "0.18.0"
}
},
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -19793,6 +19534,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -19803,6 +19545,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
@@ -20781,11 +20524,6 @@
"isexe": "^2.0.0"
}
},
"which-module": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/which-module/-/which-module-2.0.1.tgz",
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
},
"wildcard": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",

View File

@@ -16,10 +16,9 @@
"dayjs": "^1.8.14",
"decimal.js": "^10.4.3",
"echarts": "^5.2.2",
"element-ui": "^2.15.13",
"element-ui": "^2.15.9",
"less": "^4.1.3",
"less-loader": "^11.1.3",
"qrcode": "^1.5.4",
"qs": "^6.11.2",
"sass": "^1.65.1",
"sass-loader": "^13.3.2",

View File

@@ -32,10 +32,6 @@
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=2560bbf04daef66c810c5e6a97e8c508&plugin=AMap.AutoComplete,AMap.PlaceSearch,AMap.Geolocation,AMap.Geocoder,AMap.Marker,AMap.Driving"></script>
<!-- <script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>-->
<script>
window.selfLink = window.location.href;
window.selfSearch = window.location.search;
</script>
<script>
// VConsole 默认会挂载到 `window.VConsole` 上
// let vConsole = new window.VConsole();
@@ -56,7 +52,7 @@
if (isMobile) {// 是移动端不变
// console.log("是移动端不变")
}else{
if(window.location.pathname=='/h5/supplier/dispatch/kpiIndex' || window.location.pathname=='/h5/supplier/dispatch/kpiCaseNew'){
if(window.location.pathname=='/h5/supplier/dispatch/kpiIndex'){
// console.log("执行了执行了")
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);

View File

@@ -1,160 +0,0 @@
# 年终总结看板 Dashboard
道路救援服务年终数据可视化看板项目。
## 项目结构
```
dashboard-demo/
├── index.html # 主看板页面支持URL参数动态加载数据
├── data/
│ ├── 供应商年度KPI.xlsx # 服务商KPI数据主数据源
│ ├── 师傅案件top3.xlsx # 案件量TOP3师傅数据
│ ├── 师傅在线top3.xlsx # 在线时长TOP3师傅数据
│ ├── 拒单率最高地区.xlsx # 拒单率最高地区数据
│ └── 拒单率最高时段.xlsx # 拒单率最高时段数据
└── README.md # 项目说明
```
## 功能特性
- 深色主题数据可视化看板
- **直接读取Excel文件**无需转换为JSON
- 支持通过URL参数 `?providerId=XXX` 切换不同服务商
- 右上角下拉框可实时切换服务商自动从Excel读取服务商列表
- 使用 Chart.js 实现饼状图和雷达图
- 使用 SheetJS (xlsx) 解析Excel文件
- 响应式布局,支持不同屏幕尺寸
- 数据与页面分离,便于维护
## 数据指标
看板展示以下数据指标:
1. **总案件量分布**(饼状图)
- 小修、困境、拖车三类案件占比
2. **年度聚合案件量**
3. **案件量TOP3师傅**
4. **车辆平均总在线时长**
5. **在线时长TOP3师傅**
6. **拒单率最高地区**
7. **拒单率最高时段**
8. **APP使用率**
- 年度APP使用率展示
## Excel数据结构
### 1. 供应商年度KPI.xlsx
| 列名 | 说明 |
|------|------|
| 服务商id | 服务商唯一标识 |
| 服务商 | 服务商名称 |
| 完成案件量 | 总案件数量 |
| 拖车完成量 | 拖车案件数 |
| 小修完成量 | 小修案件数 |
| 困境完成量 | 困境案件数 |
| 聚合案件量 | 聚合案件数量 |
| APP使用率. | APP使用率小数形式如0.998 |
| 年度车辆平均总在线时长(小时) | 车辆平均在线时长 |
### 2. 师傅案件top3.xlsx
| 列名 | 说明 |
|------|------|
| 服务商id | 服务商唯一标识 |
| 服务商 | 服务商名称 |
| 服务人员工号 | 师傅姓名/工号 |
| 完成案件量 | 该师傅完成的案件数 |
### 3. 师傅在线top3.xlsx
| 列名 | 说明 |
|------|------|
| 服务商名称 | 服务商名称 |
| 司机姓名 | 师傅姓名 |
| 年度总在线时长(小时) | 在线时长 |
### 4. 拒单率最高地区.xlsx
| 列名 | 说明 |
|------|------|
| 供应商名称 | 服务商名称 |
| 地区 | 拒单率最高的地区 |
| 拒单率 | 拒单率(小数形式) |
### 5. 拒单率最高时段.xlsx
| 列名 | 说明 |
|------|------|
| 供应商名称 | 服务商名称 |
| 时段 | 拒单率最高的时段 |
| 拒单率 | 拒单率(小数形式) |
## 使用方式
### 1. 启动本地服务器
由于页面使用 `fetch` 加载JSON数据需要通过HTTP服务器访问
```bash
cd C:\Users\Administrator\dashboard-demo
# 使用 Python
python -m http.server 8080
# 或使用 Node.js
npx serve .
# 或使用 PHP
php -S localhost:8080
```
### 2. 访问页面
- 默认服务商:`http://localhost:8080`(自动加载第一个服务商)
- 指定服务商:`http://localhost:8080?providerId=1128`使用服务商id
- 切换服务商:使用页面右上角的下拉框
### 3. 更新数据
直接替换 `data/` 目录下的Excel文件即可页面会自动读取最新数据。
服务商列表从Excel自动生成无需手动配置。
## 技术栈
- HTML5 / CSS3
- JavaScript (ES6+)
- Chart.js - 图表库(饼图、雷达图)
- SheetJS (xlsx) - Excel文件解析
- CSS Grid / Flexbox - 布局
## 后续优化方向
- [ ] 添加更多图表类型(柱状图、折线图等)
- [ ] 支持时间范围筛选
- [ ] 添加数据导出功能
- [ ] 移动端适配优化
- [ ] 添加数据加载骨架屏
- [ ] 支持主题切换(深色/浅色)
## 更新日志
### 2025-01-21
- 改为直接读取Excel文件无需JSON转换
- 服务商列表从Excel自动生成
- 将"AB段里程对比"改为"APP使用率"展示
- 新增服务商选择下拉框
### 2025-01-20
- 初始版本
- 实现基础看板布局
- 支持URL参数切换服务商
- 数据JSON化与页面分离

View File

@@ -1,47 +0,0 @@
{
"serviceProviderId": "SP001",
"serviceProviderName": "上海道路救援服务中心",
"year": 2025,
"summary": {
"totalCases": 100,
"caseBreakdown": {
"minorRepair": 20,
"predicament": 20,
"towing": 60
},
"aggregatedCases": 15
},
"topMastersByCases": [
{ "rank": 1, "name": "小王", "cases": 18 },
{ "rank": 2, "name": "小张", "cases": 16 },
{ "rank": 3, "name": "小李", "cases": 12 }
],
"onlineHours": {
"averageTotal": 2920,
"topMasters": [
{ "rank": 1, "name": "小王", "hours": 3230 },
{ "rank": 2, "name": "小张", "hours": 3028 },
{ "rank": 3, "name": "小李", "hours": 2996 }
]
},
"rejectionRate": {
"highestRegion": {
"name": "崇明",
"rate": 21.2
},
"highestTimeSlot": {
"period": "18:00-22:00",
"description": "晚高峰时段"
}
},
"abMileage": {
"highest": {
"region": "崇明",
"distance": 62
},
"lowest": {
"region": "黄浦",
"distance": 6
}
}
}

View File

@@ -1,47 +0,0 @@
{
"serviceProviderId": "SP002",
"serviceProviderName": "浦东汽车救援有限公司",
"year": 2025,
"summary": {
"totalCases": 156,
"caseBreakdown": {
"minorRepair": 35,
"predicament": 41,
"towing": 80
},
"aggregatedCases": 22
},
"topMastersByCases": [
{ "rank": 1, "name": "老陈", "cases": 28 },
{ "rank": 2, "name": "大刘", "cases": 24 },
{ "rank": 3, "name": "阿强", "cases": 19 }
],
"onlineHours": {
"averageTotal": 3150,
"topMasters": [
{ "rank": 1, "name": "老陈", "hours": 3580 },
{ "rank": 2, "name": "大刘", "hours": 3420 },
{ "rank": 3, "name": "阿强", "hours": 3210 }
]
},
"rejectionRate": {
"highestRegion": {
"name": "奉贤",
"rate": 18.5
},
"highestTimeSlot": {
"period": "07:00-09:00",
"description": "早高峰时段"
}
},
"abMileage": {
"highest": {
"region": "金山",
"distance": 55
},
"lowest": {
"region": "静安",
"distance": 8
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -70,51 +70,3 @@ export function driverRealName( data) {
contentType: 'application/json'
})
}
//获取需要确认的人员信息列表
export function getConfirmPerson(key){
return request({
url: '/supplierAppV2/dispatchApp/wechat/getNeedConfirmPersonInfo',
method:'GET',
params: key
})
}
//微信相关 获取联系我 二维码
export function getQrCode(key){
return request({
url: '/supplierAppV2/dispatchApp/wechat/getQrCode',
method:'GET',
params: key
})
}
//获取服务商的确认状态
export function getConfirmStatus(key){
return request({
url: '/supplierAppV2/dispatchApp/wechat/getSupplier',
method:'GET',
params: key
})
}
//确认已添加微信按钮
export function confirmAddWechat(key){
return request({
url: '/supplierAppV2/dispatchApp/wechat/confirmAddWechat',
method:'GET',
params: key
})
}
//确认无误
export function confirm(key){
return request({
url: '/supplierAppV2/dispatchApp/wechat/confirm',
method:'GET',
params: key
})
}
//提交审批
export function submitConfirm( data) {
return request('/supplierAppV2/dispatchApp/wechat/submitConfirm', {
data: data,
method:'POST',
contentType: 'application/json'
})
}

View File

@@ -82,40 +82,3 @@ export function getDriverName(key) {
}
});
}
export function getVehicleName(key) {
return request({
url: '/supplier/select/vehicle',
method: 'GET',
params: {
key: key ,
}
});
}
// 车辆 总览
export function vehicleTotalInfo(data) {
return request({
url: '/supplier/supplierKPI/querySupplierVehicleStatisticsKpi',
method: 'POST',
data
});
}
// 服务商维度查询车辆
export function vehicleInfoBySupplier(data) {
return request({
url: '/supplier/supplierKPI/querySupplierStatisticsKpiBySupplier',
method: 'POST',
data
});
}
// 车辆维度查询车辆
export function vehicleInfoByVehicle(data) {
return request({
url: '/supplier/supplierKPI/querySupplierVehicleKpi',
method: 'POST',
data
});
}

View File

@@ -18,34 +18,6 @@ export function saveVehicle(data){
data
})
}
//提交审批车辆信息
export function saveSupplierApproval(data){
return request({
url:'/supplier/approval/saveSupplierDriverVehicleApproval',
method:'POST',
contentType:'application/json',
data
})
}
/*车辆更改状态 /supplierAppV2/dispatchApp/user/enableVehicle*/
export function enableVehicle(data){
return request({
url:'/supplierAppV2/dispatchApp/user/enableVehicle',
method:'POST',
contentType:'application/json',
data
})
}
//编辑车辆信息
export function updateInsurance(data){
return request({
url:'/supplierAppV2/dispatchApp/user/updateInsurance',
method:'POST',
data
})
}
// 获取车辆信息(用于修改时回显的值,只需传vehicleId
export function getInfoById(data){
return request({
@@ -78,61 +50,6 @@ export function supplierServiceTree(){
method:'POST'
})
}
// 服务商服务能力
export function supplierServicePartTree(data){
return request({
url:'/supplier/approval/getSupplierServiceTree',
method:'POST',
data
})
}
// 申请加入
export function saveSupplier(data){
return request({
url:'/supplier/potential/save',
method:'POST',
data
})
}
// 申请加入
export function auditSupplier(data){
return request({
url:'/supplier/potential/audit',
method:'POST',
data
})
}
// 修改申请信息
export function getSupplierInfo(key){
return request({
url:'/supplier/potential/getById',
method:'GET',
params:key
})
}
// 获取企微二维码
export function getOrCodeInfo(data){
return request({
url:'/agg-api/wxcp/createContactQrCode',
method:'POST',
data
})
}
// 获取是否添加企微结果
export function getContactQrCodeResult(data){
return request({
url:'/agg-api/wxcp/getContactQrCodeResult',
method:'POST',
data
})
}
//司机列表
export function driverList(data){
return request({
@@ -401,20 +318,11 @@ export function unifiedOCRWithCompress(data){
})
}
export function getArea(data){
return request({
url:'/base/area/tree',
method:'POST',
data
})
}
// 服务商是否培训
export function jumpPage(data){
return request({
url:'/supplierAppV2/dispatchApp/user/jumpPage',
method:'POST',
contentType:'application/json',
data
})
}

View File

@@ -77,15 +77,6 @@ export function updateOrderSettlement(data){
data
})
}
// 获取司机信息
export function getDriverInfo(data){
return request({
url:'/supplierAppV2/dispatchApp/order/getDriverInfo',
method:'POST',
contentType:'application/json',
data
})
}
// 电瓶数量列表
export function batteryCountList(){
return request({
@@ -160,20 +151,4 @@ export function dealWithAlarm(data) {
})
}
//获取当前任务信息
export function getConfigByCode(data){
return request({
url: '/base/baseConfig/getConfigByCode',
method:'POST',
data
})
}
//获取最新版本
export function getNewVersion(key){
return request({
url: '/driverApp/app/updateVersion',
method:'GET',
params: key
})
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 643 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 870 B

View File

@@ -39,13 +39,5 @@ const authenticationRouter = [
title: '银行卡信息认证',
}
},
{
path: '/personList',
name: 'personList',
component: () => import('@/views/mine/personList.vue'),
meta:{
title: '人员信息',
}
},
]
export default authenticationRouter

View File

@@ -11,30 +11,6 @@ const routes = [
path: '/',
redirect: '/index'
},
{
path: '/supplierAdd',
name: 'supplierAdd',
component: () => import('@/views/index/supplierAdd'),
meta:{
title: '信息录入',
}
},
{
path: '/supplierAddResult',
name: 'supplierAddResult',
component: () => import('@/views/index/supplierAddResult'),
meta:{
title: '审核中',
}
},
{
path: '/supplierInfo',
name: 'supplierInfo',
component: () => import('@/views/index/supplierInfo'),
meta:{
title: '信息查看',
}
},
{
path: '/toDoList',
name: 'toDoList',
@@ -172,14 +148,6 @@ const routes = [
title: '车辆新增或修改'
}
},
{
path: "/continueInsurance",
name: 'continueInsurance',
component: () => import('@/views/index/continueInsurance'),
meta: {
title: '续保更新'
}
},
{
path: '/driverManage',
name: 'driverManage',
@@ -324,14 +292,6 @@ const routes = [
title:'电瓶详情'
}
},
{
path: '/goToApp',
name: 'goToApp',
component:()=>import('@/views/goToApp/goToApp.vue'),
meta: {
title:'电瓶详情'
}
},
...kpiRouter,
...invoiceRouter,
...secondHandRouter,

View File

@@ -7,13 +7,5 @@ const kpiRouter = [
title: 'kpi首页',
}
},
{
path: '/kpiCaseNew',
name: 'kpiCaseNew',
component: () => import('@/views/kpi/kpiCaseNew'),
meta:{
title: 'kpi服务商案件&车辆情况',
}
},
]
export default kpiRouter

View File

@@ -23,17 +23,6 @@
div {
padding-top: 8px;
}
.commonNum{
padding: 2px 5px;
background-color: #9C9C9C;
color: white;
border-radius: 3px;
font-size: 13px;
margin-left: 3px;
}
.notFinish{
background-color: red;
}
.active {
color: #3678FF;
position: relative;

View File

@@ -1,6 +1,6 @@
@import "@/styles/mixin.scss";
::v-deep .van-nav-bar__content{
//background-color: #3A3A3A !important;
background-color: #3A3A3A !important;
}
.wrap{
@include wh(100%,100%);

View File

@@ -19,7 +19,6 @@ if( token ) {
service.interceptors.request.use(
config => {
let reqUrl=config.url
// console.log('config',config)
config.data = config.contentType ? config.data : qs.stringify(config.data)
if (config.testFlag) {
config.data = qs.stringify(config.data, {arrayFormat: 'indices', allowDots: true})
@@ -28,17 +27,12 @@ service.interceptors.request.use(
let token = localStorage.getItem('token');
// let token='eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJBTkNIQU5HIiwidXNlcklkIjo0NTY3MSwibmFtZSI6IuWuieeVhSIsInVzZXJOYW1lIjoiQU5DSEFORyIsInN1cHBsaWVySWQiOjExMjgsImlzWmQiOjAsImV4cCI6MTc1NTQyMjUyNX0.xzDZhaANJFnbeViIHJA0SEtOyTv7Ja3rKmXqRKRuFkc'
// let token='eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJTSEhQWEIiLCJ1c2VySWQiOjU0NzI2LCJuYW1lIjoiI-a1i-ivleWwj-eZveeZvSIsInVzZXJOYW1lIjoiU0hIUFhCIiwic3VwcGxpZXJJZCI6MTAwMDE2NSwiZXhwIjoxNzQ0NTEwNzkwfQ.JPk0OA7slYJN3FIi_uhW4Y0CiWRvl6R1dK8MRTbyhD8'
// if(!(reqUrl=='/supplier/supplierTraining/trainingTask' || reqUrl=='/supplier/supplierTraining/normalList' || reqUrl=='/supplier/supplierTraining/trainingList')){
if (reqUrl=='/supplier/supplierTraining/trainingList' && config?.params?.type==1){
console.log('司机app使用该请求不挂token')
} else {
if(!(reqUrl=='/supplier/supplierTraining/trainingTask' || reqUrl=='/supplier/supplierTraining/normalList' || reqUrl=='/supplier/supplierTraining/trainingList')){
if(token) {
config.headers['Authorization'] = `${token}`;
config.headers['token'] = `${token}`;
}
}
// }
return config
},
error => {
@@ -48,7 +42,6 @@ service.interceptors.request.use(
service.interceptors.response.use(
response => {
console.log('response', response.data)
const res = response.data
if ( res.code === 401 || res.code === 400 || res.code == 500) {
Toast(res.msg || 'Error')

View File

@@ -1,102 +0,0 @@
import dayjs from "dayjs";
export const kpiMixins = {
data() {
return {
isMobile: false,
isZd: '',
current:'2024-10',
supplierId:'',
supplierName:'',
startMonthTime: '',
startTime: '',
endTime: '',
}
},
methods: {
applicateHandle() {
if (window.parent) {
const hasListener = window.parent.dispatchEvent(new Event('checkCloseDialog'));
if (hasListener) {
const data = {
action: 'closeDialog',
message: this.supplierId,
// 其他需要传递的参数
};
window.parent.postMessage(data, '*');
} else {
window.history.back();
}
}
},
toOnlineHours(minutes) {
let _hours = parseInt(minutes / 60);
let _minutes = parseInt(minutes % 60);
return _hours + '时' + _minutes + '分'
},
// 初始化获取当月日期
initDate() {
const today = dayjs(); // 获取当前日期
const currentDay = today.date(); // 获取今天是几号1-31
let targetMonth = today; // 默认目标月份是当前月
if (currentDay === 1) {
targetMonth = today.subtract(1, 'month'); // 上个月
}
this.current = targetMonth.format('YYYY-MM');
this.startTime = targetMonth.startOf('month').format('YYYY-MM-DD HH:mm:ss');
let endTime;
if (targetMonth.isSame(today, 'month')) {
endTime = today.subtract(1, 'day').endOf('day');
} else {
endTime = targetMonth.endOf('month');
}
this.endTime = endTime.format('YYYY-MM-DD HH:mm:ss');
this.startMonthTime=this.getStartTimeFromEndTime(this.endTime)
},
//获取近四个月的开始时间
getStartTimeFromEndTime(endTimeStr) {
const startTime = dayjs(endTimeStr).subtract(3, 'month').startOf('month');
return startTime.format('YYYY-MM-DD HH:mm:ss');
},
padZero(num) {
return num < 10 ? `0${num}` : num;
},
checkMobile() {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
this.isMobile = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(userAgent);
},
// 通用函数,用于处理百分比数据
processPercentage(value) {
value *= 100;
if (value % 1 !== 0) {
value = value.toFixed(2);
}
return value;
},
formatPercentage(value) {
let result = value * 100;
if (Number.isInteger(result)) {
return result.toString() + '%';
} else {
return result.toFixed(2) + '%';
}
},
// 格式化承接案件量数据
formatCurrency(value) {
if (!value) return '';
let num = parseInt(value);
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
formatCurrency1(value) {
if (!value) return ''; // 如果值为空,返回空字符串
// 如果值已经包含逗号,直接返回原值
if (value.toString().includes(',')) {
return value;
}
// 否则,添加千分号
let num = parseInt(value);
if (isNaN(num)) return ''; // 如果转换失败,返回空字符串
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
},
}
}

View File

@@ -94,7 +94,6 @@ export const myMixins = {
isWebFunc(){
let res=false
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
console.log('isMobile',isMobile)
if (!isMobile) {// 是移动端不变
res=true
}

View File

@@ -1,28 +1,6 @@
<template>
<div class="wrap">
<div class="navBar">
<van-nav-bar
left-arrow
left-arrow-color="#FFFFFF"
:border="false"
:fixed="true"
:safe-area-inset-top="true"
@click-left="goBack"
>
<template slot="title">
<div v-show="!show">培训文档</div>
<van-field v-model="keyword" placeholder="请输入关键词" v-show="show" @input="getTrainingList"/>
</template>
<template slot="right">
<div class="rightWrap" @click="show = !show">
<img src="@/assets/serach.png" class="img2" v-show="!show"/>
<img src="@/assets/delKey.png" class="img2" v-show="show" @click="initShow"/>
</div>
</template>
</van-nav-bar>
</div>
<!-- <div class="navBar">
<van-nav-bar
:border="false"
:fixed="true"
@@ -46,8 +24,7 @@
</template>
</van-nav-bar>
</div>
-->
<!-- <div class="statisticContainer">
<div class="statisticContainer">
<div class="statisticWrap">
<div class="line1">
<span>培训统计</span>
@@ -66,12 +43,11 @@
</div>
</div>
</div>
</div>-->
<div class="tab_wrap">
</div>
<div class="driver_tab_wrap">
<div v-for="(item, index) in tabArr" :key="index" :class="{'active' : activeIndex == index}"
@click="changeTab(index)">
{{ item.name }}<span v-if="item.count" :class="{'commonNum':true,'notFinish':index==2}">{{item.count}}</span>
<!-- {{ item.name }}-->
{{ item.name }}
</div>
</div>
<div class="contentWrap" v-show="!showEmpty">
@@ -108,14 +84,12 @@ export default {
mixins:[myMixins],
data(){
return{
tabArr: [{name: '全部文档', status: 1,count:0}, {name: '已培训', status:2,count:0},{name: '未培训', status: 3,count:0}],
// tabArr: [{name: '车型技术参数', status: 1}, {name: '中道服务规范', status:2},{name: '中道小课堂', status: 3}],
tabArr: [{name: '车型技术参数', status: 1}, {name: '中道服务规范', status:2},{name: '中道小课堂', status: 3}],
activeIndex: 0,
pageList:[],
totalList:[],
numInfo:'',
keyword:'',
serviceTypeName:'',
show:false,
showEmpty:false,
isLoading:false,
@@ -128,7 +102,6 @@ export default {
this.driverId = urlParams.get('driverId');
this.time=timeFormat(Date.now())
this.keyword=urlParams.get('keyword') || ''
this.serviceTypeName=urlParams.get('serviceTypeName') || ''
this.getTrainingList();
document.addEventListener('visibilitychange', async ( ) => {
let state = document.visibilityState
@@ -140,10 +113,6 @@ export default {
});
},
methods:{
initShow(){
this.keyword= ''
this.getTrainingList()
},
onRefresh() {
this.getTrainingList()
setTimeout(() => {
@@ -160,42 +129,21 @@ export default {
type:1,
id:this.driverId,
text:this.keyword || '',
serviceTypeName:this.serviceTypeName || ''
})
this.totalList=[]
this.pageList=[]
this.tabArr[0].count=0
this.tabArr[1].count=0
this.tabArr[2].count=0
this.numInfo=res.data
if(res.data.totalNum){
this.tabArr[0].count=res.data.totalNum
}
if(res.data.readNum){
this.tabArr[1].count=res.data.readNum
}
if(res.data.notReadNum){
this.tabArr[2].count=res.data.notReadNum
}
/* this.totalList=res.data.list
this.totalList=res.data.list
let result=[]
if(this.activeIndex === 0){
result=this.totalList?.filter(q => q.title === '车型技术参数');
}else if(this.activeIndex === 1){
result=this.totalList?.filter(q => q.title === '中道服务规范');
}else if(this.activeIndex === 2){
result=this.totalList?.filter(q => q.title === '中道小课堂');
}*/
let result=[]
this.totalList=res?.data?.list ? res?.data?.list[0]?.materials : []
if(this.activeIndex === 0){
result=this.totalList || []
}else if(this.activeIndex === 1){
result=this.totalList?.filter(item => item.alreadyRead==1) || []
}else if(this.activeIndex === 2){
result=this.totalList?.filter(item => item.alreadyRead!=1) || []
}
if(result){
this.pageList=result
this.pageList=result[0].materials
this.time=timeFormat(Date.now())
}
if(this.pageList?.length === 0){
@@ -212,19 +160,6 @@ export default {
@import "@/styles/mixin.scss";
@import "@/styles/docment.scss";
@import "@/styles/driverDocment.scss";
/*::v-deep .van-nav-bar__content{
background-color: #3A3A3A !important;
}*/
.tab_wrap {
.active:after {
width: 37px;
left: 0%;
transform: translateX(0%);
}
.active1:after {
width:48px !important;
}
}
.read{
padding: 2px 8px;
border-radius: 5px;

View File

@@ -94,7 +94,6 @@ export default {
showEmpty:false,
supplierId:'',
driverId:'',
serviceTypeName:'',
}
},
mounted() {
@@ -104,7 +103,6 @@ export default {
if(this.driverId){
this.keyword=urlParams.get('keyword') || ''
}
this.serviceTypeName=urlParams.get('serviceTypeName') || ''
this.getNormalList()
},
methods:{
@@ -130,7 +128,6 @@ export default {
type:this.supplierId ? 2 : 1,
id: this.supplierId ? this.supplierId : this.driverId,
text:this.keyword || '',
serviceTypeName:this.serviceTypeName || ''
})
this.totalList=res.data.list
let result=[]

View File

@@ -22,9 +22,9 @@
</van-nav-bar>
</div>
<div class="tab_wrap">
<div v-for="(item, index) in tabArr" :key="index" :class="{'active' : activeIndex == index,'active1':activeIndex==0}"
<div v-for="(item, index) in tabArr" :key="index" :class="{'active' : activeIndex == index}"
@click="changeTab(index)">
{{ item.name }}<span v-if="item.count" :class="{'commonNum':true,'notFinish':index==2}">{{item.count}}</span>
{{ item.name }}
</div>
</div>
<div class="contentWrap" v-show="!showEmpty">
@@ -61,30 +61,22 @@ export default {
mixins:[myMixins],
data(){
return{
tabArr: [{name: '全部文档', status: 1,count:0}, {name: '已培训', status:2,count:0},{name: '未培训', status: 3,count:0}],
tabArr: [{name: '车型技术参数', status: 1}, {name: '中道服务规范', status:2},{name: '中道小课堂', status: 3}],
activeIndex: 0,
pageNum:1,
pageSize:10,
pageList:[],
totalList:[],
keyword:'',
serviceTypeName:'',
show:false,
showEmpty:false,
isLoading:false,
supplierId:'',
numInfo:'',
}
},
activated() {
console.log('activated')
},
mounted() {
console.log('mounted')
const urlParams = new URLSearchParams(window.location.search);
this.supplierId = urlParams.get('supplierId');
this.keyword=urlParams.get('keyword') || ''
this.serviceTypeName=urlParams.get('serviceTypeName') || ''
this.getTrainingList();
document.addEventListener('visibilitychange', async ( ) => {
let state = document.visibilityState
@@ -112,39 +104,20 @@ export default {
type:2,
id: this.supplierId,
text:this.keyword || '',
serviceTypeName:this.serviceTypeName || ''
})
this.totalList=[]
this.pageList=[]
this.tabArr[0].count=0
this.tabArr[1].count=0
this.tabArr[2].count=0
this.totalList=res?.data?.list ? res?.data?.list[0]?.materials : []
this.numInfo=res.data
if(res.data.totalNum){
this.tabArr[0].count=res.data.totalNum
}
if(res.data.readNum){
this.tabArr[1].count=res.data.readNum
}
if(res.data.notReadNum){
this.tabArr[2].count=res.data.notReadNum
}
// console.log(' this.totalList',this.totalList)
console.log(' this.tabArr',this.tabArr)
this.totalList=res.data.list
let result=[]
if(this.activeIndex === 0){
result=this.totalList || []
// result=this.totalList?.filter(q => q.title === '车型技术参数');
result=this.totalList?.filter(q => q.title === '车型技术参数');
}else if(this.activeIndex === 1){
// result=this.totalList?.filter(q => q.title === '中道服务规范');
result=this.totalList?.filter(item => item.alreadyRead==1) || []
result=this.totalList?.filter(q => q.title === '中道服务规范');
}else if(this.activeIndex === 2){
result=this.totalList?.filter(item => item.alreadyRead!=1) || []
// result=this.totalList?.filter(q => q.title === '中道小课堂');
result=this.totalList?.filter(q => q.title === '中道小课堂');
}
if(result){
this.pageList=result
this.pageList=result[0].materials
}
if(this.pageList?.length === 0){
this.showEmpty = true
@@ -153,7 +126,7 @@ export default {
}
},
initShow(){
this.keyword= ''
this.keyword= '',
this.getTrainingList()
}
}
@@ -163,16 +136,6 @@ export default {
@import "@/styles/common.scss";
@import "@/styles/mixin.scss";
@import "@/styles/docment.scss";
.tab_wrap {
.active:after {
width: 37px;
left: 0%;
transform: translateX(0%);
}
.active1:after {
width:48px !important;
}
}
.read{
padding: 2px 8px;
border-radius: 5px;

View File

@@ -1,73 +0,0 @@
<template>
<div class="wrap">
<div class="content">
<div class="goToBtn" @click="goAppHandler">立即打开</div>
<div class="content_tip">
<div class="font_cls">如未安装请点击下载</div>
<div class="font_cls">如已安装未自动跳转 <span @click="downLoadHandler">立即下载</span></div>
</div>
</div>
</div>
</template>
<script>
import { getNewVersion } from "@/api/order"
export default {
name: "goToApp",
methods: {
goAppHandler() {
window.location.href = "rvdriver://page/pagesLogin/phoneLogin?source=h5Link";
},
async downLoadHandler() {
getNewVersion({
appType: 5
}).then((res) => {
window.location.href = res?.result?.path
}).catch(() => {
this.$message.error('请求版本失败,请重试');
});
}
}
}
</script>
<style lang="scss" scoped>
.wrap {
width: 100%;
height: 100vh;
background-image: url('@/assets/toAppBg.png');
background-repeat: no-repeat;
background-size: 100% 100%;
}
.content {
width: 100%;
position: fixed;
top: 74vh;
}
.goToBtn {
width: 70%;
height: 45px;
margin-left: 15%;
background: linear-gradient( 270deg, #2347C0 0%, #72A3FF 100%);
border-radius: 23px;
//font-weight: bold;
font-size: 17px;
color: #FFFFFF;
letter-spacing: 2px;
line-height: 45px;
text-align: center;
}
.content_tip {
width: 100%;
margin-top: 15px;
.font_cls {
font-size: 14px;
color: #808080;
line-height: 20px;
text-align: center;
span {
color: #007BE9;
}
}
}
</style>

View File

@@ -1,494 +0,0 @@
<template>
<div class="wrap vehicleAdd">
<div class="navBar">
<van-nav-bar
title="续保更新"
left-arrow
left-arrow-color="#FFFFFF"
:border="false"
:fixed="true"
:safe-area-inset-top="true"
@click-left="back"
/>
</div>
<div class="addContentWrap">
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span>有无投保救援职业责任险或货运险</span>
</div>
<div class="isJoin">
<van-radio-group v-model="hasLiabilityInsurance" @change="isChange" class="joinWrap">
<van-radio :name="1" style="margin-right: 26px">
<img
slot="icon"
slot-scope="props"
:src="props.checked ? activeIcon : inactiveIcon"
>
</van-radio>
<van-radio :name="0">
<img
slot="icon"
slot-scope="props"
:src="props.checked ? activeIcon : inactiveIcon"
>
</van-radio>
</van-radio-group>
</div>
</div>
<span style="color: red">如有投保未投保选不必上传交强险或者商业险等其他保单</span>
<div class="lineBot"></div>
<template v-if="hasLiabilityInsurance == 1">
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span style="line-height: 20px">请上传救援职业责任险或货运险保单PDF或者关键信息页截图</span>
</div>
<van-uploader
v-model="insurancePictureFiles"
:after-read="insurancePictureFilesHandler"
max-count="1"
:preview-size="54"
accept="image "
/>
</div>
<div class="lineBot"></div>
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span>承保保司</span>
</div>
<el-select
v-model="insuranceCorp"
value-key="name"
class="elSelect"
collapse-tags="collapse-tags"
placeholder="请选择" style="width: 55%"
>
<el-option
v-for="item in insuranceOptions"
:key="item.name"
:label="item.name"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="lineBot"></div>
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span>保险有效期</span>
</div>
<el-input style="width: 55%" readonly @focus="showDatePicker = true" v-model="dateVal" placeholder="请选择发布日期" :class="{'customSel':true,'customInput':true , 'has-value': dateVal }" >
<template #suffix>
<i
v-if="dateVal"
class="el-icon-circle-close el-input__icon"
@click="dateVal = ''"
></i>
</template>
</el-input>
</div>
<div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
<div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')" style="align-items: center">
<div class="titleType" style="width: 60px">
<img class="startImg" src="@/assets/start.png" />
<span>保费</span>
</div>
<van-field
type="number"
class="vanIpt"
v-model="liabilityInsuranceAmount"
input-align="right"
>
<template slot="right-icon" >
<span style="white-space: nowrap;"></span>
</template>
</van-field>
</div>
<div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
<div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span>保额</span>
</div>
<div style="display:flex;align-items: center;justify-content: flex-end">
<el-select
v-model="liabilityInsuranceQuota"
value-key="name"
class="elSelect"
collapse-tags="collapse-tags"
placeholder="请选择" style="width: 55%"
>
<el-option
v-for="item in liabilityQuotaOptions"
:key="item.value"
:label="item.value"
:value="item.value"
>
</el-option>
</el-select><span style="margin-right: 16px;opacity: .5;">万元</span>
</div>
<!-- <van-field
type="number"
class="vanIpt"
v-model="liabilityInsuranceQuota"
input-align="right"
>
<template slot="right-icon" >
<span style="white-space: nowrap;">万元 </span>
</template>
</van-field>-->
</div>
</template>
<common-btn title="保存" @submitClick="submitBtn"/>
<van-calendar v-model="showDatePicker" :min-date="minDate"
:max-date="maxDate" type="range" @confirm="onConfirm" />
</div>
</div>
</template>
<script>
import {Dialog} from "vant";
import {myMixins} from "@/utils/myMixins"
import {formatDate1} from "@/utils/common"
import { uploadImage, updateInsurance, getInfoById,userOperationPermissions} from "@/api/mine"
import CommonBtn from "@/components/commonBtn.vue"
export default {
name: "vehicleAdd",
mixins:[myMixins],
data(){
return{
defaultProps: {
children: 'children',
label: 'name'
},
liabilityQuotaOptions:[{value:10},{value:20},{value:30},{value:50},{value:70},{value:80},{value:100},{value:200}],
minDate: new Date(1970, 0, 1), // 设置最小可选日期1970年1月1日
maxDate: new Date(2099, 11, 31), // 设置最大可选日期2099年12月31日
showDatePicker: false,
dateVal: '',
hasLiabilityInsurance: 1, // 有无责任险
activeIcon: require('@/assets/check.png'),
inactiveIcon: require('@/assets/uncheck.png'),
// result: [],
checked: true,
show:false,
imageUrl: require('@/assets/arr_right.png'),
insurancePictureFiles: [],
insurancePicturePhoto: '', // 保单照片
isMultiple: false, // 是否支持多选
insuranceCorp: '',
liabilityInsuranceAmount:'',
liabilityInsuranceQuota:'',
permissonList:[],
insuranceOptions: [{
name: '太平洋',
value: 1
}, {
name: '人保',
value: 2
}, {
name: '平安',
value: 3
}, {
name: '中华联合',
value: 4
}, {
name: '大地',
value: 5
}, {
name: '阳光',
value: 6
}, {
name: '太平',
value: 7
}, {
name: '人寿',
value: 8
}, {
name: '永安',
value: 9
}, {
name: '华安',
value: 10
}, {
name: '申能',
value: 11
}, {
name: '大家',
value: 12
}, {
name: '富德',
value: 13
}, {
name: '其他',
value: 14
}]
}
},
computed: {
},
watch:{
},
async mounted() {
this.id=this.$route.params?.id
await this.getPermissions()
if( this.id){
// await this.vehicleInfo()
}
},
methods:{
back() {
this.$router.push({
name:'vehicleAdd',
params:{
id: this.id
}
})
},
async getPermissions(){
let res = await userOperationPermissions();
this.permissonList = res.data
},
async vehicleInfo(){
let res= await getInfoById({
vehicleId:this.id
})
let result=res.data;
this.id=result.vehicleId
this.insurancePicturePhoto = result.insurancePicturePhoto;
this.hasLiabilityInsurance = result.hasLiabilityInsurance
this.insuranceCorp = result.insuranceCorp;
if(this.insurancePicturePhoto) {
this.insurancePictureFiles = [{url: this.insurancePicturePhoto}]
}
if( result.liabilityInsuranceEndTime && result.liabilityInsuranceStartTime ) {
this.dateVal = formatDate1(result.liabilityInsuranceStartTime) + ' - ' + formatDate1(result.liabilityInsuranceEndTime)
}
},
formatDate(date) {
return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`;
},
onConfirm(date) {
const [start, end] = date;
this.showDatePicker = false;
this.dateVal = `${this.formatDate(start)} - ${this.formatDate(end)}`;
},
formatDateTimeRange(str) {
const [startStr, endStr] = str.split(' - ').map(s => s.trim());
const startDate = new Date(startStr);
const startTime = `${startDate.getFullYear()}-${(startDate.getMonth() + 1).toString().padStart(2, '0')}-${startDate.getDate().toString().padStart(2, '0')} 00:00:00`;
const endDate = new Date(endStr);
const endTime = `${endDate.getFullYear()}-${(endDate.getMonth() + 1).toString().padStart(2, '0')}-${endDate.getDate().toString().padStart(2, '0')} 23:59:59`;
return {
startTime,
endTime
};
},
async insurancePictureFilesHandler(file) {
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.insurancePicturePhoto = res.data;
},
isChange(e){
this.hasLiabilityInsurance=e
if (e === 0) {
Dialog.confirm({
title: '提醒',
message: '有救援职业责任险车辆会提升案件聚合能力和接单能力。',
confirmButtonText: '我已知晓', // 确认按钮文字,默认为“确认”
showCancelButton: false // 是否显示取消按钮,默认为 true。如果不需要取消按钮可以设置为 false。
})
.then(() => { /* 确认后的操作 */ })
.catch(() => { /* 取消后的操作 */ });
}
},
async submitBtn(){
if(this.hasLiabilityInsurance === null || this.hasLiabilityInsurance === undefined || this.hasLiabilityInsurance === '') { // 有职业责任险,就需要有保单照片
this.$toast('救援职业责任险不能为空')
return
}
if(!this.insurancePicturePhoto && this.hasLiabilityInsurance == 1) { // 有职业责任险,就需要有保单照片
this.$toast('保单照片不能为空')
return
}
if(!this.insuranceCorp && this.hasLiabilityInsurance == 1) { // 有职业责任险,就需要有保单照片
this.$toast('承保保司不能为空')
return
}
if(!this.dateVal && this.hasLiabilityInsurance == 1) { // 有职业责任险,就需要有保单照片
this.$toast('保单有效期不能为空')
return
}
if(this.hasLiabilityInsurance == 1 && this.permissonList?.includes('hasInsuranceAudit') && !this.liabilityInsuranceAmount && this.liabilityInsuranceAmount!=0){
this.$toast('保费不能为空')
return
}
if(this.hasLiabilityInsurance == 1 && !this.liabilityInsuranceQuota && this.permissonList?.includes('hasInsuranceAudit')){
this.$toast('保额不能为空')
return
}
let timeObj;
if(this.dateVal) {
timeObj = this.formatDateTimeRange(this.dateVal)
}
let params = {
id: this.id ? this.id : '',
renewInsureInfo: JSON.stringify({
hasLiabilityInsurance: this.hasLiabilityInsurance,
insurancePictureUrls: this.hasLiabilityInsurance == 1 ? this.insurancePicturePhoto : '',
insuranceCorp: this.hasLiabilityInsurance == 1 ? this.insuranceCorp : '',
liabilityInsuranceStartTime: this.hasLiabilityInsurance == 1 ? (timeObj?.startTime || '' ) : '',
liabilityInsuranceEndTime: this.hasLiabilityInsurance == 1 ? (timeObj?.endTime || '') : '',
liabilityInsuranceQuota:this.liabilityInsuranceQuota || '',
liabilityInsuranceAmount:this.liabilityInsuranceAmount || '',
})
}
await updateInsurance(params)
if(this.id){
this.$toast('修改成功')
}else{
this.$toast('添加成功')
}
setTimeout(()=>{
// this.$router.back();
this.back()
},2000)
}
},
components:{
CommonBtn
}
}
</script>
<style>
.vehicleAdd .van-field__control:disabled {
color: #323643 !important;
-webkit-text-fill-color: #323643 !important;
}
</style>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
.mySelect{
@include fontWeightSize(bold,13px);
color: #323643;
appearance: none;
padding-right: 16px;
background: url('@/assets/arrow_bot.png') no-repeat right center / 15px 14px;
}
.checkbox-group {
display: none;
}
.navBar{
margin-bottom: 46px;
}
.wrap{
@include wh(100%,100%);
overflow-y: auto;
}
.addContentWrap{
margin-left: 16px;
.item_content_btn {
padding-right: 25px;
text-align: right;
span {
display: inline-block;
background: #354D93;
padding: 5px 10px;
font-size: 12px;
font-weight: bold;
color: #fff;
border-radius: 4px;
margin-bottom: 5px;
}
}
.itemContent{
@include flexColBet;
line-height: 56px;
box-sizing: border-box;
padding-right: 25px;
.titleType{
@include fontWeightSize(bold,14px);
color: #323643;
}
.isJoin{
display: flex;
.joinWrap{
display: flex;
}
img{
@include widHeiMar(16px,16px,6px)
}
}
.startImg{
@include widHeiMar(6px,6px,3px);
vertical-align: super;
}
input{
border: none;
text-align: right;
@include fontWeightSize(bold,13px);
opacity: .5;
}
}
.lineBot{
@include wh(100%,1px);
background: #E9E9EA;
opacity: 0.6;
}
.serviceType{
@include fontWeightSize(bold,13px);
margin-left: 15px;
.trailerService{
margin-bottom: 10px;
}
.serviceline{
@include flexCenter;
margin-bottom: 10px;
}
.item{
margin: 20px 0;
@include flexCenter;
}
.radioWrap{
margin-left: 10px;
}
.service{
@include colorOpa(#323643,0.7);
line-height: 18px;
white-space: nowrap;
}
.line{
display: inline-block;
@include wh(240px,2px);
opacity: 0.16;
border-bottom: 1px solid;
border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
}
img{
@include widHeiMar(16px,16px,12px)
}
}
.btn{
width: 90%;
margin: 40px 0 30px 8px;
}
}
.elSelect ::v-deep .el-input__inner{
border: none !important;
text-align: right !important;
}
.disabled-tree {
pointer-events: none;
opacity: 0.6;
}
</style>

View File

@@ -67,7 +67,7 @@
accept="image "
/>
</div>
<!-- <div class="lineBot"></div>
<div class="lineBot"></div>
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
@@ -80,12 +80,11 @@
:preview-size="54"
accept="image "
/>
</div>-->
</div>
<div class="lineBot"></div>
<div class="itemContent">
<div class="titleType">
<img class="startImg" src="@/assets/start.png" />
<span>免冠正面照</span>
<span>头像</span>
</div>
<van-uploader
v-model="iconList"
@@ -308,7 +307,7 @@ export default {
let res = await uploadImage(formData)
this.drivingLicenceContrary = res.data;
},
async iconListHandler(file) { // 上传免冠正面照
async iconListHandler(file) { // 上传头像
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData)
@@ -400,13 +399,9 @@ export default {
this.$toast('驾驶证首页未上传')
return
}
/* if(!this.drivingLicenceContrary) {
if(!this.drivingLicenceContrary) {
this.$toast('驾驶证副页未上传')
return
}*/
if(!this.icon) {
this.$toast('免冠正面照未上传')
return
}
let drivingLicenceName=this.drivingLicenceName.replace(/[^\u4e00-\u9fff]+/g, '');
let driverName=this.driverName.replace(/[^\u4e00-\u9fff]+/g, '');

View File

@@ -18,43 +18,6 @@
</template>
</van-nav-bar>
</div>
<van-search
v-model="searchVal"
show-action
placeholder="请输入司机姓名、电话、身份证号"
@search="resetHandler"
>
<template #action>
<div @click="resetHandler">搜索</div>
</template>
</van-search>
<div class="filterWrap">
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="idCardStatusList" placeholder="身份证录入状态" :class="{'customSel':true , 'has-value': idCardStatusList }" clearable>
<el-option
v-for="item in idCardStatusListOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="driverLicenseStatusList" placeholder="驾驶证录入状态" :class="{'customSel':true , 'has-value': driverLicenseStatusList }" clearable>
<el-option
v-for="item in driverLicenseStatusListOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="authStatusList" placeholder="认证状态" :class="{'customSel':true , 'has-value': authStatusList }" clearable>
<el-option
v-for="item in authStatesOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="wrap_cls">
<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
<van-list
v-model="loading"
@@ -62,33 +25,14 @@
finished-text="没有更多了"
@load="onLoad"
>
<div class="itemWrap" v-for="(item,index) in driverList" :key="index" @click.stop="updateDriver(item)">
<div class="itemWrap" v-for="(item,index) in driverList" :key="index">
<div class="name-status">
<div class="namephone">{{ item.driverName }} / {{ item.driverPhone }}
<span style="margin-left: 10px" :class="item.states?.code == 1 ? 'statusYes' : 'statusNo'">{{ item.states?.label }}</span>
</div>
<div class="namephone">{{ item.driverName }} / {{ item.driverPhone }}</div>
<div class="twoBtn">
<!-- 只有启用状态下才展示停用按钮-->
<button v-if="permissonList.includes('driverModifyBtn') && item.states?.code==1" class="del" @click.stop="handleStatus(item)">停用</button>
<!-- <button v-if="permissonList.includes('driverModifyBtn')" class="revise" @click="updateDriver(item)">修改</button>-->
<button v-if="permissonList.includes('driverModifyBtn')" class="del" @click="handleStatus(item)">{{ item.states?.label == '启用' ? '停用' : '启用' }}</button>
<button v-if="permissonList.includes('driverModifyBtn')" class="revise" @click="updateDriver(item)">修改</button>
</div>
</div>
<div class="juhe flex-between">
<span class="zdJuhe">录入状态</span>
<span class="flex-right">
<span class="common_cls" v-if="item.idCardStatusStr" :class="getClass(item.idCardStatus)?.className">{{item.idCardStatusStr}}</span>
<span class="common_cls" v-if="item.driverLicenseStatusStr" :class="getClass(item.driverLicenseStatus)?.className">{{item.driverLicenseStatusStr}}</span>
</span>
<!-- <span class="flex-right" v-if="item.idCardStatusStr">
<span class="common_cls" :class="getClass(item.idCardStatus)?.className">{{item.idCardStatusStr}}</span>
</span>-->
</div>
<div class="juhe flex-between">
<span class="zdJuhe">认证状态</span>
<span class="flex-right" v-if="item.authStatusStr">
<span class="common_cls" :class="getClass(item.authStatusStr)?.className">{{item.authStatusStr}}</span>
</span>
</div>
<div class="" style="display: flex">
<div class="sex" style="margin-right: 40px">
<span class="halfOpci">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span>
@@ -103,24 +47,22 @@
<span class="halfOpci">身份证号:</span>
<span class="allOpci">{{ item.identityCardNumber }}</span>
</div>
<van-icon class="arrow_position" v-if="permissonList.includes('driverModifyBtn')" name="arrow" />
<!-- <div>
<div>
<span class="halfOpci">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:</span>
<span :class="item.states?.code == 1 ? 'statusYes' : 'statusNo'">{{ item.states?.label }}</span>
</div>-->
</div>
</div>
</van-list>
</van-pull-refresh>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {driverList, enableAction, userOperationPermissions} from "@/api/mine"
import {Dialog} from "vant";
import {driverList,enableAction,userOperationPermissions} from "@/api/mine"
export default {
name: "driverManage",
mixins:[myMixins],
@@ -137,40 +79,6 @@ export default {
loading: false,
finished: false,
permissonList:[],
searchVal:'',
idCardStatusList:[],
driverLicenseStatusList:[],
authStatusList:[],
idCardStatusListOptions: [{
name: '身份证未录入',
value: 0
},{
name: '身份证核验通过',
value: 1
},{
name: '身份证核验不通过',
value: 2
}],
authStatesOptions: [{
name: '免冠正面照未录入',
value: 1
},{
name: '免冠正面照认证通过',
value: 3
},{
name: '免冠正面照认证不通过',
value: 2
}],
driverLicenseStatusListOptions: [{
name: '驾驶证未录入',
value: 0
},{
name: '驾驶证认证通过',
value: 1
},{
name: '驾驶证认证不通过',
value: 2
}],
}
},
mounted() {
@@ -180,41 +88,9 @@ export default {
// this.getDriverList()
},
methods:{
getClass(id) {
const ids = String(id)
const steps = {
0: {
className: 'default_cls'
},
1: {
className: 'success_cls'
},
2: {
className: 'danger_cls'
},
'免冠正面照未录入': {
className: 'default_cls'
},
'免冠正面照认证通过': {
className: 'success_cls'
},
'免冠正面照认证不通过': {
className: 'danger_cls'
},
}
return steps[ids] || { className: 'default_cls' }
},
async resetHandler() {
this.pageNum=1
this.finished = false;
this.total = 0;
await this.getDriverList();
},
async onLoad(){
await this.getDriverList()
if (this.total>10){
this.pageNum++;
}
// 加载状态结束
this.loading = false;
// 数据全部加载完成
@@ -242,11 +118,7 @@ export default {
async getDriverList(){
let res = await driverList({
pageNum:this.pageNum,
pageSize:this.pageSize,
searchVal: this.searchVal,
idCardStatusList: this.idCardStatusList,
driverLicenseStatusList: this.driverLicenseStatusList,
authStatusList: this.authStatusList,
pageSize:this.pageSize
});
if(res.code == 200){
this.total=res.total
@@ -258,11 +130,12 @@ export default {
this.driverList = preList.concat(arr)
}
}
console.log('this.driverList',this.driverList)
},
async getPermissions(){
let res = await userOperationPermissions();
this.permissonList = res.data
// console.log("司机管理",this.permissonList.includes('driverAddBtn'))
},
async handleStatus(item){
if(item.states.code === 0){
@@ -270,23 +143,14 @@ export default {
}else{
this.states = 0
}
Dialog.confirm({
message: '当前状态为启用,是否要改为停用?',
}).then(async () => {
await enableAction({
driverId:item.driverId,
states:this.states
})
this.pageNum = 1;
await this.getDriverList();
}).catch(() => {
});
},
updateDriver(item){
if(!this.permissonList.includes('driverModifyBtn')){//有权限才能修改
return
}
// 在当前组件中进行路由跳转并传递参数对象
this.$router.push({
name: 'driverAdd', // 目标路由的名称
@@ -321,7 +185,7 @@ export default {
.wrap {
background: #F4F5F7;
//@include sizingPadding(13px,13px);
@include sizingPadding(13px,13px);
@include wh(100%, 100%);
overflow-y: auto;
}
@@ -344,7 +208,7 @@ export default {
}
.itemWrap {
@include wh(100%, 140px);
@include wh(100%, 104px);
@include radiusSizing(6px);
@include fontWeightSize(400, 12px);
@include flexBetween;
@@ -352,7 +216,6 @@ export default {
box-shadow: 0px 2px 10px 0px rgba(216, 216, 216, 0.5);
margin-bottom: 10px;
padding: 11px 13px 9px 15px;
position: relative;
.halfOpci {
opacity: .5;
margin-right: 5px;
@@ -361,15 +224,15 @@ export default {
opacity: 1;
}
.statusNo {
color: red;
color: #FF0000;
}
.statusYes {
color: green
color: #09B820
}
}
.name-status {
@include flexBetCen;
@include flexColBet;
.namephone {
@include fontWeightSize(bold, 14px)
}
@@ -393,128 +256,6 @@ export default {
margin-left: 15px;
}
}
}
.filterWrap {
width: 100%;
padding-right: 13px;
padding-left: 13px;
display: flex;
overflow-x: auto; /* 允许横向滚动 */
white-space: nowrap; /* 防止子元素换行 */
padding-bottom: 10px;
-webkit-overflow-scrolling: touch; /* 在iOS上平滑滚动 */
scrollbar-width: none; /* Firefox */
padding-bottom: 10px;
/*padding: 10px;*/
margin-bottom: 10px;
background-color: #fff;
box-sizing: border-box;
&::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.customSel {
flex: 0 0 auto; /* 防止子元素被压缩 */
width: calc(33% - 5px);
/*width: 100%;*/
height: 25px;
background: #F5F5F5;
border-radius: 4px;
font-size: 10px;
color: #323233;
margin-right: 5px;
::v-deep .el-input__inner{
padding: 0 2px;
height: 25px;
font-size: 10px;
background: #F5F5F5;
border-radius: 4px;
border: none;
}
::v-deep .el-input__icon{
line-height: 25px;
font-size: 10px;
width: 18px;
color: #2A5094;
}
::v-deep .el-input__suffix{
right: 2px;
}
}
.customInput{
/*width: 49%;*/
width: 130px;
}
.has-value ::v-deep .el-input__inner{
background: #F1F6FF ;
color: #007BE9;
font-weight: bold;
padding-left: 8px;
}
.has-value ::v-deep .el-input__icon{
color: #007BE9;
}
.priceSel{
display: flex;
justify-content: space-around;
align-items: center;
color: #C0C4CC;
.iconSpan{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8px;
}
}
.has-price{
color: #007BE9 !important;
}
}
.wrap_cls {
width: 100%;
padding-left: 13px;
padding-right: 13px;
box-sizing: border-box;
}
.common_cls {
color: #fff;
padding: 4px 8px;
border-radius: 3px;
margin-right: 6px;
}
.default_cls {
background-color: #B0BEC5;
}
.danger_cls {
background-color: red;
}
.success_cls {
background-color: #4CAF50;
}
.info_cls {
background-color: #FF9800;
}
.main_cls {
background-color: #6C9BFF;
}
.arrow_position {
position: absolute;
right: 5px;
top: 50px;
font-size: 20px;
opacity: 0.6;
}
.carType,.zdJuhe{
opacity: .7;
@include fontWeightSize(400,12px);
margin-right: 8px;
}
/*.zdJuhe {
width: 80px;
text-align: right;
margin-left: -10px;
}*/
.flex-between{
line-height: 24px;
}
</style>

View File

@@ -175,7 +175,7 @@ export default {
confirmButtonColor: '#0E76F4',
showCancelButton: false,
}).then(async() => {
this.goPage('newTrainingList', { supplierId : this.supplierId, type: 'invoice' })
this.goPage('newTrainingList', { supplierId : this.supplierId })
}).catch(() => {
// on cancel
});
@@ -189,9 +189,7 @@ export default {
this.getNotifyList()
},
async getJumpHandler() {
let res = await jumpPage({
type: 'invoice'
});
let res = await jumpPage();
return res
},
getMonth(item) {

View File

@@ -1,648 +0,0 @@
<template>
<div class="wrap">
<div class="top_banner">
<img src="@/assets/supplier/topBg.png" alt="">
</div>
<van-form @submit="applyAdd">
<div class="content_wrap">
<div class="credentials_info">
<img class="title1" src="@/assets/supplier/title1.png" alt="">
<div class="credentials_wrap">
<div class="credentials_item">
<div class="credentials_title">1.法人身份证人像页</div>
<van-uploader
accept="image/*"
v-model="idFrontPhotoList"
:after-read="idFrontPhotoHandler"
:max-size="5 * 1024 * 1024"
max-count="1">
<div class="custom-background">
<img src="@/assets/supplier/idCardPerson.png" alt="">
</div>
</van-uploader>
</div>
<div class="credentials_item ml2">
<div class="credentials_title">2.法人身份证国徽页</div>
<van-uploader
accept="image/*"
v-model="idBackPhotoList"
:after-read="idBackPhotoHandler"
:max-size="5 * 1024 * 1024"
max-count="1">
<div class="custom-background">
<img src="@/assets/supplier/idCardBack.png" alt="">
</div>
</van-uploader>
</div>
<div class="credentials_item ml2">
<div class="credentials_title">3.营业执照</div>
<van-uploader
accept="image/*"
v-model="companyPhotoList"
:after-read="companyPhotoHandler"
:max-size="5 * 1024 * 1024"
max-count="1">
<div class="custom-background">
<img src="@/assets/supplier/companyPhoto.png" alt="">
</div>
</van-uploader>
</div>
<div class="credentials_item">
<div class="credentials_title">4.开户许可证/基本存款账户信息</div>
<van-uploader
accept="image/*"
v-model="licensePhotoList"
:after-read="licensePhotoHandler"
:max-size="5 * 1024 * 1024"
max-count="1">
<div class="custom-background">
<img src="@/assets/supplier/licensePhoto.png" alt="">
</div>
</van-uploader>
</div>
</div>
</div>
<div class="company_info">
<img class="title2" src="@/assets/supplier/title2.png" alt="">
<div class="company_wrap">
<van-field :border="true" readonly v-model="form.name" class="required" name="name" label="服务商名称" placeholder="请输入" :rules="[{ required: true, message: '请输入服务商名称' }]" />
<van-field :border="true" readonly v-model="form.areaName" class="required" name="areaName" label="注册地址" placeholder="请输入" :rules="[{ required: true, message: '请输入注册地址' }]" />
<van-field :border="true" readonly v-model="form.legalName" class="required" name="legalName" label="法人姓名" placeholder="请输入" :rules="[{ required: true, message: '请输入法人姓名' }]" />
<van-field :border="true" v-model="form.linkName" class="required" name="linkName" label="联系人姓名" placeholder="请输入" :rules="[{ required: true, message: '请输入联系人姓名' }]" />
<van-field :border="true" v-model="form.linkPhone" class="required" name="linkPhone" label="联系电话" placeholder="请输入" :rules="phoneVerify" />
<van-field :border="true" v-model="form.linkEmail" class="required" name="linkEmail" label="邮箱" placeholder="请输入" :rules="emailVerify" />
<van-field :border="true" class="required" name="serviceType" label="服务能力">
<template #input>
<el-tree
show-checkbox
node-key="id"
ref="tree"
:highlight-current="true"
:expand-on-click-node="false"
:data="bigServiceList"
:props="defaultProps">
</el-tree>
</template>
</van-field>
<van-field :border="true" v-model="form.trailCount" name="trailCount" label="拖车数量" placeholder="请输入" />
<van-field :border="true" v-model="form.minorCount" name="minorCount" label="抢修车数量" placeholder="请输入" />
<van-field :border="true" class="required" label="服务区域" placeholder="请选择">
<template #input>
<el-cascader
v-model="form.serviceAreaCode"
:options="areaList"
:props="areaProps"
ref="areaCascader"
popper-class="responsive-cascader"
:popper-append-to-body="false"
filterable
clearable></el-cascader>
</template>
</van-field>
<div class="wei_code_wrap" v-if="form.name && !id">
<div class="wei_title">请先添加企业微信保证申请流程正常进行</div>
<div class="wei_code_bg">
<img v-if="qrCodeUrl" :src="qrCodeUrl" alt="企业微信二维码" />
</div>
</div>
</div>
</div>
</div>
<div class="btn_wrap">
<van-button class="btn" block type="info" :native-type="'submit'">提交申请</van-button>
</div>
</van-form>
<van-popup
v-model="areaShow"
position="bottom"
>
<van-area title="服务区域" :area-list="areaList" :columns-num="3" closeable="true" :value="form.areaCode ? String(form.areaCode) : ''"
@cancel="areaShow = false" @confirm="confirmHandle"/>
</van-popup>
</div>
</template>
<script>
import {leftCopy} from "@/utils/common"
import QRCode from 'qrcode'
import { uploadImage, ocrHandler, unifiedOCRWithCompress, getArea, saveSupplier, getSupplierInfo, getOrCodeInfo, getContactQrCodeResult } from "@/api/mine"
import {myMixins} from "@/utils/myMixins"
import {Dialog} from "vant";
export default {
name: "supplierAdd",
mixins:[myMixins],
data() {
return {
clickFlag: true,
phoneVerify: [{ required: true, message: '请输入联系电话' }, { validator: value => { return /^1[3456789]\d{9}$/.test(value) }, message: '联系电话格式不正确' }],
emailVerify: [{ required: true, message: '请输入邮箱' }, { validator: value => { return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test(value) }, message: '邮箱格式不正确' }],
id:'', //车辆Id
idBackPhotoList: [],
idBackPhoto: '',
idFrontPhotoList: [],
idFrontPhoto: '',
companyPhotoList: [],
licensePhotoList: [],
companyPhoto: '',
licensePhoto:'',
form: {
name: '',
legalName: '',
areaName: '',
linkName: '',
linkPhone: '',
serviceType: '',
trailCount: '',
minorCount: '',
serviceAreaCode: [],
linkEmail:'',
accountInfoDTO:{
dutyParagraph:'',
accountNumber:'',
accountName:'',
accountType:'',
invoiceType:'',
settlementType:'',
shouldRate:'',
realRate:'',
unitName:'',
bankNo:'',
billingPhone:'',
billingAddress:'',
billHead:'',
companyType:'',
}
},
qrCodeUrl: '',
qrCode: '',
areaShow: false,
areaList: [],
supplierServiceList: [],
bigServiceList: [{
id: 1002,
title: '拖车服务'
}, {
id: 1003,
title: '抢修服务'
}, {
id: 1004,
title: '困境救援'
}],
defaultProps: {
children: 'children',
label: 'title',
},
areaProps: { multiple: true, checkStrictly: true, value: 'id',label: 'title', emitPath: false},
configId: '',
wechatId: '',
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.id = this.$route.query.id || urlParams.get('id');
await this.getAreaTree();
if(this.id) {
await this.getInfoHandler();
}
// await this.getSupplierServiceTree();
},
methods: {
async QrCodeHandler() {
await this.QrCodeInfo()
await this.getQrCode();
},
async QrCodeInfo() {
let res = await getOrCodeInfo({
name: this.form.name
});
this.configId = res?.configId;
this.qrCode = res?.qrCode
console.log('idid', res);
},
async getInfoHandler() {
let res = await getSupplierInfo({
id: this.id
});
let _data = res?.data
leftCopy(this.form, {..._data})
this.idFrontPhoto = _data?.idCardFrontUrl;
this.idBackPhoto = _data?.idCardBackUrl;
this.companyPhoto = _data?.businessLicense;
this.licensePhoto = _data?.accountUrl;
this.wechatId = _data?.wechatId
if(this.idFrontPhoto) {
this.idFrontPhotoList = [{ url : this.idFrontPhoto }];
}
if(this.idBackPhoto) {
this.idBackPhotoList = [{ url : this.idBackPhoto }];
}
if(this.companyPhoto) {
this.companyPhotoList = [{ url : this.companyPhoto }];
}
if(this.licensePhoto){
this.licensePhotoList= [{ url : this.licensePhoto }];
}
if( _data.service ) {
this.$refs.tree.setCheckedKeys(_data.service.split(','))
}
if(_data?.serviceAreaCode) {
this.$set(this.form, 'serviceAreaCode', _data?.serviceAreaCode.split(',').map(item => Number(item)));
// this.form.serviceAreaCode = _data?.serviceAreaCode.split(',').map(item => Number(item));
}
},
async applyAdd() {
if( !this.idFrontPhoto ) {
this.$toast('法人身份证人像页未上传')
return
}
if( !this.idBackPhoto ) {
this.$toast('法人身份证国徽页未上传')
return
}
if( !this.companyPhoto ) {
this.$toast('营业执照未上传')
return
}
if( !this.licensePhoto ) {
this.$toast('开户许可证未上传')
return
}
if( !(this.form.serviceAreaCode.length > 0) ) {
this.$toast('服务区域不能为空')
return
}
// this.wechatId='wmOTNXBwAABrvKkE_Fh8ZN8Xm2S9v2wQ'
if(!this.wechatId) {
await this.QrCodeResult();
if( !this.wechatId ) {
this.$toast('请先添加企微再申请')
return
}
}
if( this.$refs.tree.getCheckedKeys().length > 0 ) {
await this.saveHandler()
} else {
this.$toast('服务能力不能为空')
return
}
},
async QrCodeResult() { //获取添加企微结果
let res = await getContactQrCodeResult({
configId: this.configId
});
console.log('resres', res)
this.wechatId = res?.data?.wechatId
},
async saveHandler() {
if( this.clickFlag ) {
try {
this.clickFlag = false
let _node = this.$refs.areaCascader.getCheckedNodes();
let checkArr = [];
_node.map(item => {
checkArr.push(item.data.id)
})
let res = await saveSupplier({
id: this.id,
...this.form,
accountInfoJson:JSON.stringify(this.form.accountInfoDTO),
accountInfoDTO:{},
idCardFrontUrl: this.idFrontPhoto,
idCardBackUrl: this.idBackPhoto,
businessLicense: this.companyPhoto,
accountUrl:this.licensePhoto,
service: this.$refs.tree.getCheckedKeys().join(',') ,
serviceAreaCode: checkArr.join(','),
wechatId: this.wechatId,
});
Dialog.alert({
title: '提示',
message: "操作成功"
}).then(async () => {
this.goPage('supplierAddResult', { id : res?.data })
setTimeout(() => {
this.clickFlag = true
}, 1000)
});
} finally {
setTimeout(() => {
this.clickFlag = true
}, 1000)
}
}
},
async getAreaTree() {
let res = await getArea();
let result = res?.data
result?.map(item=>{
if( item.parentId == 0 ) {
this.$set(item , 'disabled' ,true)
} else {
this.$set(item , 'disabled' ,false)
}
})
this.areaList = result;
},
/*async getSupplierServiceTree(){
let res = await supplierServicePartTree({
serviceTypes: '1002,1003,1004',
treeType: 2
});
this.supplierServiceList=res.data
this.bigServiceList = [];
res.data.map(item => {
let obj = {...item, children: null}
this.bigServiceList.push(obj)
})
},*/
confirmHandle(val){
this.region=[]
val?.forEach(item => this.region.push(item.name))
let code=[]
val?.forEach(item => code.push(item.code))
this.form.areaCode=code[code.length - 1]
this.areaShow=false
},
async getQrCode() {
try {
this.qrCodeUrl = await QRCode.toDataURL(this.qrCode, {
width: 150,
margin: 2,
color: {
dark: '#000000',
light: '#FFFFFF'
},
})
} catch (error) {
console.error('生成二维码失败:', error)
}
},
async idBackPhotoHandler(file) {
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.idBackPhoto = res.data
},
async idFrontPhotoHandler(file) {
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.idFrontPhoto = res.data;
await this.idCardOcrHandler();
},
async idCardOcrHandler() { // 身份证正面 ocr识别
this.form.legalName = '';
let res = await ocrHandler({
ocrType: 1,
imageUrl: this.idFrontPhoto,
cardSide: 'FRONT'
})
this.form.legalName = res?.data?.name
},
async companyPhotoHandler(file) {
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.companyPhoto = res.data
await this.companyOcrHandler()
},
async companyOcrHandler() { // 营业照 ocr识别
this.form.name = '';
this.form.areaName = '';
let res = await unifiedOCRWithCompress({
ocrType: 7,
imageUrl: this.companyPhoto,
cardSide: 'FRONT'
})
this.form.name = res?.data?.name;
this.form.areaName = res?.data?.address
this.form.accountInfoDTO.dutyParagraph=res?.data?.regNum
this.form.accountInfoDTO.unitName = res?.data?.name
this.form.accountInfoDTO.companyType=res?.data?.type
await this.QrCodeHandler();
},
async licensePhotoHandler(file){// 开户许可证
const formData = new FormData();
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.licensePhoto = res.data
await this.licenseOcrHandler()
},
async licenseOcrHandler(){// 开户许可证ocr识别
let res = await ocrHandler({
ocrType: 15,
imageUrl: this.licensePhoto,
})
this.form.accountInfoDTO.accountNumber=res?.data?.accountNumber
this.form.accountInfoDTO.accountName = res?.data?.accountBank
},
},
computed: {
regionText() {
return this.region.length ? `${this.region[0]}/${this.region[1]}/${this.region[2]}` : '请选择所在地区';
}
},
}
</script>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
.wrap{
@include wh(100%,100%);
box-sizing: border-box;
padding-bottom: 100px;
overflow-y: auto;
}
.top_banner {
width: 100%;
img {
width: 100%;
height: 169px;
}
}
.content_wrap {
padding: 0 20px;
}
.credentials_info {
//height: 170px;
}
.credentials_wrap {
display: flex;
width: 100%;
margin-top: 10px;
flex-wrap: wrap;
.credentials_item {
width: 32%;
text-align: center;
.credentials_title {
font-size: 12px;
color: #4A4A4A;
padding: 10px 0;
}
.custom-background img {
width: 97px;
height: 64px;
}
}
.ml2 {
margin-left: 2%;
}
}
::v-deep .van-uploader__preview-image {
width: 97px;
height: 64px;
}
.title1 {
width: 106px;
height: 19px;
margin-top: 25px;
}
.title2 {
width: 90px;
height: 18px;
margin-top: 25px;
margin-bottom: 10px;
}
.van-cell.required::before{
content: "";
position: absolute;
color: #F00;
left: 0px;
top: .25rem;
font-size: .3rem;
}
.wei_code_wrap {
margin-top: 10px;
.wei_title {
font-size: 15px;
color: #FF553B;
text-align: center;
}
.wei_code_bg {
width: 163px;
height: 173px;
background-image: url("~@/assets/supplier/weiCodeBg.png");
background-size: 100% 100%;
margin: 8px auto;
display: flex;
align-items: center;
justify-content: center;
}
}
.btn_wrap {
width: 100%;
padding: 15px 0;
position: fixed;
bottom: 0;
background: #F7F7F9;
box-shadow: 0px -7px 24px 0px rgba(0, 0, 0, 0.11);
z-index: 10000 !important;
.btn {
width: calc(100% - 80px);
margin-left: 40px;
height: 46px;
background: #0E76F4;
border-radius: 5px;
font-size: 15px;
color: #FFFFFF;
text-align: center;
line-height: 46px;
}
}
/*::v-deep .el-cascader {
width: 100% !important;
}
::v-deep .el-input__inner {
width: 100% !important;
border: none !important;
padding-left: 0 !important;
background: transparent !important;
}
::v-deep .el-input {
width: 100% !important;
}
::v-deep .el-input__suffix {
right: 0 !important;
}*/
</style>
<style>
.responsive-cascader .el-cascader-menu {
min-width: 100px !important;
}
.responsive-cascader .el-cascader-panel {
font-size: 12px !important;
}
.responsive-cascader .el-cascader-node {
padding-left: 5px !important;
padding-right: 4px !important;
}
/* !* 级联选择器下拉框样式 *!
.responsive-cascader {
width: 90vw !important;
max-width: 400px !important;
left: 50% !important;
transform: translateX(-50%) !important;
}
.responsive-cascader .el-cascader-panel {
display: flex !important;
width: 100% !important;
max-height: 60vh !important;
}
.responsive-cascader .el-cascader-node {
padding: 12px 16px !important;
font-size: 12px !important;
height: 20px !important;
!*min-height: 44px !important;*!
display: flex !important;
align-items: center !important;
}
.responsive-cascader .el-cascader-node__label {
font-size: 12px !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
flex: 1 !important;
}
!* 移动端触摸优化 *!
.responsive-cascader .el-cascader-node {
padding: 6px 6px !important;
}
!* 选中状态 *!
.responsive-cascader .el-cascader-node.in-active-path,
.responsive-cascader .el-cascader-node.is-active {
color: #1989fa !important;
background-color: #f2f8ff !important;
}
!* 移动端适配 *!
@media (max-width: 768px) {
.responsive-cascader {
width: 95vw !important;
max-width: none !important;
}
.responsive-cascader .el-cascader-menu {
width: 33.33% !important;
flex: none !important;
}
.responsive-cascader .el-cascader-node__label {
font-size: 13px !important;
}
}*/
</style>

View File

@@ -1,83 +0,0 @@
<template>
<div class="wrap">
<div class="top-wrap"></div>
<div class="center-info">
<img class="wait_icon" src="@/assets/supplier/successIcon.png" alt="">
<div class="info-tip">信息录入完成请等待审核结果</div>
</div>
<div class="btn_wrap">
<div class="btn" @click="searchInfo">信息查看</div>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
export default {
name: "supplierAddResult",
mixins:[myMixins],
data() {
return {
id: '',
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.id = this.$route.query.id || urlParams.get('id');
},
methods: {
searchInfo() {
this.goPage('supplierInfo', { id : this.id })
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
.wrap{
@include wh(100%,100%);
box-sizing: border-box;
padding-bottom: 100px;
overflow-y: auto;
background: linear-gradient( 180deg, #FBFDFE 0%, #F6FBFF 73%, #F0F7FF 100%);
backdrop-filter: blur(5.602678571428572px);
}
.top-wrap {
width: 100%;
height: 175px;
background: linear-gradient( 180deg, #DAECFF 0%, rgba(233,243,255,0) 100%);
}
.center-info {
text-align: center;
.wait_icon {
width: 54px;
height: 54px;
margin-bottom: 15px;
}
.info-tip {
font-size: 20px;
font-weight: 500;
color: #2C2A53;
}
}
.btn_wrap {
width: 100%;
padding: 15px 0;
position: fixed;
bottom: 10px;
z-index: 10000 !important;
.btn {
width: calc(100% - 80px);
margin-left: 40px;
height: 46px;
background: #0E76F4;
border-radius: 5px;
font-size: 15px;
color: #FFFFFF;
text-align: center;
line-height: 46px;
}
}
</style>

View File

@@ -1,363 +0,0 @@
<template>
<div class="wrap">
<div class="nav_bar_bg" :class="{ 'status_wait': supplierInfo?.state == 0, 'status_danger': supplierInfo?.state == 99, 'status_success': supplierInfo?.state == 1 }">
<template v-if="supplierInfo?.state == 0">
<div class="status_wrap">
<img class="wait_icon" src="@/assets/supplier/waitIcon.png" alt="">
<span class="wait_status">审批中</span>
</div>
</template>
<template v-if="supplierInfo?.state == 1">
<div class="status_wrap">
<img class="wait_icon" src="@/assets/supplier/successIcon.png" alt="">
<span class="wait_status success_status">恭喜你审核通过</span>
</div>
</template>
<template v-if="supplierInfo?.state == 99">
<div class="status_wrap">
<img class="wait_icon" src="@/assets/supplier/failIcon.png" alt="">
<span class="wait_status danger_status">审核不通过</span>
</div>
<div class="danger_tip">
{{supplierInfo?.failReason}}
</div>
</template>
</div>
<div class="supplier_content">
<div class="credentials_info">
<div class="common_title">证件照信息</div>
<div class="credentials_wrap">
<div class="credentials_item">
<div class="credentials_title">1.法人身份证人像页</div>
<img :src="supplierInfo?.idCardFrontUrl" alt="">
</div>
<div class="credentials_item ml2">
<div class="credentials_title">2.法人身份证国徽页</div>
<img :src="supplierInfo?.idCardBackUrl" alt="">
</div>
<div class="credentials_item ml2">
<div class="credentials_title">3.营业执照</div>
<img :src="supplierInfo?.businessLicense" alt="">
</div>
<div class="credentials_item">
<div class="credentials_title">4.开户许可证/基本存款账户信息</div>
<img v-if="supplierInfo?.accountUrl" :src="supplierInfo?.accountUrl" alt="">
<div v-else class="empty"></div>
</div>
</div>
</div>
<div class="company_info">
<div class="common_title">公司信息</div>
<div class="info_wrap">
<div class="info_item">
<div class="label">服务商名称</div>
<div class="content">{{supplierInfo?.name}}</div>
</div>
<div class="info_item" v-if="supplierInfo?.abbr">
<div class="label">服务商简称</div>
<div class="content">{{supplierInfo?.abbr}}</div>
</div>
<div class="info_item" v-if="supplierInfo?.supplierCode">
<div class="label">服务商编号</div>
<div class="content">{{supplierInfo?.supplierCode}}</div>
</div>
<div class="info_item" v-if="supplierInfo?.areaName">
<div class="label">注册地址</div>
<div class="content">{{supplierInfo?.areaName}}</div>
</div>
<div class="info_item">
<div class="label">法人姓名</div>
<div class="content">{{supplierInfo?.legalName}}</div>
</div>
<div class="info_item">
<div class="label">联系人姓名</div>
<div class="content">{{supplierInfo?.linkName}}</div>
</div>
<div class="info_item">
<div class="label">联系电话</div>
<div class="content">{{supplierInfo?.linkPhone}}</div>
</div>
<div class="info_item">
<div class="label">邮箱</div>
<div class="content">{{supplierInfo?.linkEmail}}</div>
</div>
<div class="info_item">
<div class="label">服务能力</div>
<div class="content service_color">{{supplierInfo?.serviceCategoryName}}</div>
</div>
<div class="info_item">
<div class="label">拖车数量</div>
<div class="content">{{supplierInfo?.trailCount || ''}}</div>
</div>
<div class="info_item">
<div class="label">抢修车数量</div>
<div class="content">{{supplierInfo?.minorCount || ''}}</div>
</div>
<div class="info_item">
<div class="label">服务区域</div>
<div class="content">{{supplierInfo?.serviceAreaName}}</div>
</div>
<template v-if="type == 'audit' && supplierInfo?.state != 1">
<div class="info_item">
<div class="label"><span style="color: red;margin-right: 2px">*</span>审批</div>
<div class="content">
<van-radio-group v-model="form.state" direction="horizontal" icon-size="18px">
<van-radio name="1">审批通过</van-radio>
<van-radio name="99">审批不通过</van-radio>
</van-radio-group>
</div>
</div>
<div class="info_item" v-if="form.state == 1">
<div class="label"><span style="color: red;margin-right: 2px">*</span>服务商简称</div>
<div class="content">
<el-input style="width: 100%" v-model.trim="form.abbr" placeholder="请输入服务商简称"></el-input>
</div>
</div>
<div class="info_item" v-if="form.state == 99">
<div class="label"><span style="color: red;margin-right: 2px">*</span>不通过原因</div>
<div class="content">
<textarea class="report_textarea" rows="4" maxlength="200" show-word-limit placeholder="点击这里输入不通过原因" v-model.trim="form.failReason"></textarea>
</div>
</div>
</template>
</div>
</div>
<div class="btn_wrap" v-if="type == 'show' && supplierInfo?.state == 99 && origin != 'web'">
<div class="btn" @click="goModifyPage">修改信息</div>
</div>
<div class="btn_wrap" v-if="type == 'audit' && supplierInfo?.state != 1">
<div class="btn" v-if="type == 'audit'" @click="auditSupplier"> </div>
</div>
</div>
</div>
</template>
<script>
import { getSupplierInfo, auditSupplier } from "@/api/mine"
import {myMixins} from "@/utils/myMixins"
export default {
name: "supplierInfo",
mixins:[myMixins],
data() {
return {
id:'', //车辆Id
form: {
state: '',
abbr: '',
failReason: '',
},
supplierInfo: {},
type: 'show',
origin: '',
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.id=this.$route.query.id || urlParams.get('id');
this.type=this.$route.query.type || urlParams.get('type') || 'show';
this.origin = this.$route.query.origin || ''
await this.getInfoHandler();
},
methods: {
goModifyPage() {
this.goPage('supplierAdd', { id : this.id })
},
async auditSupplier() {
if( !this.form.state ) {
this.$toast('请选择审批结果')
return
}
if( this.form.state == 99 && !this.form.failReason ) {
this.$toast('请输入不通过原因')
return
}
if( this.form.state == 1 ) {
const reg = /^[\u4e00-\u9fa5]{2}$/;
if(!this.form.abbr) {
this.$toast('请输入服务商简称')
return
}
if(!(reg.test(this.form.abbr))) {
this.$toast('服务商简称请输入两位汉字')
return
}
}
try {
await auditSupplier({
id: this.id,
...this.form,
wechatId: 'test', // 参数将会被去掉
})
} finally {
this.closeParentDialog();
}
},
async getInfoHandler() {
let res = await getSupplierInfo({
id: this.id,
});
this.supplierInfo = res?.data;
},
}
}
</script>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
.report_textarea {
width: 100%;
box-sizing: border-box;
border-radius: 6px;
min-height: 95px;
border: 1px solid #E2EAF6;
padding: 10px;
font-size: 13px;
}
.wrap{
@include wh(100%,100%);
box-sizing: border-box;
padding-bottom: 100px;
overflow-y: auto;
}
.nav_bar_bg {
width: 100%;
height: 125px;
padding-top: 50px;
}
.status_wait {
background: linear-gradient( 180deg, #FFE4C9 0%, rgba(255,248,233,0) 100%);
}
.status_success {
background: linear-gradient( 180deg, #DAFFF8 0%, rgba(237,255,233,0) 100%);
}
.status_danger {
background: linear-gradient( 180deg, #FFE8DA 0%, rgba(255,233,233,0) 100%);
}
.status_wrap {
display: flex;
align-items: center;
.wait_icon {
width: 34px;
height: 34px;
margin-left: 31px;
}
.wait_status {
color: #E69B0B;
font-weight: 600;
font-size: 16px;
margin-left: 11px;
}
.success_status {
color: #37B864;
}
.danger_status {
color: #ED440C;
}
}
.danger_tip {
font-size: 12px;
color: #FF553B;
line-height: 18px;
padding-left: 38px;
padding-right: 23px;
margin-top: 5px;
}
.supplier_content {
padding: 0 20px;
width: 100%;
box-sizing: border-box;
}
.common_title {
font-weight: 500;
font-size: 14px;
color: rgba(50, 54, 67, 0.66);
padding-left: 2px;
}
.common_title::after {
content: '';
display: block;
width: 100%;
border: 1px solid;
margin-top: 10px;
opacity: 0.16;
border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
}
.credentials_wrap {
display: flex;
width: 100%;
margin-top: 10px;
flex-wrap: wrap;
.credentials_item {
width: 32%;
text-align: center;
.credentials_title {
font-size: 12px;
color: #4A4A4A;
padding: 10px 0;
}
img,.empty{
width: 97px;
height: 64px;
}
.empty{
border: 1px solid silver;
margin-left: 8px;
}
}
.ml2 {
margin-left: 2%;
}
}
.company_info {
margin-top: 20px;
/*.company_wrap {*/
.info_wrap {
margin-top: 10px;
.info_item {
display: flex;
padding: 10px 2px;
.label {
font-size: 13px;
color: rgba(50, 54, 67, 0.6);
width: 90px;
flex-shrink: 0;
}
.content {
font-size: 13px;
color: #323643;
/*font-weight: bold;*/
flex: 1;
}
.service_color {
color: rgba(230, 155, 11, 0.9);
}
}
/*}*/
}
}
.btn_wrap {
width: 100%;
padding: 15px 0;
position: fixed;
bottom: 0;
background: #F7F7F9;
box-shadow: 0px -7px 24px 0px rgba(0, 0, 0, 0.11);
z-index: 10000 !important;
left: 0;
.btn {
width: calc(100% - 80px);
margin-left: 40px;
height: 46px;
background: #0E76F4;
border-radius: 5px;
font-size: 15px;
color: #FFFFFF;
text-align: center;
line-height: 46px;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -18,57 +18,6 @@
</template>
</van-nav-bar>
</div>
<van-search
v-model="searchVal"
show-action
placeholder="请输入车辆名称、车牌号、车架号"
@search="resetHandler"
>
<template #action>
<div @click="resetHandler">搜索</div>
</template>
</van-search>
<div class="filterWrap">
<!-- <div >-->
<!--<el-input v-model="searchVal" @blur="resetHandler" placeholder="车辆名称/车牌号/车架号" :class="{'customSel':true,'customInput':true , 'has-value': searchVal }" >
<template #suffix>
<i
v-if="searchVal"
class="el-icon-circle-close el-input__icon"
@click="searchVal = ''"
></i>
</template>
</el-input>-->
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="authStates" placeholder="认证状态" :class="{'customSel':true , 'has-value': authStates }" clearable>
<el-option
v-for="item in authStatesOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="inputStatusList" placeholder="录入状态" :class="{'customSel':true , 'has-value': inputStatusList }" clearable>
<el-option
v-for="item in inputStatusListOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<!-- </div>-->
<!-- <div>-->
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="liabilityInsuranceAuditList" placeholder="职业责任险" :class="{'customSel':true , 'has-value': liabilityInsuranceAuditList }" clearable>
<el-option
v-for="item in insuresOptions"
:key="item.value"
:label="item.name"
:value="item.value">
</el-option>
</el-select>
<!-- </div>-->
</div>
<div class="wrap_cls">
<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
<van-list
v-model="loading"
@@ -76,52 +25,31 @@
finished-text="没有更多了"
@load="onLoad"
>
<div class="carItem" v-for="(item,index) in vehicleList" :key="index" @click.stop="updateVehicle(item)">
<div class="carItem" v-for="(item,index) in vehicleList" :key="index">
<div class="carCode">
<div class="codeLeft">{{item.plateNumber}} / {{item.vehicleTypeString}}
<span class="ml10" :class="{'insuranceSuccess': item.vehicleStatus == 1, 'insuranceDanger': item.vehicleStatus == 2 ,'insuranceGray': !item.vehicleStatus }">{{ item.vehicleStatus == 1 ? '启用' :( item.vehicleStatus == 2 ? '停用' : ( item.vehicleStatus == 12 ? '否-服务商停用' : '无状态')) }} </span>
<div class="codeLeft">{{item.plateNumber}} / {{item.vehicleTypeString}}</div>
<div class="twoBtn">
<button v-if="permissonList.includes('vehicleAddBtn')" class="del" @click="deleteItem(item.vehicleId)">删除</button>
<button v-if="permissonList.includes('vehicleModifyBtn')" class="revise" @click="updateVehicle(item)">修改</button>
</div>
<div class="codeRight" v-if="item.vehicleStatus == 1" @click.stop="updateStatus(item)">停用</div>
</div>
<div class="juhe flex-between">
<span class="zdJuhe">核验认证</span>
<span class="flex-right">
<span class="common_cls" v-if="item.inputStatusString" :class="getClass(item.inputStatusString)?.className">{{item.inputStatusString}}</span>
<span class="common_cls" v-if="item.authStateString" :class="getClass(item.authStateString)?.className">{{item.authStateString}}</span>
</span>
<div class="carType">{{ item.serviceName }}</div>
<div class="juhe">
<span class="zdJuhe">是否参与中道聚合: </span>
<span :class="item.hasPolymerization.code == 0 ? 'isYes' :'isNo'">{{item.hasPolymerization.label}}</span>
</div>
<div class="juhe flex-between">
<span class="zdJuhe">救援责任险</span>
<span class="flex-right" v-if="item.rescueInsurance">
<span class="common_cls" @click.stop="showTip(item.liabilityInsuranceAuditMsg)" :class="getClass(item.rescueInsurance)?.className">{{item.rescueInsurance}}</span>
</span>
</div>
<!-- <div class="juhe flex-between">
<span class="zdJuhe">车辆信息</span>
<span class="flex-right" v-if="item.auditStatusStr">
<span class="common_cls" @click.stop="showTip(item.auditMsg)" :class="getClass(item.auditStatusStr)?.className">{{item.auditStatusStr}}</span>
</span>
</div>-->
<div class="juhe flex-between">
<span class="zdJuhe">最近登录时间</span>
<span class="flex-right">{{item.lastLoginTime}}</span>
</div>
<van-icon class="arrow_position" v-if="permissonList.includes('vehicleModifyBtn')" name="arrow" />
</div>
</van-list>
</van-pull-refresh>
</div>
<van-dialog v-model="show" title="确定删除吗" show-cancel-button @confirm="handleConfirm"></van-dialog>
</div>
</template>
<script>
import {Dialog} from "vant";
import { myMixins} from "@/utils/myMixins";
import {supplierVehicleList, deleteVehicle, userOperationPermissions, enableVehicle} from "@/api/mine"
import {supplierVehicleList,deleteVehicle,userOperationPermissions} from "@/api/mine"
export default {
name: "vehicleManage",
mixins:[myMixins],
@@ -136,134 +64,27 @@ export default {
isLoading: false,
loading: false,
finished: false,
showPopover: false,
permissonList:[],
inputStatusList: [],
searchVal: '',
authStates: [],
liabilityInsuranceAuditList: [],
inputStatusListOptions: [{
name: '行驶证未录入',
value: 0
},{
name: '行驶证核验通过',
value: 1
},{
name: '行驶证核验不通过',
value: 2
}],
authStatesOptions: [{
name: '车头照片未录入',
value: 1
},{
name: '车头照片认证通过',
value: 2
},{
name: '车头照片认证不通过',
value: 3
}],
insuresOptions: [{
name: '待审核',
value: 1
},{
name: '有责任险',
value: 2
},{
name: '有货物险',
value: 3
},{
name: '未通过',
value: 4
},{
name: '无',
value: 5
},{
name: '空',
value: 6
},{
name: '原责任险过期',
value: 8
},{
name: '原货物险过期',
value: 9
}],
}
},
mounted() {
// this.getVehicleList();
this.getPermissions();
},
methods:{
showTip(msg) {
Dialog.alert({
title: '未通过原因',
message: msg,
}).then(() => {
});
},
getClass(id) {
const ids = String(id)
const steps = {
'待审核': {
className: 'main_cls'
},
'有责任险': {
className: 'success_cls'
},
'有货物险': {
className: 'info_cls'
},
'未通过': {
className: 'danger_cls'
},
'原责任险过期': {
className: 'danger_cls'
},
'原货物险过期': {
className: 'danger_cls'
},
'无': {
className: 'default_cls'
},
'空': {
className: 'default_cls'
},
'行驶证未录入': {
className: 'default_cls'
},
'行驶证核验通过': {
className: 'success_cls'
},
'行驶证核验不通过': {
className: 'danger_cls'
},
'车头照未录入': {
className: 'default_cls'
},
'车头照认证通过': {
className: 'success_cls'
},
'车头照认证不通过': {
className: 'danger_cls'
}
}
return steps[ids] || { className: 'default_cls' }
},
async onLoad(){
await this.getVehicleList()
if(this.total>10){
this.pageNum++;
}
// 加载状态结束
this.loading = false;
// 数据全部加载完成
if (this.vehicleList.length >= this.total) {
this.finished = true;
} else {
this.finished = false;
}
},
async onRefresh() {
await this.resetHandler()
onRefresh() {
this.pageNum=1
// this.getVehicleList()
setTimeout(() => {
this.$toast('刷新成功');
this.isLoading = false;
@@ -272,11 +93,7 @@ export default {
async getVehicleList(){
let result = await supplierVehicleList({
pageNum:this.pageNum,
pageSize:this.pageSize,
searchVal: this.searchVal,
inputStatusList: this.inputStatusList,
authStates: this.authStates,
liabilityInsuranceAuditList: this.liabilityInsuranceAuditList,
pageSize:this.pageSize
})
this.total=result.total
if(this.pageNum == 1){// 第一页直接赋值
@@ -304,42 +121,13 @@ export default {
this.pageNum=1
await this.getVehicleList();
},
async resetHandler() {
this.pageNum=1
this.finished = false;
this.total = 0;
// this.vehicleList = [];
await this.getVehicleList();
},
updateStatus(item){
if(item.vehicleStatus != 1){
return
}
Dialog.confirm({
message: '当前状态为启用,是否要改为停用?',
}).then(async () => {
// on confirm
await enableVehicle({
vehicleId:item.vehicleId,
vehicleStatus:2,
})
this.pageNum=1
await this.getVehicleList()
console.log("item",item)
}).catch(() => {
// on cancel
});
},
updateVehicle(item){//修改
if( this.permissonList.includes('vehicleModifyBtn') ) {
this.$router.push({
name:'vehicleAdd',
params:{
id:item.vehicleId,
supplierId:item.supplierId
id:item.vehicleId
}
})
}
},
}
@@ -349,41 +137,12 @@ export default {
<style scoped lang="scss">
@import "@/styles/mixin.scss";
@import "@/styles/common.scss";
.ml10 {
margin-left: 10px;
}
.wrap{
background: #F4F5F7;
@include sizingPadding(13px,13px);
@include wh(100%, 100%);
overflow-y: auto;
}
.wrap_cls {
width: 100%;
padding-left: 13px;
padding-right: 13px;
box-sizing: border-box;
}
.common_cls {
color: #fff;
padding: 4px 8px;
border-radius: 3px;
margin-right: 6px;
}
.default_cls {
background-color: #B0BEC5;
}
.danger_cls {
background-color: red;
}
.success_cls {
background-color: #4CAF50;
}
.info_cls {
background-color: #FF9800;
}
.main_cls {
background-color: #6C9BFF;
}
.navBar{
margin-bottom: 46px;
.rightWrap{
@@ -402,28 +161,20 @@ export default {
}
}
.carItem{
@include wh(100%,120px);
@include wh(100%,86px);
background: #FFFFFF;
box-shadow: 0px 2px 10px 0px rgba(216,216,216,0.5);
@include radiusSizing(6px);
padding: 11px 13px 11px 15px;
margin-bottom: 10px;
@include flexBetween;
position: relative;
.carCode{
@include flexColBet;
.codeLeft{
@include fontWeightSize(bold,14px)
}
.codeRight{
padding: 2px 8px;
border: 1px solid #DDDDDD;
border-radius: 3px;
font-weight: bold;
}
.twoBtn{
display: flex;
align-items: center;
button{
border: none;
padding: 4px 8px;
@@ -451,11 +202,6 @@ export default {
opacity: .7;
@include fontWeightSize(400,12px)
}
.zdJuhe {
width: 80px;
text-align: right;
margin-left: -10px;
}
.isYes{
color: #09B820;
@include fontWeightSize(400,12px);
@@ -465,125 +211,4 @@ export default {
@include fontWeightSize(400,12px);
}
}
.arrow_position {
position: absolute;
right: 5px;
top: 50px;
font-size: 20px;
opacity: 0.6;
}
.mr10 {
margin-right: 10px;
}
.insuranceMain {
color: #354D93;
}
.insuranceSuccess {
color: green;
}
.insuranceTip {
color: orange;
}
.insuranceDanger {
color: red;
}
.insuranceGray{
color: #aaa;
}
.flex-between {
display: flex;
justify-content: space-between;
align-items: center;
}
.filterWrap {
width: 100%;
padding-right: 13px;
padding-left: 13px;
display: flex;
overflow-x: auto; /* 允许横向滚动 */
white-space: nowrap; /* 防止子元素换行 */
padding-bottom: 10px;
-webkit-overflow-scrolling: touch; /* 在iOS上平滑滚动 */
scrollbar-width: none; /* Firefox */
padding-bottom: 10px;
/*padding: 10px;*/
margin-bottom: 10px;
background-color: #fff;
box-sizing: border-box;
&::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.customSel {
flex: 0 0 auto; /* 防止子元素被压缩 */
width: calc(33% - 5px);
/*width: 100%;*/
height: 25px;
background: #F5F5F5;
border-radius: 4px;
font-size: 10px;
color: #323233;
margin-right: 5px;
::v-deep .el-input__inner{
padding: 0 2px;
height: 25px;
font-size: 10px;
background: #F5F5F5;
border-radius: 4px;
border: none;
}
::v-deep .el-input__icon{
line-height: 25px;
font-size: 10px;
width: 18px;
color: #2A5094;
}
::v-deep .el-input__suffix{
right: 2px;
}
}
.customInput{
/*width: 49%;*/
width: 130px;
}
.has-value ::v-deep .el-input__inner{
background: #F1F6FF ;
color: #007BE9;
font-weight: bold;
padding-left: 8px;
}
.has-value ::v-deep .el-input__icon{
color: #007BE9;
}
.priceSel{
display: flex;
justify-content: space-around;
align-items: center;
color: #C0C4CC;
.iconSpan{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 8px;
}
}
.has-price{
color: #007BE9 !important;
}
}
::v-deep .el-select .el-select__tags>span {
display: flex;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.flex-right {
display: flex;
flex: 1;
justify-content: flex-start;
margin-left: 10px;
}
</style>

View File

@@ -1,17 +1,12 @@
<template>
<div class="wrap">
<div class="baseInfo common" :style="{'height':orderDetailInfo.contractParentId == 110 ? '300px' : '240px'}">
<div class="baseInfo common">
<div class="title">基本信息:</div>
<div class="line"></div>
<div class="infoWrap fontColor">
<div class="leftTitle">
<div class="leftItem">工单编号:</div>
<div class="leftItem">合同:</div>
<template v-if="orderDetailInfo.contractParentId == 110">
<div class="leftItem">机构名称:</div>
<div class="leftItem">销售人员:</div>
<div class="leftItem">司机号码:</div>
</template>
<div class="leftItem">结算方式:</div>
<div class="leftItem">客户姓名:</div>
<div class="leftItem">客户电话:</div>
@@ -24,11 +19,6 @@
<img @click="copyText" src="@/assets/copy.png" style="width: 35px;height: 15px;margin-left: 10px"/>
</div>
<div class="rightItem">{{ orderDetailInfo.contractName }}</div>
<template v-if="orderDetailInfo.contractParentId == 110">
<div class="rightItem">{{ orderDetailInfo.organizeName }}</div>
<div class="rightItem">{{ orderDetailInfo.saleName }}</div>
<div class="rightItem">{{ orderDetailInfo.driverPhone ? orderDetailInfo.driverPhone : ' '}}</div>
</template>
<div class="rightItem">{{ orderDetailInfo.contractSettleType?.label }}</div>
<div class="rightItem">{{ orderDetailInfo.userName }}</div>
<div class="rightItem">{{ orderDetailInfo.userPhone }}</div>
@@ -46,9 +36,6 @@
<div class="item">
<span class="leftTitle fontColor">服务类型:</span><span class="rightContent">{{ orderDetailInfo.taskServiceName }}</span>
</div>
<div class="item" v-if="orderDetailInfo?.userVehicleTypeString">
<span class="leftTitle fontColor">车辆类型:</span><span class="rightContent">{{ orderDetailInfo.userVehicleTypeString }}<van-icon class="icon" name="question" @click="showCarTypeShow = true" /></span>
</div>
<div class="item">
<span class="leftTitle fontColor">车辆位于:</span><span class="rightContent">{{ orderDetailInfo.positionEnvironment?.label }}</span>
</div>
@@ -74,7 +61,6 @@
<div class="item">
<span class="leftTitle fontColor">服务师傅:</span><span class="rightContent">{{ orderDetailInfo.driverName }} {{orderDetailInfo.drivePhone ? '/' : ''}} {{orderDetailInfo.drivePhone }}
<span v-if="queryType == 5" class="driverPoiBtn" @click="noMultipleClicks(showMap)">查看司机位置</span>
<span v-if="orderDetailInfo.driverName && orderDetailInfo.proprietary?.code==1" class="driverPoiBtn" @click="noMultipleClicks(createDriverInfo)">生成司机信息</span>
</span>
</div>
<div class="item" v-if="queryType == 9 || queryType ==11 || queryType ==12">
@@ -99,15 +85,7 @@
</div>
</div>
</div>
<van-popup v-model="showCarTypeShow" round position="center" class="popupCenter">
<table v-for="(item, index) in carTypeList" :key="index">
<tr>
<td width="50">{{item.type}}:</td>
<td>{{item.abbr}}</td>
</tr>
</table>
<!-- <div v-for="(item, index) in carTypeList" :key="index"><span style="margin-right: 5px">{{item.type}}:</span><span>{{item.abbr}}</span></div>-->
</van-popup>
<div class="map" v-show="showPopup" id="container">
<img @click="showPopup = false" src="@/assets/delKey.png" class="mapImg">
</div>
@@ -115,7 +93,7 @@
</template>
<script>
import {myMixins} from '@/utils/myMixins'
import {getOrderDetail,showVehiclePositionInfo, getConfigByCode,getDriverInfo} from "@/api/order"
import {getOrderDetail,showVehiclePositionInfo} from "@/api/order"
import minePosition from '@/assets/minePosition.png';
import vehiclePosition from '@/assets/vehiclePosition.png';
import desitationPosition from '@/assets/desitationPosition.png'
@@ -133,8 +111,6 @@ export default {
map: '',
driverPoiInfo:{},
noClick:true,
showCarTypeShow: false,
carTypeList: []
}
},
async mounted() {
@@ -145,7 +121,6 @@ export default {
this.userOrderId = urlParams.get('userOrderId');
this.orderCode=urlParams.get('orderCode');
this.taskOrderId=urlParams.get('taskOrderId') ? urlParams.get('taskOrderId') : '';
await this.getConfigByCodeHandler();
await this.getDetail();
if(this.queryType == 5){
await this.getDriverPoi();
@@ -156,36 +131,6 @@ export default {
},
methods:{
async getConfigByCodeHandler() {
let res = await getConfigByCode({
code: 'userVehicleTypeConfig'
});
this.carTypeList = res?.data?.userVehicleType
},
async getDriverInfo(){
let result=await getDriverInfo({
driverId:this.orderDetailInfo.driverId
})
if(result.data){
// console.log('--result--',result.data)
let params={
'姓名:':this.orderDetailInfo.driverName,
'身份证:':result.data.identityCardNumber,
'车牌:':this.orderDetailInfo.plateNumber,
'手机:':this.orderDetailInfo.driverPhone,
}
let data = {"action":"copyToClipboard","params":JSON.stringify(params)}
var u = navigator.userAgent;
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if(isiOS){
window.webkit.messageHandlers.nativeObject.postMessage(data);
}else {
window.android.copyToClipboard(JSON.stringify(params));
}
}else {
this.$toast('未获取到司机信息')
}
},
async getDetail(){
let result=await getOrderDetail({
queryType:this.queryType,
@@ -201,9 +146,6 @@ export default {
this.showPopup = true;
this.mapMarkers();
},
async createDriverInfo(){//生成司机信息
await this.getDriverInfo()
},
checkPhoto(){
let isAllowImage = this.queryType == 9 ? 0 : 1
let data = {
@@ -321,8 +263,7 @@ export default {
line-height: 24px;
}
.baseInfo{
width: 100%;
//@include wh(100%,260px);
@include wh(100%,260px);
margin-bottom: 12px;
.infoWrap{
display: flex;
@@ -335,9 +276,6 @@ export default {
.rightContent{
height: 189px;
width: calc(100% - 60px);
.rightItem{
height: 24px;
}
}
}
}
@@ -392,8 +330,4 @@ export default {
margin: 7px 0;
border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
}
.popupCenter {
padding: 20px 10px;
width: 80%;
}
</style>

View File

@@ -1,46 +0,0 @@
<template>
<div class="wrap">
<el-table :data="tableData"
stripe
border
style="width: 100%"
height="100%"
v-loading="loading"
class="custom-table">
<el-table-column v-for="item in labelList" :key="item.prop" :label="item.label" :prop="item.prop" align="center">
<template slot-scope="scope">{{scope.row[item.prop]}} </template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "fit-table",
props: ['tableData', 'labelList', 'loading', 'isMobile','active'],
data() {
return {}
},
mounted() {
},
methods: {
}
}
</script>
<style scoped lang="scss">
@import "@/styles/mixin.scss";
::v-deep .el-table{
font-size: 11px;
}
::v-deep .el-table thead{
color: #1D2129;
font-weight: bold;
}
::v-deep .el-table th.el-table__cell.is-leaf {
background-color: #E5E6EB;
}
::v-deep .el-table .el-table__cell{
padding: 4px 0 !important;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -39,13 +39,14 @@
<van-tabs v-model="active" sticky @click="tabClickHandle">
<van-tab v-for="(item,index) in tabArr" :key="index" :title="item.name"></van-tab>
<div v-if="isMobile && !([0,1,2,3].includes(active))" class="tipArrow left">{{ leftArr }}</div>
<div v-if="isMobile && !([7,8, 9].includes(active))" class="tipArrow right">>>></div>
<div v-if="isMobile && !([9,10, 11].includes(active))" class="tipArrow right">>>></div>
</van-tabs>
<div v-loading="loadingData" :class="{'contentWrap':true,'webcontentWrap':!isMobile}" v-if="active===0">
<!--<div :class="{'reciceOrder':true,'webCom':!isMobile}">
<div :class="{'reciceOrder':true,'webCom':!isMobile}">
<div :class="{'title':true,'webTitle':!isMobile}">接单指标</div>
<div class="reciceOrderIWrap">
<div class="left common">
<!-- indexData && -->
<div class="num">{{ formatCurrency(indexData?.receiveOrderCount) }}</div>
<div class="itemTitle">承接案件量</div>
</div>
@@ -58,7 +59,7 @@
<div class="itemTitle" style="cursor: pointer">超时率 ></div>
</div>
</div>
</div>-->
</div>
<div :class="{'reciceOrder':true,'webCom':!isMobile,'evaluate':isMobile}">
<div class="title">客户评价</div>
<div class="reciceOrderIWrap" v-if="indexData">
@@ -111,28 +112,38 @@
<circle-char v-show="showScoreChart" ref="Doughnut7" :data="indexData && indexData.score" :bg-color="Number(indexData?.score || 0) >= 60 ? 'green' : 'red'" :is-store="true"></circle-char>
<div v-show="!showScoreChart" class="detailScore">
<div class="left">
<!-- <div><span class="defen">接单得分:</span></div>-->
<div><span class="defen">接单时效得分:</span></div>
<div><span class="defen">到达时效得分:</span></div>
<div><span class="defen">聚合成功率得分:</span></div>
<div><span class="defen">APP使用率得分:</span></div>
<div><span class="defen">催促率得分:</span></div>
<div><span class="defen">投诉率得分:</span></div>
<div><span class="defen">超时率得分:</span></div>
<div><span class="defen">拒单率得分:</span></div>
<div><span class="defen">3'联系率得分:</span></div>
<div>
<span class="defen">接单得分:</span>
</div>
<div>
<span class="defen">接单时效得分:</span>
</div>
<div>
<span class="defen">接单时效得分:</span>
</div>
<div><span class="defen">聚合成功率得分:</span>
</div>
<div><span class="defen">APP使用率得分:</span>
</div>
<div><span class="defen">催促率得分:</span>
</div>
<div><span class="defen">投诉率得分:</span>
</div>
</div>
<div class="right">
<!-- <div><span>{{ indexData.orderScore }}</span></div>-->
<div><span>{{ indexData.orderAgeingScore }}</span></div>
<div><span>{{ indexData.arriveAgeingScore }}</span></div>
<div>
<span>{{ indexData.orderScore }}</span>
</div>
<div>
<span>{{ indexData.orderAgeingScore }}</span>
</div>
<div>
<span>{{ indexData.arriveAgeingScore }}</span>
</div>
<div> <span>{{ indexData.polymerizationSuccessScore }}</span></div>
<div> <span>{{ indexData.appUseScore }}</span></div>
<div> <span>{{ indexData.urgeScore }}</span></div>
<div><span>{{ indexData.urgeScore }}</span></div>
<div> <span>{{ indexData.timeOutScore }}</span></div>
<div> <span>{{ indexData.refuseOrderScore }}</span></div>
<div><span>{{ indexData.threeMinutesContactSocre }}</span></div>
</div>
</div>
</div>
@@ -153,7 +164,7 @@
<div v-if="active==1" style="width: 100%">
<div id="chartWrap" style="width: 100%;height:300px"></div>
</div>
<div v-if="activeIndex==2" class="selectWrap">
<div v-if="activeIndex==3" class="selectWrap">
<el-select v-model="value" @change="changeHandle">
<el-option
v-for="item in options"
@@ -165,7 +176,7 @@
</div>
</template>
<template v-else>
<div v-if="[0,1].includes(activeIndex)">
<div v-if="[0,1,2].includes(activeIndex)">
<div id="chartWrap" style="width: 100%;height:300px"></div>
</div>
<div v-else style="width: 100%;display: flex;justify-content: space-between">
@@ -189,8 +200,8 @@
<noFit-table v-else :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"></noFit-table>
</div>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[2,3,4].includes(active)">
<div class="searchDriverName" v-if="[3,4].includes(active)">
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[2,4,5].includes(active)">
<div class="searchDriverName" v-if="[5,4].includes(active)">
<el-select
v-model="driverName"
filterable
@@ -212,12 +223,12 @@
</el-select>
</div>
<div :class="{'tabWrap':true,'webTabWrap':!isMobile,'mobileTab':isMobile}">
<div v-for="(item,index) in (active===3 ? driverList : list)" :class="activeIndex===index ? 'active' : ''"
<div v-for="(item,index) in (active===4 ? driverList : list)" :class="activeIndex===index ? 'active' : ''"
:key="index"
@click="changeTab(index)">{{ item.name }}
</div>
</div>
<div :class="{'comTab':active !== 3,'comTabActive3':active === 3}">
<div :class="{'comTab':active !== 4,'comTabActive3':active === 4}">
<noFit-table :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"></noFit-table>
</div>
<el-pagination
@@ -232,13 +243,13 @@
:total="total">
</el-pagination>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[5,6,7,8,9].includes(active)">
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[3,6,7,8,9,10, 11].includes(active)">
<div :class="{'comTab':true,'detailTable':isMobile}">
<noFit-table :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"
></noFit-table>
</div>
<el-pagination
v-if="active !== 8"
v-if="active !== 10"
small
:page-sizes="[20, 50, 100]"
:current-page.sync="pageNum"
@@ -261,9 +272,8 @@ import {
getStatisticsKpi,
getSupplierId,
getDriverName,getDriverStatisticsKpi,
getRecentSupplierKpi,
getRecentSupplierKpi, querySupplierDriverStatisticsScore
} from "@/api/kpi.js"
// querySupplierDriverStatisticsScore
import {myMixins} from "@/utils/myMixins"
import CircleChar from "@/views/kpi/components/circleChar.vue";
import NoFitTable from "@/views/kpi/components/noFit-table.vue";
@@ -279,14 +289,11 @@ export default {
activeIndex: 0,
//
tabArr: [
{name: '总览',value:0}, {name: '月/总'}, {name: '日/总'},{name: '月/师傅'}, {name: '日/师傅'}, /*{name: '拒单明细'},*/
/*{name: '超时明细'},*/ {name: '催促明细'},{name: '投诉明细'}, {name: '不使用APP案件明细'}, {name: '车辆在线情况'} , {name: '聚合失败案件明细'}
{name: '总览'}, {name: '月/总'}, {name: '日/总'},{name: '师傅满意度'},{name: '月/师傅'}, {name: '日/师傅'}, {name: '拒单明细'},
{name: '超时明细'}, {name: '投诉明细'}, {name: '不使用APP案件明细'}, {name: '车辆在线情况'} , {name: '聚合失败案件明细'}
],
list: [ {name: '服务评价'}, {name: 'APP使用情况'}, {name: ' 时效 '}],
// driverList: [{name: '得分总览'},{name: '接单情况'}, {name: '服务评价'}, {name: 'APP使用情况'}, {name: '时效 '}],
// {name: '接单情况'},
driverList: [{name: '服务评价'}, {name: 'APP使用情况'}, {name: '时效 '}],//story#7149,要求暂时隐藏得分总览
list: [{name: '接单指标'}, {name: '客户评价'}, {name: 'APP使用'}, {name: ' 时效 '}],
driverList: [{name: '得分总览'},{name: '接单情况'}, {name: '服务评价'}, {name: 'APP使用情况'}, {name: '时效 '}],
startMonthTime: '',
startTime: '',
endTime: '',
@@ -309,6 +316,7 @@ export default {
isMobile: false,
isZd: '',
current:'2024-10',
// current: dayjs(new Date()).format('M'),
supplierName:'',
value: '1',
options: [
@@ -362,13 +370,21 @@ export default {
}
},
monthChangeHandle(value){
console.log('valuevaluevalue', dayjs(new Date(value)).format('YYYY-MM-DD'))
if (value) {
this.current = dayjs(new Date(value)).format('YYYY-MM')
const _tempDate = dayjs(new Date(value)).format('YYYY-MM-DD')
const lastDay = dayjs(_tempDate).endOf('month');
/*const year = value.getFullYear();
const month = value.getMonth() + 1; // 月份从 0 开始,需要加 1
const yearAndMonth = year + '-' + (month > 9 ? month : '0' + month);
this.current = dayjs(new Date(yearAndMonth)).format('YYYY-MM')*/
this.startTime = `${this.current}-01 00:00:00`;
// const lastDay = new Date(year, month, 0).getDate(); // 获取该月的最后一天
this.endTime = `${this.current}-${this.padZero(lastDay.date())} 23:59:59`;
this.startMonthTime=this.getStartTimeFromEndTime(this.endTime)
console.log(" this.startMonthTime", this.startMonthTime)
this.selectSupplierNameHandle();
if(this.active===1){
this.tabClickHandle()
@@ -384,7 +400,7 @@ export default {
return
}
this.$refs.Doughnut1.initCircle()
// this.$refs.Doughnut2.initCircle()
this.$refs.Doughnut2.initCircle()
this.$refs.Doughnut3.initCircle()
this.$refs.Doughnut4.initCircle()
this.$refs.Doughnut5.initCircle()
@@ -497,7 +513,7 @@ export default {
let myChart = echarts.init(document.getElementById('chartWrap'))
let option;
//接单指标
/*let series1 = [{
let series1 = [{
name: '派遣案件量',
type: 'bar',
data: this.v1?.map(item => Number(item?.toString()?.replace(/,/g, ''))),
@@ -536,19 +552,19 @@ export default {
formatter: '{c}%'
},
},
// {
// name: '客户取消率',
// type: "line",
// data: this.v4,
// yAxisIndex: 1,
// smooth: true,
// label: {
// show: true,
// position: 'top',
// formatter: '{c}%'
// },
// },
]*/
/* {
name: '客户取消率',
type: "line",
data: this.v4,
yAxisIndex: 1,
smooth: true,
label: {
show: true,
position: 'top',
formatter: '{c}%'
},
},*/
]
let series2 = [
{
name: '投诉率',
@@ -724,7 +740,7 @@ export default {
},
},
]
/*let yAxis1 = [
let yAxis1 = [
{type: 'value'},
{
type: 'value',
@@ -732,7 +748,7 @@ export default {
formatter: '{value}%'
}
},
]*/
]
let yAxis2 = [
{
type: 'value',
@@ -763,17 +779,16 @@ export default {
let series = []
let yAxis = []
if (this.active === 1) {
/* if (this.activeIndex === 0) {
if (this.activeIndex === 0) {
series = series1
yAxis = yAxis1
} else*/
if (this.activeIndex === 0) {
} else if (this.activeIndex === 1) {
series = series2
yAxis = yAxis2
} else if (this.activeIndex === 1) {
} else if (this.activeIndex === 2) {
series = []
yAxis = []
} else if (this.activeIndex === 2) {
} else if (this.activeIndex === 3) {
if (this.value == 1) {
series = series4
yAxis = yAxis4
@@ -785,7 +800,7 @@ export default {
}
option = {
title: {
text: this.isMobile ? this.getTitle(this.activeIndex) : (this.active === 1 && this.activeIndex === 1) ? '' : '师傅接单时效',
text: this.isMobile ? this.getTitle(this.activeIndex) : (this.active === 1 && this.activeIndex === 2) ? '' : '师傅接单时效',
textStyle: {
fontSize: 12
},
@@ -797,7 +812,7 @@ export default {
right: '1%',
itemWidth: this.isMobile ? 10 : 18, // 设置图例图标的宽度,从而调整图标大小
itemHeight: this.isMobile ? 6 : 10,
width: (this.active == 1 && this.activeIndex == 1) ? '60%' : '100%',
width: (this.active == 1 && this.activeIndex == 2) ? '60%' : '100%',
},
xAxis: {
type: 'category',
@@ -970,7 +985,7 @@ export default {
async getKpiData() {
try {
this.loading = true
if (this.active === 0) {//总览
if (this.active === 0) {
await this.allDataChart()
let res = await getStatisticsKpiByMonth({
startTime: this.startTime,
@@ -1001,7 +1016,7 @@ export default {
this.indexData[key] = this.processPercentage(this.indexData[key]);
}
}
} else if ([1, 2].includes(this.active)) {//月总 日总
} else if ([1, 2].includes(this.active)) {
let res = await getStatisticsKpi({
startTime: this.active === 1 ? this.startMonthTime : this.startTime,
endTime: this.endTime,
@@ -1032,6 +1047,8 @@ export default {
item.minorFortyMinutesArrivalRate=this.formatPercentage(item.minorFortyMinutesArrivalRate) ;
let formatVal = dayjs(item.statisticsDate).format('DD');
let formatVal1 = dayjs(item.statisticsDate).format('M');
// console.log("formatVal1",formatVal1)
// return {...item, date: formatVal, month: (formatVal1 == this.current) ? '本月' : (formatVal1 + '月')};
return {...item, date: formatVal, month: formatVal1 + '月'};
});
this.loading = false
@@ -1039,8 +1056,33 @@ export default {
this.xAxisArr.push(item.month)
this.xAxisArr = [...new Set(this.xAxisArr)]; // 去重
})
console.log(" this.xAxisArr", this.xAxisArr)
// this.xAxisArr[this.xAxisArr.length - 1] = '本月'
await this.twoTabHanldeData()
} else if ([3,4].includes(this.active)) {//月师傅 日师傅
}else if (this.active === 3) {
let res = await querySupplierDriverStatisticsScore({
startTime: this.startTime ,
endTime: this.endTime,
statisticsType: 1,
supplierId: this.supplierId,
driverId: this.driverId,
driverName:this.driverName,
pageNum: this.pageNum,
pageSize: this.pageSize
})
this.total = res.total
this.detailList = res.data?.map(item => {
let formatVal = dayjs(item.statisticsDate).format('DD');
return {...item, date: formatVal};
});
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '案件总量', prop: 'orderCount'},
{label: '满意度得分 ', prop: 'driverSatisfaction'},
]
this.loading = false;
}
else if ([4,5].includes(this.active)) {
let res = await getDriverStatisticsKpi({
startTime: this.startTime ,
endTime: this.endTime,
@@ -1071,32 +1113,13 @@ export default {
return {...item, date: formatVal};
});
this.loading = false;
/* if(this.active===5 && !this.driverName){
if(this.active===5 && !this.driverName){
this.detailList=[]
this.total=0
}*/
}
await this.twoTabHanldeData();
}
/* else if (this.active ===7) {
let res = await querySupplierDriverStatisticsScore({
startTime: this.startTime ,
endTime: this.endTime,
statisticsType: 1,
supplierId: this.supplierId,
driverId: this.driverId,
driverName:this.driverName,
pageNum: this.pageNum,
pageSize: this.pageSize
})
this.total = res.total
this.detailList = res.data?.map(item => {
let formatVal = dayjs(item.statisticsDate).format('DD');
return {...item, date: formatVal};
});
this.loading = false;
} */
else if ([ 5,6,7, 8,9].includes(this.active)) {
else if ([ 6, 7, 8,9,10, 11].includes(this.active)) {
this.detailList = []
this.labelList = []
let result = await getKpiDetailsData({
@@ -1113,7 +1136,7 @@ export default {
return {...item, date: formatVal};
});
this.loading = false
/*if (this.active === 5) {//拒单明细
if (this.active === 6) {//拒单明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@@ -1123,7 +1146,7 @@ export default {
{label: '拒绝时间', prop: 'time'},
{label: '拒单原因', prop: 'reason'},
]
} else if (this.active === 6) {//超时明细
} else if (this.active === 7) {//超时明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@@ -1133,25 +1156,7 @@ export default {
{label: '超时时间', prop: 'time'},
{label: '超时原因', prop: 'reason'},
]
} else */
if (this.active === 5) {//催促明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '二级合同名称', prop: 'contractName'},
{label: '案件创建时间', prop: 'orderCreateTime'},
{label: '催促创建时间 ', prop: 'urgeTime'},
{label: '服务商接单时间 ', prop: 'taskAcceptTime'},
{label: '备注内容(催促内容) ', prop: 'urgeRemark'},
{label: '催促次数', prop: 'urgeCount'},//无催促次数,催促一次生成一条新的
{label: '服务商名称', prop: 'supplierName'},
{label: '服务车辆', prop: 'vehicleName'},
{label: '服务完成状况', prop: 'orderStatusString'},
{label: '案件完成时间', prop: 'finishTime'},
{label: '省(B)', prop: 'bprovince'},
{label: '市(B)', prop: 'bcity'},
{label: '区(B)', prop: 'area'},
]
} else if (this.active === 6) {//投诉明细
} else if (this.active === 8) {//投诉明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@@ -1160,7 +1165,7 @@ export default {
{label: '投诉类型', prop: 'complainTypeString'},
{label: '责任供应商扣罚金额', prop: 'compensateFee'},
]
} else if (this.active === 7) {//不使用App案件明细
} else if (this.active === 9) {//不使用App案件明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@@ -1169,16 +1174,17 @@ export default {
{label: '案件创建时间', prop: 'orderCreateTime'},
{label: '事发地', prop: 'vehiclePointAddress'},
]
} else if (this.active === 8) {//车辆在线情况
} else if (this.active === 10) {//车辆在线情况
this.labelList = [
// {label: '总车辆数', prop: 'totalCount'},
{label: '在线车辆数(取每日的12点)', prop: 'twelveClockVehicleCount'},
{label: '在线拖车数(12点)', prop: 'trailCount'},
{label: '在线小修车数(12点)', prop: 'minorCount'},
{label: '在线率(在线车辆数/总车辆数)', prop: 'onlineRate'},
// {label: '车辆平均在线时长', prop: ''},
{label: '日期', prop: 'date'},
{label: '0点在线车辆数', prop: 'zeroClockVehicleCount'},
{label: '8点在线车辆数量', prop: 'eightClockVehicleCount'},
{label: '12点在线车辆数量', prop: 'twelveClockVehicleCount'},
{label: '16点在线车辆数', prop: 'sixteenClockVehicleCount'},
{label: '20点在线车辆数量', prop: 'twentyClockVehicleCount'},
{label: '22点在线车辆数量', prop: 'twentyTwoClockVehicleCount'},
]
} else if (this.active === 9) {//聚合失败案件明细
} else if (this.active === 11) {//车辆在线情况
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@@ -1202,6 +1208,22 @@ export default {
},
// 初始化获取当月日期
initDate() {
/*let year=''
let month=''
if( this.current ) {
year = new Date(this.current).getFullYear();
month = new Date(this.current).getMonth() + 1;
} else {
year = new Date().getFullYear();
month = new Date().getMonth() + 1;
}
let yearAndMonth = year + '-' + (month > 9 ? month : '0' + month);
this.current = dayjs(new Date(yearAndMonth)).format('YYYY-MM')
this.startTime = dayjs(new Date()).format('YYYY-MM') + '-01 00:00:00'
this.endTime = dayjs(new Date()).format('YYYY-MM') + '-' + this.getDayLen()+' 23:59:59'*/
// test
// let _testDate = new Date('2024-11-01 00:00:01')
const today = dayjs(); // 获取当前日期
const currentDay = today.date(); // 获取今天是几号1-31
let targetMonth = today; // 默认目标月份是当前月
@@ -1218,6 +1240,7 @@ export default {
}
this.endTime = endTime.format('YYYY-MM-DD HH:mm:ss');
this.startMonthTime=this.getStartTimeFromEndTime(this.endTime)
console.log(" this.startMonthTime", this.startMonthTime,this.startTime)
},
// 获取当月天数
getDayLen() {
@@ -1272,12 +1295,12 @@ export default {
twoTabHanldeData() {
this.etlDetailList=[]
this.etlLabelList=[]
if (this.active === 1) {//月总
if (this.active === 1) {
const columnObj = {} //创建标题数组中第一个对象
columnObj.label = 'KPI' //第一个标题名称
columnObj.prop = 'month' //第一个标题名称对应的字段
this.etlLabelList.push(columnObj)
/*if (this.activeIndex === 0) {//接单指标
if (this.activeIndex === 0) {//接单指标
this.etlDetailList=[{ 'month': '派遣量' },{ 'month': '承接量' },{ 'month': '完成量' },
{ 'month': '拒单量' },{ 'month': '拒单率(%)' },{ 'month': '超时接单量' },{ 'month': '超时率(%)' },{ 'month': '客户取消率(%)' }]
let props = 'prop' //自定义字段名称
@@ -1313,22 +1336,20 @@ export default {
{label: '超时率(%)', prop: 'timeoutOrderRate'},
{label: '取消率(%)', prop: 'cancelRate'},
]
} else*/
if (this.activeIndex === 0) {
// ,{ 'month': '平安好评量' }, { 'month': '平安好评率' }
this.etlDetailList=[{ 'month': '投诉量' },{ 'month': '投诉率(%)' }]
} else if (this.activeIndex === 1) {
this.etlDetailList=[{ 'month': '投诉量' },{ 'month': '投诉率(%)' },{ 'month': '平安好评量' }, { 'month': '平安好评率' }]
console.log('detailList', this.detailList)
let props = 'prop' //自定义字段名称
this.detailList?.map((item,index) => {
this.v1.push(item.complainOrderCount)
this.v2.push(item.complainOrderRate?.replace('%', ''))
// this.v3.push(item?.pinganFavorableCount)
// this.v4.push(item.pinganFavorableRate?.replace('%', ''))
this.v3.push(item?.pinganFavorableCount)
this.v4.push(item.pinganFavorableRate?.replace('%', ''))
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
this.etlLabelList.push(columnObj)
// 'pinganFavorableCount','pinganFavorableRate'
let mappings = [ 'complainOrderCount', 'complainOrderRate' ];
let mappings = [ 'complainOrderCount', 'complainOrderRate', 'pinganFavorableCount','pinganFavorableRate' ];
for (let i = 0; i < mappings.length; i++) {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
@@ -1337,23 +1358,22 @@ export default {
{label: '月份', prop: 'month'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率', prop: 'complainOrderRate'},
{label: '平安好评量', prop: 'pinganFavorableCount'},
{label: '平安好评率', prop: 'pinganFavorableRate'},
]
/* {label: '平安好评量', prop: 'pinganFavorableCount'},
{label: '平安好评率', prop: 'pinganFavorableRate'},*/
} else if (this.activeIndex === 1) {
// { 'month': '平安聚合成功量' },{ 'month': '平安聚合成功率' },
this.etlDetailList=[{ 'month': 'APP使用量' }, { 'month': 'APP使用率' },
} else if (this.activeIndex === 2) {
this.etlDetailList=[{ 'month': 'APP使用量' }, { 'month': 'APP使用率' }, { 'month': '平安聚合成功量' },{ 'month': '平安聚合成功率' },
{ 'month': '中华联合聚合成功量' }, { 'month': '中华联合聚合成功率' }, { 'month': '整体聚合成功量' }, { 'month': '整体聚合成功率' }]
let props = 'prop' //自定义字段名称
this.detailList?.map((item,index) => {
this.v1.push(item.appUseCount)
this.v2.push(item.appRate.replace('%', ''))
/*this.v3.push(item.pinganJuheSuccessCount)
this.v4.push(item.pinganPolymerizationSuccessRate.replace('%', ''))*/
this.v3.push(item.zhonghuaPolymerizationSuccessCount)
this.v4.push(item.zhonghuaPolymerizationSuccessRate.replace('%', ''))
this.v5.push(item.wholeJuheSuccessCount)
this.v6.push(item.wholeJuheSuccessRate.replace('%', ''))
this.v3.push(item.pinganJuheSuccessCount)
this.v4.push(item.pinganPolymerizationSuccessRate.replace('%', ''))
this.v5.push(item.zhonghuaPolymerizationSuccessCount)
this.v6.push(item.zhonghuaPolymerizationSuccessRate.replace('%', ''))
this.v7.push(item.wholeJuheSuccessCount)
this.v7.push(item.wholeJuheSuccessRate.replace('%', ''))
const columnObj = {}
columnObj.label = item.month // 每一列的标题的名称
columnObj.prop = props + index //自定义每一列标题字段名称
@@ -1363,20 +1383,19 @@ export default {
this.$set(this.etlDetailList[i], columnObj.prop, item[mappings[i]]);
}
})
/*{label: '平安聚合成功量', prop: 'pinganJuheSuccessCount'},
{label: '平安聚合成功率', prop: 'pinganPolymerizationSuccessRate'},*/
this.labelList = [
{label: '月份', prop: 'month'},
{label: 'APP使用量', prop: 'appUseCount'},
{label: 'APP使用率', prop: 'appRate'},
{label: '平安聚合成功量', prop: 'pinganJuheSuccessCount'},
{label: '平安聚合成功率', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华联合聚合成功量', prop: 'zhonghuaPolymerizationSuccessCount'},
{label: '中华联合聚合成功率', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '整体聚合成功量', prop: 'wholeJuheSuccessCount'},
{label: '整体聚合成功率', prop: 'wholeJuheSuccessRate'},
]
} else if (this.activeIndex === 2) {
// ,{'month':'平安聚合成功到达时效'}
this.etlDetailList=[{ 'month': '接单时效' },{ 'month': '3分钟联系客户率' },{ 'month': '到达时效' }]
} else if (this.activeIndex === 3) {
this.etlDetailList=[{ 'month': '接单时效' },{ 'month': '3分钟联系客户率' },{ 'month': '到达时效' },{'month':'平安聚合成功到达时效'}]
let props = 'prop' //自定义字段名称
if (this.isMobile) {
if (this.value == 1) {
@@ -1420,16 +1439,16 @@ export default {
})
}
}
// {label: '平安聚合成功到达时效', prop: 'pinganJuheSuccessArriving'},
this.labelList = [
{label: '月份', prop: 'month'},
{label: '接单时效', prop: 'receiving'},
{label: '3分钟联系客户率', prop: 'threeMinutesContactRate'},
{label: '到达时效', prop: 'arriving'},
{label: '平安聚合成功到达时效', prop: 'pinganJuheSuccessArriving'},
]
}
} else if (this.active === 2) {//日总
/*if (this.activeIndex === 0) {//接单指标
} else if (this.active === 2) {
if (this.activeIndex === 0) {//接单指标
this.labelList = [
{label: '日', prop: 'date'},
{label: '派单量', prop: 'dispatchOrderCount'},
@@ -1441,8 +1460,7 @@ export default {
{label: '超时率', prop: 'timeoutOrderRate'},
// {label: '客户取消率(%)', prop: 'cancelRate'},
]
} else*/
if (this.activeIndex === 0) {
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '投诉量', prop: 'complainOrderCount'},
@@ -1450,9 +1468,9 @@ export default {
/* {label: '好评量', prop: 'favorableCount'},
{label: '好评率', prop: 'favorableRate'},*/
{label: '平安评价率', prop: 'pinganEvaluateRate'},
// {label: '平安好评率', prop: 'pinganFavorableRate'},
{label: '平安好评率', prop: 'pinganFavorableRate'},
]
} else if (this.activeIndex === 1) {
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '日', prop: 'date'},
{label: 'APP使用量', prop: 'appUseCount'},
@@ -1464,17 +1482,21 @@ export default {
{label: '整体聚合成功量', prop: 'wholeJuheSuccessCount'},
{label: '整体聚合成功率', prop: 'wholeJuheSuccessRate'},
]
} else if (this.activeIndex === 2) {
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3分钟联系客户率', prop: 'threeMinutesContactRate'},
{label: '到达时效(分)', prop: 'arriving'},
// {label: '平安聚合成功到达时效(分)', prop: 'pinganJuheSuccessArriving'},
{label: '平安聚合成功到达时效(分)', prop: 'pinganJuheSuccessArriving'},
]
}
} else if (this.active === 3) {//月师傅
/* if (this.activeIndex === 0) {
}
/* else if(this.active === 3){
} */
else if (this.active === 4) {
if (this.activeIndex === 0) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '总分', prop: 'score'},
@@ -1502,100 +1524,92 @@ export default {
{label: '新手入列得分', prop: 'listedScore'},
{label: '星级评分', prop: 'starRank'},
]
}else*/
/* if (this.activeIndex === 0) {
}if (this.activeIndex === 1) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '派单量', prop: 'dispatchOrderCount'},
{label: '接单量', prop: 'receiveOrderCount'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%)', prop: 'refuseOrderRate'},
{label: '超时量', prop: 'timeoutOrderCount'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%)', prop: 'timeoutOrderRate'},
]
} else */
if (this.activeIndex === 0) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
// {label: '承接案件量', prop: 'receiveOrderCount'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%)', prop: 'complainOrderRate'},
{label: '平安评价量', prop: 'pinganEvaluateCount'},
{label: '平安评价率(%)', prop: 'pinganEvaluateRate'},
/* {label: '平安好评量', prop: 'pinganFavorableCount'},
{label: '平安好评率(%)', prop: 'pinganFavorableRate'},*/
// {label: '催促率(%)', prop: 'urgeRate'},
]
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: 'App使用量', prop: 'appUseCount'},
{label: 'App使用率(%)', prop: 'appRate'},
// {label: '3联系客户率(%)', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功量', prop: 'pinganPolymerizationSuccessCount'},
{label: '平安聚合成功率(%)', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华联合聚合成功量', prop: 'zhonghuaPolymerizationSuccessCount'},
{label: '中华联合聚合成功率(%)', prop: 'zhonghuaPolymerizationSuccessRate'},
// {label: '中道聚合成功率(%)', prop: 'zdPolymerizationSuccessRate'},
{label: '整体聚合成功量', prop: 'wholeJuheSuccessCount'},
{label: '整体聚合成功率(%)', prop: 'wholeJuheSuccessRate'},
// {label: '日均在线时长(h)', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%)', prop: 'complainOrderRate'},
{label: '客户满意度(%)', prop: 'customerSatisfaction'},
{label: '客户评价率(%)', prop: 'customerEvaluateRate'},
{label: '催促率(%)', prop: 'urgeRate'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: 'App使用率(%)', prop: 'appRate'},
{label: '3联系客户率(%)', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%)', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%)', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%)', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%)', prop: 'polymerizationSuccessRate'},
{label: '日均在线时长(h)', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 4) {
this.labelList = [
{label: '师傅姓名', prop: 'driverName'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3联系客户率(%)', prop: 'threeMinutesReceivingRate'},
{label: '3接单率(%)', prop: 'threeMinutesReceivingRate'},
{label: '到达时效(分)', prop: 'arriving'},
// {label: '40到达率(%)', prop: 'fortyMinutesArrivalRate'},
// {label: '平安聚合成功到达时效(分)', prop: 'pinganJuheSuccessArriving'},
{label: '40到达率(%)', prop: 'fortyMinutesArrivalRate'},
{label: '聚合成功到达时效(分)', prop: 'polymerizationSuccessArriving'},
]
}
} else if (this.active === 4) {//日师傅
/*if (this.activeIndex === 0) {//接单指标
} else if (this.active === 5) {
if (this.activeIndex === 0) {//接单指标
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{label: '派量', prop: 'dispatchOrderCount'},
{label: '接单量', prop: 'receiveOrderCount'},
{label: '派遣案件量', prop: 'dispatchOrderCount'},
{label: '承接案件量', prop: 'receiveOrderCount'},
{label: '完成量', prop: 'finishOrderCount'},
{label: '拒单量', prop: 'refuseOrderCount'},
{label: '拒单率(%)', prop: 'refuseOrderRate'},
{label: '超时量', prop: 'timeoutOrderCount'},
{label: '超时接单量', prop: 'timeoutOrderCount'},
{label: '超时率(%)', prop: 'timeoutOrderRate'},
]
} else */
if (this.activeIndex === 0) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%)', prop: 'complainOrderRate'},
{label: '平安评价量', prop: 'pinganEvaluateCount'},
{label: '平安评价率(%)', prop: 'pinganEvaluateRate'},
// {label: '平安好评量', prop: 'pinganFavorableCount'},
// {label: '平安好评率(%)', prop: 'pinganFavorableRate'},
{label: '客户取消率(%)', prop: 'cancelRate'},
]
} else if (this.activeIndex === 1) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{label: 'App使用量', prop: 'appUseCount'},
{label: 'App使用率(%)', prop: 'appRate'},
{label: '平安聚合成功量', prop: 'pinganPolymerizationSuccessCount'},
{label: '平安聚合成功率(%)', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华联合聚合成功量', prop: 'zhonghuaPolymerizationSuccessCount'},
{label: '中华联合聚合成功率(%)', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '整体聚合成功量', prop: 'wholeJuheSuccessCount'},
{label: '整体聚合成功率(%)', prop: 'wholeJuheSuccessRate'},
{label: '投诉量', prop: 'complainOrderCount'},
{label: '投诉率(%)', prop: 'complainOrderRate'},
{label: '客户满意度(%)', prop: 'customerSatisfaction'},
{label: '客户评价率(%)', prop: 'customerEvaluateRate'},
{label: '催促率(%)', prop: 'urgeRate'},
]
} else if (this.activeIndex === 2) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{label: '使用率(%)', prop: 'appRate'},
{label: '3联系客户率(%)', prop: 'threeMinutesContactRate'},
{label: '平安聚合成功率(%)', prop: 'pinganPolymerizationSuccessRate'},
{label: '中华聚合成功率(%)', prop: 'zhonghuaPolymerizationSuccessRate'},
{label: '中道聚合成功率(%)', prop: 'zdPolymerizationSuccessRate'},
{label: '总聚合成功率(%)', prop: 'polymerizationSuccessRate'},
{label: '日均在线时长(h)', prop: 'onlineDuration'},
]
} else if (this.activeIndex === 3) {
this.labelList = [
{label: '日', prop: 'date'},
{label: '师傅姓名', prop: 'driverName'},
{label: '接单时效(分)', prop: 'receiving'},
{label: '3联系客户率(%)', prop: 'threeMinutesReceivingRate'},
{label: '3接单率(%)', prop: 'threeMinutesReceivingRate'},
{label: '到达时效(分)', prop: 'arriving'},
// {label: '平安聚合成功到达时效(分)', prop: 'pinganJuheSuccessArriving'},
{label: '40到达率(%)', prop: 'fortyMinutesArrivalRate'},
{label: '聚合成功到达时效(分)', prop: 'polymerizationSuccessArriving'},
]
}
}
@@ -1607,32 +1621,30 @@ export default {
},
setType(type) {
switch (type) {
/*case 5:
case 6:
return 1;
case 6:
return 2;*/
case 5:
return 7;
case 6:
return 3;
case 7:
return 4;
return 2;
case 8:
return 5;
return 3;
case 9:
return 4;
case 10:
return 5;
case 11:
return 6;
}
},
getTitle(type) {
switch (type) {
case 0:
return '客户评价';
return '接单时效';
case 1:
return 'APP使用';
return '客户评价';
case 2:
return 'APP使用';
case 3:
return '时效';
/* case 3:
return '时效';*/
}
},
}

View File

@@ -22,7 +22,7 @@
为此中道救援经过与保司沟通协调特为与中道救援合作紧密的服务商提供救援职业责任险参保渠道提升服务商服务能力降低运营风险实现共同进步
</div>
<div>救援职业责任险简介</div>
<div> 1综合保额100万元其中救援责任50万元物流责任50万元可全方位覆盖我们日常的经营活动</div>
<div>1综合保额50万元可全方位覆盖我们日常的经营活动</div>
<div> 2保费支付可采用救援服务费抵扣的方式降低资金压力</div>
<div> 3详细保险条款保费和其他问题如需了解请与辖区区域经理联系</div>
<div> 其他意见建议如需交流请与18621558505曲仁杰联系</div>
@@ -65,7 +65,6 @@ export default {
return {
showPoup: false,
used:false,
saveLoading: true,
}
},
async mounted() {
@@ -74,19 +73,12 @@ export default {
},
methods: {
async saveHandle() {
if( this.saveLoading ) {
try {
this.saveLoading = false;
await sendInsuranceEmail();
this.$toast('操作成功');
this.showPoup = false
setTimeout(() => {
this.showPoup=false
setTimeout(()=>{
this.goBack()
}, 1500)
} finally {
this.saveLoading = true;
}
}
},1500)
},
}
}

View File

@@ -1,453 +0,0 @@
<template>
<div class="wrap">
<div class="navBar">
<van-nav-bar
title="人员信息"
:left-arrow="Boolean(!isWebFunc())"
left-arrow-color="#FFFFFF"
:border="false"
:fixed="true"
:safe-area-inset-top="true"
@click-left="goBack"
/>
</div>
<div :class="{'tipWrap':true,'yelBg':type==3,'greBg':type==4}">
<img v-show="[1,2].includes(type)" src="@/assets/unpass.png" />
<img v-show="[3].includes(type)" src="@/assets/yelTip.png" />
<img v-show="[4].includes(type)" src="@/assets/greTip.png" />
<span v-if="type==1">请立即核对或修改以下信息姓名/身份/电话/微信号/邮箱</span>
<span v-else-if="type==2">角色无法修改如需修改角色请联系区域经理提交审批后请到管理人员模块进行查看</span>
<span v-else-if="type==3">当前信息正在确认中如需调整请联系区域经理</span>
<span v-else-if="type==4">当前信息已确认如需调整请联系区域经理</span>
</div>
<van-loading v-show="personList.length<=0" class="loadingWrap" type="spinner" color="#1989fa" />
<div class="contentWrap" v-show="personList.length>0"
:style="{'height':([1,2].includes(type) && isMaster) ? 'calc(100% - 160px)' : 'calc(100% - 90px)'}">
<div class="itemWrap" v-for="(item,index) in personList" :key="index">
<div class="opaCol">人员{{(index+1)}}:</div>
<div class="line"></div>
<div class="item">
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>姓名</span></div>
<div class="right">
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model="item.name" placeholder="请输入" />
</div>
</div>
<div class="item">
<div class="left opaCol"><span class="star" style="opacity: 0">*</span><span>角色</span></div>
<div class="right" :class="{'opaCol':type==2}">
<van-field :input-align="type==2 ? 'right' : 'left'" readonly v-model="item.roleName" placeholder="请输入" />
</div>
</div>
<div class="item">
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>电话1</span></div>
<div class="right">
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model.number="item.phone1" placeholder="请输入" @blur="blurHandle" />
</div>
</div>
<div class="item">
<div class="left" :class="{'opaCol':type!=2}"><span class="star" style="opacity: 0">*</span><span>电话2</span></div>
<div class="right">
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model.number="item.phone2" @blur="blurHandle" placeholder="请输入" />
</div>
</div>
<div class="item">
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>微信号</span></div>
<div class="right wechatRight">
<span class="reviseBtn" v-show="type==2" @click="wechatRevise(item,index)">修改</span>
<van-field :input-align="type==2 ? 'right' : 'left'" readonly v-model="item.wechatName" />
</div>
</div>
<div class="item">
<div class="left" :class="{'opaCol':type!=2}"><span class="star" style="opacity: 0">*</span><span>邮箱</span></div>
<div class="right">
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model="item.email" placeholder="请输入" />
</div>
</div>
</div>
</div>
<div class="btnWrap" v-if="isMaster && [1,2].includes(type)">
<div v-show="type==2" class="audit common" @click="auditHandle">提交审批</div>
<div v-show="type==1" class="revise common" @click="reviseHandle">立即修改</div>
<div v-show="type==1" class="confirm common" @click="confirmHandle">确认信息无误</div>
</div>
<van-dialog v-model="dialogShow" title="请将此二维码发送至相应人员进行添加,成功添加后将更新微信号。" show-cancel-button
confirmButtonText="确认已添加" confirmButtonColor="#354E93" className="customDialog"
@confirm="wechatConfirm" @cancel="cancelHandle">
<img v-if="wechatInfo?.qrCode" :src="wechatInfo.qrCode" style="width: 83%"/>
</van-dialog>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {getConfirmPerson,getConfirmStatus,getQrCode,confirmAddWechat,confirm,submitConfirm} from "@/api/authentication";
import { Dialog } from 'vant';
export default {
name: "personList",
mixins:[myMixins],
data(){
return{
noClick:true,
id:'',
type:'',//1确认信息 2修改 3审批中 4已确认
personList:[],
dialogShow:false,
reviseIndex:-1,
supplierId:'',
wechatInfo:'',
personInfoId:'',
personInfo:'',
isMaster:false,
}
},
async mounted() {
window.addEventListener('message', (event) => {
if (event.data === 'dialogClosed') {
// console.log('Dialog 已关闭 // 执行关闭后的逻辑');
}
});
// console.log('isWebFunc()',this.isWebFunc())
const urlParams = new URLSearchParams(window.location.search);
this.id=this.$route.query.id || urlParams.get('id');
this.supplierId=this.$route.query.supplierId || urlParams.get('supplierId');
// this.supplierId=1128
console.log('1111',this.supplierId)
await this.getPersonList()
},
methods:{
blurHandle(e){
let val= e.target.value || ''
let flag=this.validatePhone(val)
// console.log('flag',flag)
if(!flag){
this.$toast('电话号码格式不正确')
}
},
validatePhone(val) {
console.log('val',val)
if(!val){
return true
}
const purePhone = String(val).trim()
const mobileReg = /^1[3-9]\d{9}$/ // 大陆手机号正则表达式
const hkMobileReg = /^[569]\d{3}[\s-]?\d{4}$/ // 香港手机号正则表达式,允许使用空格或 "-" 分隔
const macauMobileReg = /^6\d{3}[\s-]?\d{4}$/ // 澳门手机号正则表达式,允许使用空格或 "-" 分隔
const telReg = /^(0\d{2,3})([\s-])?\d{7,8}$/ // 大陆座机号正则表达式,允许区号和座机号用空格或 "-" 分开
const hkTelReg = /^\(?\d{2,4}\)?[\s-]?\d{4}[\s-]?\d{4}$/ // 香港座机号正则表达式,允许使用空格或 "-" 分隔
const macauTelReg = /^\(?\d{2,4}\)?[\s-]?\d{4}[\s-]?\d{4}$/ // 澳门座机号正则表达式,允许使用空格或 "-" 分隔
const phone400Reg = /^400[\s-]?\d{3}[\s-]?\d{4}$/ // 以 "400" 开头的号码正则表达式,允许使用空格或 "-" 分隔
// 情况112位且首位是0、第二位是1 → 去0后按大陆手机号校验
if (/^01[0-9]{10}$/.test(purePhone)) {
return true
}
// 匹配任意一种格式即为合法
if (mobileReg.test(purePhone) || hkMobileReg.test(purePhone) || macauMobileReg.test(purePhone) ||
telReg.test(purePhone) || hkTelReg.test(purePhone) || macauTelReg.test(purePhone) ||
phone400Reg.test(purePhone)) {
return true
}
// 其他情况 → 不合法
return false
},
async getPersonList(){
let result=await getConfirmStatus({supplierId:this.supplierId})
if(result.data?.wechatConfirmStatus==2){
this.type=3
}else if(result.data?.wechatConfirmStatus==3){
this.type=4
}else if(!result.data?.wechatConfirmStatus || result.data?.wechatConfirmStatus==1){
this.type=1
}
this.isMaster=result.data.isMaster
// this.type=2
let res=await getConfirmPerson({supplierId:this.supplierId})
if(res.data && res.data.length>0){
this.personList=res.data
}else{
this.personList=[]
}
},
async wechatConfirm(){//确认已添加微信按钮
Dialog.confirm({
message:'请确认相关人员是否已添加该二维码。',
confirmButtonText:'确认',
cancelButtonText:'取消',
confirmButtonColor:'#354E93',
}).then(async() => {
let res=await confirmAddWechat({supplierId:this.supplierId,supplierPersonInfoId:this.personInfoId})
console.log('res',this.personInfo,res.data?.name,this.personInfo.wechatName)
if((res.data?.name == this.personInfo.wechatName) || (!res.data && this.personInfo.wechatName)){
console.log('11111111')
this.$set(this.personList[this.reviseIndex],'isChange',false)
}else {
console.log('2222222')
this.$set(this.personList[this.reviseIndex],'isChange',true)
}
console.log('this.personList',this.personList)
let flagRevise=this.personList.some(item => 'isChange' in item && !item.isChange)
console.log('存在未修改',flagRevise)
if(res.data){
this.personList[this.reviseIndex].wechatId=res.data?.externalUserId
this.personList[this.reviseIndex].wechatName=res.data?.name
}
await this.cancelHandle()
}).catch(async () => {
await this.cancelHandle()
});
},
cancelHandle(){
this.dialogShow=false
this.wechatInfo=''
this.reviseIndex=-1
this.personInfoId=''
},
async wechatRevise(item,index){
console.log('item,index',item,index)
// console.log('item',item)
this.personInfoId=item.id
this.reviseIndex=index
this.personInfo=item
await this.getCode()
this.dialogShow=true
},
async getCode(){//获取二维码
let res = await getQrCode({supplierId:this.supplierId,supplierPersonInfoId:this.personInfoId})
// console.log('res--getCode',res)
this.wechatInfo=res.data || ''
},
async auditHandle(){//提交审批
let flag=this.personList.every(item => item.name && item.phone1 && item.wechatId && item.wechatName)
if(!flag){
this.$toast('必填项不可为空')
return
}
console.log('----',this.personList)
let flagRevise=this.personList.some(item => 'isChange' in item && !item.isChange)
console.log('存在未修改',flagRevise)
if(flagRevise){
this.$toast('您仍未修改微信号,请先修改再提交审批。')
return
}
let phone1Flag= this.personList.every(item => this.validatePhone(item.phone1))
let phone2Flag= this.personList.every(item => (item.phone2 && this.validatePhone(item.phone2) || !item.phone2))
console.log('phone1Flag',phone1Flag)
console.log('phone2Flag',phone2Flag)
if(!phone1Flag || !phone2Flag){
this.$toast('电话号码格式不正确')
return
}
await submitConfirm({supplierId:this.supplierId,infos:this.personList})
this.$toast('操作成功')
if(this.isWebFunc()){
setTimeout(()=>{
this.closeParentDialog()
},1500)
}else{
setTimeout(()=>{
this.goBack()
},1500)
}
},
async reviseHandle(){//修改
this.type=2
},
async confirmHandle(){//确认信息无误
let flag=this.personList.every(item => item.name && item.phone1 && item.wechatId && item.wechatName)
if(!flag){
this.$toast('必填项不可为空,请点击“立即修改”将信息补充完整')
return
}
Dialog.confirm({
message:'请务必仔细确认信息是否无误。',
confirmButtonText:'确认无误',
cancelButtonText:'返回',
confirmButtonColor:'#354E93',
}).then(async() => {
// console.log('确认无误')
await confirm({supplierId:this.supplierId})
this.$toast('操作成功')
if(this.isWebFunc()){
setTimeout(()=>{
this.closeParentDialog()
},1500)
}else{
setTimeout(()=>{
this.goBack()
},1500)
}
}).catch(() => {
});
},
}
}
</script>
<style lang="scss">
.customDialog {
.van-dialog__content{
text-align: center !important;
}
.van-dialog__header {
box-sizing: border-box;
padding: 12px;
}
}
</style>
<style scoped lang="scss">
@import "@/styles/common.scss";
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
background-color: #F6F6F6;
}
.navBar{
margin-bottom: 46px;
}
.tipWrap{
width: 100%;
box-sizing: border-box;
padding: 8px 8px 8px 18px;
margin-bottom: 10px;
display: flex;
background-color: #FFF6F2;
img{
width: 14px;
height: 14px;
//vertical-align: middle;
margin-right: 5px;
margin-top: 2px;
}
span{
color: #FC3C06;
}
}
.yelBg{
background-color: #FFFFED ;
span{
color: #F36708;
}
}
.greBg{
background-color: #E8FFF3;
span{
color: #19AC43;
}
}
/*.headerWrap{
width: 100%;
box-sizing: border-box;
padding: 15px 16px;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
.back{
@include wh(15px,15px);
}
span{
font-weight: bold;
font-size: 16px;
color: #203152;
}
}*/
.loadingWrap{
width: 100%;
height: calc(100% - 90px);
text-align: center;
line-height: 200px;
}
.contentWrap{
//height: calc(100% - 160px);
//height: calc(100% - 90px);//没有按钮时
overflow-y: auto;
.itemWrap{
font-size: 14px;
width: 100%;
margin-bottom: 10px;
background-color: #FFFFFF;
box-sizing: border-box;
padding:10px 15px 10px 20px;
.line{
width: 100%;
text-align: center;
border-bottom: 2px solid;
opacity: 0.16;
margin-top: 10px;
border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
}
.item{
//line-height: 36px;
display: flex;
align-items: center;
.left{
width: 66px;
}
.right{
flex: 1;
}
.wechatRight{
display: flex;
align-items: center;
justify-content: space-between;
.reviseBtn{
display: inline-block;
width: 60px;
text-align: center;
border-radius: 4px;
background-color: #354D93;
color: #FFFFFF;
box-sizing: border-box;
padding: 2px 0;
}
}
}
.opaCol{
color: #323643;
opacity: .65;
}
.star{
font-weight: bold;
font-size: 13px;
color: #FF0808;
}
}
}
.btnWrap{
width: 100%;
position: fixed;
bottom: 0;
left: 0;
box-sizing: border-box;
padding: 10px 19px;
display: flex;
align-items: center;
justify-content: space-between;
background-color: #F6F6F6;
.common{
background: #354D93;
height: 48px;
line-height: 48px;
text-align: center;
border-radius: 5px;
font-weight: 500;
font-size: 14px;
color: #FFFFFF;
cursor: pointer;
}
.audit{
width: 100%;
}
.revise{
width: 30%;
background-color: #FFFFFF;
color: #354D93;
box-sizing: border-box;
border: 1px solid #354D93;
}
.confirm{
width: 67%;
}
}
</style>

View File

@@ -78,11 +78,9 @@ export default {
isLoading:false,
showPoup:true,//进入弹框
isFinished:false,
type: '',
}
},
mounted() {
this.type = this.$route.query?.type;
// this.onRefresh();
this.getList();
@@ -122,7 +120,6 @@ export default {
pageSize:this.pageSize,
docType:1,
trainingType:4,
type: this.type,
})
this.pageList=res.data?.list || [];
if(res.data.assessState == 0){

View File

@@ -2,7 +2,7 @@
<div class="bottom_wrap">
<div class="report_item" v-for="(item, index) in reportList" @click="goReportHandler(item)" :key="index">
<img class="report_icon" :src="item?.iconUrl" alt="">
<!-- <div class="report_title">{{item.name}}</div>-->
<div class="report_title">{{item.name}}</div>
</div>
</div>
</template>
@@ -43,8 +43,8 @@ export default {
margin-top: 20px;
text-align: center;
.report_icon {
width: 60px;
height: 60px;
width: 45px;
height: 45px;
}
.report_title {
color: rgba(53, 53, 53, 0.67);

View File

@@ -1,581 +0,0 @@
<template>
<!-- <van-pull-refresh v-model="isLoading" class="custom-pull-refresh safe-pull-refresh" @refresh="onRefresh">-->
<div class="main_wrap">
<div class="top_bg" :class="{'dispatch' : type == 1 , 'driver' : type != 1}">
<!-- <div class="title">报备中心</div>-->
</div>
<div class="service_wrap">
<service-item :order-info="orderInfo" @refresh="onRefreshHandler"></service-item>
</div>
<div class="chat_list" ref="chatList" >
<!--ai对话框 s -->
<div v-for="(item, index) in recordList" :key="index">
<template v-if="item.messageType == 4">
<div class="top_tip_wrap">为了快速解决问题请选择下方咨询类型</div>
<div class="ai_chat" >
<div class="ai_left">
<img class="report_ai" src="@/assets/report/report_ai.png" alt="">
</div>
<div class="ai_right">
<div class="ai_title">{{ orderInfo?.driverName }}你好请选择报备内容</div>
<ul>
<li v-for="_item in item.content" :key="_item.id" @click="addReportHandler(_item)">{{_item.name}}</li>
</ul>
</div>
</div>
</template>
<template v-if="[2, 3].includes(Number(item.messageType))">
<!--ai对话框 e -->
<div class="tip_wrap">{{item.createTime}}</div>
<!--客服对话框 s -->
<div class="customer_item mb20">
<div class="customer_left">
<img class="profile_photo mr" src="@/assets/report/report_customer.png" alt="">
</div>
<div class="common_right customer_cls">
<div class="customer_status">{{item.reportConfigName}}</div>
<div class="response_con">{{item.remark}}</div>
</div>
</div>
</template>
<template v-if="item.messageType == 1">
<!--服务人员对话框 e -->
<div class="tip_wrap">{{item.createTime}}</div>
<!--服务人员对话框 s -->
<div class="server_item mb20">
<div class="common_right service_cls">
<div class="service_status">{{item.reportConfigName}}</div>
<div class="response_con">{{item.remark}}</div>
</div>
<div class="customer_left">
<img class="profile_photo ml" v-if="type == 1" src="@/assets/report/report_dispatch.png" alt="">
<img class="profile_photo ml" v-else src="@/assets/report/report_driver.png" alt="">
</div>
</div>
<!--服务人员对话框 e -->
</template>
</div>
</div>
<report-list-item :report-list.sync="reportList" @getReport="getReportHandler" />
<van-popup ref="addReportModal" v-model="addReportShow" :close-on-click-overlay="false" closeable duration="0" round position="bottom">
<div class="dialog_wrap">
<img class="add_report_bg" src="@/assets/report/add_report_bg.png" alt="">
<div class="report_content">
<template v-if="currentInfo.component == 'time'">
<!--预约时间报备 s -->
<div class="report_title">
<img class="dot" src="@/assets/report/add_report_dot.png" alt="">
<span>预约时间</span>
</div>
<div class="report_time_content" @click="showDatetime = true">
<div class="report_time_left">
<img class="add_report_time" src="@/assets/report/add_report_time.png" alt="">
<span>{{appointTime || '请选择时间'}}</span>
</div>
<img class="report_arrow" src="@/assets/report/add_report_arrow.png" alt="">
</div>
<!--预约时间报备 e -->
</template>
<template v-if="currentInfo.component == 'address'">
<!--修改地址报备 s -->
<div class="report_title">
<img class="dot" src="@/assets/report/add_report_dot.png" alt="">
<span>修改地址</span>
</div>
<div class="report_time_content" @click="goPage('addressMap')">
<div class="report_time_left">
<img class="add_report_time" src="@/assets/report/add_report_address.png" alt="">
<span>{{address || '请选择地址'}}</span>
</div>
<img class="report_arrow" src="@/assets/report/add_report_arrow.png" alt="">
</div>
<!--修改地址报备 e -->
</template>
<div class="report_title">
<img class="dot" src="@/assets/report/add_report_dot.png" alt="">
<span>补充报备内容</span>
</div>
<div class="report_common_content">
<textarea class="report_textarea" id="text-input" rows="4" placeholder="点击这里输入补充报备内容" v-model.trim="remark"></textarea>
<!-- <van-field-->
<!-- v-model="remark"-->
<!-- class="report_textarea"-->
<!-- placeholder="点击这里输入补充报备内容" />-->
</div>
</div>
<div class="report_btn" @click="saveHandler">
提交报备
</div>
</div>
</van-popup>
<van-popup v-model="showDatetime" round position="bottom">
<van-datetime-picker
class="dataTime"
v-if="showDatetime"
v-model="appointTime"
type="datetime"
:min-date="minDate"
:filter="filter"
@confirm="onConfirm"
@cancel="showDatetime = false"
/>
</van-popup>
</div>
<!-- </van-pull-refresh>-->
</template>
<script>
import { getReportListByOrder, reportHistory, newOrderReporting, getOrderInfo } from "@/api/report"
import { myMixins} from "@/utils/myMixins";
import {timeFormat} from "@/utils/common";
import reportListItem from '@/views/report/components/report-list-item'
import serviceItem from "@/views/report/components/service-item"
import {Dialog, Toast} from "vant";
export default {
name: "reportIndex",
components: { serviceItem, reportListItem },
mixins: [myMixins],
data() {
return {
addReportShow: false,
remark: '',
showDatetime: false,
appointTime: '',
minDate: new Date(),
address: '',
lat: '',
lng: '',
reportList: [],
recordList: [],
orderInfo: {},
type: '', // 1 调度 2 司机
currentInfo: '',
userOrderId: '',
userOrderCode: '',
driverId: '',
clickFlag: true,
isLoading: false,
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.userOrderId = this.$route.query.userOrderId || urlParams.get('userOrderId');
this.userOrderCode = this.$route.query.userOrderCode || urlParams.get('userOrderCode');
this.type = this.$route.query.type || urlParams.get('type');
this.driverId = this.$route.query.driverId || urlParams.get('driverId');
await this.getReportList();
await this.getDetail();
await this.getRecordList();
await this.scrollToBottom();
},
activated() {
let addressSession = sessionStorage.getItem('reportAddress');
if(addressSession) {
let _obj = JSON.parse(addressSession)
this.address = _obj.startPoiAddress;
this.lat = _obj.startLat;
this.lng = _obj.startLng;
this.adCode = _obj.adCode;
}
},
methods: {
filter(type, options) {
if (type === 'minute') {
return options.filter((option) => option % 5 === 0);
}
return options;
},
onRefreshHandler() {
setTimeout(async () => {
try {
this.recordList = [];
await this.getReportList();
await this.getDetail();
await this.getRecordList();
await this.scrollToBottom();
} finally {
this.isLoading = false; // 结束加载状态
}
}, 100)
},
// 添加滚动方法
scrollToBottom() {
this.$nextTick(() => {
const container = this.$refs.chatList
container.scrollTop = container.scrollHeight
})
},
async getRecordList() {
let recordList = await reportHistory({
userOrderId: this.userOrderId,
userOrderCode: this.userOrderCode,
driverId: this.driverId,
source: Number(this.type),
})
this.recordList = recordList.data;
},
async saveHandler() {
if( this.clickFlag ) {
let data = {
source: Number(this.type),
reportContent: this.remark,
userOrderId: Number(this.userOrderId),
reportConfigId: this.currentInfo.id,
userOrderCode: this.userOrderCode,
driverId: this.driverId,
}
if(this.currentInfo.component == 'time') {
if( !this.appointTime ) {
Toast('预约时间不能为空')
return
}
if( new Date(this.appointTime).getTime() <= new Date().getTime() ) {
Toast('预约时间不能小于当前时间')
return
}
data.time = this.appointTime
}
if(this.currentInfo.component == 'address') {
if( !this.address ) {
Toast('地址不能为空')
return
}
data.address = this.address
data.lat = this.lat;
data.lng = this.lng;
}
if( !this.remark ) {
Toast('备注内容不能为空')
return
}
this.clickFlag = false;
try {
await newOrderReporting(data)
Dialog.alert({
title: '提示',
message: "报备添加成功"
}).then(async () => {
await this.getRecordList()
this.addReportShow = false
this.scrollToBottom();
this.initDialogData();
this.clickFlag = true
});
} finally {
this.clickFlag = true
}
}
},
initDialogData() {
this.appointTime = '';
this.address = '';
this.lat = '';
this.lng = '';
this.remark = '';
},
addReportHandler(data) { // 点击添加报备弹框
console.log('currentInfocurrentInfo', data)
this.currentInfo = data;
this.remark = '';
this.addReportShow = true
},
getReportHandler(data) { // 点击获取当前报备信息
console.log('dadadada', data.child)
this.recordList.push({
messageType: 4,
content: data.child
})
this.scrollToBottom();
if( data.child?.length == 1 ) {
this.addReportHandler(data.child[0])
}
},
async getDetail(){ // 订单详情
if(this.userOrderId) {
let result = await getOrderInfo({
userOrderId: this.userOrderId,
userOrderCode: this.userOrderCode
})
this.orderInfo = result.data
} else {
this.orderInfo = {}
}
},
async getReportList() { // 报备大类
let res = await getReportListByOrder({
orderId: this.userOrderId
});
this.reportList = res.data
},
onConfirm(data) {
this.appointTime = timeFormat(new Date(data))
this.showDatetime = false;
}
}
}
</script>
<style lang="scss">
.custom-pull-refresh {
height: 100% !important;
}
</style>
<style lang="scss" scoped>
#app {
background: #F9FCFF !important;
height: 100%;
}
.main_wrap {
width: 100%;
height: 100%;
background: #F9FCFF !important;
display: flex;
flex-direction: column;
// 添加以下样式确保正确的高度计算
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.top_bg {
width: 100%;
height: 87px;
/*.title {
color: #fff;
text-align: center;
padding-top: 52px;
font-size: 17px;
line-height: 24px;
}*/
}
.dispatch { // 调度app头部背景色
background: #354683;
}
.driver { // 司机app头部背景色
background: #334885;
}
.service_wrap {
margin-top: -75px;
/*margin-bottom: 20px;*/
}
.chat_list {
flex: 1;
/*overflow: auto;*/
overflow-y: auto;
overflow-x: hidden;
-webkit-overflow-scrolling: touch; // 为了iOS平滑滚动
padding-top: 10px;
/* 修复 iOS 滚动问题 */
transform: translateZ(0);
.top_tip_wrap {
color: #7C8698;
text-align: center;
font-size: 13px;
}
.tip_wrap {
color: #7C8698;
text-align: center;
font-size: 13px;
margin-bottom: 10px;
}
.ai_chat {
padding: 25px 10px 20px;
display: flex;
.ai_left {
.report_ai {
width: 44px;
height: 44px;
margin-right: 12px;
}
}
.ai_right {
.ai_title {
color: #203152;
font-size: 15px;
font-weight: 600;
margin-bottom: 15px;
}
li {
font-size: 13px;
color: #267EF0;
line-height: 18px;
margin-bottom: 15px;
font-weight: bold;
}
li::before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background-color: #5680FA;
border-radius: 50%; /* 圆形 */
margin-right: 10px;
}
}
}
}
/*客服人员,服务人员对话弹框样式 s*/
.profile_photo {
width: 44px;
height: 44px;
}
.mr {
margin-right: 10px;
}
.ml {
margin-left: 10px;
}
.mb20 {
margin-bottom: 20px;
}
.customer_item {
display: flex;
padding-left: 10px;
padding-right: 64px;
.customer_left {
}
}
.common_right {
padding: 11px 13px;
flex: 1;
.customer_status::before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background-color: #5680FA;
border-radius: 50%; /* 圆形 */
margin-right: 10px;
}
.customer_status {
font-size: 14px;
color: #267EF0;
line-height: 20px;
font-weight: bold;
}
.service_status {
font-size: 14px;
color: #F07926;
line-height: 20px;
font-weight: bold;
}
.service_status::before {
content: "";
display: inline-block;
width: 8px;
height: 8px;
background-color: #F07926;
border-radius: 50%; /* 圆形 */
margin-right: 10px;
}
}
.customer_cls {
border-radius: 0px 6px 6px 6px;
background: #E3F0FF;
}
.service_cls {
background: #FAEBD8;
border-radius: 0px 6px 6px 6px;
}
.server_item {
display: flex;
padding-right: 10px;
padding-left: 64px;
}
.response_con {
font-size: 13px;
color: #242A37;
line-height: 18px;
font-weight: bold;
margin-top: 5px;
}
/*客服人员,服务人员对话弹框样式 e*/
.dialog_wrap {
.add_report_bg {
width: 100%;
height: 76px;
}
.report_content {
width: calc(100% - 12px);
margin: -30px auto 0;
padding-right: 14px;
padding-left: 20px;
box-sizing: border-box;
background: #fff;
position: relative;
padding-top: 25px;
border-radius: 10px;
.report_title {
font-size: 16px;
font-weight: 600;
color: #267EF0;
line-height: 22px;
margin-bottom: 10px;
.dot {
width: 7px;
height: 6px;
margin-right: 12px;
}
}
.report_time_content {
padding: 13px;
background: #F2F7FF;
border-radius: 6px;
border: 1px solid #E2EAF6;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30px;
.report_time_left {
font-size: 14px;
font-weight: bold;
color: rgba(0, 0, 0, 0.9);
display: flex;
align-items: flex-start;
}
.add_report_time {
width: 18px;
height: 18px;
margin-right: 8px;
}
.report_arrow {
width: 8px;
height: 12px;
margin-left: 5px;
}
}
.report_common_content {
margin-bottom: 27px;
.report_textarea {
width: 100%;
box-sizing: border-box;
background: #F8FAFC;
border-radius: 6px;
min-height: 95px;
border: 1px solid #E2EAF6;
padding: 10px;
font-size: 13px;
}
}
}
.report_btn {
width: calc(100% - 80px);
height: 46px;
line-height: 46px;
background: #005DD5;
border-radius: 23px;
color: #FFFFFF;
font-size: 15px;
font-weight: bold;
text-align: center;
margin: 0 auto 40px;
}
}
::v-deep .van-popup__close-icon {
color: #0F458E;
}
</style>

View File

@@ -57,30 +57,16 @@
</div>
</div>
<report-list-item :report-list.sync="reportList" @getReport="getReportHandler" />
<van-popup ref="addReportModal" v-model="addReportShow" :close-on-click-overlay="false" z-index="500" closeable duration="0" round position="bottom">
<van-popup ref="addReportModal" v-model="addReportShow" :close-on-click-overlay="false" closeable duration="0" round position="bottom">
<div class="dialog_wrap">
<img class="add_report_bg" src="@/assets/report/add_report_bg.png" alt="">
<div class="report_content">
<div class="report_title" style="margin-bottom: 10px;"><span>{{currentInfo.name}}</span></div>
<template v-if="currentInfo.component == 'time'">
<!--预约时间报备 s -->
<div class="report_title">
<img class="dot" src="@/assets/report/add_report_dot.png" alt="">
<span>预约时间</span>
</div>
<!--<el-date-picker class="report_time_content owner_time high-zindex-picker"
v-model="appointTime"
type="datetime"
:picker-options="pickerOptions"
:minutes-step="5"
format="yyyy-MM-dd HH:mm:00"
placeholder="选择日期时间">
</el-date-picker>-->
<!--<el-date-picker
v-model="appointTime"
type="datetime"
placeholder="选择日期时间">
</el-date-picker>-->
<div class="report_time_content" @click="showDatetime = true">
<div class="report_time_left">
<img class="add_report_time" src="@/assets/report/add_report_time.png" alt="">
@@ -105,15 +91,17 @@
</div>
<!--修改地址报备 e -->
</template>
<template v-if="currentInfo.component != 'time'">
<div class="report_title">
<img class="dot" src="@/assets/report/add_report_dot.png" alt="">
<span>补充反馈内容</span>
<span>补充报备内容</span>
</div>
<div class="report_common_content">
<textarea class="report_textarea" id="text-input" rows="4" placeholder="点击这里输入补充反馈内容" v-model.trim="remark"></textarea>
<textarea class="report_textarea" id="text-input" rows="4" placeholder="点击这里输入补充报备内容" v-model.trim="remark"></textarea>
<!-- <van-field-->
<!-- v-model="remark"-->
<!-- class="report_textarea"-->
<!-- placeholder="点击这里输入补充报备内容" />-->
</div>
</template>
</div>
<div class="report_btn" @click="saveHandler">
提交报备
@@ -121,16 +109,15 @@
</div>
</van-popup>
<van-popup v-model="showDatetime" round position="bottom" :close-on-click-overlay="false">
<van-popup v-model="showDatetime" round position="bottom">
<van-datetime-picker
class="dataTime"
v-if="showDatetime"
v-model="appointTime"
type="datetime"
:min-date="minDate"
:filter="filter"
@confirm="onConfirm"
@cancel="cancelHandler"
@cancel="showDatetime = false"
/>
</van-popup>
</div>
@@ -168,12 +155,6 @@
driverId: '',
clickFlag: true,
isLoading: false,
pickerOptions: {
// 可选:限制预约时间不能小于当前时间(复用你原有逻辑)
disabledDate: (time) => {
return time.getTime() <= new Date().getTime();
}
}
}
},
async mounted() {
@@ -198,12 +179,6 @@
}
},
methods: {
filter(type, options) {
if (type === 'minute') {
return options.filter((option) => option % 5 === 0);
}
return options;
},
onRefreshHandler() {
setTimeout(async () => {
try {
@@ -263,10 +238,10 @@
data.lat = this.lat;
data.lng = this.lng;
}
/*if( !this.remark ) {
if( !this.remark ) {
Toast('备注内容不能为空')
return
}*/
}
this.clickFlag = false;
try {
await newOrderReporting(data)
@@ -293,21 +268,15 @@
this.remark = '';
},
addReportHandler(data) { // 点击添加报备弹框
console.log('currentInfocurrentInfo', data)
this.currentInfo = data;
this.remark = '';
this.addReportShow = true
},
getReportHandler(data) { // 点击获取当前报备信息
console.log('dadadada', data.child)
this.recordList.push({
messageType: 4,
content: data.child
})
this.scrollToBottom();
if( data.child?.length == 1 ) {
this.addReportHandler(data.child[0])
}
},
async getDetail(){ // 订单详情
if(this.userOrderId) {
@@ -330,10 +299,6 @@
onConfirm(data) {
this.appointTime = timeFormat(new Date(data))
this.showDatetime = false;
},
cancelHandler() {
this.appointTime = ''
this.showDatetime = false
}
}
}
@@ -570,9 +535,6 @@
margin-left: 5px;
}
}
.owner_time {
padding: 0 !important;
}
.report_common_content {
margin-bottom: 27px;
.report_textarea {
@@ -603,22 +565,4 @@
::v-deep .van-popup__close-icon {
color: #0F458E;
}
::v-deep .el-date-editor.el-input,::v-deep .el-date-editor.el-input__inner {
width: 100%;
}
::v-deep .el-input__inner {
background: none !important;
}
::v-deep .el-picker-panel {
z-index: 100000000 !important;
}
.el-picker-panel{
z-index: 100000000 !important;
}
::v-deep .high-zindex-picker {
z-index: 9999 !important; // 高于 van-popup 默认层级(通常 1000-2000
}
::v-deep .el-date-editor {
overflow: visible !important;
}
</style>

View File

@@ -109,7 +109,7 @@
const urlParams = new URLSearchParams(window.location.search);
console.log('window.location',window.location)
// console.log("urlParams",urlParams)
console.log("decodeURIComponent( window.location.href)",decodeURIComponent( window.location.href))
// console.log("decodeURIComponent( window.location.href)",decodeURIComponent( window.location.href))
this.esignFlag = urlParams.get('esignFlag') || localStorage.getItem("esignFlag")
if(window.location.search){
console.log('有参数')

View File

@@ -478,21 +478,6 @@ export default {
otherPhoto:this.otherImgSrc?.join(',')
})
this.clearStorageFormInfo()
if(res.code == 200 && !res.msg){
this.$toast('发布成功')
if(this.isWebFunc()){
setTimeout(()=>{
this.closeParentDialog()
},1000)
}else{
setTimeout(()=>{
this.$router.push({ name: "mineRelease"})
sessionStorage.setItem('mineActiveTab',String(1) )
},1000)
}
}else{
this.$toast(res.msg)
}
console.log("车源发布publishCarInfo",res)
} catch (e){
console.log('e',e)