176 Commits

Author SHA1 Message Date
6420b45e09 story#5314 底部图片修改 2025-04-14 09:25:57 +08:00
e39e069705 story#5314 banner图样式3 2025-04-11 18:58:38 +08:00
63d095cc2f story#5314 banner图样式2 2025-04-11 18:58:38 +08:00
30e2b15a78 story#5314 banner图样式 2025-04-11 18:38:28 +08:00
6b27859358 二手车交易,刷新函数添加调列表接口 2025-04-11 13:51:52 +08:00
99edd5d431 story#5314 二手车系统优化需求 2025-04-11 11:01:47 +08:00
9ac5860ef8 story#5314 二手车系统优化需求 2025-04-11 10:52:57 +08:00
e56de7ff8b story#5314 二手车系统的优化需求 2025-04-11 09:28:56 +08:00
4a70d881b8 story#5256 供应商整改界面完善20250327 2025-04-09 16:26:27 +08:00
5de1efc5fb story#5314 二手车系统的优化需求 需要UI和接口的修改 2025-04-07 16:07:02 +08:00
7b7e926f8a story#5314 照片显示比例失调的问题需要优化 2025-04-02 13:23:18 +08:00
ba1cd9fcac story#5314 含税价格--> 售价(含税) 2025-04-02 11:42:03 +08:00
3fe67c1015 story#5314 在查看车源列表的界面,鼠标在移动到可以点击的区域时,改成手指的样式。 2025-04-02 11:00:19 +08:00
cdc63e6c42 story#5314 h5端 点击车源查看详情的照片,无法再点击放大,需要改成可以点击查看大图 2025-04-02 10:56:30 +08:00
0e138e22f4 story#5314 web端 点击车源查看详情的照片,无法再点击放大,需要改成可以点击查看大图2 2025-04-02 10:46:55 +08:00
b5c5f24c49 story#5314 web端 点击车源查看详情的照片,无法再点击放大,需要改成可以点击查看大图。 2025-04-02 10:43:13 +08:00
d3d6226bcd story#5314 点击车源查看详情的照片:一是要改成照片自动滚动播放,二是左右切换照片的按钮改为更明显的样式,三是照片张数显示改为更明显的样式,目前的按钮不醒目 2 2025-04-02 10:38:55 +08:00
a426b67a51 story#5314 点击车源查看详情的照片:一是要改成照片自动滚动播放,二是左右切换照片的按钮改为更明显的样式,三是照片张数显示改为更明显的样式,目前的按钮不醒目 2025-04-02 10:31:53 +08:00
efe76bb675 story#5314 二、名称优化,含税价格,点击车源查看详情的照片部分优化 2025-04-02 10:24:08 +08:00
de9d73a642 二手车交易,发布列表的navBar自定义 2025-03-25 14:54:19 +08:00
044813f411 二手车交易,售价输入0开头时,后边不允许输入任何数字 2025-03-25 14:15:57 +08:00
b90b7ea89c 二手车交易,发布时,求购可以输入0,但不允许输入多个0 2025-03-25 13:16:06 +08:00
4c02dcd075 二手车交易,求购发布样式优化 2025-03-25 11:38:30 +08:00
3cd768b973 二手车交易,排放标准添加国三选项 2025-03-25 11:05:02 +08:00
db6a3facae 二手车交易,行驶公里保留一位小数 2025-03-19 18:00:01 +08:00
48ab0cfb52 二手车交易,后台点击弹框关闭时记录浏览量 2025-03-19 10:14:13 +08:00
c5176ebc02 二手车交易,测试记录浏览量1 2025-03-19 09:48:27 +08:00
f666d9bcb4 二手车交易,测试记录浏览量 2025-03-19 09:23:17 +08:00
6864a1330f 二手车交易,记录浏览量 2025-03-19 09:08:34 +08:00
e373acb818 二手车交易,用户离开记录浏览量 2025-03-18 21:22:33 +08:00
fe71adf6e3 二手车交易,用户离开记录浏览量 2025-03-18 21:21:00 +08:00
b6d0ae476c 二手车交易,用户离开记录浏览量 2025-03-18 20:58:50 +08:00
c80a2f6e6b 二手车交易,行驶公里换行显示 2025-03-18 20:53:01 +08:00
06e860592b 二手车交易,vconsole删除 2025-03-18 10:19:45 +08:00
afd9d570a4 二手车交易,缓存问题,删除照片的bug 2025-03-18 10:06:21 +08:00
3668ee7f0a 二手车交易,缓存问题 2025-03-17 17:34:18 +08:00
abd4b2a84b 二手车交易,缓存问题 2025-03-17 17:28:03 +08:00
815c94e81c 二手车交易,缓存问题 2025-03-17 17:15:46 +08:00
ad1c6f1c9c 二手车交易,缓存问题 2025-03-17 17:12:04 +08:00
b914dd9738 二手车交易,缓存问题 2025-03-17 17:07:56 +08:00
728fa2ccb2 二手车交易,缓存问题 2025-03-17 17:04:53 +08:00
abe17223af 二手车交易,缓存问题 2025-03-17 17:02:49 +08:00
857f30c11f 二手车交易,缓存问题 2025-03-17 17:02:08 +08:00
affe57159d 二手车交易,必填项回到原本 2025-03-17 16:53:13 +08:00
cf45da3ef7 二手车交易,车源报错 2025-03-17 16:47:20 +08:00
82d4c86936 二手车交易,反馈建议调整 2025-03-17 16:44:32 +08:00
8558eee259 二手车交易,错误提示抛出 2025-03-17 16:32:11 +08:00
d7242ab1a5 二手车交易,照片缓存报错 2025-03-17 16:25:59 +08:00
9c7ec8969e 二手车交易,ios打电话报错 2025-03-17 16:22:43 +08:00
75f5dabf3d 二手车交易,ios打电话报错 2025-03-17 16:11:37 +08:00
ee69ed0c2b 二手车交易,写建议弹框优化 2025-03-17 16:11:02 +08:00
b5f01b70b7 二手车交易,直辖市的显示问题 2025-03-17 15:18:31 +08:00
301babc54e 二手车交易,直辖市的code取第一个 2025-03-17 13:56:59 +08:00
88293b2089 二手车交易,VConsole删除 2025-03-17 13:07:27 +08:00
8b94d8b689 二手车交易,web端查看图片无法变回原本样子 2025-03-17 11:51:27 +08:00
0b49fd502a 二手车交易,web端查看图片无法变回原本样子 2025-03-17 11:41:25 +08:00
aea127d12b 二手车交易,我的发布记录index优化 2025-03-17 10:29:06 +08:00
3cd7ff0318 二手车交易,协议代码部分优化 2025-03-17 10:19:23 +08:00
ef8df96818 二手车交易,购车详情查看 2025-03-17 09:56:31 +08:00
db26230208 二手车交易,优化 2025-03-17 09:23:37 +08:00
eddabd68b4 二手车交易,缓存问题解决 2025-03-16 21:14:58 +08:00
22e6c58e65 二手车交易,缓存问题解决 2025-03-15 17:49:25 +08:00
678d4f6436 二手车交易,打电话问题 2025-03-15 16:47:01 +08:00
4f20dffc52 二手车交易,打电话问题 2025-03-14 17:14:42 +08:00
ab9402e591 二手车交易,打电话问题 2025-03-14 17:09:45 +08:00
88606bd31d 二手车交易,打电话问题 2025-03-14 16:53:21 +08:00
397d234637 二手车交易,打电话问题 2025-03-14 16:50:58 +08:00
79ddd02342 二手车交易,打电话问题 2025-03-14 16:42:29 +08:00
f72304459c 二手车交易,我的发布tab切 2025-03-14 16:38:03 +08:00
9bffcb22cb 二手车交易,我的发布显示问题 2025-03-14 16:18:20 +08:00
3fbd0b2769 二手车交易,选择其他时的修改 2025-03-14 16:00:51 +08:00
23a9bf9e80 二手车交易,其他的原因要加上 2025-03-14 15:44:32 +08:00
f9a29e81dc 二手车交易,其他的原因要加上 2025-03-14 15:28:25 +08:00
57d0e47c9b 二手车交易,详情加loading 2025-03-14 15:25:26 +08:00
260eb01dcb 二手车交易,车源的钱换字段 2025-03-14 15:19:29 +08:00
4dbf2dc8c7 二手车交易,审核加字段 2025-03-14 15:07:35 +08:00
509ab301a2 二手车交易,缓存问题 2025-03-14 14:57:54 +08:00
546ec672c7 二手车交易,审核 2025-03-14 14:55:26 +08:00
6926f1b140 二手车交易,添加了打印 2025-03-14 14:54:35 +08:00
104c6a33b5 二手车交易,其他照片上传问题 2025-03-14 14:44:15 +08:00
48fe4d404f 二手车交易,上传照片抛出异常 2025-03-14 14:35:23 +08:00
dde6c337e2 二手车交易,审核不掉发布成功提示 2025-03-14 14:23:20 +08:00
7e0455f695 二手车交易,返回按钮路径 2025-03-14 14:19:18 +08:00
082a3ab6b6 二手车交易,返回按钮路径 2025-03-14 14:19:07 +08:00
3ea4168b87 二手车交易,返回按钮路径 2025-03-14 14:18:15 +08:00
b349671004 二手车交易,返回按钮路径 2025-03-14 13:57:07 +08:00
b9ae7eef5d 二手车交易,上传去除限制 2025-03-14 13:55:01 +08:00
94051d88c0 二手车交易,小手添加 2025-03-14 13:43:13 +08:00
1a9633106c 二手车交易,隐私后台返回 2025-03-14 13:35:53 +08:00
0feee005d5 二手车交易,隐私后台返回 2025-03-14 13:33:25 +08:00
989e950f99 二手车交易,下架原因清空 2025-03-14 13:30:38 +08:00
f0c3b499cc 二手车交易,审核 2025-03-14 13:28:46 +08:00
dc028cdfae 二手车交易,车源详情宽度弄一起 2025-03-14 13:26:50 +08:00
e5554e17b5 二手车交易,图片更换 2025-03-14 13:19:07 +08:00
bc0b666171 二手车交易,列表显示数据调整 2025-03-14 13:01:56 +08:00
11ee4a031a 二手车交易,审核修改掉接口 2025-03-14 11:51:53 +08:00
905bfc0785 二手车交易,车源发布做缓存 2025-03-14 11:44:06 +08:00
558e3e3e8c 二手车交易,车源发布做缓存 2025-03-14 11:40:25 +08:00
90c0852ace 二手车交易,求购做缓存 2025-03-14 11:28:32 +08:00
0155ff7e00 二手车交易,打电话 2025-03-14 10:55:45 +08:00
f76ce0a65f 二手车交易,打电话 2025-03-14 10:52:52 +08:00
f3ca98b2ff 二手车交易,打电话 2025-03-14 10:50:10 +08:00
0cdfab8de6 二手车交易,高度遮挡调整 2025-03-14 10:39:14 +08:00
74fcbe55df 二手车交易,高度遮挡调整 2025-03-14 10:36:43 +08:00
27ad6d414d 二手车交易,我的发布记录tab切 2025-03-14 10:18:04 +08:00
fe105df6c6 二手车交易,我的发布记录tab切 2025-03-14 10:15:46 +08:00
7afefb162c 二手车交易,我的发布记录tab切 2025-03-14 10:12:03 +08:00
2810bb9c6f 二手车交易,我的发布记录tab切 2025-03-14 10:04:06 +08:00
c7b49b5ffe 二手车交易,自己发布供应商 2025-03-14 09:59:41 +08:00
f73927c01e 二手车交易,审核中的数据中 下架按钮 2025-03-14 09:49:04 +08:00
ae711d5726 二手车交易,小手 2025-03-14 09:40:49 +08:00
d498734739 二手车交易,识别接口更换 2025-03-14 09:33:44 +08:00
938d6c9386 二手车交易,调数字键盘 2025-03-14 09:27:04 +08:00
34d228099c 二手车交易,自己发布的点进去不要按钮 2025-03-13 20:24:19 +08:00
9472933a68 二手车交易,檫亮按钮当天不展示 2025-03-13 20:16:12 +08:00
d280b1bcd1 二手车交易,檫亮按钮当天不展示 2025-03-13 20:15:15 +08:00
c1bdcae830 二手车交易,报错解决 2025-03-13 20:14:24 +08:00
3a3d74ac69 二手车交易,打电话添加取消按钮事件 2025-03-13 20:00:52 +08:00
91ce9fb3c7 二手车交易,vconsole的添加 2025-03-13 19:57:45 +08:00
1d491e501f 二手车交易,测试优化 2025-03-13 19:47:15 +08:00
2e6f855cf8 二手车交易,下架原因根据车源和求购 2025-03-13 16:37:00 +08:00
05e4df5751 二手车交易,swiper显示查看做两套 2025-03-13 16:21:37 +08:00
c8964508f2 二手车交易,发布信息抛出异常 2025-03-13 16:04:28 +08:00
2a03a95963 二手车交易,切换接口调用次数 2025-03-13 15:29:09 +08:00
5a236926d7 二手车交易,首页列表和我的发布加加载分页功能 2025-03-13 15:27:02 +08:00
18bfc4517e 二手车交易,首页添加价格区间的筛选 2025-03-13 15:10:05 +08:00
ca6d1ef728 二手车交易,按钮逻辑判断修改 2025-03-13 14:20:59 +08:00
328874064a 二手车交易,按钮逻辑判断修改 2025-03-13 14:19:10 +08:00
f5e0af4753 二手车交易,审核后派发界面事件 2025-03-13 14:06:21 +08:00
03df02174d 二手车交易,所在城市只能选择两级 2025-03-13 14:02:10 +08:00
22f76aaa73 二手车交易,协议链接加返回按钮 2025-03-13 13:54:43 +08:00
d4485779c6 二手车交易,公里转化数值转化 2025-03-13 13:31:37 +08:00
16321333d2 二手车交易,协议条款url更换 2025-03-13 13:19:01 +08:00
e01e7c44c1 二手车交易,监听筛选框的值,重新获取列表 2025-03-13 09:49:04 +08:00
7d42853f39 二手车交易,监听筛选框的值 2025-03-13 09:24:28 +08:00
8b44ce326a 二手车交易,返回按钮的控制 2025-03-12 17:29:36 +08:00
eb34457173 二手车交易,返回按钮的控制 2025-03-12 17:05:07 +08:00
252660c8a8 二手车交易,添加车型品牌显示 2025-03-12 16:40:15 +08:00
d008612675 二手车交易,所在城市不调用键盘 2025-03-12 16:26:04 +08:00
5754e05a7f 二手车交易,声明的添加,测试的优化 2025-03-12 16:06:27 +08:00
f8ad6a109b 二手车交易,我的发布按钮逻辑优化 2025-03-12 13:14:32 +08:00
c71b1fc709 二手车交易,不通过原因必填 2025-03-12 09:43:48 +08:00
5371e43b53 二手车交易,全部接口对接 2025-03-12 09:32:57 +08:00
76c6d6ef5b 二手车交易,全部页面&对接部分接口 2025-03-11 11:09:01 +08:00
24f25635d5 二手车交易,全部页面&对接部分接口 2025-03-11 11:08:08 +08:00
d789e88b05 二手车交易,全部页面&对接部分接口 2025-03-11 11:07:54 +08:00
292e8bdfb1 二手车交易,静态列表页面 2025-03-07 17:22:41 +08:00
4ca8385a36 补结算单,输入框是否可变价添加判断 2025-03-07 17:21:38 +08:00
b84d2a7767 二手车交易,新增资源图片 2025-03-07 17:15:19 +08:00
6c1863efdf 二手车交易,所有资源图片 2025-03-07 13:51:54 +08:00
68d9a7b7b5 story#,车辆,新增车头照车牌号码字段 2025-02-19 15:02:59 +08:00
cfb032d8da story#,补充结算单页面,提交按钮显示添加逻辑判断 2025-02-17 16:20:10 +08:00
406fba2615 story#,补充结算单页面,提交按钮显示添加逻辑判断 2025-02-17 15:25:03 +08:00
1c1f62d99c 上传发票修改 2025-02-14 09:30:52 +08:00
54881a9c19 story#6071,选择小修车且只有一项数据时需清除原本的拖车服务类型 2025-01-21 16:45:39 +08:00
179dd8f18d story#6071,选择小修车时需清除原本的拖车服务类型 2025-01-20 13:40:22 +08:00
b9c10e8df3 车辆添加ocr识别,添加牌照 2025-01-20 11:33:07 +08:00
653a86cf00 story#6071,车辆类型为小修车时需清除拖车服务类型id 2025-01-20 10:05:26 +08:00
ea5c817057 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 17:25:05 +08:00
f88bddb65b story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 15:23:29 +08:00
34f968e596 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 13:59:27 +08:00
4016d2b7c4 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 13:59:07 +08:00
81a3b4b7a4 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 11:49:13 +08:00
c93655976b story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 11:23:58 +08:00
d53bbbbe72 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 11:08:50 +08:00
5ed64b07e3 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-17 10:32:01 +08:00
e4a893815d story#6071,编辑车辆页面选择服务逻辑修改 2025-01-16 21:01:22 +08:00
45b910fdc4 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-16 20:55:26 +08:00
2a5dad2211 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-16 20:03:49 +08:00
8072894f97 story#6071,编辑车辆页面选择服务逻辑修改 2025-01-16 19:55:52 +08:00
e00db98396 记账页面修改2 2025-01-16 13:35:12 +08:00
8f43f46abf 记账页面修改 2025-01-16 13:29:10 +08:00
d2c4542a5e 上傳發票-與後臺同步 2025-01-13 10:15:28 +08:00
156b3f04db task#,月总图表X轴数据去重
(cherry picked from commit 7b8e2efbb4)
2025-01-09 17:03:13 +08:00
7158e4aa2a task#,师傅相关还原 2025-01-02 20:58:55 +08:00
dfddc69c4a task#,师傅相关还原 2025-01-02 17:39:22 +08:00
75 changed files with 4307 additions and 103 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ pnpm-debug.log*
*.njsproj
*.sln
*.sw?
/yarn.lock

12
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "scheduline-app-h5",
"version": "0.1.0",
"dependencies": {
"@vant/area-data": "^2.0.0",
"amfe-flexible": "^2.2.1",
"axios": "^1.4.0",
"core-js": "^3.8.3",
@ -2365,6 +2366,12 @@
"@types/node": "*"
}
},
"node_modules/@vant/area-data": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@vant/area-data/-/area-data-2.0.0.tgz",
"integrity": "sha512-zgP4AA8z09S9QTNgVCCHo9cHjcybrv22RJDYPjuCkecn4SB98T5EoPQh2TwqbQXmUhbaOGgiZGy3OUaUxnY7qg==",
"license": "MIT"
},
"node_modules/@vant/icons": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@vant/icons/-/icons-3.0.2.tgz",
@ -13621,6 +13628,11 @@
"@types/node": "*"
}
},
"@vant/area-data": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/@vant/area-data/-/area-data-2.0.0.tgz",
"integrity": "sha512-zgP4AA8z09S9QTNgVCCHo9cHjcybrv22RJDYPjuCkecn4SB98T5EoPQh2TwqbQXmUhbaOGgiZGy3OUaUxnY7qg=="
},
"@vant/icons": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@vant/icons/-/icons-3.0.2.tgz",

View File

@ -9,10 +9,14 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@vant/area-data": "^2.0.0",
"amfe-flexible": "^2.2.1",
"axios": "^1.4.0",
"core-js": "^3.8.3",
"dayjs": "^1.8.14",
"decimal.js": "^10.4.3",
"echarts": "^5.2.2",
"element-ui": "^2.15.9",
"less": "^4.1.3",
"less-loader": "^11.1.3",
"qs": "^6.11.2",
@ -21,10 +25,7 @@
"vant": "^2.13.2",
"vue": "^2.6.14",
"vue-router": "^3.0.7",
"vuex": "^3.6.2",
"element-ui": "^2.15.9",
"dayjs": "^1.8.14",
"decimal.js": "^10.4.3"
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",

View File

@ -35,7 +35,7 @@
// VConsole 默认会挂载到 `window.VConsole` 上
// let vConsole = new window.VConsole();
(function (doc, win) {
console.log("==window.location.pathname===",window.location.pathname)
// console.log("==window.location.pathname===",window.location.pathname)
let docEl = doc.documentElement
let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
recalc = function () {

78
public/res/privacy.html Normal file
View File

@ -0,0 +1,78 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>免责声明</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
/*margin: 20px;*/
padding: 0;
/*background-color: #f9f9f9;*/
color: #333;
}
h3 {
text-align: center;
/*font-size: 24px;*/
margin-bottom: 20px;
}
h4 {
/*font-size: 20px;*/
margin-top: 30px;
margin-bottom: 10px;
color: #555;
}
p {
margin: 10px 0;
text-indent: 2em;
}
ul {
margin: 10px 0;
padding-left: 40px;
}
li {
margin: 5px 0;
}
.container {
font-size: 14px;
padding-bottom: 20px;
}
</style>
</head>
<body>
<div class="container">
<h3>声明</h3>
<p>本平台为二手车买卖双方提供免费信息发布服务。在您使用本平台之前,请仔细阅读并理解本免责声明。一旦使用本平台,即视为您已阅读、理解并同意接受本免责声明的所有条款。</p>
<h4>一、平台性质</h4>
<p>1. 本平台仅为信息发布平台,不参与任何二手车交易环节,包括但不限于交易洽谈、合同签订、款项支付、车辆交付等,实际交易价格由买卖双方自行协商确定。</p>
<p>2. 本平台不对发布信息的真实性、准确性、完整性、合法性进行任何形式的担保或保证,用户应自行判断信息的真实性并承担由此产生的风险。</p>
<h4>二、用户责任</h4>
<p>1. 用户应保证发布的信息真实、准确、完整、合法,并对其发布的信息承担全部责任。</p>
<p>2. 用户不得发布任何虚假、违法、侵权、违反公序良俗的信息,包括但不限于:</p>
<ul>
<li>虚假车源信息</li>
<li>事故车、水泡车、火烧车等存在重大安全隐患的车辆信息</li>
<li>盗抢车辆信息</li>
<li>侵犯他人知识产权或其他合法权益的信息</li>
<li>含有淫秽、色情、赌博、暴力、恐怖等内容的信息</li>
<li>其他违反法律法规或平台规则的信息</li>
</ul>
<h4>三、免责条款</h4>
<p>1. 因用户发布的信息引起的任何纠纷或损失,本平台不承担任何责任。</p>
<p>2. 因不可抗力、计算机病毒、黑客攻击、系统不稳定、用户所在位置、用户关机以及其他任何网络、技术、通信线路等原因造成的服务中断或不能满足用户要求的风险,本平台不承担任何责任。</p>
<p>3. 本平台不对用户之间的交易行为承担任何责任,用户应自行承担交易风险。</p>
<h4>四、其他</h4>
<p>1. 本平台有权根据法律法规的变化或平台运营的需要,随时修改本免责声明,并在平台上公布,修改后的内容自公布之日起生效。</p>
<p>2. 本免责声明的解释权归中道救援股份有限公司所有。</p>
<p>请您在使用本平台前务必仔细阅读并理解本免责声明。</p>
<p>如果您对本免责声明有任何疑问,请联系我们。</p>
</div>
</body>
</html>

View File

@ -308,3 +308,12 @@ export function ocrHandler(data){
data
})
}
///agg-api/tencent-ocr/unifiedOCRWithCompress
export function unifiedOCRWithCompress(data){
return request({
url:'/agg-api/tencent-ocr/unifiedOCRWithCompress',
method:'POST',
contentType:'application/json',
data
})
}

View File

@ -94,4 +94,21 @@ export function batteryDetailList (data){
contentType:'application/json',
data
})
}
}
// 查询未读告知函
export function selectUnReadNotifyBySupplier() {
return request({
url: '/supplierManage/correction/notify/selectUnReadNotifyBySupplier',
method:'POST',
})
}
// 阅读告知函
export function correctionHandle(data) {
return request({
url: '/supplierManage/correction/record/correctionHandle',
method:'POST',
data
})
}

96
src/api/secondHandCar.js Normal file
View File

@ -0,0 +1,96 @@
import request from '@/utils/http'
// 车源/求购列表
export function appPageList(data){
return request({
url: '/toc-user/car-app/appPageList',
method:'POST',
contentType: 'application/json',
data
})
}
// 我的发布列表
export function minePublishPageList(data){
return request({
url: '/toc-user/car-app/minePublishPageList',
method:'POST',
contentType: 'application/json',
data
})
}
// 审核不通过数量
export function auditFailCount (data){
return request({
url: '/toc-user/car-app/auditFailCount ',
method:'POST',
// contentType: 'application/json',
data
})
}
// 信息详情查询
export function carInfoDetail(data){
return request({
url: '/toc-user/car-app/carInfoDetail',
method:'POST',
contentType: 'application/json',
data
})
}
// 发布编辑信息
export function publishCarInfo(data){
return request({
url: '/toc-user/car-app/publishCarInfo',
method:'POST',
contentType: 'application/json',
data
})
}
// 用户信息反馈
export function userFeedback(data){
return request({
url: '/toc-user/car-app/userFeedback',
method:'POST',
contentType: 'application/json',
data
})
}
//二手车信息擦亮
export function usedCarPolish(data){
return request({
url: `/toc-user/car-app/usedCarPolish/${data}`,
method:'POST',
})
}
//二手车信息下架
export function usedCarRemove(data){
return request({
url: '/toc-user/car-app/usedCarRemove',
method:'POST',
contentType: 'application/json',
data
})
}
//二手车信息重新上架
export function usedCarReShelf(data){
return request({
url: `/toc-user/car-app/usedCarReShelf/${data}`,
method:'POST',
})
}
//审批信息
export function auditCarInfo(data){
return request({
url: '/toc-user/car-admin/auditCarInfo',
method:'POST',
data
})
}
// 保存信息记录
export function saveRecord(data){
return request({
url: '/toc-user/car-record/saveRecord',
method:'POST',
contentType: 'application/json',
data
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 933 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 822 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -3,6 +3,7 @@ import VueRouter from "vue-router";
Vue.use(VueRouter);
import kpiRouter from './kpi-router'
import invoiceRouter from "@/router/invoice-router";
import secondHandRouter from "@/router/second-hand-router";
const routes = [
{
path: '/',
@ -185,6 +186,14 @@ const routes = [
title:'文档资料'
}
},
{
path: '/notificationList',
name: 'notificationList',
component:()=>import('@/views/index/notificationList'),
meta: {
title:'告知函'
}
},
{
path: '/caseList',
name: 'caseList',
@ -267,6 +276,7 @@ const routes = [
},
...kpiRouter,
...invoiceRouter,
...secondHandRouter,
]
const router = new VueRouter({

View File

@ -0,0 +1,59 @@
const secondHandCar = [
{
path: '/indexList',
name: 'indexList',
component: () => import('@/views/secondHandCar/indexList.vue'),
meta:{
title: '首页列表',
}
},
{
path: '/carSource',
name: 'carSource',
component: () => import('@/views/secondHandCar/carSource.vue'),
meta:{
title: '车源发布',
}
},
{
path: '/wantBuy',
name: 'wantBuy',
component: () => import('@/views/secondHandCar/wantBuy.vue'),
meta:{
title: '求购发布',
}
},
{
path: '/forSale',
name: 'forSale',
component: () => import('@/views/secondHandCar/forSale.vue'),
meta:{
title: '查看车源',
}
},
{
path: '/wantBuySale',
name: 'wantBuySale',
component: () => import('@/views/secondHandCar/wantBuySale.vue'),
meta:{
title: '查看求购',
}
},
{
path: '/mineRelease',
name: 'mineRelease',
component: () => import('@/views/secondHandCar/mineRelease.vue'),
meta:{
title: '我的发布',
}
},
{
path: '/privacyComponent',
name: 'privacyComponent',
component: () => import('@/views/secondHandCar/privacy.vue'),
meta:{
title: '免责声明',
}
},
]
export default secondHandCar

View File

@ -45,7 +45,6 @@ select{
margin-left: 0;
font-weight: normal;
font-size: 14px;
//@include fontWeightSize(400,14px);
color: #000000;
}

View File

@ -1,7 +1,6 @@
import axios from "axios";
import qs from 'qs'
import { Toast } from 'vant'
// console.log('process.env.VUE_APP_BASE_API', process.env.VUE_APP_BASE_API)
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
@ -11,38 +10,26 @@ const service = axios.create({
timeout: 10000
})
const urlParams = new URLSearchParams(window.location.search);
let token = urlParams.get('token') ;
let token = urlParams.get('token');
localStorage.setItem('token', token);
service.interceptors.request.use(
config => {
let reqUrl=config.url
// console.log("reqUrl",reqUrl)
config.data = config.contentType ? config.data : qs.stringify(config.data)
if (config.testFlag) {
config.data = qs.stringify(config.data, {arrayFormat: 'indices', allowDots: true})
}
config.headers['Content-Type'] = config.contentType || 'application/x-www-form-urlencoded'
config.headers['Content-Type'] = config.contentType || 'application/x-www-form-urlencoded'
let token = localStorage.getItem('token');
// let token='4099761587129c46b03c9316c9e866c9'
// let token='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJzb25nIiwiYXVkIjpbInN1cHBsaWVyLWFwcCJdLCJuYmYiOjE3MTI0NTQ5NTMsInVzZXJfaW5mbyI6eyJ1c2VySWQiOjU0NjU0LCJwaG9uZSI6IjE3NjMwMDM1NjU4IiwibmFtZSI6InNvbmciLCJzdXBwbGllck5hbWUiOiJDLeS4iua1t-a1i-ivleacjeWKoeWVhiIsInN1cHBsaWVySWQiOjMzMDQxLCJzdXBwbGllclR5cGUiOjIsInVzZXJuYW1lIjoic29uZyIsInVzZXJUeXBlIjoicmVzY3VlQXBwIiwiZGV2aWNlSWQiOiIyMmI0OWNhMjBmOWI4MzMwZDk4NzIxNzNmMzllYTY4YmMiLCJhdXRob3JpdGllcyI6W119LCJzY29wZSI6WyJhbGwiXSwiaXNzIjoiaHR0cHM6Ly9zaW5vYXNzaXN0LmNvbSIsImV4cCI6MTcxMjU0MTM1MywiaWF0IjoxNzEyNDU0OTUzfQ.sPU9_OD_TOWcTwqmlawEGyo4mCPrEaRYw2R02gnvYJw'
// let token='eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJTSEhQWEIiLCJ1c2VySWQiOjU0NzI2LCJuYW1lIjoiI-a1i-ivleWwj-eZveeZvSIsInVzZXJOYW1lIjoiU0hIUFhCIiwic3VwcGxpZXJJZCI6MTAwMDE2NSwiZXhwIjoxNzQ0NTEwNzkwfQ.JPk0OA7slYJN3FIi_uhW4Y0CiWRvl6R1dK8MRTbyhD8'
if(!(reqUrl=='/supplier/supplierTraining/trainingTask' || reqUrl=='/supplier/supplierTraining/normalList' || reqUrl=='/supplier/supplierTraining/trainingList')){
config.headers['Authorization'] = `${token}`;
config.headers['token'] = `${token}`;
}
/* if (reqUrl.includes("/driverApp")) {
// console.log("司机app")
config.headers['token'] = `${token}`;
} else if(reqUrl.includes("/supplierApp") || reqUrl.includes("/supplierKPI") || reqUrl.includes('/supplier/select') || reqUrl.includes('/order') || reqUrl.includes('/order/taskInvoiceBatch') || reqUrl.includes('/supplier') ){
// console.log("调度app服务商kpi")
config.headers['Authorization'] = `${token}`;
}else{
config.headers['token'] = `${token}`;
}*/
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
@ -50,27 +37,17 @@ service.interceptors.request.use(
service.interceptors.response.use(
response => {
const res = response.data
// return res //请求响应数据
// if(res.code === 401){
// Toast('token不合法或过期')
// }else if(){
//
// }
if ( res.code === 401 || res.code === 400 || res.code == 500) {
Toast(res.msg || 'Error')
return Promise.reject(res.msg)
} else {
return res
// if( res.code === 200 ) {
// return res.data
// } else {
// return res.data
// }
}
},
error => {
console.log('err' + error)
Toast(error.message)
if(error.message != 'Network Error'){
Toast(error.message)
}
return Promise.reject(error)
}
)

View File

@ -1,9 +1,7 @@
export const myMixins = {
data() {
return {
touchStart: [],
touchEnd: [],
slideShow: true
}
},
methods: {
@ -72,12 +70,38 @@ export const myMixins = {
methods();
}
setTimeout(() => {
console.log("shengxiaoxi")
that.noClick = true;
}, 3000)
} else {
// 这里是重复点击的判断
}
}
},
formatNumber(num) {
if (num < 10000) {
// 小于 5 位数,显示为 0.x 万
return `${(num / 10000).toFixed(1)}`;
} else {
// 大于或等于 5 位数,显示为 x 万,四舍五入到小数点后一位
return `${Math.round(num / 1000) / 10}`;
}
},
isWebFunc(){
let res=false
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
if (!isMobile) {// 是移动端不变
res=true
}
return res
},
closeParentDialog() {
if (window.parent) {
const hasListener = window.parent.dispatchEvent(new Event('checkCloseDialog'));
if (hasListener) {
window.parent.postMessage('closeDialog', '*');
} else {
window.history.back();
}
}
},
}
}

View File

@ -0,0 +1,161 @@
<template>
<div>
<div class="dialog-wrapper">
<div class="title">
{{ '告知函('+(currentIndex + 1)+'/'+ list.length+')' }}
</div>
<h3 class="top">{{currentItem?.title?currentItem?.title:(currentItem?.type==1 ? '质量不合格整改' : '质量不合格调整告知')}}</h3>
<div class="center">
<div v-html="formattedContent(currentItem)"></div>
</div>
<div class="end">
<div>中道汽车救援股份有限公司</div>
<div>区域管理部</div>
<div>{{formatDate(currentItem)}}</div>
</div>
<div class="iptWrap">
<div class="tip">请仔细阅读告知函内容并在下方输入"我已阅读”以表明您已充分理解函件中的各项信息。</div>
<el-input style="width: 50%" v-model.trim="content" placeholder="请输入我已阅读"></el-input>
</div>
<div class="dialog-footer">
<el-button type="info" size="small" v-if="num > 0">还需阅读{{num}}秒</el-button>
<el-button type="primary" size="small" v-if="num==0" @click="confirmHandle(currentItem)">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {selectUnReadNotifyBySupplier, correctionHandle} from "@/api/order"
export default {
name: "notificationList",
mixins: [myMixins],
data() {
return {
list: [],
currentIndex: 0,
num:10,
timer: null,
content: '',
}
},
computed: {
currentItem() {
return this.list[this.currentIndex];
}
},
watch: {
currentIndex() {
this.content = '';
this.num = 10;
this.startCountdown();
},
},
async mounted() {
await this.getLetterList();
this.timer && clearInterval(this.timer)
this.startCountdown();
},
methods: {
async confirmHandle(item){
if (this.content === '我已阅读') {
console.log('item', item)
let res = await correctionHandle({
handleType:4,
operationType:'modify',
recordId:item.recordId,
planId:item.planId,
notifyId:item.id,
});
console.log('阅读res', res)
// 确认成功后处理下一个告知函
this.currentIndex++;
if (this.currentIndex < this.list.length) {
this.content = '';
this.num = 10;
this.startCountdown();
} else {
this.closeHandle();
}
} else {
this.$message.error('请输入"我已阅读"以确认');
}
},
async getLetterList(){
let res = await selectUnReadNotifyBySupplier();
let result = res?.data || []
if(result && result.length>0){
this.list = result
}
},
formatDate(val){
/** 日期格式化
* */
if(!val?.updateTime){
return
}
const date = new Date(val.updateTime);
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从 0 开始,需要加 1
const day = date.getDate();
const formattedDate = `${year}年${month}月${day}日`;
return formattedDate
},
formattedContent(val) {
/** 转换文本,能被 v-html 识别
* */
return val?.content?.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>');
},
startCountdown() {
this.stopCountdown()
this.timer = setInterval(() => {
if (this.num > 0) {
this.num--;
}
}, 1000);
},
closeHandle() {
this.stopCountdown();
// 调用 app 的方法
this.goBack();
},
stopCountdown() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
},
}
}
</script>
<style scoped lang="scss">
.dialog-wrapper {
padding: 10px 20px;
}
.title {
}
.top {
text-align: center;
}
.center {
margin: 20px 0;
line-height: 24px;
.hight{
color: #0B99E4;
}
}
.end{
text-align: right;
line-height: 24px;
}
.tip{
margin-top: 40px;
margin-bottom: 10px;
}
.dialog-footer {
text-align: right;
}
</style>

View File

@ -6,15 +6,15 @@
<div class="metersWrap">
<div class="item" v-show="supplierSettlementType != 1">
<div class="leftKiloMeters">AB段公里数</div>
<div class="rightInput"><input type="number" v-model="form.reportMileageAb"/>公里</div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.reportMileageAb"/>公里</div>
</div>
<div class="item" v-show="supplierSettlementType == 1 || supplierSettlementType == 2 || supplierSettlementType == 3 || supplierSettlementType == 4">
<div class="leftKiloMeters">BC段公里数</div>
<div class="rightInput"><input type="number" v-model="form.reportMileageBc"/>公里</div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.reportMileageBc"/>公里</div>
</div>
<div class="item" v-show=" supplierSettlementType == 3 || supplierSettlementType == 4">
<div class="leftKiloMeters">CA段公里数</div>
<div class="rightInput"><input type="number" v-model="form.reportMileageCa"/>公里</div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.reportMileageCa"/>公里</div>
</div>
</div>
</div>
@ -24,15 +24,15 @@
<div class="metersWrap">
<div class="item" v-show="supplierSettlementType != 1">
<div class="leftKiloMeters">AB段路桥费</div>
<div class="rightInput"><input type="number" v-model="form.bridgeAmountAb"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.bridgeAmountAb"/></div>
</div>
<div class="item" v-show="supplierSettlementType == 1 || supplierSettlementType == 2 || supplierSettlementType == 3 || supplierSettlementType == 4">
<div class="leftKiloMeters">BC段路桥费</div>
<div class="rightInput"><input type="number" v-model="form.bridgeAmountBc"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.bridgeAmountBc"/></div>
</div>
<div class="item" v-show=" supplierSettlementType == 3 || supplierSettlementType == 4">
<div class="leftKiloMeters">CA段路桥费</div>
<div class="rightInput"><input type="number" v-model="form.bridgeAmountCa"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.bridgeAmountCa"/></div>
</div>
</div>
</div >
@ -42,23 +42,23 @@
<div class="metersWrap">
<div class="item" >
<div class="leftKiloMeters">小轮个数</div>
<div class="rightInput"><input type="number" v-model="form.tyreNumber" @input="handleInput"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.tyreNumber" @input="handleInput"/></div>
</div>
<div class="item">
<div class="leftKiloMeters">等候费</div>
<div class="rightInput"><input type="number" v-model="form.waitAmount"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.waitAmount"/></div>
</div>
<div class="item" >
<div class="leftKiloMeters">困境费</div>
<div class="rightInput"><input type="number" v-model="form.dilemmaFee"/></div>
<div class="rightInput"><input type="number" :disabled="!taskCostShow" v-model="form.dilemmaFee"/></div>
</div>
<div class="item blueColor" >
<div class="leftKiloMeters">收取客户金额</div>
<div class="rightInput blueColor"><input class="blueColor" type="number" v-model="form.customerAmount"/></div>
<div class="rightInput blueColor"><input class="blueColor" type="number" :disabled="!taskCostShow" v-model="form.customerAmount"/></div>
</div>
</div>
</div>
<div class="btn">
<div class="btn" v-if="taskCostShow || finishLt7">
<button @click="submit">提交</button>
</div>
</div>
@ -86,7 +86,9 @@ export default {
waitAmount:'',
dilemmaFee:'',
customerAmount:'',
taskFlowId:''
taskFlowId:'',
auditStatus:'',
finishTime:'',
}
}
},
@ -97,6 +99,14 @@ export default {
this.orderCode = urlParams.get('orderCode')
await this.getDetail()
},
computed:{
taskCostShow() {
return this.form.auditStatus?.code && !([3, 4, 6].includes(this.form.auditStatus.code))
},
finishLt7(){
return !this.form.finishTime || (this.form.finishTime && new Date().getTime() - new Date(this.form.finishTime).getTime() <= 7 * 24 * 60 * 60 * 1000)
},
},
methods:{
handleInput(event) {
const newValue = parseInt(event.target.value, 10);
@ -118,7 +128,6 @@ export default {
})
leftCopy(this.form,{...res.data});
this.supplierSettlementType= res.data.supplierSettlementType?.code
// this.form.taskFlowId =1
},
async updatSettlement(){
let result =await updateOrderSettlement({

View File

@ -73,6 +73,7 @@
</template>
<script>
import { Decimal } from 'decimal.js';
import { Dialog } from "vant";
import { myMixins } from "@/utils/myMixins"
import { uploadInvoice, getBillingInfo, deleteInvoice, createBatch } from "@/api/mine"
@ -120,7 +121,7 @@
invoiceTotal () {
let total = 0;
this.list?.map(item => {
total += item.invoiceMoney
total = new Decimal(total).plus(new Decimal(item.invoiceMoney)).toNumber()
})
return total
}
@ -278,6 +279,15 @@
if(ocrName != billName && diffNumber > 2 && !res.data.ocrInvoiceRes.data.sellerName.startsWith("国家税务总局")){
errorStr = errorStr + "上传发票抬头与服务商配置不一致,设置抬头为:" + (this.billInfo.unitName || '未设置') + ",识别抬头为:" + res.data.ocrInvoiceRes.data.sellerName + ";如发票确认无误请联系结算部021-53682525";
}
let conList = res.data.ocrInvoiceRes.data.invoiceDetails.filter(a => a.itemName.includes("*"))
if(!res.data.ocrInvoiceRes.data.sellerName.startsWith("国家税务总局") &&
conList.every(a => {
let items = a.itemName.split("*")
return (!items[1].includes("现代服务") && !items[1].includes("运输服务")) || (!items[2].includes("拖车") && !items[2].includes("救援") && !items[2].includes("施救") && !items[2].includes("清障") && !items[2].includes("道路救援"))
})
){
errorStr = errorStr + "分类必须包含:现代服务/运输服务,服务名称必须包含:拖车/救援/施救/清障/道路救援 ;例如《*现代服务*拖车费》";
}
if( !flag ) {
Dialog.alert({

View File

@ -74,9 +74,64 @@
<img class="startImg" src="@/assets/start.png" />
<span>车辆类型</span>
</div>
<select id="mySelect" class="mySelect" v-model="selectedOption">
<option v-for="(item,index) in typeList" :key="index" :value="index">{{item}}</option>
<!--
<select
id="mySelect"
class="mySelect"
v-model="selectedOption"
multiple
>
<option
v-for="item in typeList"
:key="item"
:value="item"
:disabled="isOptionDisabled(item)"
>
{{ item }}
</option>
</select>
-->
<el-select
multiple
:multiple-limit="isMultiple ? 2 : 1"
v-model="selectedOption"
value-key="name"
class="elSelect"
collapse-tags="collapse-tags"
placeholder="请选择" style="width: 55%"
>
<el-option
v-for="item in vehicleTypes"
:key="item.name"
:label="item.name"
:value="item.value"
:disabled="!item.disabled ? false : true"
>
</el-option>
</el-select>
</div>
<div class="itemContent">
<div class="titleType">
<span>牌照</span>
</div>
<el-select
v-model="vehicleLicense"
disabled
value-key="name"
class="elSelect"
collapse-tags="collapse-tags"
placeholder="请选择" style="width: 55%"
>
<el-option
v-for="item in vehicleLicenseOptions"
:key="item.name"
:label="item.name"
:value="item.value"
>
</el-option>
</el-select>
</div>
<div class="lineBot"></div>
<div class="itemContent">
@ -121,7 +176,7 @@
<span class="line"></span>
</div>
<div :ref="'checkboxGroup' + index" class="checkbox-group">
<van-checkbox-group v-model="serviceIds" v-for="(item2,index2) in item.children" :key="index2" class="radioWrap" >
<van-checkbox-group v-model="serviceIds" v-for="(item2,index2) in item.children" :key="index2" class="radioWrap">
<van-checkbox class="item" :name="item2.id">{{item2.name }}</van-checkbox>
</van-checkbox-group>
</div>
@ -152,10 +207,11 @@ export default {
checked: true,
carNum:"",//车牌号
typeList:[],//车辆类型列表
selectedOption:'1',//车辆类型
selectedOption:[],//车辆类型
id:'',//车辆Id
serviceIds:[],//车辆服务种类,
supplierServiceList:[],
oldSupplierServiceList:[],
show:false,
imageUrl: require('@/assets/arr_right.png'),
vehicleLicenseFrontList: [],
@ -168,21 +224,116 @@ export default {
vehicleFrontPhoto: '', // 车头照
vehicleLicenseInfo: {},
vehicleLicenseBackOcrFlag: false, // 行驶证副页 修改时默认不需要 ocr识别
isMultiple: false, // 是否支持多选
vehicleLicense:'',//牌照
vehicleFrontLicensePlate:'',//车头照车牌号码
vehicleTypes:[{
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 },
],
vehicleLicenseOptions: [{
name: '蓝牌',
value: 1
}, {
name: '黄牌',
value: 2
}, {
name: '新能源',
value: 3
}, {
name: '临牌',
value: 4
}, {
name: '其他',
value: 5
}]
}
},
watch:{
selectedOption(newVal){
if(newVal == 4){
this.isMultiple = true
this.vehicleTypes[2].disabled=true
this.vehicleTypes[5].disabled=true
this.vehicleTypes[6].disabled=true
this.vehicleTypes[7].disabled=true
this.vehicleTypes[8].disabled=true
this.vehicleTypes[9].disabled=true
}else{
this.isMultiple = false
this.vehicleTypes[2].disabled=false
this.vehicleTypes[5].disabled=false
this.vehicleTypes[6].disabled=false
this.vehicleTypes[7].disabled=false
this.vehicleTypes[8].disabled=false
this.vehicleTypes[9].disabled=false
}
if (newVal == 1 || newVal == 7){
let arr = []
this.supplierServiceList.forEach((item)=>{
if(!(item.name == '拖车服务' || item.name == '大型车救援')){
arr.push(item)
}
})
this.supplierServiceList = arr
}else{
this.supplierServiceList = this.oldSupplierServiceList
}
},
},
async mounted() {
this.id=this.$route.params?.id
const selectElement = document.getElementById('mySelect');
selectElement.addEventListener('change', function() {
this.selectedOption=selectElement.value;
});
await this.getSupplierServiceTree();
await this.getTypeList();
if( this.id){
await this.vehicleInfo()
}
await this.getSupplierServiceTree();
},
methods:{
getVehicleLicense(color) {
if( color == '蓝' ) {
this.vehicleLicense = 1
} else if(color == '黄') {
this.vehicleLicense = 2
} else if(color == '临牌') {
this.vehicleLicense = 4
} else if(color.includes('绿')) {
this.vehicleLicense = 3
} else {
this.vehicleLicense = 5
}
},
async vehicleLicenseFrontHandler(file) { // 上传 行驶证首页
const formData = new FormData();
formData.append("file" , file.file);
@ -209,6 +360,16 @@ export default {
formData.append("file" , file.file);
let res = await uploadImage(formData);
this.vehicleFrontPhoto = res.data;
await this.ocrCarFrontHandler()
},
async ocrCarFrontHandler() { // 车辆正面 orc 识别
let res = await ocrHandler({
ocrType: 10,
imageUrl: this.vehicleFrontPhoto,
cardSide: 'FRONT'
});
this.vehicleFrontLicensePlate=res.data?.number
this.getVehicleLicense(res.data.color)
},
async vehicleOcrHandler() { // 行驶证首页 ocr 识别
this.vehicleLicenseInfo.licensePlateNumber = '';
@ -287,29 +448,41 @@ export default {
},
async getTypeList() {
let result=await vehicleTypeList();
this.typeList=[]
if(result.code === 200){
this.typeList=result.data
for (const key in result.data){
// console.log("keys",result.data[key])
this.typeList.push({name:result.data[key],disabled:false,value:(key+1)})
// this.typeList.push(result.data[key])
}
}
},
async getSupplierServiceTree(){
let res = await supplierServiceTree();
this.supplierServiceList=res.data
this.oldSupplierServiceList=this.supplierServiceList
},
async vehicleInfo(){
let res= await getInfoById({
vehicleId:this.id
})
let result=res.data;
console.log("result",result)
this.id=result.vehicleId
this.carNum=result.plateNumber
this.isJoin=result.hasPolymerization.code
this.selectedOption=result.vehicleType;
this.selectedOption=result.vehicleType?.split(',').map((item)=>{
return Number(item);
});
this.serviceIds=result.serviceIds
this.vehicleLicenseFront = result.vehicleLicenseFront;
this.vehicleLicenseBack = result.vehicleLicenseBack;
this.vehicleFrontPhoto = result.vehicleFrontPhoto;
this.vehicleLicenseInfo = result.vehicleLicenseInfo;
this.vehicleLicenseCarPhoto = result.vehicleLicenseCarPhoto;
this.vehicleLicense = result.vehicleLicense;
this.vehicleFrontLicensePlate = result.vehicleFrontLicensePlate;
if( this.vehicleLicenseFront ) {
this.vehicleLicenseFrontList = [{ url : this.vehicleLicenseFront }];
}
@ -339,7 +512,7 @@ export default {
this.$toast('行驶证车辆照片页不能为空')
return
}
if( !this.vehicleLicenseBack ) {
if( !this.vehicleFrontPhoto ) {
this.$toast('车头照片不能为空')
return
}
@ -351,10 +524,18 @@ export default {
this.$toast('行驶证副页识别失败')
return
}
await saveVehicle({
if(!(this.selectedOption.length > 0)){
this.$toast('车辆类型不能为空')
return
}
if(this.selectedOption?.length==1 && this.selectedOption.includes(1)){//选择小修车时需清除原本的拖车服务类型
let data=this.oldSupplierServiceList.filter(item => item.name ==='拖车服务')
this.serviceIds = this.serviceIds.filter(item => !data[0].children.some(obj => obj.id === item));
}
await saveVehicle({
vehicleId:this.id ? this.id : '',
plateNumber:this.carNum ? this.carNum :'',
vehicleType:this.selectedOption ? this.selectedOption : '',
vehicleType:this.selectedOption?.length>0 ? this.selectedOption.join(',') : '',
hasPolymerization:this.isJoin,
serviceIds:this.serviceIds ? this.serviceIds : [],
vehicleLicenseFront: this.vehicleLicenseFront,
@ -362,6 +543,8 @@ export default {
vehicleFrontPhoto: this.vehicleFrontPhoto,
vehicleLicenseInfo: this.vehicleLicenseInfo,
vehicleLicenseCarPhoto: this.vehicleLicenseCarPhoto,
vehicleLicense: this.vehicleLicense,
vehicleFrontLicensePlate:this.vehicleFrontLicensePlate,
})
if(this.id){
this.$toast('修改成功')
@ -480,4 +663,8 @@ export default {
margin: 40px 0 30px 8px;
}
}
.elSelect ::v-deep .el-input__inner{
border: none !important;
text-align: right !important;
}
</style>

View File

@ -13,7 +13,7 @@
<template slot-scope="scope">{{scope.row[item.prop]}} </template>
</el-table-column>
</template>
<!-- <template v-else-if="active===4">
<template v-else-if="active===4">
<el-table-column v-for="(column,index) in filteredLabelList" :key="column.prop" :prop="column.prop" :label="column.label"
:fixed="index===0" align="center" min-width="100"
:width="(isMobile && (column.label=='案件编号' || column.label=='服务内容')) ? 70 : 'auto'">
@ -25,7 +25,7 @@
<span v-else>{{ scope.row[column.prop] }}</span>
</template>
</el-table-column>
</template>-->
</template>
<template v-else>
<el-table-column v-for="column in labelList" :key="column.prop" :prop="column.prop" :label="column.label"
align="center" min-width="100" :width="(isMobile && (column.label=='案件编号' || column.label=='服务内容')) ? 70 : 'auto'">
@ -45,12 +45,12 @@ export default {
mounted() {
},
computed: {
/* filteredLabelList() {
filteredLabelList() {
if(this.active!==4){
return
}
return this.labelList.filter(column => column.label !== '星级评分');
}*/
}
},
methods: {
setTableCellStyle({ row, column,columnIndex }) {

View File

@ -39,7 +39,7 @@
<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].includes(active))" class="tipArrow right">>>></div>
<div v-if="isMobile && !([9,10].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}">
@ -202,7 +202,7 @@
<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].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"
@ -245,7 +245,7 @@
:total="total">
</el-pagination>
</div>
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[3,4,5,6,7,8].includes(active)">
<div v-loading="loadingData" class="contentWrap monthTotal" v-if="[3,6,7,8,9,10].includes(active)">
<div :class="{'comTab':true,'detailTable':isMobile}">
<noFit-table :active='active' :is-mobile='isMobile' :table-data="detailList" :label-list="labelList"
></noFit-table>
@ -273,7 +273,7 @@ import {
getStatisticsKpiByMonth,
getStatisticsKpi,
getSupplierId,
getDriverName,
getDriverName,getDriverStatisticsKpi,
getRecentSupplierKpi, querySupplierDriverStatisticsScore
} from "@/api/kpi.js"
import {myMixins} from "@/utils/myMixins"
@ -289,9 +289,9 @@ export default {
return {
active:0,
activeIndex: 0,
// {name: '月/师傅'}, {name: '日/师傅'},
//
tabArr: [
{name: '总览'}, {name: '月/总'}, {name: '日/总'},{name: '师傅满意度'}, {name: '拒单明细'},
{name: '总览'}, {name: '月/总'}, {name: '日/总'},{name: '师傅满意度'},{name: '月/师傅'}, {name: '日/师傅'}, {name: '拒单明细'},
{name: '超时明细'}, {name: '投诉明细'}, {name: '不使用APP案件明细'}, {name: '车辆在线情况'}
],
list: [{name: '接单指标'}, {name: '客户评价'}, {name: 'APP使用'}, {name: ' 时效 '}],
@ -1054,8 +1054,9 @@ export default {
this.loading = false
this.detailList?.map(item => {
this.xAxisArr.push(item.month)
this.xAxisArr = [...new Set(this.xAxisArr)]; // 去重
})
// console.log(" this.xAxisArr", this.xAxisArr)
console.log(" this.xAxisArr", this.xAxisArr)
// this.xAxisArr[this.xAxisArr.length - 1] = '本月'
await this.twoTabHanldeData()
}else if (this.active === 3) {
@ -1081,7 +1082,7 @@ export default {
]
this.loading = false;
}
/* else if ([4,5].includes(this.active)) {
else if ([4,5].includes(this.active)) {
let res = await getDriverStatisticsKpi({
startTime: this.startTime ,
endTime: this.endTime,
@ -1117,9 +1118,8 @@ export default {
this.total=0
}
await this.twoTabHanldeData();
}*/
else if ([ 4,5,6, 7, 8].includes(this.active)) {
}
else if ([ 6, 7, 8,9,10].includes(this.active)) {
this.detailList = []
this.labelList = []
let result = await getKpiDetailsData({
@ -1136,7 +1136,7 @@ export default {
return {...item, date: formatVal};
});
this.loading = false
if (this.active === 4) {//拒单明细
if (this.active === 6) {//拒单明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@ -1147,7 +1147,7 @@ export default {
{label: '中道派单时间', prop: 'dispatchTime'},
{label: '拒绝原因', prop: 'reason'},
]
} else if (this.active === 5) {//超时明细
} else if (this.active === 7) {//超时明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@ -1157,7 +1157,7 @@ export default {
{label: '上游接单来源', prop: 'workSource'},
{label: '中道派单时间', prop: 'dispatchTime'},
]
} else if (this.active === 6) {//投诉明细
} else if (this.active === 8) {//投诉明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@ -1166,7 +1166,7 @@ export default {
{label: '投诉时间', prop: 'complainCreateTime'},
{label: '投诉类型', prop: 'complainTypeString'},
]
} else if (this.active === 7) {//不使用App案件明细
} else if (this.active === 9) {//不使用App案件明细
this.labelList = [
{label: '案件编号', prop: 'orderCode'},
{label: '服务内容', prop: 'serviceName'},
@ -1174,7 +1174,7 @@ export default {
{label: '工单创建时间', prop: 'orderCreateTime'},
{label: '事发地', prop: 'vehiclePointAddress'},
]
} else if (this.active === 8) {//车辆在线情况
} else if (this.active === 10) {//车辆在线情况
this.labelList = [
{label: '日期', prop: 'date'},
{label: '0点在线车辆数量', prop: 'zeroClockVehicleCount'},
@ -1587,15 +1587,15 @@ export default {
},
setType(type) {
switch (type) {
case 4:
return 1;
case 5:
return 2;
case 6:
return 3;
return 1;
case 7:
return 4;
return 2;
case 8:
return 3;
case 9:
return 4;
case 10:
return 5;
}
},

View File

@ -0,0 +1,795 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<img class="bg" src="@/assets/secondHandCar/bg.png" />
<div class="navWrap">
<div v-if="isWebFunc()" style="opacity: 0;" class="back"></div>
<img v-else class="back" @click="backHandle" src="@/assets/secondHandCar/back.png" />
<img class="navIcon" src="@/assets/secondHandCar/cheyuan_big.png" />
<div style="opacity: 0;" class="back"></div>
</div>
<div class="audit" v-if="status==3 && auditRemark">
<span><img class="noAudit" src="@/assets/secondHandCar/noAudit.png" />审核不通过</span>
<span>{{auditRemark}}</span>
</div>
<div class="audit supplierInfo" v-if="type==2">
<div><span>供应商名称</span><span>{{supplierName}}</span></div>
<div><span>供应商编号</span><span>{{supplierCode}}</span></div>
</div>
</div>
<div class="contentWrap" :style="id ? 'height: calc(100% - 100px);' : 'height: calc(100% - 42px);'" :class="[type==1 ? 'noContentAudit': 'hasContentAudit']">
<div class="oneContent content">
<img class="sort" src="@/assets/secondHandCar/one_cheyuan.png" />
<div class="uploadWrap">
<upload-common @success1="getDrivingLicense" @delete1="deleteImg1"
:text="'行驶证照片'" :multiple="false" :files.sync="vehicleLicensePhotoList"/>
<upload-common @success2="getPlateColor" @delete2="deleteImg2"
:text="'车辆45度照'" :multiple="false" :files.sync="vehicleAnglePhotoList" />
<upload-common @success4="getBackPhoto" @delete4="deleteImgBack"
:text="'车辆后方45度'" :multiple="false" :files.sync="vehicleRearPhotoList" />
<upload-common @success3="getOtherImg" @delete3="handleDeleteOtherImg"
:text="'其他照片0/6'" :multiple="true" :files.sync="otherImgSrcList"/>
</div>
</div>
<div class="line"></div>
<div class="twoContent content">
<img class="sort" src="@/assets/secondHandCar/two_desc.png" />
<div class="ocrInfo">
<div class="item"><span>牌照类型</span><span class="orc">{{ form.licenseType==1 ? '蓝牌' : (form.licenseType==2 ? '黄牌' : (form.licenseType==3 ? '绿牌' : '')) }}</span></div>
<div class="item"><span>上装品牌</span><span class="orc">{{form.brandModel}}</span></div>
<div class="item"><span>注册日期</span><span class="orc">{{form.registerDate?.substring(0,10)}}</span></div>
</div>
<div class="item vehicleTypeItem">
<span> <span class="star">*</span>车辆类型 </span>
<van-radio-group v-model="form.vehicleType" direction="horizontal" class="radioWrap">
<van-radio name="平板拖车" :class="{'checked':form.vehicleType=='平板拖车','vehicleRadio':true}">平板拖车</van-radio>
<van-radio name="地库车" :class="{'checked':form.vehicleType=='地库车','vehicleRadio':true}">地库车</van-radio>
<van-radio name="牵引车" :class="{'checked':form.vehicleType=='牵引车','vehicleRadio':true}">牵引车</van-radio>
<van-radio name="随车吊" :class="{'checked':form.vehicleType=='随车吊','vehicleRadio':true}">随车吊</van-radio>
</van-radio-group>
</div>
<div class="item" v-if="form.vehicleType=='平板拖车'">
<span> <span class="star">*</span>落板方式 </span>
<van-radio-group v-model="form.boardType" direction="horizontal" class="radioWrap">
<van-radio name="1" :class="{'checked':form.boardType==1}">全落地</van-radio>
<van-radio name="2" :class="{'checked':form.boardType==2}">斜落一体</van-radio>
<van-radio name="3" :class="{'checked':form.boardType==3}">普通斜板</van-radio>
</van-radio-group>
</div>
<div class="item">
<span> <span class="star">*</span>排放标准 </span>
<van-radio-group v-model="form.emissionStandard" direction="horizontal" class="radioWrap">
<van-radio name="3" :class="{'checked':form.emissionStandard==3}">国3</van-radio>
<van-radio name="4" :class="{'checked':form.emissionStandard==4}">国4</van-radio>
<van-radio name="5" :class="{'checked':form.emissionStandard==5}">国5</van-radio>
<van-radio name="6" :class="{'checked':form.emissionStandard==6}">国6</van-radio>
</van-radio-group>
</div>
<div class="item">
<span> <span class="star">*</span>刹车系统 </span>
<van-radio-group v-model="form.brakeSystem" direction="horizontal" class="radioWrap">
<van-radio name="1" :class="{'checked':form.brakeSystem==1}">气刹</van-radio>
<van-radio name="2" :class="{'checked':form.brakeSystem==2}">油刹</van-radio>
</van-radio-group>
</div>
<div class="item">
<span> <span class="star">*</span>所在城市 </span>
<van-field
@focus="areaShow = true"
class="radioWrap"
readonly
v-model="areaName"
input-align="right"
> </van-field>
</div>
<div class="item">
<span> <span class="star">*</span>行驶里程 </span>
<van-field
type="number"
class="radioWrap"
v-model="form.mileage"
input-align="right"
>
<template slot="right-icon" >
<span style="white-space: nowrap; margin-left: 8px;"> 公里 </span>
</template>
</van-field>
</div>
<div class="item">
<span> <span class="star">*</span>联系号码 </span>
<van-field
type="number"
class="radioWrap"
v-model="form.contactNumber"
input-align="right"
> </van-field>
</div>
<div class="item">
<span> <span class="star">*</span>售价(含税)</span>
<van-field
type="number"
class="radioWrap"
v-model="form.minPrice"
@input="validatePrice"
input-align="right"
>
<template slot="right-icon" >
<span style="white-space: nowrap; margin-left: 8px;"> </span>
</template>
</van-field>
</div>
<div class="item" style="margin-bottom:20px">
<span> <span class="star">*</span>底盘品牌</span>
<van-field
class="radioWrap"
v-model="form.underpanBrand"
input-align="right"
>
</van-field>
</div>
</div>
<div class="line lastLine"></div>
<div class="threeContent content">
<img class="sort" src="@/assets/secondHandCar/three.png" />
<el-input class="ipt" v-model.trim="form.desc" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }"
maxlength="500" show-word-limit placeholder="描述车辆信息:如事故、额外加装、无线遥控"></el-input>
<div v-if="type==2" style="margin: 10px 3px">不通过原因</div>
<el-input v-if="type==2" class="ipt" v-model.trim="auditReason" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }"
maxlength="200" show-word-limit placeholder="请填写不通过原因"></el-input>
<div class="checkedWrap" v-if="type==1">
<img v-show="radio==1" @click="radio=0" class="radioIcon" src="@/assets/secondHandCar/checked.png" />
<img v-show="radio==0" @click="radio=1" class="radioIcon" src="@/assets/secondHandCar/uncheck.png" />
<span>我已阅读并同意</span>
<span @click="viewPrivacy">二手车交易条款</span>
</div>
<div class="btnWrap" >
<div v-if="type==1" class="btn commonBtn" @click="noMultipleClicks(submitHandle)">发布</div>
<div v-if="type==2" class="auditBtn">
<div class="commonBtn" @click="noMultipleClicks(auditHandle,0)">审核不通过</div>
<div class="commonBtn" @click="noMultipleClicks(auditHandle,1)"><span style="margin-right: 6px"></span>审核通过</div>
</div>
</div>
</div>
</div>
<van-popup
v-model="areaShow"
closeable
position="bottom"
>
<van-area title="标题" :area-list="areaList" :columns-num="2" closeable="true" :value="form.areaCode ? String(form.areaCode) : ''"
@cancel="areaShow = false" @confirm="confirmHandle"/>
</van-popup>
</div>
</template>
<script>
import {publishCarInfo,carInfoDetail,auditCarInfo} from "@/api/secondHandCar"
import {myMixins} from "@/utils/myMixins"
import uploadCommon from "@/views/secondHandCar/components/upload-common.vue";
import {areaList} from "@vant/area-data";
export default {
name: "carSource",
mixins:[myMixins],
components:{uploadCommon},
data(){
return{
form:{
id:'',
type:1,
vehicleLicensePhoto:'',
vehicleAnglePhoto:'',
vehicleRearPhoto: '',
otherPhoto:'',
licenseType:'',
brandModel:'',
vinCode:'',
plateNumber:'',
vehicleFrontLicensePlate:'',
registerDate:'',
vehicleType:'',
boardType:'',
emissionStandard:'',
areaCode:'',
mileage:'',
contactNumber:'',
minPrice:'',
desc:'',
underpanBrand: '',
brakeSystem: '',
},
radio: 0,
type:'',//1为发布&修改 2为审核
id:'',
queryType:'',
areaList: areaList,
areaShow:false,
noClick:true,
auditRemark:'',
auditReason:'',
areaName:'',
vehicleLicensePhotoList:[],
vehicleAnglePhotoList:[],
vehicleRearPhotoList: [],
otherImgSrcList:[],
otherImgSrc:[],
status:'',
supplierName:'',
supplierCode:'',
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.type=this.$route.query.type || urlParams.get('type');
this.id=this.$route.query.id || urlParams.get('id');
this.queryType=this.$route.query.queryType || urlParams.get('queryType');
if( this.id){
let res = await carInfoDetail({
id:this.id,
queryType:this.queryType ,
})
this.form={...res.data}
this.form.licenseType=res.data.licenseType?.code
this.form.boardType=res.data.boardType?.code
this.form.emissionStandard=res.data.emissionStandard?.code
this.auditRemark=res.data?.auditRemark
this.status=res.data?.status?.code
const municipalities = ['北京市', '天津市', '上海市', '重庆市'];
const isMunicipality = municipalities.some(city => res.data.areaName.includes(city));
this.areaName= isMunicipality ? res.data.areaName?.substring(0, 3) : res.data.areaName;
this.supplierName=res.data?.supplierName
this.supplierCode=res.data?.supplierCode
if(res.data?.otherPhoto){
this.otherImgSrc=res.data.otherPhoto?.split(',')
this.otherImgSrc?.map(item=>this.otherImgSrcList.push({url:item}))
}
this.vehicleLicensePhotoList=[{url:res.data?.vehicleLicensePhoto}]
this.vehicleAnglePhotoList=[{url:res.data?.vehicleAnglePhoto}]
this.vehicleRearPhotoList = [{ url: res.data?.vehicleRearPhoto }]
}
let carSourceFormInfo=localStorage.getItem("carSourceFormInfo") ? JSON.parse(localStorage.getItem("carSourceFormInfo")) : ''
if(!carSourceFormInfo){
return
}
this.form={...carSourceFormInfo.form}
this.radio=carSourceFormInfo.radio
this.areaName=carSourceFormInfo.areaName
if(this.form?.otherPhoto){
this.otherImgSrc=this.form.otherPhoto?.split(',')
this.otherImgSrc?.map(item=>this.otherImgSrcList.push({url:item}))
}
if(this.form.vehicleLicensePhoto){
this.vehicleLicensePhotoList=[{url:this.form.vehicleLicensePhoto}]
}
if(this.form.vehicleAnglePhoto){
this.vehicleAnglePhotoList=[{url:this.form.vehicleAnglePhoto}]
}
if( this.form.vehicleRearPhoto ) {
this.vehicleRearPhotoList = [{url: this.form.vehicleRearPhoto}]
}
// console.log("carSourceFormInfo",carSourceFormInfo)
if(carSourceFormInfo.otherImgSrc0){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc0)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc0})
}
if(carSourceFormInfo.otherImgSrc1){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc1)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc1})
}
if(carSourceFormInfo.otherImgSrc2){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc2)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc2})
}
if(carSourceFormInfo.otherImgSrc3){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc3)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc3})
}
if(carSourceFormInfo.otherImgSrc4){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc4)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc4})
}
if(carSourceFormInfo.otherImgSrc5){
this.otherImgSrc.push(carSourceFormInfo.otherImgSrc5)
this.otherImgSrcList.push({url:carSourceFormInfo.otherImgSrc5})
}
// console.log("--",this.vehicleLicensePhotoList,this.vehicleAnglePhotoList,this.otherImgSrcList)
},
methods:{
validatePrice(value) {
if (value?.startsWith(0) && value?.length > 1) {
this.$nextTick(() => {
this.form.minPrice = 0
})
}
},
clearStorageFormInfo(){
localStorage.setItem("carSourceFormInfo",'')
},
backHandle(){
if(this.$route.query.homePage){//返回列表
this.$router.push({ name: "indexList"})
}else{//返回我的发布
this.$router.push({ name: "mineRelease"})
}
this.clearStorageFormInfo()
},
viewPrivacy(){
let data={
form:this.form,radio:this.radio,areaName:this.areaName,
otherImgSrc0: this.otherImgSrc[0],
otherImgSrc1: this.otherImgSrc[1],
otherImgSrc2:this.otherImgSrc[2],
otherImgSrc3:this.otherImgSrc[3],
otherImgSrc4:this.otherImgSrc[4],
otherImgSrc5:this.otherImgSrc[5],
}
localStorage.setItem("carSourceFormInfo",JSON.stringify(data))
this.$router.push({ name: "privacyComponent"})
},
confirmHandle(val){
if(val[0].name.includes('市')){
this.areaName=val[0].name
this.form.areaCode=val[0].code
}else{
this.areaName=val[0].name +val[1].name
this.form.areaCode=val[1].code
}
this.areaShow=false
},
getDrivingLicense(data){
console.log("getDrivingLicense",data)
this.form.vehicleLicensePhoto=data.url
this.form.brandModel=data.info.model
this.form.vinCode=data.info.vin
this.form.plateNumber=data.info.plateNo
this.form.registerDate=data.info.registerDate +' 00:00:00'
// this.form.vehicleType=data.info.vehicleType
},
deleteImg1(){
this.form.vehicleLicensePhoto=''
},
getPlateColor(data){
console.log("getPlateColor",data)
this.form.vehicleAnglePhoto=data.url
this.form.licenseType=data.colorStatus
this.form.vehicleFrontLicensePlate=data.plateType
},
deleteImg2(){
this.form.vehicleAnglePhoto=''
},
getOtherImg(data){
this.otherImgSrc.push(data.url)
},
getBackPhoto(data) {
console.log("datadata",data)
this.form.vehicleRearPhoto = data.url
},
deleteImgBack() {
this.form.vehicleRearPhoto = '';
},
handleDeleteOtherImg(file,index) {
this.otherImgSrc = this.otherImgSrc.filter((item,i) => index !== i);
this.otherImgSrcList = this.otherImgSrcList.filter((item,i) => index !== i);
},
// 审核操作
async auditHandle(type){
if (!type && !this.auditReason){
this.$toast('请填写不通过原因')
return
}
if (!this.form.vehicleLicensePhoto) {
this.$toast('行驶证不能为空')
return
}
if (!this.form.vehicleAnglePhoto) {
this.$toast('车辆45度不能为空')
return
}
if(!this.form.vehicleRearPhoto && type == 1) {
this.$toast('车辆后方45度不能为空')
return
}
let flag=this.validateHandle()
if(flag){
this.$toast(flag)
return
}
if (this.form.vehicleType=='平板拖车' && !this.form.boardType) {
this.$toast('落板方式不能为空')
return
}else if(this.form.vehicleType !=='平板拖车'){
this.form.boardType=''
}
let rule
if( type == 1 ) {
rule = this.validationRules.find(item =>
item.value === null ||
item.value === undefined ||
item.value === ''
)
} else {
rule = this.validationRulesSimple.find(item =>
item.value === null ||
item.value === undefined ||
item.value === ''
)
}
if(rule){
this.$toast(rule.name)
return
}
try {
await auditCarInfo({
id: this.id,
auditResult: type ? 1 : 0 ,
auditReason: this.auditReason,
...this.form,
otherPhoto:this.otherImgSrc?.join(',')
})
this.clearStorageFormInfo()
setTimeout(()=>{
this.closeParentDialog()
},1000)
} finally {
console.log(type)
}
},
// 发布车源
async submitHandle(){
if (!this.radio) {
this.$toast('请勾选我已阅读并同意')
return
}
if (!this.form.vehicleLicensePhoto) {
this.$toast('行驶证不能为空')
return
}
if (!this.form.vehicleAnglePhoto) {
this.$toast('车辆45度不能为空')
return
}
if(!this.form.vehicleRearPhoto) {
this.$toast('车辆后方45度不能为空')
return
}
let flag=this.validateHandle()
if(flag){
this.$toast(flag)
return
}
if (this.form.vehicleType=='平板拖车' && !this.form.boardType) {
this.$toast('落板方式不能为空')
return
}else if(this.form.vehicleType !=='平板拖车'){
this.form.boardType=''
}
let rule = this.validationRules.find(item =>
item.value === null ||
item.value === undefined ||
item.value === ''
)
if(rule){
this.$toast(rule.name)
return
}
try {
let res = await publishCarInfo({
...this.form,
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)
} finally {
console.log(111)
}
},
// 手机号验证方法
validateHandle() {
const contactNumberPattern = /^1[3-9]\d{9}$/; // 手机号正则表达式
let str=''
if (!this.form.contactNumber) {
str='联系方式不能为空'
// return
} else if (!contactNumberPattern.test(this.form.contactNumber)) {
str='联系方式格式错误'
} else {
str=''
}
return str
},
},
computed: {
validationRules() {
return [
{ value: this.form.vehicleType, name: '车辆类型不能为空' },
{ value: this.form.emissionStandard, name: '排放标准不能为空' },
{ value: this.form.brakeSystem, name: '刹车系统不能为空' },
{ value: this.form.areaCode, name: '所在城市不能为空' },
{ value: this.form.mileage, name: '行驶里程不能为空' },
{ value: this.form.contactNumber, name: '联系方式不能为空' },
{ value: this.form.minPrice, name: '售价不能为空' },
{ value: this.form.underpanBrand, name: '底盘品牌不能为空' },
];
},
validationRulesSimple() {
return [
{ value: this.form.vehicleType, name: '车辆类型不能为空' },
{ value: this.form.emissionStandard, name: '排放标准不能为空' },
{ value: this.form.areaCode, name: '所在城市不能为空' },
{ value: this.form.mileage, name: '行驶里程不能为空' },
{ value: this.form.contactNumber, name: '联系方式不能为空' },
{ value: this.form.minPrice, name: '售价不能为空' },
];
},
},
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
}
.headerWrap{
width: 100%;
box-sizing: border-box;
padding-top: 15px;
padding-bottom: 15px;
position: relative;
.navWrap{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 0 16px 10px;
}
.bg{
position: absolute;
width: 100%;
height: 120px;
line-height: 120px;
top: 0;
left: 0;
opacity: 0.5;
z-index: -1;
}
.back{
@include wh(15px,15px);
}
.navIcon{
@include wh(84px,21px);
}
.audit{
@include wh(100%,43px);
background: #FFF7F4;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
color: #FF6B3B;
.noAudit{
@include wh(13px,12px);
margin-right: 5px;
vertical-align: bottom;
}
span:first-child{
font-weight: 600;
}
}
.supplierInfo{
justify-content: space-around;
background-color: #F5F7F9;
color: #606266;;
}
}
.navBar{
margin-bottom: 46px;
}
.noContentAudit{
height: calc(100% - 42px);
}
//100px
.hasContentAudit{
height: calc(100% - 85px);
}
.contentWrap{
width: 100%;
overflow-y: auto;
.sort{
@include wh(91px, 19px);
margin-bottom: 15px;
}
.line{
width: 100%;
border-bottom: 1px solid #F2F2F2;
margin-top: 26px;
margin-bottom: 17px;
}
.lastLine{
margin-top: 3px !important;
}
.content{
width: 100%;
box-sizing: border-box;
padding: 0 14px 0 20px;
//padding:0 20px;
}
.oneContent{
.uploadWrap{
display: flex;
flex-wrap: wrap;
//justify-content: space-between;
}
}
.twoContent{
.ocrInfo{
background: #FAFBFC;
border-radius: 4px;
}
.item{
display: flex;
//align-items: center;
font-weight: 400;
font-size: 13px;
color: #2C3D54;
line-height: 44px;
width: 100%;
box-sizing: border-box;
padding-left: 21px;
padding-right: 9px;
span:first-child{
display: inline-block;
width:70px;
font-size: 13px;
color: rgba(44, 61, 84, 0.59);
}
span:last-child{
display: inline-block;
width:calc(100% - 70px);
border-bottom: 1px solid #E9E9EA;
}
.orc{
box-sizing: border-box;
padding-left: 6px;
}
}
.vehicleTypeItem{
line-height: 13px !important;
margin-top: 8px;
}
.star{
color: #FF4B4B !important;
opacity: 1 !important;
font-weight: bold;
font-size: 12px;
margin-right: 6px;
margin-left: -6px;
}
.radioWrap{
width:calc(100% - 70px);
border-bottom: 1px solid #E9E9EA;
}
}
.threeContent{
.checkedWrap{
cursor: pointer;
color:#808D99 ;
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
margin-bottom: 10px;
font-size: 12px;
.radioIcon{
@include wh(16px, 16px);
margin-right: 6px;
}
span:last-child{
color: #0E76F4;
}
}
.btnWrap{
padding-bottom: 20px;
padding-top: 15px;
}
.commonBtn{
height: 46px;
line-height: 46px;
text-align: center;
font-weight: bold;
border-radius: 5px;
color: #FFFFFF;
cursor: pointer;
}
.btn{
width: 296px;
background: #4A7FEB;
margin: 0 auto;
font-size: 15px;
}
.auditBtn{
display: flex;
justify-content: space-between;
font-size: 14px;
box-sizing: border-box;
padding: 0 6px;
div:first-child{
width: 100px;
opacity: 0.79;
background: #1C2C49;
}
div:last-child{
width: 200px;
background: #4A7FEB;
}
}
}
}
::v-deep .van-icon-success{
display: none !important;
}
::v-deep .van-radio__label{
margin-left: 0;
width: 54px;
height: 23px;
border-radius: 13px;
border: 1px solid #9F9F9F;
opacity: 0.5;
text-align: center;
line-height: 23px;
font-size: 12px;
color: #323233;
opacity: 1;
}
::v-deep .van-radio--horizontal{
margin-right: 4px;
}
::v-deep .van-radio--horizontal:last-child{
margin-right: 0;
}
::v-deep .checked .van-radio__label{
background: #FFF1EC !important;
border: 1px solid #FF5C26 !important;
color: #FE5006 !important;
border-radius: 13px !important;
}
::v-deep .van-field__right-icon{
margin-right: 0;
padding: 0;
}
::v-deep .ipt .el-textarea__inner{
background: #F5F7F9;
border-radius: 4px;
//opacity: 0.74;
font-size: 12px;
border: none;
}
::v-deep .van-popup__close-icon--top-right{
display: none;
}
::v-deep .vehicleRadio .van-radio__label{
margin-bottom: 8px !important;
}
</style>

View File

@ -0,0 +1,260 @@
<template>
<van-uploader
v-model="filesList"
:after-read="handleFileRead"
:before-delete="deleteHandle"
:preview-size="103"
accept="image "
:preview-full-image="false"
:max-count="multiple ? 6 : 1"
@click-preview="handlePreviewClick"
>
<div class="upload">
<img class="icon" src="@/assets/secondHandCar/upload.png"/>
<span class="text">{{ displayText }}</span>
</div>
<template v-if="text.includes('其他照片')" #preview-cover="{ index }">
<div class="preview-cover van-ellipsis">{{ index + 1 }}/6</div>
</template>
</van-uploader>
</template>
<script>
import { ImagePreview } from 'vant';
import {unifiedOCRWithCompress, uploadImage} from "@/api/mine";
export default {
name: "uploadCommon",
props: {
text: {
type: String,
default: ''
},
multiple: {
type: Boolean,
default: false
},
files: {
type: Array,
default: () => []
}
},
data() {
return {
filesList: [],
}
},
watch: {
files: {
immediate: true,
deep:true,
handler(newVal) {
this.$nextTick(() => {
this.filesList = newVal || [];
})
},
},
filesList: {
handler(newVal) {
this.$emit("update:files", newVal);
},
deep: true,
},
},
computed: {
displayText() {
if (this.text === "其他照片0/6") {
return `其他照片 ${this.filesList.length}/${this.multiple ? 6 : 1}`;
}
return this.text;
},
},
methods: {
// 点击预览图片时触发
handlePreviewClick(file, detail) {
this.showFullScreenPreview(file.url || file.content,detail);
},
// 全屏预览
showFullScreenPreview(imageUrl,detail) {
const images = this.filesList.map(file => file.url || file.content); // 所有图片的 URL
ImagePreview({
images,
startPosition: detail.index,
closeable: true,
onClose: () => {}
});
},
async deleteHandle(file, detail) {
this.filesList = this.filesList.filter((item, i) => i !== detail.index);
if (this.text === "行驶证照片") {
this.$emit("delete1");
} else if (this.text === "车辆45度照") {
this.$emit("delete2");
} else if(this.text == '车辆后方45度') {
this.$emit("delete4");
} else {
console.log("file, detail", file, detail)
this.$emit("delete3", file, detail.index);
}
return true;
},
async handleFileRead(file) {
const formData = new FormData();
if(!file.file){
this.$toast('获取文件失败,请重新上传')
}
formData.append("file", file.file);
let res = await uploadImage(formData);
// 为文件添加唯一标识符
file.uid = Date.now(); // 使用时间戳作为唯一标识符
if (this.text == '行驶证照片') {
// 行驶证识别
let result = await unifiedOCRWithCompress({
ocrType: 3,
imageUrl: res.data,
cardSide: 'FRONT'
});
let data = {url: res?.data, info: {...result?.data?.frontInfo}}
this.$emit('success1', data)
} else if (this.text == '车辆45度照') {
let result = await unifiedOCRWithCompress({
ocrType: 10,
imageUrl: res.data,
cardSide: 'FRONT'
});
let num = this.getVehicleLicense(result.data.color)
let data = {url: res?.data, colorStr: result.data.color, colorStatus: num, plateType: result.data.number}
this.$emit('success2', data)
} else if(this.text == '车辆后方45度') {
this.$emit('success4', {url: res?.data, uid: file.uid})
} else {
this.$emit('success3', {url: res?.data, uid: file.uid})
}
},
getVehicleLicense(color) {
let vehicleLicense = ''
if (color == '蓝') {
vehicleLicense = 1
} else if (color == '黄') {
vehicleLicense = 2
} else if (color == '临牌') {
vehicleLicense = 4
} else if (color.includes('绿')) {
vehicleLicense = 3
} else {
vehicleLicense = 5
}
return vehicleLicense
},
}
}
</script>
<style scoped lang="scss">
.preview-image {
width: 100%;
height: 100%;
object-fit: cover;
cursor: pointer; /* 鼠标悬停时显示手型 */
}
.custom-preview {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.custom-preview img {
max-width: 90%;
max-height: 90%;
}
.close-icon {
position: absolute;
top: 20px;
right: 20px;
color: #fff;
font-size: 24px;
cursor: pointer;
}
.preview-cover {
position: absolute;
bottom: 0;
box-sizing: border-box;
width: 100%;
padding: 4px;
color: #fff;
font-size: 12px;
text-align: center;
background: rgba(0, 0, 0, 0.3);
}
::v-deep .van-uploader {
margin-bottom: 5px;
}
.upload {
position: relative;
width: 103px;
height: 70px;
background: #F1F6FF;
box-shadow: 0px 0px 2px 0px rgba(235, 235, 235, 0.38);
border-radius: 4px;
border: 1px solid #B8CBE9;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding-top: 14px;
padding-bottom: 3px;
.icon {
width: 30px;
height: 30px;
}
.text {
width: 80px;
background: #5A6FFF;
border-radius: 7px;
opacity: 0.9;
text-align: center;
font-weight: 600;
font-size: 11px;
color: #FFFFFF;
}
}
::v-deep .van-uploader__preview {
margin: 0 4px 4px 0;
}
::v-deep .van-uploader__input-wrapper {
margin: 0 4px 4px 0;
}
::v-deep .van-uploader__preview-image {
height: 70px !important;
border-radius: 4px !important;
}
::v-deep .van-uploader__preview-delete {
background-image: url('@/assets/secondHandCar/delete.png'); /* 替换为你的图片路径 */
background-size: cover;
background-color: transparent;
border: none;
width: 15px;
height: 15px;
}
::v-deep .van-uploader__preview-delete-icon {
display: none !important; /* 强制隐藏伪元素 */
}
</style>

View File

@ -0,0 +1,402 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<div v-if="isWebFunc()" style="opacity: 0;" class="back"></div>
<img v-else class="back" @click="h5GoBack" src="@/assets/secondHandCar/back.png" />
<span>在售</span>
<div style="opacity: 0;" class="back"></div>
</div>
<van-loading v-show="!detailInfo" class="loadingWrap" type="spinner" color="#1989fa" />
<div class="contentWrap" v-show="detailInfo">
<el-carousel v-if="isWebFunc()" trigger="click" height="215px" :autoplay="true">
<el-carousel-item v-for="(item,i) in imgSrcList" :key="i">
<el-image
:src="item"
v-if="item"
:preview-src-list="[item]"
class="swipeImg"
/>
<!-- <img v-if="item" class="swipeImg" :src="item" />-->
</el-carousel-item>
</el-carousel>
<van-swipe v-else @change="onChange" :autoplay="3000">
<van-swipe-item v-for="(item,i) in imgSrcList" :key="i" @click="showImagePreview(i)">
<img v-if="item" class="swipeImg" :src="item" />
</van-swipe-item>
<template #indicator>
<div class="custom-indicator">{{ current + 1 }}/{{imgSrcList.length}}</div>
</template>
</van-swipe>
<div class="infoWrap">
<div class="titleWrap wrapCommon">
<div class="info">
<span>{{ detailInfo.vehicleType }}</span>
<span>{{ detailInfo.boardType?.label }}</span>
<span>{{ detailInfo.licenseType?.label }}</span>
<span>{{detailInfo.brandModel?.match(/^[\u4e00-\u9fa5]+/)?.[0]?.replace(/牌$/, '')}}</span>
<span>{{ formatToWan(detailInfo.mileage) }}公里</span>
<span>{{ detailInfo.emissionStandard?.label }}</span>
</div>
<div class="time">
<span>{{ detailInfo.createTime?.substring(0,10) }}</span><span>{{ detailInfo.areaName }}</span><span>发布</span>
</div>
<div class="price">
售价含税
<span>{{ formatNumber(detailInfo.minPrice) }}</span>
<span></span>
</div>
</div>
<div class="detailInfoWrap wrapCommon">
<div>
<img class="descImg firstDescImg" src="@/assets/secondHandCar/details.png" />
</div>
<div class="descItem descCommon">
<div class="itemInfo">
<span>{{ detailInfo.licenseType?.label }}</span>
<span>牌照类型</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<span>{{ detailInfo.vehicleType }}</span>
<span>车辆类型</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<span>{{ detailInfo.boardType?.label }}&nbsp;&nbsp;</span>
<span>落板方式</span>
</div>
</div>
<div class="descItem descCommon">
<div class="itemInfo">
<span>{{detailInfo.brandModel?.match(/^[\u4e00-\u9fa5]+/)?.[0]?.replace(/牌$/, '')}}</span>
<span>上装品牌</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<span>{{ detailInfo.emissionStandard?.label }}</span>
<span>排放标准</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<el-tooltip class="item" effect="dark" :content="formatToWan(detailInfo.mileage)+'公里'" placement="top">
<span style="display: inline-block;width:100%;cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">{{ formatToWan(detailInfo.mileage)}}公里</span>
</el-tooltip>
<span>行驶公里</span>
</div>
</div>
<div class="descItem descCommon">
<div class="itemInfo dateItemInfo">
<span>{{ detailInfo.registerDate?.substring(0,10) }}</span>
<span>注册日期</span>
</div>
</div>
<div>
<img class="descImg" src="@/assets/secondHandCar/description1.png" />
</div>
<div class="descCommon desc">{{detailInfo.desc}}</div>
</div>
<div class="btnWrap" >
<div v-if="isList && !detailInfo.selfSupplierPublish" class="btn commonBtn" @click="noMultipleClicks(handle)">我想要</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {carInfoDetail,saveRecord} from "@/api/secondHandCar";
import { ImagePreview, Dialog } from 'vant';
export default {
name: "forSale",
mixins:[myMixins],
data(){
return{
current: 0,
noClick:true,
id:'',
queryType:'',
detailInfo:'',
imgSrcList:[],
duration:'',
startTime: null, // 记录进入时间
recordType:1,
isList:false,//是否是首页列表跳转过来的
}
},
async mounted() {
window.addEventListener('message', (event) => {
if (event.data === 'dialogClosed') {
console.log('Dialog 已关闭');
this.getDuration(1)
// 执行关闭后的逻辑
}
});
this.startTime = new Date();
const urlParams = new URLSearchParams(window.location.search);
this.id=this.$route.query.id || urlParams.get('id');
this.queryType=this.$route.query.queryType || urlParams.get('queryType');
this.isList=this.$route.query.isList || urlParams.get('isList');
if( this.id){
let res = await carInfoDetail({
id:this.id,
queryType:this.queryType ,
})
this.detailInfo=res?.data
const municipalities = ['北京市', '天津市', '上海市', '重庆市'];
const isMunicipality = municipalities.some(city => res.data.areaName.includes(city));
this.detailInfo.areaName= isMunicipality ? res.data.areaName?.substring(0, 3) : res.data.areaName;
if(res.data.otherPhoto){
this.imgSrcList=res.data.otherPhoto.split(',') || []
}
if( res?.data?.vehicleRearPhoto ) {
this.imgSrcList.unshift(res?.data?.vehicleRearPhoto)
}
this.imgSrcList.unshift(res?.data?.vehicleAnglePhoto)
}
},
destroyed() {
this.getDuration(1)
},
methods:{
showImagePreview(index) {
ImagePreview({
images: this.imgSrcList.map(item => item),
startPosition: index,
closeable: true
});
},
formatToWan(num) {
let result = (num / 10000).toString(); // 转换为万单位
if (result.includes('.')) {
let decimalPart = result.split('.')[1]; // 获取小数部分
if (decimalPart.length > 1) {
result = parseFloat(result).toFixed(1); // 保留一位小数
}
}
return result + '万';
},
getDuration(type){
// 页面卸载时记录离开时间并计算浏览时长
const endTime = new Date();
const duration = (endTime - this.startTime) / 1000; // 计算时长(秒)\
this.saveRecord(duration,type);
},
async saveRecord(duration,type){
await saveRecord({type: type, carInfoId: this.id, duration})
},
handle(){
this.getDuration(2)
Dialog.alert({
message:this.detailInfo.contactNumber ,
confirmButtonText:'拨打电话',
showCancelButton:true,
}).then(async() => {
window.location.href = `tel:${this.detailInfo.contactNumber}`;
}).catch(() => {
// on cancel
});
},
onChange(index) {
this.current = index;
},
}
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
background-color: #F6F6F6;
}
.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% - 42px);
text-align: center;
line-height: 200px;
}
.contentWrap{
height: calc(100% - 42px);
overflow-y: auto;
.infoWrap{
box-sizing: border-box;
padding: 0 6px;
margin-top: -15px;
position: relative;
z-index: 111;
}
.wrapCommon{
width: 100%;
background: #FFFFFF;
border-radius: 6px;
backdrop-filter: blur(5.602678571428572px);
box-sizing: border-box;
margin-bottom: 12px;
}
.titleWrap{
height: 108px;
padding: 18px 0 15px 21px;
display: flex;
flex-direction: column;
justify-content: space-between;
.info{
font-weight: 600;
font-size: 15px;
color: #212020;
line-height: 21px;
span{
margin-right: 10px;
}
}
.time{
font-weight: 400;
font-size: 12px;
color: #999999;
line-height: 17px;
span:first-child{
margin-right: 20px;
}
span:last-child{
margin-left: 10px;
}
}
.price{
color: #FF5533;
line-height: 28px;
font-weight: 600;
span:first-child{
font-size: 20px;
margin-right: 4px;
}
span:last-child{
font-size: 11px;
}
}
}
.detailInfoWrap{
box-sizing: border-box;
padding: 18px 28px 15px 22px;
.descImg{
@include wh(72px, 19px);
}
.firstDescImg{
margin-bottom: 24px;
}
.descCommon{
width: 100%;
box-sizing: border-box;
padding-left: 15px;
}
.descItem{
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 20px;
}
.dateItemInfo{
width: 40% !important;
}
.itemInfo{
display: flex;
flex-direction: column;
width: 23%;
span:first-child{
font-weight: bold;
font-size: 14px;
color: #282828;
line-height: 20px;
margin-bottom: 2px;
}
span:last-child{
font-weight: 400;
font-size: 10px;
color: #999999;
line-height: 14px;
}
}
.suGang{
width: 1px;
height: 8px;
border-right: 1px solid #999999;
opacity: 0.5;
}
.desc{
font-weight: 400;
font-size: 12px;
color: #282828;
margin-top: 10px;
}
}
.btnWrap{
padding-bottom: 20px;
}
.commonBtn{
height: 46px;
line-height: 46px;
text-align: center;
font-weight: bold;
border-radius: 5px;
color: #FFFFFF;
cursor: pointer;
}
.btn{
width: 296px;
background: #4A7FEB;
margin: 0 auto;
font-size: 15px;
}
}
.custom-indicator {
position: absolute;
right: 5px;
bottom: 20px;
padding: 2px 5px;
font-size: 12px;
background: rgba(0, 0, 0, 0.1);
color: wheat;
}
.van-swipe-item{
height: 215px;
background-color: pink;
}
.swipeImg{
width: 100%;
height: 100%;
object-fit: cover; /* 保持比例填充容器,裁剪多余部分 */
object-position: center; /* 居中显示 */
}
::v-deep .el-carousel__button {
height: 0.15rem !important;
width: 0.3rem;
}
::v-deep .el-carousel__indicators--horizontal {
padding: 0.32rem 0.08rem;
}
::v-deep .el-carousel__arrow {
background-color: rgba(31, 45, 61, 1);
font-size: 0.5rem;
}
::v-deep .el-carousel__indicators--horizontal {
bottom: 10px;
}
</style>

View File

@ -0,0 +1,684 @@
<template>
<div class="wrap">
<div class="navBar">
<van-nav-bar
title="二手车信息"
left-arrow
left-arrow-color="#FFFFFF"
:border="false"
:fixed="true"
:safe-area-inset-top="true"
@click-left="goBack"
/>
</div>
<div class="headerWrap">
<img class="bg" src="@/assets/secondHandCar/bg.png" />
<img class="mine" src="@/assets/secondHandCar/mine.png" @click="goMine" />
<el-input
@blur="getList"
placeholder="请输入"
v-model.trim="topSearch">
<img slot="suffix" class="search" src="@/assets/secondHandCar/search.png"/>
</el-input>
</div>
<div class="firstTab">
<div>
<img class="big com" v-show="activeTab === 0" src="@/assets/secondHandCar/cheyuanBig.png" @click="tabClick(0)" />
<img class="small com" v-show="activeTab === 1" src="@/assets/secondHandCar/cheyuanSmall.png" @click="tabClick(0)"/>
<img class="big" v-show="activeTab === 1" src="@/assets/secondHandCar/qiugouBig.png" @click="tabClick(1)"/>
<img class="small" v-show="activeTab === 0" src="@/assets/secondHandCar/qiugouSmall.png" @click="tabClick(1)"/>
</div>
<div @click="poupShow = true">
<img class="suggest" src="@/assets/secondHandCar/suggest.png" />
</div>
</div>
<div class="filterWrap">
<el-select v-model="licenseType" placeholder="牌照类型" :class="{'customSel':true , 'has-value': licenseType }" clearable>
<el-option
v-for="item in licenseTypeOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="vehicleType" placeholder="车辆类型" :class="{'customSel':true , 'has-value': vehicleType }" clearable>
<el-option
v-for="item in vehicleTypeOption"
:key="item.value"
:label="item.label"
:value="item.label">
</el-option>
</el-select>
<div class="customSel priceSel" @click.stop="changePrice">
<span :class="{'has-price': priceSort }">价格</span>
<span class="iconSpan">
<van-icon :class="{'has-price': priceSort==1 ,'icon':true}" name="arrow-up" />
<van-icon :class="{'has-price': priceSort==2 ,'icon':true}" name="arrow-down" />
</span>
<span v-show="priceSort"><van-icon @click.stop="clearPrice" :class="{'has-price': priceSort ,'icon':true}" name="close" /></span>
</div>
<el-select v-model="emissionStandard" placeholder="排放标准" :class="{'customSel':true , 'has-value': emissionStandard }" clearable>
<el-option
v-for="item in emissionStandardOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="boardType" placeholder="落板方式" :class="{'customSel':true , 'has-value': boardType }" clearable>
<el-option
v-for="item in boardTypeOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="proprietary" placeholder="发布方" :class="{'customSel':true , 'has-value': (proprietary || proprietary === 0) ? true : false }" clearable>
<el-option
v-for="item in proprietaryOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<div class="contentWrap" v-show="!show">
<van-pull-refresh v-model="isLoading" @refresh="onRefresh" style="min-height:85vh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div class="contentItem">
<div class="item" v-for="(item,index) in pageList" :key="index" @click="viewCarSource(item)">
<div class="left">
<img class="owner_logo" v-if="item.proprietary == 1" src="@/assets/secondHandCar/icon_zdOwner.png" alt="">
<img class="saled_logo" v-if="item.status.code == 6 && item.downReason == '已售出'" src="@/assets/secondHandCar/icon_saled.png" alt="">
<img class="img" v-if="item.vehicleAnglePhoto" :src="item.vehicleAnglePhoto" />
<div v-else class="qiugou">{{item.vehicleType?.substring(0,2)}}</div>
</div>
<div class="right">
<div class="title">{{item.vehicleType}}</div>
<div v-if="activeTab==0" class="type">{{ item.boardType?.label ? item.boardType?.label+' | ' : ''}} {{ item.licenseType?.label }} |
{{ item.brandModel?.match(/^[\u4e00-\u9fa5]+/)?.[0]?.replace(/$/, '') }} | {{item.emissionStandard?.label}} | {{ formatToWan(item.mileage) }}公里</div>
<div v-else class="type">{{ item.boardType?.label ? item.boardType?.label+' | ' : ''}} {{item.emissionStandard?.label}}</div>
<div class="date" v-show="activeTab==0 && item.registerDate">注册日期 {{item.registerDate?.substring(0,10)}}</div>
<div v-if="activeTab==0" class="price">售价含税<span></span> <span>{{formatNumber(item.minPrice) }}</span> <span></span> </div>
<div v-else class="priceRange">
售价含税
<span class="num">{{formatNumber(item.minPrice) }}</span> <span class="danwei"></span>
<span class="su">~</span>
<span class="num">{{formatNumber(item.maxPrice) }}</span> <span class="danwei"></span>
</div>
<div class="line"></div>
</div>
</div>
</div>
</van-list>
</van-pull-refresh>
</div>
<div class="empty" v-show="show">
<img src="@/assets/empty.png" />
</div>
<img v-show="activeTab==0" @click="releaseHandle(1)" class="fixImg" src="@/assets/secondHandCar/sellCar.png" />
<img v-show="activeTab==1" @click="releaseHandle(2)" class="fixImg" src="@/assets/secondHandCar/buyCar.png" />
<van-popup v-model="poupShow" closeable round :style="{ width: '90%' }" class="poupWrap">
<span class="title">反馈建议</span>
<div class="poupContent">
<div class="tip">如有任何建议请及时反馈我们</div>
<el-input class="ipt" v-model.trim="suggestContent" type="textarea" :autosize="{ minRows: 6, maxRows: 10 }"
maxlength="500" show-word-limit></el-input>
<div class="btnWrap">
<div class="btn" @click="submitSuggest">提交</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {appPageList,userFeedback } from "@/api/secondHandCar"
export default {
name: "indexList",
mixins:[myMixins],
watch:{
/* topSearch(){
this.setSearchVal();
this.getList()
},*/
licenseType(){
this.setSearchVal();
this.getList()
},
vehicleType(){
this.setSearchVal();
this.getList()
},
emissionStandard(){
this.setSearchVal();
this.getList()
},
boardType(){
this.setSearchVal();
this.getList()
},
proprietary() {
this.setSearchVal();
this.getList()
}
},
data(){
return{
pageList:[],
topSearch:'',
activeTab:0,
isLoading:"",
loading: false,
finished: false,
pageNum:1,
pageSize:10,
total:'',
licenseType:'',
vehicleType:'',
priceSort:'',
emissionStandard:'',
boardType:'',
proprietary: '',
licenseTypeOption:[
{value:2,label:'黄牌'},{value:3,label:'绿牌'},{value:1,label:'蓝牌'},
],
vehicleTypeOption:[
{value:1,label:'拖车'},{value:2,label:'地库车'},{value:3,label:'牵引车'},{value:4,label:'随车吊'},{value:5,label:'其他'},
],
priceOption:[
{value:1,label:'5~6'},{value:2,label:'7~8'},{value:3,label:'8~9'}
],
emissionStandardOption:[
{value:1,label:'不限'},{value:3,label:'国三'},{value:4,label:'国四'},{value:5,label:'国五'},{value:6,label:'国六'}
],
boardTypeOption:[
{value:1,label:'全落地'},{value:2,label:'斜落一体'},{value:3,label:'普通斜板'},{value:9,label:'不限'}
],
proprietaryOption: [{value: 1, label: '中道自营'}, {value: 0, label: '服务商发布'}],
poupShow:false,
suggestContent:'',
}
},
mounted() {
this.getSearchVal();
this.getList();
document.addEventListener('visibilitychange', async ( ) => {
let state = document.visibilityState
if (state == 'hidden') { // 用户离开了
}
if (state == 'visible') {
console.log('visible')
}
});
},
methods:{
formatToWan(num) {
let result = (num / 10000).toString();
if (result.includes('.')) {
let decimalPart = result.split('.')[1];
if (decimalPart.length > 1) {
result = parseFloat(result).toFixed(1);
}
}
return result + '万';
},
async tabClick(type){
this.activeTab=type
this.pageNum = 1
this.pageList = [];
this.total=0
await this.setSearchVal();
await this.getList()
},
async onLoad(){
this.pageNum++;
await this.getList()
this.loading = false;
if (this.pageList.length >= this.total) {
this.finished = true;
}
},
changePrice(){
if(!this.priceSort){
this.priceSort=1
}
if( this.priceSort==1){
this.priceSort=2
}else{
this.priceSort=1
}
this.getList();
},
clearPrice(){
this.priceSort=''
this.setSearchVal()
this.getList();
},
setSearchVal(){
sessionStorage.setItem('indexActiveTab',String(this.activeTab) );
sessionStorage.setItem('topSearch',this.topSearch);
sessionStorage.setItem('vehicleType',this.vehicleType);
sessionStorage.setItem('priceSort',this.priceSort);
sessionStorage.setItem('indexActiveTab',String(this.activeTab) );
sessionStorage.setItem('licenseType',String(this.licenseType));
sessionStorage.setItem('emissionStandard',String(this.emissionStandard));
sessionStorage.setItem('boardType',String(this.boardType));
sessionStorage.setItem('proprietary',String(this.proprietary));
},
getSearchVal(){
this.activeTab = Number(sessionStorage.getItem('indexActiveTab')) || 0;
this.topSearch = sessionStorage.getItem('topSearch') || '';
this.vehicleType = sessionStorage.getItem('vehicleType') || '';
this.priceSort = Number(sessionStorage.getItem('priceSort')) || '';
this.licenseType = Number(sessionStorage.getItem('licenseType')) || '';
this.emissionStandard = Number(sessionStorage.getItem('emissionStandard')) || '';
this.boardType = Number(sessionStorage.getItem('boardType')) || '';
this.proprietary = Number(sessionStorage.getItem('proprietary')) || '';
},
goMine(){//我的发布
this.$router.push({ name: "mineRelease"})
sessionStorage.setItem('mineActiveTab',String(1) )
},
viewCarSource(item){
if(this.activeTab===0){//车源查看
this.$router.push({ name: "forSale", query: {type:1 , id:item.id,queryType:1,isList:true }})
}else{//求购查看
this.$router.push({ name: "wantBuySale", query: { type:1 ,id:item.id ,queryType:2,isList:true}})
}
this.setSearchVal();
},
releaseHandle(type){
if(type===1){//车源发布
this.$router.push({
name: "carSource",
query: { type:1,homePage:true }
})
}else{//求购发布
this.$router.push({ name: "wantBuy", query: { type:1,homePage:true } })
}
this.setSearchVal();
},
async submitSuggest(){
if(!this.suggestContent){
this.$toast('反馈提交不能为空')
return
}
//继续提交
await userFeedback ({
content:this.suggestContent,
})
this.poupShow=false
this.suggestContent=''
this.$toast('反馈建议提交成功')
},
onRefresh() {
this.pageNum=1
this.getList()
setTimeout(() => {
this.$toast('刷新成功');
this.isLoading = false;
}, 1000);
},
async getList(){
let res= await appPageList({
pageNum:this.pageNum,
pageSize:this.pageSize,
type:this.activeTab==0 ? 1 : 2,
topSearch:this.topSearch,
licenseType:this.licenseType,
vehicleType:this.vehicleType,
priceSort:this.priceSort,
boardType:this.boardType,
emissionStandard:this.emissionStandard,
proprietary: this.proprietary
})
this.total=res.total
if(this.pageNum == 1){// 第一页直接赋值
this.pageList=res.data
}else{// 第二页数据拼接
let preList = this.pageList;
let arr = res.data;
this.pageList = preList.concat(arr)
}
},
goApp(){
let data = {"action":"goBack","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.sendMessage("goBack");
}
},
},
computed:{
show() {
return (this.pageList.length < 0 || this.pageList.length == 0); // 判断数组长度是否大于 0
},
},
}
</script>
<style scoped lang="scss">
@import "@/styles/common.scss";
@import "@/styles/mixin.scss";
.wrap{
position: relative;
width: 100%;
height: 100%;
}
.navBar{
margin-bottom: 46px;
}
.fixImg{
width: 210px;
height: 102px;
position: fixed;
bottom: 0;
left: 50%;
transform: translateX(-50%);
z-index: 11;
cursor: pointer;
}
.headerWrap{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding-left: 15px;
padding-right: 10px;
padding-top: 10px;
position: relative;
.bg{
position: absolute;
width: 100%;
height: 144px;
top: 0;
left: 0;
z-index: -1;
}
.mine{
width: 55px;
height: 43px;
margin-right: 15px;
}
.search{
width: 17px;
height: 17px;
}
::v-deep .el-input__inner{
background: rgba(255,255,255,0.8);
border-radius: 20px;
border: 2px solid #264B94;
}
::v-deep .el-input__suffix{
top: 12px;
right: 10px;
}
}
.firstTab{
width: 100%;
padding-top: 18px;
display: flex;
justify-content: space-between;
align-items: center;
img{
cursor: pointer;
}
.big,.small{
width: 52px;
height: 21px;
}
.com{
margin-left: 32px;
margin-right: 25px;
}
.suggest{
width: 87px;
height: 38px;
}
}
.filterWrap {
width: calc(100% - 5px);
padding-right: 5px;
display: flex;
/*justify-content: space-around;*/
overflow-x: auto; /* 允许横向滚动 */
white-space: nowrap; /* 防止子元素换行 */
padding-bottom: 10px;
-webkit-overflow-scrolling: touch; /* 在iOS上平滑滚动 */
scrollbar-width: none; /* Firefox */
padding-bottom: 10px;
&::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.customSel {
flex: 0 0 auto; /* 防止子元素被压缩 */
width: 80px;
height: 25px;
background: #F5F5F5;
border-radius: 4px;
font-size: 10px;
color: #323233;
margin-left: 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;
}
}
.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;
}
}
.contentWrap{
width: 100%;
height: calc(100% - 126px);
overflow-y: auto;
background-color: #F2F2F2 ;
box-sizing: border-box;
padding: 10px 6px 0;
.contentItem{
width: 100%;
background-color: #FFFFFF;
border-radius: 10px;
box-sizing: border-box;
padding-left: 8px;
padding-top: 18px;
.item{
display: flex;
justify-content: space-between;
cursor: pointer;
}
.left{
width: 115px;
height: 77px;
position: relative;
.img, .qiugou{
width: 115px;
height: 77px;
border-radius: 7px;
margin-right: 10px;
}
.qiugou{
line-height: 77px;
text-align: center;
color: #FFFFFF;
font-size: 18px;
letter-spacing: 5px;
background-color: #6C81CD;
}
.img {
object-fit: cover; /* 保持比例填充容器,裁剪多余部分 */
object-position: center; /* 居中显示 */
}
.owner_logo {
width: 60px;
height: 23px;
position: absolute;
left: -4px;
top: -3px;
}
.saled_logo {
width: 76px;
height: 48px;
position: absolute;
left: 24px;
top: 16px;
}
}
.right{
.title{
font-weight: 600;
font-size: 14px;
color: #212020;
line-height: 28px;
}
.type{
font-weight: 400;
font-size: 12px;
color: #282828;
line-height: 23px;
width: 200px;
white-space: nowrap; /* 强制文本在一行显示 */
overflow: hidden; /* 隐藏超出部分 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.date{
font-weight: 400;
font-size: 11px;
color: #999999;
line-height: 20px;
}
.price{
color: #FF5533;
span:first-child{
font-weight: 600;
font-size: 13px;
}
span:nth-child(2){
font-weight: bold;
font-size: 18px;
line-height: 25px;
margin-right: 2px;
}
span:nth-child(3){
font-weight: 600;
font-size: 11px;
line-height: 16px;
}
}
.priceRange{
color: #FF5533;
display: flex;
align-items: center;
.num{
font-weight: bold;
font-size: 18px;
margin-right: 5px;
}
.danwei{
font-weight: 600;
font-size: 11px;
}
.su{
font-weight: 600;
font-size: 11px;
margin: 0 6px;
}
}
.line{
width: 224px;
border-bottom: 2px solid #F5F5F5;
margin: 10px 0;
}
}
}
}
.poupWrap{
width: 100%;
padding-top: 20px;
padding-left: 20px;
.title{
font-size: 14px;
font-weight: bold;
color: #c8c9cc;
}
.poupContent{
width: 100%;
box-sizing: border-box;
padding: 10px 20px 10px 10px;
.tip,.ipt{
margin-bottom: 15px;
}
.ipt{
}
.btnWrap{
width: 100%;
text-align: -webkit-right;
.btn{
width: 80px;
height: 30px;
line-height: 30px;
background-color: #4C81F5;
color: #FFFFFF;
text-align: center;
border-radius: 8px;
}
}
}
}
.empty{
@include flexTwoCenter;
height:calc(100% - 86px);
background-color: #FAFAFA;
img{
width: 100%;
}
}
</style>

View File

@ -0,0 +1,487 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<img class="bg" src="@/assets/secondHandCar/bg.png" />
<div class="nav">
<img class="back" @click="goPage('indexList',indexActiveTab)" src="@/assets/secondHandCar/back.png" />
<span>我的发布</span>
<div style="opacity: 0;" class="back"></div>
</div>
<div class="tabBar">
<div v-for="(item,i) in tabList" :key="i" :class="{'active':activeTab == (i+1)}" @click="tabClickHandle(item)">{{item.name}}
<span v-if="i==0 && noPassNum">{{noPassNum}}</span>
</div>
</div>
</div>
<div class="contentWrap" v-show="!show">
<van-pull-refresh v-model="isLoading" @refresh="onRefresh" style="min-height:85vh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad"
>
<div class="contentItem">
<div class="item" v-for="(item,index) in pageList" :key="index" @click.stop="itemHandle(item)">
<div class="left">
<img v-if="item.vehicleAnglePhoto" class="img" :src="item.vehicleAnglePhoto" />
<div v-else class="qiugou">{{item.vehicleType?.substring(0,2)}}</div>
<img v-if="item.type==1" class="smallImg" src="@/assets/secondHandCar/mine_cheyuan.png" />
<img v-else class="smallImg" src="@/assets/secondHandCar/mine_qiugou.png" />
</div>
<div class="right">
<div class="title">
<span>{{item.vehicleType}}</span>
<img class="titleImg" :src="getStatus(item.status?.code)" />
</div>
<div v-if="activeTab==0" class="type">{{ item.boardType?.label ? item.boardType?.label+' | ' : ''}} {{ item.licenseType?.label }} |
{{ item.mileage }}km | {{item.emissionStandard?.label}}</div>
<div v-else class="type">{{ item.boardType?.label ? item.boardType?.label+' | ' : ''}}
{{item.vehicleType }} | {{item.emissionStandard?.label}}</div>
<div v-if="item.type==1" class="price">售价含税<span>{{formatNumber(item.minPrice) }}</span> <span></span> </div>
<div v-else class="priceRange">
售价含税
<span class="num">{{formatNumber(item.minPrice) }}</span> <span class="danwei"></span>
<span class="su">~</span>
<span class="num">{{formatNumber(item.maxPrice) }}</span> <span class="danwei"></span>
</div>
<div class="btnWrap">
<img v-if="(activeTab==1 && item.status?.code==3) || activeTab==2" @click.stop="noMultipleClicks(reviseHandle,item)" class="revise" src="@/assets/secondHandCar/revise.png" />
<img v-if="(activeTab==1 && (item.status?.code==1 || item.status?.code==3)) || activeTab==2" @click.stop="noMultipleClicks(xiajiaHandle,item)" class="xiajia" src="@/assets/secondHandCar/xiajia.png" />
<img v-if="((activeTab==3 && item.status?.code==7) || activeTab==2) && !isToday(item.wapTime)" @click.stop="noMultipleClicks(polishHandle,item)" class="polish" src="@/assets/secondHandCar/polish.png" />
<img v-if="activeTab==3 && item.type==1 && item.downReason=='不卖了' " @click.stop="noMultipleClicks(reShangJiaHandle,item)" class="reshangjia" src="@/assets/secondHandCar/reshangjia.png" />
</div>
<div class="line"></div>
</div>
</div>
</div>
</van-list>
</van-pull-refresh>
</div>
<div class="empty" v-show="show">
<img src="@/assets/empty.png" />
</div>
<van-popup v-model="poupShow" closeable round :style="{ width: '70%',height:'18%' }" class="poupWrap">
<span class="title">下架原因</span>
<div class="poupContent">
<van-radio-group v-model="radio" class="radioWrap">
<van-radio name="1">{{xiajiaInfo?.type==1 ? '已售出' : '已买到'}}</van-radio>
<van-radio name="2">{{xiajiaInfo?.type==1 ? '不卖了' : '不买了'}}</van-radio>
</van-radio-group>
<div class="btnWrap">
<div class="btn" @click="noMultipleClicks(submitHandle)">确认</div>
</div>
</div>
</van-popup>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import { minePublishPageList,auditFailCount,usedCarPolish,usedCarReShelf,usedCarRemove} from "@/api/secondHandCar"
export default {
name: "mineRelease",
mixins:[myMixins],
data(){
return{
activeTab:1,
tabList:[{value:1,name:'审核中'},{value:2,name:'已发布'},{value:3,name:'已下架'},],
noClick:true,
poupShow:false,
radio:'',
pageList:[],
noPassNum:'',
showEmpty:false,
isLoading:false,
xiajiaInfo:'',
loading: false,
finished: false,
pageNum:1,
pageSize:10,
total:'',
indexActiveTab:'',
}
},
async mounted() {
this.activeTab =Number(sessionStorage.getItem('mineActiveTab')) || 1;
this.indexActiveTab=Number(sessionStorage.getItem('indexActiveTab')) || 0
await this.getCount()
await this.getList()
},
methods:{
async onLoad(){
this.pageNum++;
await this.getList()
this.loading = false;
if (this.pageList.length >= this.total) {
this.finished = true;
}
},
onRefresh() {
this.pageNum=1
setTimeout(() => {
this.$toast('刷新成功');
this.isLoading = false;
}, 1000);
},
itemHandle(item){//审核
this.$router.push({
name: item.type==1 ? "forSale" : 'wantBuySale',
query: { id:item.id,queryType:3,isList:false},
})
sessionStorage.setItem('mineActiveTab',String(this.activeTab) )
},
async getList(){
await this.getCount()
let res= await minePublishPageList({
pageNum:this.pageNum,
pageSize:this.pageSize,
queryType:this.activeTab
})
this.total=res.total
if(this.pageNum == 1){// 第一页直接赋值
this.pageList=res.data
}else{// 第二页数据拼接
let preList = this.pageList;
let arr = res.data;
this.pageList = preList.concat(arr)
}
},
async getCount(){//获取审核不通数量
let res= await auditFailCount()
this.noPassNum=res.data
},
async submitHandle(){//提交下架原因
if(!this.radio){
this.$toast('下架原因不能为空')
return
}
await usedCarRemove({
id:this.xiajiaInfo.id,
downReason:this.radio==1 ? (this.xiajiaInfo?.type==1 ? '已售出' : '已买到') : (this.xiajiaInfo?.type==1 ? '不卖了' : '不买了')
})
this.poupShow=false
this.radio = ''
await this.getList()
},
reviseHandle(item){//修改
this.$router.push({
name: item.type==1 ? "carSource" : 'wantBuy',
query: { type:1 ,id:item.id,queryType:3,homePage:false},
})
},
async polishHandle(item){//檫亮
try {
await usedCarPolish(item.id)
this.$toast('你的曝光度已提升')
await this.getList()
}catch (e){
console.log('polishHandle',e)
} finally {
console.log(1122)
}
},
async reShangJiaHandle(item){//重新上架
try {
await usedCarReShelf(item.id)
await this.getList()
} catch (e) {
console.log('reShangJiaHandle',e)
}
},
xiajiaHandle(item){//下架
this.poupShow=true
this.xiajiaInfo=item
},
isToday(time) {
const now = new Date();
const targetTime = new Date(time);
return (
now.getFullYear() === targetTime.getFullYear() &&
now.getMonth() === targetTime.getMonth() &&
now.getDate() === targetTime.getDate()
);
},
async tabClickHandle(i) {
this.activeTab = i.value
sessionStorage.setItem('mineActiveTab',String(this.activeTab) )
this.pageNum = 1
this.pageList = [];
this.total=0
await this.getList()
},
getStatus(i){
switch (i){
case 5://已发布
return require('@/assets/secondHandCar/fabuing.png')
case 6://已下架
return require('@/assets/secondHandCar/alreayXiajia.png')
case 7://信息过期
return require('@/assets/secondHandCar/expire.png')
case 1://待审核
return require('@/assets/secondHandCar/wait_verify.png')
default://未通过
return require('@/assets/secondHandCar/nopass.png')
}
},
},
computed:{
show() {
return (this.pageList.length < 0 || this.pageList.length == 0); // 判断数组长度是否大于 0
},
},
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
}
.headerWrap{
width: 100%;
box-sizing: border-box;
padding: 15px 16px 0;
position: relative;
.nav {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.bg{
position: absolute;
width: 100%;
height: 120px;
line-height: 120px;
top: 0;
left: 0;
opacity: 0.5;
z-index: -1;
}
.back{
@include wh(15px,15px);
}
span{
font-weight: bold;
font-size: 16px;
color: #203152;
}
.tabBar{
display: flex;
justify-content: space-around;
font-size: 13px;
color: #6A727C;
height: 30px;
line-height: 30px;
span{
background-color: #4C81F5;
padding: 2px 6px;
border-radius: 8px;
font-size: 12px;
color: #FFFFFF;
}
}
.active{
font-weight: 600;
font-size: 15px;
color: #06336D;
position: relative;
}
.active:after {
content: '';
display: block;
background: linear-gradient( 270deg, #33A3FF 0%, #176AFE 100%);
border-radius: 2px;
@include wh(26px,2px);
position: absolute;
border-radius: 2px;
left: 50%;
transform: translateX(-50%);
}
}
.contentWrap{
height: calc(100% - 100px);
overflow-y: auto;
background-color: #F2F2F2;
box-sizing: border-box;
padding: 10px 6px 0;
margin-top: 10px;
}
.contentItem{
width: 100%;
background-color: #FFFFFF;
border-radius: 10px;
box-sizing: border-box;
padding-left: 8px;
padding-top: 18px;
.item{
display: flex;
justify-content: space-between;
}
.left{
position: relative;
.img,.qiugou{
width: 115px;
height: 77px;
border-radius: 7px;
margin-right: 10px;
}
.smallImg{
position: absolute;
top: 0;
left: 0;
width: 36px;
height: 18px;
}
.qiugou{
line-height: 77px;
text-align: center;
color: #FFFFFF;
font-size: 18px;
letter-spacing: 5px;
background-color: #6C81CD;
}
}
.right{
.title{
box-sizing: border-box;
padding-right: 18px;
font-weight: 600;
font-size: 14px;
color: #212020;
line-height: 28px;
display: flex;
align-items: center;
justify-content: space-between;
.titleImg{
width: 43px;
height: 14px;
}
}
.type{
font-weight: 400;
font-size: 12px;
color: #282828;
line-height: 23px;
width: 200px;
white-space: nowrap; /* 强制文本在一行显示 */
overflow: hidden; /* 隐藏超出部分 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
.date{
font-weight: 400;
font-size: 11px;
color: #999999;
line-height: 20px;
}
.price{
color: #FF5533;
span:first-child{
font-weight: bold;
font-size: 18px;
line-height: 25px;
margin-right: 2px;
}
span:last-child{
font-weight: 600;
font-size: 11px;
line-height: 16px;
}
}
.priceRange{
color: #FF5533;
display: flex;
align-items: center;
.num{
font-weight: bold;
font-size: 18px;
margin-right: 5px;
}
.danwei{
font-weight: 600;
font-size: 11px;
}
.su{
font-weight: 600;
font-size: 11px;
margin: 0 6px;
}
}
.line{
width: 224px;
border-bottom: 2px solid #F5F5F5;
margin: 10px 0;
}
.btnWrap{
width: 100%;
box-sizing: border-box;
padding-right: 18px;
text-align: right;
img{
margin-left: 10px;
}
img:first-child{
margin-left: 0;
}
.revise,.xiajia{
@include wh(56px,25px)
}
.polish{
@include wh(69px,25px)
}
.reshangjia{
@include wh(78px,25px)
}
}
}
}
.poupWrap{
width: 100%;
padding-top: 20px;
padding-left: 20px;
.title{
font-size: 14px;
font-weight: bold;
color: #c8c9cc;
}
.radioWrap{
display: flex;
justify-content: space-around;
align-items: center;
margin-top: 7px;
margin-bottom: 15px;
}
.poupContent{
width: 100%;
box-sizing: border-box;
padding: 10px 20px 4px 10px;
.btnWrap{
width: 100%;
text-align: -webkit-right;
//margin-top: 20px;
.btn{
width: 80px;
height: 30px;
line-height: 30px;
background-color: #4C81F5;
color: #FFFFFF;
text-align: center;
border-radius: 8px;
}
}
}
}
.empty{
@include flexTwoCenter;
height:calc(100% - 86px);
background-color: #FAFAFA;
img{
width: 100%;
}
}
</style>

View File

@ -0,0 +1,76 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<img class="back" @click="h5GoBack" src="@/assets/secondHandCar/back.png" />
<span>免责声明</span>
<div style="opacity: 0;" class="back"></div>
</div>
<div class="contentWrap">
<iframe :src="urls"></iframe>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
export default {
name: "privacyComponent",
mixins:[myMixins],
data(){
return{
urls:''
}
},
async mounted() {
let url='';
if (window.location.href.includes('www.sinoassist.com')) {
url = 'https://www.sinoassist.com'
} else if (window.location.href.includes('ccreview.sino-assist.com')) {
url = 'https://ccreview.sino-assist.com'
} else if (window.location.href.includes('uat.sino-assist.com')) {
url = 'https://api-uat.sino-assist.com'
} else {
url = 'https://crm1.sino-assist.com'
}
this.urls=url + '/h5/supplier/dispatch/res/privacy.html'
},
methods:{ }
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
background-color: #F6F6F6;
}
.headerWrap{
width: 100%;
box-sizing: border-box;
padding: 15px 16px;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
background: #FFFFFF;
.back{
@include wh(15px,15px);
cursor: pointer;
}
span{
font-weight: bold;
font-size: 16px;
color: #203152;
}
}
.contentWrap{
height: calc(100% - 42px);
iframe{
overflow-y:hidden;
width: 100%;
height: 100%;
background-color: #FFFFFF;
border: none;
}
}
</style>

View File

@ -0,0 +1,582 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<img class="bg" src="@/assets/secondHandCar/bg.png" />
<div class="navWrap">
<div v-if="isWebFunc()" style="opacity: 0;" class="back"></div>
<img v-else class="back" @click="backHandle" src="@/assets/secondHandCar/back.png" />
<img class="navIcon" src="@/assets/secondHandCar/qiugou_big.png" />
<div style="opacity: 0;" class="back"></div>
</div>
<div class="audit" v-if="status==3 && auditRemark">
<span><img class="noAudit" src="@/assets/secondHandCar/noAudit.png" />审核不通过</span>
<span>{{auditRemark}}</span>
</div>
<div class="audit supplierInfo" v-if="type==2">
<div><span>供应商名称</span><span>{{supplierName}}</span></div>
<div><span>供应商编号</span><span>{{supplierCode}}</span></div>
</div>
</div>
<div class="contentWrap" :class="[type==1 ? 'noContentAudit': 'hasContentAudit']">
<div class="oneContent content">
<img class="sort" src="@/assets/secondHandCar/one_qiugou.png" />
<div class="item vehicleTypeItem">
<span> <span class="star">*</span>求购类型 </span>
<div class="radioWrap">
<van-radio-group v-model="form.vehicleType" direction="horizontal">
<van-radio name="拖车" :class="{'checked':form.vehicleType=='拖车','vehicleRadio':true}">平板拖车</van-radio>
<van-radio name="地库车" :class="{'checked':form.vehicleType=='地库车','vehicleRadio':true}">地库车</van-radio>
<van-radio name="牵引车" :class="{'checked':form.vehicleType=='牵引车','vehicleRadio':true}">牵引车</van-radio>
<van-radio name="随车吊" :class="{'checked':form.vehicleType=='随车吊','vehicleRadio':true}">随车吊</van-radio>
<van-radio name="其他" :class="{'checked':form.vehicleType=='其他','vehicleRadio':true}">其他</van-radio>
</van-radio-group>
<van-field
v-show="form.vehicleType=='其他'"
placeholder="请填写求购物品名称"
v-model="ortherReason"
> </van-field>
</div>
</div>
<div class="item" v-if="form.vehicleType=='拖车'">
<span> <span class="star">*</span>落板方式 </span>
<van-radio-group v-model="form.boardType" direction="horizontal" class="radioWrap">
<van-radio name="1" :class="{'checked':form.boardType==1}">全落地</van-radio>
<van-radio name="2" :class="{'checked':form.boardType==2}">斜落一体</van-radio>
<van-radio name="3" :class="{'checked':form.boardType==3}">普通斜板</van-radio>
<van-radio name="9" :class="{'checked':form.boardType==9}">不限</van-radio>
</van-radio-group>
</div>
<div class="item vehicleTypeItem" >
<span> <span class="star">*</span>排放标准 </span>
<van-radio-group v-model="form.emissionStandard" direction="horizontal" class="radioWrap" style="padding-top: 5px">
<van-radio name="3" :class="{'checked':form.emissionStandard==3,'vehicleRadio':true}">国3</van-radio>
<van-radio name="4" :class="{'checked':form.emissionStandard==4,'vehicleRadio':true}">国4</van-radio>
<van-radio name="5" :class="{'checked':form.emissionStandard==5,'vehicleRadio':true}">国5</van-radio>
<van-radio name="6" :class="{'checked':form.emissionStandard==6,'vehicleRadio':true}">国6</van-radio>
<van-radio name="1" :class="{'checked':form.emissionStandard==1,'vehicleRadio':true}">不限</van-radio>
</van-radio-group>
</div>
<div class="item">
<span> <span class="star">*</span>联系号码 </span>
<van-field
type="number"
class="radioWrap"
v-model="form.contactNumber"
input-align="right"
> </van-field>
</div>
<div class="item priceItem">
<span> <span class="star">*</span>价格区间 </span>
<div style="display: flex;align-items: center" class="price">
<el-input type="tel" v-model.number="form.minPrice" @input="validatePrice">
<template slot="suffix" >
</template>
</el-input>
<span style="font-size: 14px;color: rgba(44, 61, 84, 0.59);margin: 0 6px">-</span>
<el-input type="tel" v-model.number="form.maxPrice" @input="validatePrice1">
<template slot="suffix" >
</template>
</el-input>
</div>
</div>
</div>
<div class="line"></div>
<div class="twoContent content">
<img class="sort" src="@/assets/secondHandCar/two_supply.png" />
<el-input class="ipt" v-model.trim="form.desc" type="textarea" :autosize="{ minRows: 6, maxRows: 6 }"
maxlength="500" show-word-limit placeholder="描述车辆信息:如事故、额外加装、无线遥控"></el-input>
<div v-if="type==2" style="margin: 10px 3px">不通过原因</div>
<el-input v-if="type==2" class="ipt" v-model.trim="auditReason" type="textarea" :autosize="{ minRows: 2, maxRows: 6 }"
maxlength="200" show-word-limit placeholder="请填写不通过原因"></el-input>
<div class="checkedWrap" v-if="type==1">
<img v-show="radio==1" @click="radio=0" class="radioIcon" src="@/assets/secondHandCar/checked.png" />
<img v-show="radio==0" @click="radio=1" class="radioIcon" src="@/assets/secondHandCar/uncheck.png" />
<span>我已阅读并同意</span>
<span @click="viewPrivacy">二手车交易条款</span>
</div>
<div class="btnWrap" >
<div v-if="type==1" class="btn commonBtn" @click="noMultipleClicks(submitHandle)">发布</div>
<div v-if="type==2" class="auditBtn">
<div class="commonBtn" @click="noMultipleClicks(auditHandle,0)">审核不通过</div>
<div class="commonBtn" @click="noMultipleClicks(auditHandle,1)"><span style="margin-right: 6px"></span>审核通过</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {publishCarInfo, carInfoDetail, auditCarInfo} from "@/api/secondHandCar"
export default {
name: "wantBuy",
mixins:[myMixins],
data(){
return{
form:{
id:'',
type:2,
licenseType:'',
vehicleType:'',
boardType:'',
emissionStandard:'',
contactNumber:'',
minPrice:'',
maxPrice:'',
desc:'',
},
radio: 0,
ortherReason:'',
type:'',
id:'',
queryType:'',
noClick:true,
auditReason:'',
auditRemark:'',
status:'',
supplierName:'',
supplierCode:'',
}
},
async mounted() {
const urlParams = new URLSearchParams(window.location.search);
this.type=this.$route.query.type || urlParams.get('type');
this.id=this.$route.query.id || urlParams.get('id');
this.queryType=this.$route.query.queryType || urlParams.get('queryType');
if( this.id){
let res = await carInfoDetail({
id:this.id,
queryType:this.queryType ,
})
this.form={...res.data}
this.form.boardType=res.data.boardType?.code
this.form.emissionStandard=res.data.emissionStandard?.code
this.auditRemark=res.data?.auditRemark
this.status=res.data?.status?.code
this.supplierName=res.data?.supplierName
this.supplierCode=res.data?.supplierCode
if(res.data.vehicleType.includes(',')){
let result=res.data.vehicleType?.split(',')
this.form.vehicleType=result[0]
this.ortherReason=result[1]
}
}
let wantBuyFormInfo=localStorage.getItem("wantBuyFormInfo") ? JSON.parse(localStorage.getItem("wantBuyFormInfo")) : ''
if(!wantBuyFormInfo){
return
}
this.form={...wantBuyFormInfo.form}
this.radio=wantBuyFormInfo.radio
this.ortherReason=wantBuyFormInfo.ortherReason
},
methods:{
validatePrice(value) {
if (value?.startsWith(0) && value?.length > 1) {
this.$nextTick(() => {
this.form.minPrice = 0
})
}
},
validatePrice1(value) {
if (value?.startsWith(0) && value?.length > 1) {
this.$nextTick(() => {
this.form.maxPrice = 0
})
}
},
clearStorageFormInfo(){
localStorage.setItem("wantBuyFormInfo",'')
},
backHandle(){
if(this.$route.query.homePage){//返回列表
this.$router.push({ name: "indexList"})
}else{//返回我的发布
this.$router.push({ name: "mineRelease"})
}
this.clearStorageFormInfo();
},
viewPrivacy(){
let data={form:this.form,radio:this.radio,ortherReason:this.ortherReason}
localStorage.setItem("wantBuyFormInfo",JSON.stringify(data))
this.$router.push({ name: "privacyComponent"})
},
// 审核操作
async auditHandle(type){
if (!type && !this.auditReason){
this.$toast('请填写不通过原因')
return
}
let flag=this.validateHandle()
if(flag){
this.$toast(flag)
return
}
if (this.form.vehicleType=='拖车' && !this.form.boardType) {
this.$toast('落板方式不能为空')
return
}else if(this.form.vehicleType !=='拖车'){
this.form.boardType=''
}
let rule = this.validationRules.find(item =>
item.value === null ||
item.value === undefined ||
item.value === ''
)
if(rule){
this.$toast(rule.name)
return
}
try {
await auditCarInfo({
id: this.id,
auditResult: type ? 1 : 0 ,
auditReason: this.auditReason,
...this.form,
vehicleType: this.ortherReason ? (this.form.vehicleType+','+this.ortherReason) : this.form.vehicleType
})
this.clearStorageFormInfo()
setTimeout(()=>{
this.closeParentDialog()
},1000)
} catch (e){
console.log(e)
}
finally {
console.log(type)
}
},
// 发布求购
async submitHandle(){
if (!this.radio) {
this.$toast('请勾选我已阅读并同意')
return
}
let flag=this.validateHandle()
if(flag){
this.$toast(flag)
return
}
if (this.form.vehicleType=='拖车' && !this.form.boardType) {
this.$toast('落板方式不能为空')
return
}else if(this.form.vehicleType !=='拖车'){
this.form.boardType=''
}
let rule = this.validationRules.find(item =>
item.value === null ||
item.value === undefined ||
item.value === ''
)
if(rule){
this.$toast(rule.name)
return
}
try {
let res = await publishCarInfo({
...this.form,
vehicleType: this.ortherReason ? (this.form.vehicleType+','+this.ortherReason) : this.form.vehicleType
})
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)
}
},
// 手机号验证方法
validateHandle() {
const contactNumberPattern = /^1[3-9]\d{9}$/; // 手机号正则表达式
let str=''
if (!this.form.contactNumber) {
str='联系方式不能为空'
} else if (!contactNumberPattern.test(this.form.contactNumber)) {
str='联系方式格式错误'
} else {
str=''
}
return str
},
},
computed: {
validationRules() {
return [
{ value: this.form.vehicleType, name: '车辆类型不能为空' },
{ value: this.form.emissionStandard, name: '排放标准不能为空' },
{ value: this.form.contactNumber, name: '联系方式不能为空' },
{ value: this.form.minPrice, name: '售价不能为空' },
{ value: this.form.maxPrice, name: '售价不能为空' },
];
},
},
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
}
.headerWrap{
width: 100%;
box-sizing: border-box;
padding-top: 15px;
padding-bottom: 15px;
position: relative;
.navWrap{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 0 16px 10px;
}
.bg{
position: absolute;
width: 100%;
height: 120px;
line-height: 120px;
top: 0;
left: 0;
opacity: 0.5;
z-index: -1;
}
.back{
@include wh(15px,15px);
}
.navIcon{
@include wh(84px,21px);
}
.audit{
@include wh(100%,43px);
background: #FFF7F4;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
color: #FF6B3B;
.noAudit{
@include wh(13px,12px);
margin-right: 5px;
vertical-align: bottom;
}
span:first-child{
font-weight: 600;
}
}
.supplierInfo{
justify-content: space-around;
background-color: #F5F7F9;
color: #606266;
}
}
.noContentAudit{
height: calc(100% - 42px);
}
.hasContentAudit{
height: calc(100% - 85px);
}
.contentWrap{
width: 100%;
//height: calc(100% - 42px);
overflow-y: auto;
.sort{
@include wh(91px, 19px);
margin-bottom: 15px;
}
.line{
width: 100%;
border-bottom: 1px solid #F2F2F2;
margin-top: 26px;
margin-bottom: 17px;
}
.lastLine{
margin-top: 3px !important;
}
.content{
width: 100%;
box-sizing: border-box;
padding:0 20px;
}
.oneContent{
.priceItem{
margin-top: 10px;
}
.vehicleTypeItem{
line-height: 13px !important;
}
.item{
display: flex;
//align-items: center;
font-weight: 400;
font-size: 13px;
color: #2C3D54;
line-height: 44px;
width: 100%;
box-sizing: border-box;
padding-left: 21px;
padding-right: 9px;
span:first-child{
display: inline-block;
width:70px;
font-size: 13px;
color: rgba(44, 61, 84, 0.59);
}
span:last-child{
display: inline-block;
width:calc(100% - 70px);
border-bottom: 1px solid #E9E9EA;
}
.orc{
box-sizing: border-box;
padding-left: 6px;
}
}
.star{
color: #FF4B4B !important;
opacity: 1 !important;
font-weight: bold;
font-size: 12px;
margin-right: 6px;
margin-left: -6px;
}
.radioWrap{
width:calc(100% - 70px);
border-bottom: 1px solid #E9E9EA;
}
.price{
display: flex;
align-items: center;
justify-content: space-around;
::v-deep .el-input__inner{
text-align: center;
width: 108px;
height: 36px;
background: rgba(230,238,255,0.34);
border-radius: 4px;
border: none;
}
::v-deep .el-input__suffix{
margin-right: 15px;
}
}
}
.twoContent{
.checkedWrap{
cursor: pointer;
color:#808D99 ;
display: flex;
align-items: center;
justify-content: center;
margin-top: 20px;
margin-bottom: 10px;
font-size: 12px;
.radioIcon{
@include wh(16px, 16px);
margin-right: 6px;
}
span:last-child{
color: #0E76F4;
}
}
.btnWrap{
padding-bottom: 20px;
padding-top: 15px;
}
.commonBtn{
height: 46px;
line-height: 46px;
text-align: center;
font-weight: bold;
border-radius: 5px;
color: #FFFFFF;
cursor: pointer;
}
.btn{
width: 296px;
background: #4A7FEB;
margin: 0 auto;
font-size: 15px;
}
.auditBtn{
display: flex;
justify-content: space-between;
font-size: 14px;
box-sizing: border-box;
padding: 0 6px;
div:first-child{
width: 100px;
opacity: 0.79;
background: #1C2C49;
}
div:last-child{
width: 200px;
background: #4A7FEB;
}
}
}
}
::v-deep .van-icon-success{
display: none !important;
}
::v-deep .van-radio__label{
margin-left: 0;
width: 54px;
//padding: 0px 8px;
height: 23px;
border-radius: 13px;
border: 1px solid #9F9F9F;
opacity: 0.5;
text-align: center;
line-height: 23px;
font-size: 12px;
color: #323233;
opacity: 1;
}
::v-deep .van-radio--horizontal{
margin-right: 4px;
}
::v-deep .van-radio--horizontal:last-child{
margin-right: 0;
}
::v-deep .checked .van-radio__label{
background: #FFF1EC !important;
border: 1px solid #FF5C26 !important;
color: #FE5006 !important;
border-radius: 13px !important;
}
::v-deep .vehicleRadio .van-radio__label{
margin-bottom: 8px !important;
}
::v-deep .van-field__right-icon{
margin-right: 0;
padding: 0;
}
::v-deep .ipt .el-textarea__inner{
background: #F5F7F9;
border-radius: 4px;
font-size: 12px;
border: none;
}
::v-deep .van-cell{
font-size: 13px;
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<div class="wrap" >
<div class="headerWrap">
<div v-if="isWebFunc()" style="opacity: 0;" class="back"></div>
<img v-else class="back" @click="h5GoBack" src="@/assets/secondHandCar/back.png" />
<span>求购</span>
<div style="opacity: 0;" class="back"></div>
</div>
<div class="contentWrap">
<div class="titleWrap wrapCommon">
<div class="info">
<span>{{ detailInfo.vehicleType }}</span>
</div>
<div class="time">
<span>{{ detailInfo.createTime?.substring(0,10) }}</span><span>发布</span>
</div>
<div class="price">
售价含税
<span class="num">{{formatNumber(detailInfo.minPrice) }}</span> <span class="danwei"></span>
<span class="su">~</span>
<span class="num">{{formatNumber(detailInfo.maxPrice) }}</span> <span class="danwei"></span>
</div>
</div>
<div class="detailInfoWrap wrapCommon">
<div>
<img class="descImg firstDescImg" src="@/assets/secondHandCar/details.png" />
</div>
<div class="descItem descCommon">
<div class="itemInfo">
<el-tooltip class="item" effect="dark" :content="detailInfo.vehicleType" placement="top">
<span style="cursor: pointer">{{ detailInfo.vehicleType }}</span>
</el-tooltip>
<span>车辆类型</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<span>{{ detailInfo.boardType?.label }}&nbsp;&nbsp;</span>
<span>落板方式</span>
</div>
<div class="suGang"></div>
<div class="itemInfo">
<span>{{ detailInfo.emissionStandard?.label }}</span>
<span>排放标准</span>
</div>
</div>
<div>
<img class="descImg" src="@/assets/secondHandCar/description.png" />
</div>
<div class="descCommon desc">{{detailInfo.desc}}</div>
</div>
<div v-if="isList && !detailInfo.selfSupplierPublish" class="btn" @click="noMultipleClicks(handle)">我有车源</div>
</div>
</div>
</template>
<script>
import {myMixins} from "@/utils/myMixins"
import {carInfoDetail, saveRecord} from "@/api/secondHandCar";
import {Dialog} from "vant";
export default {
name: "wantBuySale",
mixins:[myMixins],
data(){
return{
noClick:true,
id:'',
queryType:'',
detailInfo:'',
duration:'',
startTime: null, // 记录进入时间
isList:false,
}
},
async mounted() {
window.addEventListener('message', (event) => {
if (event.data === 'dialogClosed') {
console.log('Dialog 已关闭');
this.getDuration(1)
}
});
this.startTime = new Date();
const urlParams = new URLSearchParams(window.location.search);
this.id=this.$route.query.id || urlParams.get('id');
this.queryType=this.$route.query.queryType || urlParams.get('queryType');
this.isList=this.$route.query.isList || urlParams.get('isList');
if( this.id) {
let res = await carInfoDetail({
id: this.id,
queryType: this.queryType,
})
this.detailInfo = res?.data
}
},
destroyed() {
this.getDuration(1)
},
methods:{
getDuration(type){
const endTime = new Date();
const duration = (endTime - this.startTime) / 1000; // 计算时长(秒)
this.saveRecord(duration,type);
},
async saveRecord(duration,type){
await saveRecord({type:type,carInfoId:this.id,duration})
},
handle(){
this.getDuration(2)
Dialog.alert({
message:this.detailInfo.contactNumber ,
confirmButtonText:'拨打电话',
showCancelButton:true,
}).then(() => {
window.location.href = `tel:${this.detailInfo.contactNumber}`;
}).catch(() => {
// on cancel
});
},
}
}
</script>
<style scoped lang="scss">
@import '@/styles/mixin.scss';
.wrap {
@include wh(100%, 100%);
position: relative;
background-color: #F6F6F6;
}
.headerWrap{
width: 100%;
box-sizing: border-box;
padding: 15px 16px;
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
background: #FFFFFF;
.back{
@include wh(15px,15px);
}
span{
font-weight: bold;
font-size: 16px;
color: #203152;
}
}
.contentWrap{
height: calc(100% - 42px);
overflow-y: auto;
.wrapCommon{
width: 100%;
background: #FFFFFF;
border-radius: 6px;
backdrop-filter: blur(5.602678571428572px);
box-sizing: border-box;
margin: 12px 0;
}
.titleWrap{
margin-top: 10px;
height: 108px;
padding: 18px 0 15px 21px;
display: flex;
flex-direction: column;
justify-content: space-between;
.info{
font-weight: 600;
font-size: 15px;
color: #212020;
line-height: 21px;
span{
margin-right: 10px;
}
}
.time{
font-weight: 400;
font-size: 12px;
color: #999999;
line-height: 17px;
span:first-child{
margin-right: 20px;
}
}
.price{
color: #FF5533;
font-weight: 600;
display: flex;
align-items: center;
.num{
font-size: 20px;
margin-right: 4px;
}
.danwei,.su{
font-size: 11px;
}
.su{
margin: 0 4px;
}
}
}
.detailInfoWrap{
box-sizing: border-box;
padding: 18px 28px 15px 22px;
.descImg{
@include wh(72px, 19px);
}
.firstDescImg{
margin-bottom: 24px;
}
.descCommon{
width: 100%;
box-sizing: border-box;
padding-left: 15px;
}
.descItem{
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 20px;
}
.itemInfo{
display: flex;
flex-direction: column;
width: 28%;
span:first-child{
width: 100%;
font-weight: bold;
font-size: 14px;
color: #282828;
line-height: 20px;
margin-bottom: 2px;
white-space: nowrap; /* 强制文本在一行显示 */
overflow: hidden; /* 隐藏超出部分 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
}
span:last-child{
font-weight: 400;
font-size: 10px;
color: #999999;
line-height: 14px;
}
}
.suGang{
width: 1px;
height: 8px;
border-right: 1px solid #999999;
opacity: 0.5;
}
.desc{
font-weight: 400;
font-size: 12px;
color: #282828;
margin-top: 10px;
}
}
.btn{
width: 296px;
height: 46px;
line-height: 46px;
text-align: center;
font-weight: bold;
border-radius: 5px;
color: #FFFFFF;
background: #4A7FEB;
margin: 0 auto;
font-size: 15px;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
cursor: pointer;
}
}
</style>

View File

@ -170,19 +170,13 @@ export default {
pageSize:this.pageSize,
queryType:this.activeIndex+1,
})
// this.pageList=res.data
// console.log("===",this.pageList)
this.total=res.total
if(this.pageNum == 1){// 第一页直接赋值
this.pageList=res.data
}else{// 第二页数据拼接
console.log("第二页数据拼接")
let preList = this.pageList;
// console.log("preList",preList)
let arr = res.data;
// console.log("arr",arr)
this.pageList = preList.concat(arr)
console.log("this.pageList====",this.pageList)
}
},
goPageDetail(item){

View File

@ -897,11 +897,11 @@ export default {
.leftTitle {
opacity: .5;
@include wh(60px, 189px);
width: 60px;
}
.rightContent {
height: 189px;
/*height: 189px;*/
width: calc(100% - 60px);
}
@ -980,6 +980,7 @@ img {
.inputContent {
text-align: right;
flex: 1;
}
}