Compare commits
19 Commits
e800ee1b7e
...
prod-25-12
| Author | SHA1 | Date | |
|---|---|---|---|
| 284872fa73 | |||
| 703062825c | |||
| a7e217100e | |||
| 8677a0c99a | |||
| 7739f61d36 | |||
| 66f28ad8ce | |||
| e6a669e41d | |||
| a84e5a3531 | |||
| b6fd5b5db6 | |||
| 4e37efeca4 | |||
| 8979dcaf98 | |||
| f6e225ed4b | |||
| 821a35b382 | |||
| 2b0c6d6a36 | |||
| 073312a56b | |||
| d493ebca97 | |||
| ed5a0d9478 | |||
| 0a281ea877 | |||
| b42db4e98f |
@@ -1,160 +0,0 @@
|
||||
# 年终总结看板 Dashboard
|
||||
|
||||
道路救援服务年终数据可视化看板项目。
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
dashboard-demo/
|
||||
├── index.html # 主看板页面(支持URL参数动态加载数据)
|
||||
├── data/
|
||||
│ ├── 供应商年度KPI.xlsx # 服务商KPI数据(主数据源)
|
||||
│ ├── 师傅案件top3.xlsx # 案件量TOP3师傅数据
|
||||
│ ├── 师傅在线top3.xlsx # 在线时长TOP3师傅数据
|
||||
│ ├── 拒单率最高地区.xlsx # 拒单率最高地区数据
|
||||
│ └── 拒单率最高时段.xlsx # 拒单率最高时段数据
|
||||
└── README.md # 项目说明
|
||||
```
|
||||
|
||||
## 功能特性
|
||||
|
||||
- 深色主题数据可视化看板
|
||||
- **直接读取Excel文件**,无需转换为JSON
|
||||
- 支持通过URL参数 `?providerId=XXX` 切换不同服务商
|
||||
- 右上角下拉框可实时切换服务商(自动从Excel读取服务商列表)
|
||||
- 使用 Chart.js 实现饼状图和雷达图
|
||||
- 使用 SheetJS (xlsx) 解析Excel文件
|
||||
- 响应式布局,支持不同屏幕尺寸
|
||||
- 数据与页面分离,便于维护
|
||||
|
||||
## 数据指标
|
||||
|
||||
看板展示以下数据指标:
|
||||
|
||||
1. **总案件量分布**(饼状图)
|
||||
- 小修、困境、拖车三类案件占比
|
||||
|
||||
2. **年度聚合案件量**
|
||||
|
||||
3. **案件量TOP3师傅**
|
||||
|
||||
4. **车辆平均总在线时长**
|
||||
|
||||
5. **在线时长TOP3师傅**
|
||||
|
||||
6. **拒单率最高地区**
|
||||
|
||||
7. **拒单率最高时段**
|
||||
|
||||
8. **APP使用率**
|
||||
- 年度APP使用率展示
|
||||
|
||||
## Excel数据结构
|
||||
|
||||
### 1. 供应商年度KPI.xlsx
|
||||
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 服务商id | 服务商唯一标识 |
|
||||
| 服务商 | 服务商名称 |
|
||||
| 完成案件量 | 总案件数量 |
|
||||
| 拖车完成量 | 拖车案件数 |
|
||||
| 小修完成量 | 小修案件数 |
|
||||
| 困境完成量 | 困境案件数 |
|
||||
| 聚合案件量 | 聚合案件数量 |
|
||||
| APP使用率. | APP使用率(小数形式,如0.998) |
|
||||
| 年度车辆平均总在线时长(小时) | 车辆平均在线时长 |
|
||||
|
||||
### 2. 师傅案件top3.xlsx
|
||||
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 服务商id | 服务商唯一标识 |
|
||||
| 服务商 | 服务商名称 |
|
||||
| 服务人员工号 | 师傅姓名/工号 |
|
||||
| 完成案件量 | 该师傅完成的案件数 |
|
||||
|
||||
### 3. 师傅在线top3.xlsx
|
||||
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 服务商名称 | 服务商名称 |
|
||||
| 司机姓名 | 师傅姓名 |
|
||||
| 年度总在线时长(小时) | 在线时长 |
|
||||
|
||||
### 4. 拒单率最高地区.xlsx
|
||||
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 供应商名称 | 服务商名称 |
|
||||
| 地区 | 拒单率最高的地区 |
|
||||
| 拒单率 | 拒单率(小数形式) |
|
||||
|
||||
### 5. 拒单率最高时段.xlsx
|
||||
|
||||
| 列名 | 说明 |
|
||||
|------|------|
|
||||
| 供应商名称 | 服务商名称 |
|
||||
| 时段 | 拒单率最高的时段 |
|
||||
| 拒单率 | 拒单率(小数形式) |
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 1. 启动本地服务器
|
||||
|
||||
由于页面使用 `fetch` 加载JSON数据,需要通过HTTP服务器访问:
|
||||
|
||||
```bash
|
||||
cd C:\Users\Administrator\dashboard-demo
|
||||
|
||||
# 使用 Python
|
||||
python -m http.server 8080
|
||||
|
||||
# 或使用 Node.js
|
||||
npx serve .
|
||||
|
||||
# 或使用 PHP
|
||||
php -S localhost:8080
|
||||
```
|
||||
|
||||
### 2. 访问页面
|
||||
|
||||
- 默认服务商:`http://localhost:8080`(自动加载第一个服务商)
|
||||
- 指定服务商:`http://localhost:8080?providerId=1128`(使用服务商id)
|
||||
- 切换服务商:使用页面右上角的下拉框
|
||||
|
||||
### 3. 更新数据
|
||||
|
||||
直接替换 `data/` 目录下的Excel文件即可,页面会自动读取最新数据。
|
||||
服务商列表从Excel自动生成,无需手动配置。
|
||||
|
||||
## 技术栈
|
||||
|
||||
- HTML5 / CSS3
|
||||
- JavaScript (ES6+)
|
||||
- Chart.js - 图表库(饼图、雷达图)
|
||||
- SheetJS (xlsx) - Excel文件解析
|
||||
- CSS Grid / Flexbox - 布局
|
||||
|
||||
## 后续优化方向
|
||||
|
||||
- [ ] 添加更多图表类型(柱状图、折线图等)
|
||||
- [ ] 支持时间范围筛选
|
||||
- [ ] 添加数据导出功能
|
||||
- [ ] 移动端适配优化
|
||||
- [ ] 添加数据加载骨架屏
|
||||
- [ ] 支持主题切换(深色/浅色)
|
||||
|
||||
## 更新日志
|
||||
|
||||
### 2025-01-21
|
||||
- 改为直接读取Excel文件,无需JSON转换
|
||||
- 服务商列表从Excel自动生成
|
||||
- 将"AB段里程对比"改为"APP使用率"展示
|
||||
- 新增服务商选择下拉框
|
||||
|
||||
### 2025-01-20
|
||||
- 初始版本
|
||||
- 实现基础看板布局
|
||||
- 支持URL参数切换服务商
|
||||
- 数据JSON化,与页面分离
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"serviceProviderId": "SP001",
|
||||
"serviceProviderName": "上海道路救援服务中心",
|
||||
"year": 2025,
|
||||
"summary": {
|
||||
"totalCases": 100,
|
||||
"caseBreakdown": {
|
||||
"minorRepair": 20,
|
||||
"predicament": 20,
|
||||
"towing": 60
|
||||
},
|
||||
"aggregatedCases": 15
|
||||
},
|
||||
"topMastersByCases": [
|
||||
{ "rank": 1, "name": "小王", "cases": 18 },
|
||||
{ "rank": 2, "name": "小张", "cases": 16 },
|
||||
{ "rank": 3, "name": "小李", "cases": 12 }
|
||||
],
|
||||
"onlineHours": {
|
||||
"averageTotal": 2920,
|
||||
"topMasters": [
|
||||
{ "rank": 1, "name": "小王", "hours": 3230 },
|
||||
{ "rank": 2, "name": "小张", "hours": 3028 },
|
||||
{ "rank": 3, "name": "小李", "hours": 2996 }
|
||||
]
|
||||
},
|
||||
"rejectionRate": {
|
||||
"highestRegion": {
|
||||
"name": "崇明",
|
||||
"rate": 21.2
|
||||
},
|
||||
"highestTimeSlot": {
|
||||
"period": "18:00-22:00",
|
||||
"description": "晚高峰时段"
|
||||
}
|
||||
},
|
||||
"abMileage": {
|
||||
"highest": {
|
||||
"region": "崇明",
|
||||
"distance": 62
|
||||
},
|
||||
"lowest": {
|
||||
"region": "黄浦",
|
||||
"distance": 6
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
"serviceProviderId": "SP002",
|
||||
"serviceProviderName": "浦东汽车救援有限公司",
|
||||
"year": 2025,
|
||||
"summary": {
|
||||
"totalCases": 156,
|
||||
"caseBreakdown": {
|
||||
"minorRepair": 35,
|
||||
"predicament": 41,
|
||||
"towing": 80
|
||||
},
|
||||
"aggregatedCases": 22
|
||||
},
|
||||
"topMastersByCases": [
|
||||
{ "rank": 1, "name": "老陈", "cases": 28 },
|
||||
{ "rank": 2, "name": "大刘", "cases": 24 },
|
||||
{ "rank": 3, "name": "阿强", "cases": 19 }
|
||||
],
|
||||
"onlineHours": {
|
||||
"averageTotal": 3150,
|
||||
"topMasters": [
|
||||
{ "rank": 1, "name": "老陈", "hours": 3580 },
|
||||
{ "rank": 2, "name": "大刘", "hours": 3420 },
|
||||
{ "rank": 3, "name": "阿强", "hours": 3210 }
|
||||
]
|
||||
},
|
||||
"rejectionRate": {
|
||||
"highestRegion": {
|
||||
"name": "奉贤",
|
||||
"rate": 18.5
|
||||
},
|
||||
"highestTimeSlot": {
|
||||
"period": "07:00-09:00",
|
||||
"description": "早高峰时段"
|
||||
}
|
||||
},
|
||||
"abMileage": {
|
||||
"highest": {
|
||||
"region": "金山",
|
||||
"distance": 55
|
||||
},
|
||||
"lowest": {
|
||||
"region": "静安",
|
||||
"distance": 8
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -70,51 +70,3 @@ export function driverRealName( data) {
|
||||
contentType: 'application/json'
|
||||
})
|
||||
}
|
||||
//获取需要确认的人员信息列表
|
||||
export function getConfirmPerson(key){
|
||||
return request({
|
||||
url: '/supplierAppV2/dispatchApp/wechat/getNeedConfirmPersonInfo',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
//微信相关 获取联系我 二维码
|
||||
export function getQrCode(key){
|
||||
return request({
|
||||
url: '/supplierAppV2/dispatchApp/wechat/getQrCode',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
//获取服务商的确认状态
|
||||
export function getConfirmStatus(key){
|
||||
return request({
|
||||
url: '/supplierAppV2/dispatchApp/wechat/getSupplier',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
//确认已添加微信按钮
|
||||
export function confirmAddWechat(key){
|
||||
return request({
|
||||
url: '/supplierAppV2/dispatchApp/wechat/confirmAddWechat',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
//确认无误
|
||||
export function confirm(key){
|
||||
return request({
|
||||
url: '/supplierAppV2/dispatchApp/wechat/confirm',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
//提交审批
|
||||
export function submitConfirm( data) {
|
||||
return request('/supplierAppV2/dispatchApp/wechat/submitConfirm', {
|
||||
data: data,
|
||||
method:'POST',
|
||||
contentType: 'application/json'
|
||||
})
|
||||
}
|
||||
@@ -77,15 +77,6 @@ export function updateOrderSettlement(data){
|
||||
data
|
||||
})
|
||||
}
|
||||
// 获取司机信息
|
||||
export function getDriverInfo(data){
|
||||
return request({
|
||||
url:'/supplierAppV2/dispatchApp/order/getDriverInfo',
|
||||
method:'POST',
|
||||
contentType:'application/json',
|
||||
data
|
||||
})
|
||||
}
|
||||
// 电瓶数量列表
|
||||
export function batteryCountList(){
|
||||
return request({
|
||||
@@ -168,12 +159,3 @@ export function getConfigByCode(data){
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//获取最新版本
|
||||
export function getNewVersion(key){
|
||||
return request({
|
||||
url: '/driverApp/app/updateVersion',
|
||||
method:'GET',
|
||||
params: key
|
||||
})
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 868 B |
Binary file not shown.
|
Before Width: | Height: | Size: 915 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.0 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 643 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 870 B |
@@ -39,13 +39,5 @@ const authenticationRouter = [
|
||||
title: '银行卡信息认证',
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/personList',
|
||||
name: 'personList',
|
||||
component: () => import('@/views/mine/personList.vue'),
|
||||
meta:{
|
||||
title: '人员信息',
|
||||
}
|
||||
},
|
||||
]
|
||||
export default authenticationRouter
|
||||
|
||||
@@ -324,14 +324,6 @@ const routes = [
|
||||
title:'电瓶详情'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/goToApp',
|
||||
name: 'goToApp',
|
||||
component:()=>import('@/views/goToApp/goToApp.vue'),
|
||||
meta: {
|
||||
title:'电瓶详情'
|
||||
}
|
||||
},
|
||||
...kpiRouter,
|
||||
...invoiceRouter,
|
||||
...secondHandRouter,
|
||||
|
||||
@@ -48,7 +48,6 @@ service.interceptors.request.use(
|
||||
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
console.log('response', response.data)
|
||||
const res = response.data
|
||||
if ( res.code === 401 || res.code === 400 || res.code == 500) {
|
||||
Toast(res.msg || 'Error')
|
||||
|
||||
@@ -94,7 +94,6 @@ export const myMixins = {
|
||||
isWebFunc(){
|
||||
let res=false
|
||||
var isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
||||
console.log('isMobile',isMobile)
|
||||
if (!isMobile) {// 是移动端不变
|
||||
res=true
|
||||
}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<div class="wrap">
|
||||
<div class="content">
|
||||
<div class="goToBtn" @click="goAppHandler">立即打开</div>
|
||||
<div class="content_tip">
|
||||
<div class="font_cls">如未安装请点击下载</div>
|
||||
<div class="font_cls">如已安装未自动跳转,请 <span @click="downLoadHandler">立即下载</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getNewVersion } from "@/api/order"
|
||||
export default {
|
||||
name: "goToApp",
|
||||
methods: {
|
||||
goAppHandler() {
|
||||
window.location.href = "rvdriver://page/pagesLogin/phoneLogin?source=h5Link";
|
||||
},
|
||||
async downLoadHandler() {
|
||||
getNewVersion({
|
||||
appType: 5
|
||||
}).then((res) => {
|
||||
window.location.href = res?.result?.path
|
||||
}).catch(() => {
|
||||
this.$message.error('请求版本失败,请重试');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.wrap {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-image: url('@/assets/toAppBg.png');
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.content {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
top: 74vh;
|
||||
}
|
||||
.goToBtn {
|
||||
width: 70%;
|
||||
height: 45px;
|
||||
margin-left: 15%;
|
||||
background: linear-gradient( 270deg, #2347C0 0%, #72A3FF 100%);
|
||||
border-radius: 23px;
|
||||
//font-weight: bold;
|
||||
font-size: 17px;
|
||||
color: #FFFFFF;
|
||||
letter-spacing: 2px;
|
||||
line-height: 45px;
|
||||
text-align: center;
|
||||
}
|
||||
.content_tip {
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
.font_cls {
|
||||
font-size: 14px;
|
||||
color: #808080;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
span {
|
||||
color: #007BE9;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -8,7 +8,7 @@
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
:safe-area-inset-top="true"
|
||||
@click-left="back"
|
||||
@click-left="h5GoBack"
|
||||
/>
|
||||
</div>
|
||||
<div class="addContentWrap">
|
||||
@@ -92,57 +92,6 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
|
||||
<div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')" style="align-items: center">
|
||||
<div class="titleType" style="width: 60px">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>保费</span>
|
||||
</div>
|
||||
<van-field
|
||||
type="number"
|
||||
class="vanIpt"
|
||||
v-model="liabilityInsuranceAmount"
|
||||
input-align="right"
|
||||
>
|
||||
<template slot="right-icon" >
|
||||
<span style="white-space: nowrap;">元</span>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
<div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>保额</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items: center;justify-content: flex-end">
|
||||
<el-select
|
||||
v-model="liabilityInsuranceQuota"
|
||||
value-key="name"
|
||||
class="elSelect"
|
||||
collapse-tags="collapse-tags"
|
||||
placeholder="请选择" style="width: 55%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in liabilityQuotaOptions"
|
||||
:key="item.value"
|
||||
:label="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select><span style="margin-right: 16px;opacity: .5;">万元</span>
|
||||
</div>
|
||||
<!-- <van-field
|
||||
type="number"
|
||||
class="vanIpt"
|
||||
v-model="liabilityInsuranceQuota"
|
||||
input-align="right"
|
||||
>
|
||||
<template slot="right-icon" >
|
||||
<span style="white-space: nowrap;">万元 </span>
|
||||
</template>
|
||||
</van-field>-->
|
||||
</div>
|
||||
</template>
|
||||
<common-btn title="保存" @submitClick="submitBtn"/>
|
||||
<van-calendar v-model="showDatePicker" :min-date="minDate"
|
||||
@@ -155,7 +104,7 @@
|
||||
import {Dialog} from "vant";
|
||||
import {myMixins} from "@/utils/myMixins"
|
||||
import {formatDate1} from "@/utils/common"
|
||||
import { uploadImage, updateInsurance, getInfoById,userOperationPermissions} from "@/api/mine"
|
||||
import { uploadImage, updateInsurance, getInfoById} from "@/api/mine"
|
||||
import CommonBtn from "@/components/commonBtn.vue"
|
||||
export default {
|
||||
name: "vehicleAdd",
|
||||
@@ -166,7 +115,6 @@ export default {
|
||||
children: 'children',
|
||||
label: 'name'
|
||||
},
|
||||
liabilityQuotaOptions:[{value:10},{value:20},{value:30},{value:50},{value:70},{value:80},{value:100},{value:200}],
|
||||
minDate: new Date(1970, 0, 1), // 设置最小可选日期(1970年1月1日)
|
||||
maxDate: new Date(2099, 11, 31), // 设置最大可选日期(2099年12月31日)
|
||||
showDatePicker: false,
|
||||
@@ -182,9 +130,6 @@ export default {
|
||||
insurancePicturePhoto: '', // 保单照片
|
||||
isMultiple: false, // 是否支持多选
|
||||
insuranceCorp: '',
|
||||
liabilityInsuranceAmount:'',
|
||||
liabilityInsuranceQuota:'',
|
||||
permissonList:[],
|
||||
insuranceOptions: [{
|
||||
name: '太平洋',
|
||||
value: 1
|
||||
@@ -238,24 +183,11 @@ export default {
|
||||
|
||||
async mounted() {
|
||||
this.id=this.$route.params?.id
|
||||
await this.getPermissions()
|
||||
if( this.id){
|
||||
// await this.vehicleInfo()
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
back() {
|
||||
this.$router.push({
|
||||
name:'vehicleAdd',
|
||||
params:{
|
||||
id: this.id
|
||||
}
|
||||
})
|
||||
},
|
||||
async getPermissions(){
|
||||
let res = await userOperationPermissions();
|
||||
this.permissonList = res.data
|
||||
},
|
||||
async vehicleInfo(){
|
||||
let res= await getInfoById({
|
||||
vehicleId:this.id
|
||||
@@ -327,14 +259,6 @@ export default {
|
||||
this.$toast('保单有效期不能为空')
|
||||
return
|
||||
}
|
||||
if(this.hasLiabilityInsurance == 1 && this.permissonList?.includes('hasInsuranceAudit') && !this.liabilityInsuranceAmount && this.liabilityInsuranceAmount!=0){
|
||||
this.$toast('保费不能为空')
|
||||
return
|
||||
}
|
||||
if(this.hasLiabilityInsurance == 1 && !this.liabilityInsuranceQuota){
|
||||
this.$toast('保额不能为空')
|
||||
return
|
||||
}
|
||||
let timeObj;
|
||||
if(this.dateVal) {
|
||||
timeObj = this.formatDateTimeRange(this.dateVal)
|
||||
@@ -347,8 +271,6 @@ export default {
|
||||
insuranceCorp: this.hasLiabilityInsurance == 1 ? this.insuranceCorp : '',
|
||||
liabilityInsuranceStartTime: this.hasLiabilityInsurance == 1 ? (timeObj?.startTime || '' ) : '',
|
||||
liabilityInsuranceEndTime: this.hasLiabilityInsurance == 1 ? (timeObj?.endTime || '') : '',
|
||||
liabilityInsuranceQuota:this.liabilityInsuranceQuota || '',
|
||||
liabilityInsuranceAmount:this.liabilityInsuranceAmount || '',
|
||||
})
|
||||
}
|
||||
await updateInsurance(params)
|
||||
@@ -358,8 +280,7 @@ export default {
|
||||
this.$toast('添加成功')
|
||||
}
|
||||
setTimeout(()=>{
|
||||
// this.$router.back();
|
||||
this.back()
|
||||
this.$router.back();
|
||||
},2000)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
accept="image "
|
||||
/>
|
||||
</div>
|
||||
<!-- <div class="lineBot"></div>
|
||||
<div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
@@ -80,12 +80,11 @@
|
||||
:preview-size="54"
|
||||
accept="image "
|
||||
/>
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>免冠正面照</span>
|
||||
<span>头像</span>
|
||||
</div>
|
||||
<van-uploader
|
||||
v-model="iconList"
|
||||
@@ -308,7 +307,7 @@ export default {
|
||||
let res = await uploadImage(formData)
|
||||
this.drivingLicenceContrary = res.data;
|
||||
},
|
||||
async iconListHandler(file) { // 上传免冠正面照
|
||||
async iconListHandler(file) { // 上传头像
|
||||
const formData = new FormData();
|
||||
formData.append("file" , file.file);
|
||||
let res = await uploadImage(formData)
|
||||
@@ -400,13 +399,9 @@ export default {
|
||||
this.$toast('驾驶证首页未上传')
|
||||
return
|
||||
}
|
||||
/* if(!this.drivingLicenceContrary) {
|
||||
if(!this.drivingLicenceContrary) {
|
||||
this.$toast('驾驶证副页未上传')
|
||||
return
|
||||
}*/
|
||||
if(!this.icon) {
|
||||
this.$toast('免冠正面照未上传')
|
||||
return
|
||||
}
|
||||
let drivingLicenceName=this.drivingLicenceName.replace(/[^\u4e00-\u9fff]+/g, '');
|
||||
let driverName=this.driverName.replace(/[^\u4e00-\u9fff]+/g, '');
|
||||
|
||||
@@ -18,43 +18,6 @@
|
||||
</template>
|
||||
</van-nav-bar>
|
||||
</div>
|
||||
<van-search
|
||||
v-model="searchVal"
|
||||
show-action
|
||||
placeholder="请输入司机姓名、电话、身份证号"
|
||||
@search="resetHandler"
|
||||
>
|
||||
<template #action>
|
||||
<div @click="resetHandler">搜索</div>
|
||||
</template>
|
||||
</van-search>
|
||||
<div class="filterWrap">
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="idCardStatusList" placeholder="身份证录入状态" :class="{'customSel':true , 'has-value': idCardStatusList }" clearable>
|
||||
<el-option
|
||||
v-for="item in idCardStatusListOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="driverLicenseStatusList" placeholder="驾驶证录入状态" :class="{'customSel':true , 'has-value': driverLicenseStatusList }" clearable>
|
||||
<el-option
|
||||
v-for="item in driverLicenseStatusListOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="authStatusList" placeholder="认证状态" :class="{'customSel':true , 'has-value': authStatusList }" clearable>
|
||||
<el-option
|
||||
v-for="item in authStatesOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="wrap_cls">
|
||||
<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
|
||||
<van-list
|
||||
v-model="loading"
|
||||
@@ -62,33 +25,14 @@
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad"
|
||||
>
|
||||
<div class="itemWrap" v-for="(item,index) in driverList" :key="index" @click.stop="updateDriver(item)">
|
||||
<div class="itemWrap" v-for="(item,index) in driverList" :key="index">
|
||||
<div class="name-status">
|
||||
<div class="namephone">{{ item.driverName }} / {{ item.driverPhone }}
|
||||
<span style="margin-left: 10px" :class="item.states?.code == 1 ? 'statusYes' : 'statusNo'">{{ item.states?.label }}</span>
|
||||
</div>
|
||||
<div class="namephone">{{ item.driverName }} / {{ item.driverPhone }}</div>
|
||||
<div class="twoBtn">
|
||||
<!-- 只有启用状态下才展示停用按钮-->
|
||||
<button v-if="permissonList.includes('driverModifyBtn') && item.states?.code==1" class="del" @click.stop="handleStatus(item)">停用</button>
|
||||
<!-- <button v-if="permissonList.includes('driverModifyBtn')" class="revise" @click="updateDriver(item)">修改</button>-->
|
||||
<button v-if="permissonList.includes('driverModifyBtn')" class="del" @click="handleStatus(item)">{{ item.states?.label == '启用' ? '停用' : '启用' }}</button>
|
||||
<button v-if="permissonList.includes('driverModifyBtn')" class="revise" @click="updateDriver(item)">修改</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="juhe flex-between">
|
||||
<span class="zdJuhe">录入状态</span>
|
||||
<span class="flex-right">
|
||||
<span class="common_cls" v-if="item.idCardStatusStr" :class="getClass(item.idCardStatus)?.className">{{item.idCardStatusStr}}</span>
|
||||
<span class="common_cls" v-if="item.driverLicenseStatusStr" :class="getClass(item.driverLicenseStatus)?.className">{{item.driverLicenseStatusStr}}</span>
|
||||
</span>
|
||||
<!-- <span class="flex-right" v-if="item.idCardStatusStr">
|
||||
<span class="common_cls" :class="getClass(item.idCardStatus)?.className">{{item.idCardStatusStr}}</span>
|
||||
</span>-->
|
||||
</div>
|
||||
<div class="juhe flex-between">
|
||||
<span class="zdJuhe">认证状态</span>
|
||||
<span class="flex-right" v-if="item.authStatusStr">
|
||||
<span class="common_cls" :class="getClass(item.authStatusStr)?.className">{{item.authStatusStr}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="" style="display: flex">
|
||||
<div class="sex" style="margin-right: 40px">
|
||||
<span class="halfOpci">性 别:</span>
|
||||
@@ -103,24 +47,22 @@
|
||||
<span class="halfOpci">身份证号:</span>
|
||||
<span class="allOpci">{{ item.identityCardNumber }}</span>
|
||||
</div>
|
||||
<van-icon class="arrow_position" v-if="permissonList.includes('driverModifyBtn')" name="arrow" />
|
||||
<!-- <div>
|
||||
<div>
|
||||
<span class="halfOpci">状 态:</span>
|
||||
<span :class="item.states?.code == 1 ? 'statusYes' : 'statusNo'">{{ item.states?.label }}</span>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {myMixins} from "@/utils/myMixins"
|
||||
import {driverList, enableAction, userOperationPermissions} from "@/api/mine"
|
||||
import {Dialog} from "vant";
|
||||
import {driverList,enableAction,userOperationPermissions} from "@/api/mine"
|
||||
export default {
|
||||
name: "driverManage",
|
||||
mixins:[myMixins],
|
||||
@@ -137,40 +79,6 @@ export default {
|
||||
loading: false,
|
||||
finished: false,
|
||||
permissonList:[],
|
||||
searchVal:'',
|
||||
idCardStatusList:[],
|
||||
driverLicenseStatusList:[],
|
||||
authStatusList:[],
|
||||
idCardStatusListOptions: [{
|
||||
name: '身份证未录入',
|
||||
value: 0
|
||||
},{
|
||||
name: '身份证核验通过',
|
||||
value: 1
|
||||
},{
|
||||
name: '身份证核验不通过',
|
||||
value: 2
|
||||
}],
|
||||
authStatesOptions: [{
|
||||
name: '免冠正面照未录入',
|
||||
value: 1
|
||||
},{
|
||||
name: '免冠正面照认证通过',
|
||||
value: 3
|
||||
},{
|
||||
name: '免冠正面照认证不通过',
|
||||
value: 2
|
||||
}],
|
||||
driverLicenseStatusListOptions: [{
|
||||
name: '驾驶证未录入',
|
||||
value: 0
|
||||
},{
|
||||
name: '驾驶证认证通过',
|
||||
value: 1
|
||||
},{
|
||||
name: '驾驶证认证不通过',
|
||||
value: 2
|
||||
}],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -180,41 +88,9 @@ export default {
|
||||
// this.getDriverList()
|
||||
},
|
||||
methods:{
|
||||
getClass(id) {
|
||||
const ids = String(id)
|
||||
const steps = {
|
||||
0: {
|
||||
className: 'default_cls'
|
||||
},
|
||||
1: {
|
||||
className: 'success_cls'
|
||||
},
|
||||
2: {
|
||||
className: 'danger_cls'
|
||||
},
|
||||
'免冠正面照未录入': {
|
||||
className: 'default_cls'
|
||||
},
|
||||
'免冠正面照认证通过': {
|
||||
className: 'success_cls'
|
||||
},
|
||||
'免冠正面照认证不通过': {
|
||||
className: 'danger_cls'
|
||||
},
|
||||
}
|
||||
return steps[ids] || { className: 'default_cls' }
|
||||
},
|
||||
async resetHandler() {
|
||||
this.pageNum=1
|
||||
this.finished = false;
|
||||
this.total = 0;
|
||||
await this.getDriverList();
|
||||
},
|
||||
async onLoad(){
|
||||
await this.getDriverList()
|
||||
if (this.total>10){
|
||||
this.pageNum++;
|
||||
}
|
||||
// 加载状态结束
|
||||
this.loading = false;
|
||||
// 数据全部加载完成
|
||||
@@ -242,11 +118,7 @@ export default {
|
||||
async getDriverList(){
|
||||
let res = await driverList({
|
||||
pageNum:this.pageNum,
|
||||
pageSize:this.pageSize,
|
||||
searchVal: this.searchVal,
|
||||
idCardStatusList: this.idCardStatusList,
|
||||
driverLicenseStatusList: this.driverLicenseStatusList,
|
||||
authStatusList: this.authStatusList,
|
||||
pageSize:this.pageSize
|
||||
});
|
||||
if(res.code == 200){
|
||||
this.total=res.total
|
||||
@@ -258,11 +130,12 @@ export default {
|
||||
this.driverList = preList.concat(arr)
|
||||
}
|
||||
}
|
||||
console.log('this.driverList',this.driverList)
|
||||
},
|
||||
async getPermissions(){
|
||||
let res = await userOperationPermissions();
|
||||
this.permissonList = res.data
|
||||
// console.log("司机管理",this.permissonList.includes('driverAddBtn'))
|
||||
|
||||
},
|
||||
async handleStatus(item){
|
||||
if(item.states.code === 0){
|
||||
@@ -270,23 +143,14 @@ export default {
|
||||
}else{
|
||||
this.states = 0
|
||||
}
|
||||
Dialog.confirm({
|
||||
message: '当前状态为启用,是否要改为停用?',
|
||||
}).then(async () => {
|
||||
await enableAction({
|
||||
driverId:item.driverId,
|
||||
states:this.states
|
||||
})
|
||||
this.pageNum = 1;
|
||||
await this.getDriverList();
|
||||
}).catch(() => {
|
||||
});
|
||||
|
||||
},
|
||||
updateDriver(item){
|
||||
if(!this.permissonList.includes('driverModifyBtn')){//有权限才能修改
|
||||
return
|
||||
}
|
||||
// 在当前组件中进行路由跳转并传递参数对象
|
||||
this.$router.push({
|
||||
name: 'driverAdd', // 目标路由的名称
|
||||
@@ -321,7 +185,7 @@ export default {
|
||||
|
||||
.wrap {
|
||||
background: #F4F5F7;
|
||||
//@include sizingPadding(13px,13px);
|
||||
@include sizingPadding(13px,13px);
|
||||
@include wh(100%, 100%);
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -344,7 +208,7 @@ export default {
|
||||
}
|
||||
|
||||
.itemWrap {
|
||||
@include wh(100%, 140px);
|
||||
@include wh(100%, 104px);
|
||||
@include radiusSizing(6px);
|
||||
@include fontWeightSize(400, 12px);
|
||||
@include flexBetween;
|
||||
@@ -352,7 +216,6 @@ export default {
|
||||
box-shadow: 0px 2px 10px 0px rgba(216, 216, 216, 0.5);
|
||||
margin-bottom: 10px;
|
||||
padding: 11px 13px 9px 15px;
|
||||
position: relative;
|
||||
.halfOpci {
|
||||
opacity: .5;
|
||||
margin-right: 5px;
|
||||
@@ -361,15 +224,15 @@ export default {
|
||||
opacity: 1;
|
||||
}
|
||||
.statusNo {
|
||||
color: red;
|
||||
color: #FF0000;
|
||||
}
|
||||
.statusYes {
|
||||
color: green
|
||||
color: #09B820
|
||||
}
|
||||
}
|
||||
|
||||
.name-status {
|
||||
@include flexBetCen;
|
||||
@include flexColBet;
|
||||
.namephone {
|
||||
@include fontWeightSize(bold, 14px)
|
||||
}
|
||||
@@ -393,128 +256,6 @@ export default {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.filterWrap {
|
||||
width: 100%;
|
||||
padding-right: 13px;
|
||||
padding-left: 13px;
|
||||
display: flex;
|
||||
overflow-x: auto; /* 允许横向滚动 */
|
||||
white-space: nowrap; /* 防止子元素换行 */
|
||||
padding-bottom: 10px;
|
||||
-webkit-overflow-scrolling: touch; /* 在iOS上平滑滚动 */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
padding-bottom: 10px;
|
||||
/*padding: 10px;*/
|
||||
margin-bottom: 10px;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome/Safari */
|
||||
}
|
||||
.customSel {
|
||||
flex: 0 0 auto; /* 防止子元素被压缩 */
|
||||
width: calc(33% - 5px);
|
||||
/*width: 100%;*/
|
||||
height: 25px;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
font-size: 10px;
|
||||
color: #323233;
|
||||
margin-right: 5px;
|
||||
::v-deep .el-input__inner{
|
||||
padding: 0 2px;
|
||||
height: 25px;
|
||||
font-size: 10px;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
::v-deep .el-input__icon{
|
||||
line-height: 25px;
|
||||
font-size: 10px;
|
||||
width: 18px;
|
||||
color: #2A5094;
|
||||
}
|
||||
::v-deep .el-input__suffix{
|
||||
right: 2px;
|
||||
}
|
||||
}
|
||||
.customInput{
|
||||
/*width: 49%;*/
|
||||
width: 130px;
|
||||
}
|
||||
.has-value ::v-deep .el-input__inner{
|
||||
background: #F1F6FF ;
|
||||
color: #007BE9;
|
||||
font-weight: bold;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.has-value ::v-deep .el-input__icon{
|
||||
color: #007BE9;
|
||||
}
|
||||
.priceSel{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
color: #C0C4CC;
|
||||
.iconSpan{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 8px;
|
||||
}
|
||||
}
|
||||
.has-price{
|
||||
color: #007BE9 !important;
|
||||
}
|
||||
}
|
||||
.wrap_cls {
|
||||
width: 100%;
|
||||
padding-left: 13px;
|
||||
padding-right: 13px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.common_cls {
|
||||
color: #fff;
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
.default_cls {
|
||||
background-color: #B0BEC5;
|
||||
}
|
||||
.danger_cls {
|
||||
background-color: red;
|
||||
}
|
||||
.success_cls {
|
||||
background-color: #4CAF50;
|
||||
}
|
||||
.info_cls {
|
||||
background-color: #FF9800;
|
||||
}
|
||||
.main_cls {
|
||||
background-color: #6C9BFF;
|
||||
}
|
||||
.arrow_position {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50px;
|
||||
font-size: 20px;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.carType,.zdJuhe{
|
||||
opacity: .7;
|
||||
@include fontWeightSize(400,12px);
|
||||
margin-right: 8px;
|
||||
}
|
||||
/*.zdJuhe {
|
||||
width: 80px;
|
||||
text-align: right;
|
||||
margin-left: -10px;
|
||||
}*/
|
||||
.flex-between{
|
||||
line-height: 24px;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<img class="title1" src="@/assets/supplier/title1.png" alt="">
|
||||
<div class="credentials_wrap">
|
||||
<div class="credentials_item">
|
||||
<div class="credentials_title">1.法人身份证人像页</div>
|
||||
<div class="credentials_title">1. 法人身份证正面</div>
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
v-model="idFrontPhotoList"
|
||||
@@ -22,7 +22,7 @@
|
||||
</van-uploader>
|
||||
</div>
|
||||
<div class="credentials_item ml2">
|
||||
<div class="credentials_title">2.法人身份证国徽页</div>
|
||||
<div class="credentials_title">2. 法人身份证反面</div>
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
v-model="idBackPhotoList"
|
||||
@@ -35,7 +35,7 @@
|
||||
</van-uploader>
|
||||
</div>
|
||||
<div class="credentials_item ml2">
|
||||
<div class="credentials_title">3.营业执照</div>
|
||||
<div class="credentials_title">3. 营业执照</div>
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
v-model="companyPhotoList"
|
||||
@@ -47,19 +47,6 @@
|
||||
</div>
|
||||
</van-uploader>
|
||||
</div>
|
||||
<div class="credentials_item">
|
||||
<div class="credentials_title">4.开户许可证/基本存款账户信息</div>
|
||||
<van-uploader
|
||||
accept="image/*"
|
||||
v-model="licensePhotoList"
|
||||
:after-read="licensePhotoHandler"
|
||||
:max-size="5 * 1024 * 1024"
|
||||
max-count="1">
|
||||
<div class="custom-background">
|
||||
<img src="@/assets/supplier/licensePhoto.png" alt="">
|
||||
</div>
|
||||
</van-uploader>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="company_info">
|
||||
@@ -70,7 +57,6 @@
|
||||
<van-field :border="true" readonly v-model="form.legalName" class="required" name="legalName" label="法人姓名" placeholder="请输入" :rules="[{ required: true, message: '请输入法人姓名' }]" />
|
||||
<van-field :border="true" v-model="form.linkName" class="required" name="linkName" label="联系人姓名" placeholder="请输入" :rules="[{ required: true, message: '请输入联系人姓名' }]" />
|
||||
<van-field :border="true" v-model="form.linkPhone" class="required" name="linkPhone" label="联系电话" placeholder="请输入" :rules="phoneVerify" />
|
||||
<van-field :border="true" v-model="form.linkEmail" class="required" name="linkEmail" label="邮箱" placeholder="请输入" :rules="emailVerify" />
|
||||
<van-field :border="true" class="required" name="serviceType" label="服务能力">
|
||||
<template #input>
|
||||
<el-tree
|
||||
@@ -135,16 +121,13 @@
|
||||
return {
|
||||
clickFlag: true,
|
||||
phoneVerify: [{ required: true, message: '请输入联系电话' }, { validator: value => { return /^1[3456789]\d{9}$/.test(value) }, message: '联系电话格式不正确' }],
|
||||
emailVerify: [{ required: true, message: '请输入邮箱' }, { validator: value => { return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test(value) }, message: '邮箱格式不正确' }],
|
||||
id:'', //车辆Id
|
||||
idBackPhotoList: [],
|
||||
idBackPhoto: '',
|
||||
idFrontPhotoList: [],
|
||||
idFrontPhoto: '',
|
||||
companyPhotoList: [],
|
||||
licensePhotoList: [],
|
||||
companyPhoto: '',
|
||||
licensePhoto:'',
|
||||
form: {
|
||||
name: '',
|
||||
legalName: '',
|
||||
@@ -155,23 +138,6 @@
|
||||
trailCount: '',
|
||||
minorCount: '',
|
||||
serviceAreaCode: [],
|
||||
linkEmail:'',
|
||||
accountInfoDTO:{
|
||||
dutyParagraph:'',
|
||||
accountNumber:'',
|
||||
accountName:'',
|
||||
accountType:'',
|
||||
invoiceType:'',
|
||||
settlementType:'',
|
||||
shouldRate:'',
|
||||
realRate:'',
|
||||
unitName:'',
|
||||
bankNo:'',
|
||||
billingPhone:'',
|
||||
billingAddress:'',
|
||||
billHead:'',
|
||||
companyType:'',
|
||||
}
|
||||
},
|
||||
qrCodeUrl: '',
|
||||
qrCode: '',
|
||||
@@ -229,7 +195,6 @@
|
||||
this.idFrontPhoto = _data?.idCardFrontUrl;
|
||||
this.idBackPhoto = _data?.idCardBackUrl;
|
||||
this.companyPhoto = _data?.businessLicense;
|
||||
this.licensePhoto = _data?.accountUrl;
|
||||
this.wechatId = _data?.wechatId
|
||||
if(this.idFrontPhoto) {
|
||||
this.idFrontPhotoList = [{ url : this.idFrontPhoto }];
|
||||
@@ -240,9 +205,6 @@
|
||||
if(this.companyPhoto) {
|
||||
this.companyPhotoList = [{ url : this.companyPhoto }];
|
||||
}
|
||||
if(this.licensePhoto){
|
||||
this.licensePhotoList= [{ url : this.licensePhoto }];
|
||||
}
|
||||
if( _data.service ) {
|
||||
this.$refs.tree.setCheckedKeys(_data.service.split(','))
|
||||
}
|
||||
@@ -253,26 +215,21 @@
|
||||
},
|
||||
async applyAdd() {
|
||||
if( !this.idFrontPhoto ) {
|
||||
this.$toast('法人身份证人像页未上传')
|
||||
this.$toast('法人身份证正面照未上传')
|
||||
return
|
||||
}
|
||||
if( !this.idBackPhoto ) {
|
||||
this.$toast('法人身份证国徽页未上传')
|
||||
this.$toast('法人身份证反面照未上传')
|
||||
return
|
||||
}
|
||||
if( !this.companyPhoto ) {
|
||||
this.$toast('营业执照未上传')
|
||||
return
|
||||
}
|
||||
if( !this.licensePhoto ) {
|
||||
this.$toast('开户许可证未上传')
|
||||
return
|
||||
}
|
||||
if( !(this.form.serviceAreaCode.length > 0) ) {
|
||||
this.$toast('服务区域不能为空')
|
||||
return
|
||||
}
|
||||
// this.wechatId='wmOTNXBwAABrvKkE_Fh8ZN8Xm2S9v2wQ'
|
||||
if(!this.wechatId) {
|
||||
await this.QrCodeResult();
|
||||
if( !this.wechatId ) {
|
||||
@@ -280,6 +237,7 @@
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if( this.$refs.tree.getCheckedKeys().length > 0 ) {
|
||||
await this.saveHandler()
|
||||
} else {
|
||||
@@ -303,15 +261,22 @@
|
||||
_node.map(item => {
|
||||
checkArr.push(item.data.id)
|
||||
})
|
||||
|
||||
/* let treeArr = this.$refs.tree.getCheckedKeys();
|
||||
let childrenTreeArr = [];
|
||||
treeArr.map(item => {
|
||||
let _arr = this.supplierServiceList.filter(_item => _item.id == item) || [] // 获取对应的大类
|
||||
_arr[0]?.children?.map(childItem => {
|
||||
childrenTreeArr?.push(childItem?.id)
|
||||
})
|
||||
})
|
||||
let allArr = [...treeArr, ...childrenTreeArr]*/
|
||||
let res = await saveSupplier({
|
||||
id: this.id,
|
||||
...this.form,
|
||||
accountInfoJson:JSON.stringify(this.form.accountInfoDTO),
|
||||
accountInfoDTO:{},
|
||||
idCardFrontUrl: this.idFrontPhoto,
|
||||
idCardBackUrl: this.idBackPhoto,
|
||||
businessLicense: this.companyPhoto,
|
||||
accountUrl:this.licensePhoto,
|
||||
service: this.$refs.tree.getCheckedKeys().join(',') ,
|
||||
serviceAreaCode: checkArr.join(','),
|
||||
wechatId: this.wechatId,
|
||||
@@ -417,26 +382,8 @@
|
||||
})
|
||||
this.form.name = res?.data?.name;
|
||||
this.form.areaName = res?.data?.address
|
||||
this.form.accountInfoDTO.dutyParagraph=res?.data?.regNum
|
||||
this.form.accountInfoDTO.unitName = res?.data?.name
|
||||
this.form.accountInfoDTO.companyType=res?.data?.type
|
||||
await this.QrCodeHandler();
|
||||
},
|
||||
async licensePhotoHandler(file){// 开户许可证
|
||||
const formData = new FormData();
|
||||
formData.append("file" , file.file);
|
||||
let res = await uploadImage(formData);
|
||||
this.licensePhoto = res.data
|
||||
await this.licenseOcrHandler()
|
||||
},
|
||||
async licenseOcrHandler(){// 开户许可证ocr识别
|
||||
let res = await ocrHandler({
|
||||
ocrType: 15,
|
||||
imageUrl: this.licensePhoto,
|
||||
})
|
||||
this.form.accountInfoDTO.accountNumber=res?.data?.accountNumber
|
||||
this.form.accountInfoDTO.accountName = res?.data?.accountBank
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
regionText() {
|
||||
@@ -466,13 +413,12 @@
|
||||
padding: 0 20px;
|
||||
}
|
||||
.credentials_info {
|
||||
//height: 170px;
|
||||
height: 170px;
|
||||
}
|
||||
.credentials_wrap {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
.credentials_item {
|
||||
width: 32%;
|
||||
text-align: center;
|
||||
|
||||
@@ -28,22 +28,17 @@
|
||||
<div class="common_title">证件照信息</div>
|
||||
<div class="credentials_wrap">
|
||||
<div class="credentials_item">
|
||||
<div class="credentials_title">1.法人身份证人像页</div>
|
||||
<div class="credentials_title">1. 法人身份证正面</div>
|
||||
<img :src="supplierInfo?.idCardFrontUrl" alt="">
|
||||
</div>
|
||||
<div class="credentials_item ml2">
|
||||
<div class="credentials_title">2.法人身份证国徽页</div>
|
||||
<div class="credentials_title">2. 法人身份证反面</div>
|
||||
<img :src="supplierInfo?.idCardBackUrl" alt="">
|
||||
</div>
|
||||
<div class="credentials_item ml2">
|
||||
<div class="credentials_title">3.营业执照</div>
|
||||
<div class="credentials_title">3. 营业执照</div>
|
||||
<img :src="supplierInfo?.businessLicense" alt="">
|
||||
</div>
|
||||
<div class="credentials_item">
|
||||
<div class="credentials_title">4.开户许可证/基本存款账户信息</div>
|
||||
<img v-if="supplierInfo?.accountUrl" :src="supplierInfo?.accountUrl" alt="">
|
||||
<div v-else class="empty"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="company_info">
|
||||
@@ -77,10 +72,6 @@
|
||||
<div class="label">联系电话:</div>
|
||||
<div class="content">{{supplierInfo?.linkPhone}}</div>
|
||||
</div>
|
||||
<div class="info_item">
|
||||
<div class="label">邮箱:</div>
|
||||
<div class="content">{{supplierInfo?.linkEmail}}</div>
|
||||
</div>
|
||||
<div class="info_item">
|
||||
<div class="label">服务能力:</div>
|
||||
<div class="content service_color">{{supplierInfo?.serviceCategoryName}}</div>
|
||||
@@ -200,6 +191,7 @@
|
||||
id: this.id,
|
||||
});
|
||||
this.supplierInfo = res?.data;
|
||||
console.log('res', res)
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -267,7 +259,7 @@
|
||||
margin-top: 5px;
|
||||
}
|
||||
.supplier_content {
|
||||
padding: 0 20px;
|
||||
padding: 0 24px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -290,7 +282,6 @@
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
.credentials_item {
|
||||
width: 32%;
|
||||
text-align: center;
|
||||
@@ -299,14 +290,10 @@
|
||||
color: #4A4A4A;
|
||||
padding: 10px 0;
|
||||
}
|
||||
img,.empty{
|
||||
img {
|
||||
width: 97px;
|
||||
height: 64px;
|
||||
}
|
||||
.empty{
|
||||
border: 1px solid silver;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
.ml2 {
|
||||
margin-left: 2%;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
:safe-area-inset-top="true"
|
||||
@click-left="back"
|
||||
@click-left="h5GoBack"
|
||||
/>
|
||||
</div>
|
||||
<div class="addContentWrap">
|
||||
@@ -199,7 +199,7 @@
|
||||
<div class="isJoin">
|
||||
<van-radio-group v-model="vehicleStatus" :class="{ 'disabled-tree': vehicleInfoDisabled }" :disabled="vehicleInfoDisabled" @change="isVehicleChange" class="joinWrap">
|
||||
<van-radio :name="1" style="margin-right: 14px">
|
||||
启用
|
||||
启1用
|
||||
<img
|
||||
slot="icon"
|
||||
slot-scope="props"
|
||||
@@ -207,7 +207,7 @@
|
||||
>
|
||||
</van-radio>
|
||||
<van-radio :name="2" style="margin-right: 14px">
|
||||
停用
|
||||
停1用
|
||||
<img
|
||||
slot="icon"
|
||||
slot-scope="props"
|
||||
@@ -311,83 +311,9 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="lineBot" v-if="permissonList?.includes('hasInsuranceAudit')"></div>
|
||||
<div class="itemContent" v-if="permissonList?.includes('hasInsuranceAudit')">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>保费</span>
|
||||
</div>
|
||||
<van-field
|
||||
type="number"
|
||||
class="vanIpt"
|
||||
v-model="liabilityInsuranceAmount"
|
||||
input-align="right"
|
||||
>
|
||||
<template slot="right-icon" >
|
||||
<span style="white-space: nowrap;">元</span>
|
||||
</template>
|
||||
</van-field>
|
||||
</div>
|
||||
<div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>保额</span>
|
||||
</div>
|
||||
<div style="display:flex;align-items: center;justify-content: flex-end">
|
||||
<el-select
|
||||
v-model="liabilityInsuranceQuota"
|
||||
value-key="name"
|
||||
class="elSelect"
|
||||
collapse-tags="collapse-tags"
|
||||
placeholder="请选择" style="width: 55%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in liabilityQuotaOptions"
|
||||
:key="item.value"
|
||||
:label="item.value"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select><span style="margin-right: 16px;opacity: .5;">万元</span>
|
||||
</div>
|
||||
<!-- <van-field
|
||||
type="number"
|
||||
class="vanIpt"
|
||||
v-model="liabilityInsuranceQuota"
|
||||
input-align="right"
|
||||
>
|
||||
<template slot="right-icon" >
|
||||
<span style="white-space: nowrap;">万元 </span>
|
||||
</template>
|
||||
</van-field>-->
|
||||
</div>
|
||||
|
||||
<!-- <div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
<span>保单号(救援)</span>
|
||||
</div>
|
||||
<van-field
|
||||
class="vanIpt"
|
||||
style="width: 72%"
|
||||
v-model="insuranceCode"
|
||||
input-align="right"
|
||||
> </van-field>
|
||||
</div>
|
||||
<div class="lineBot"></div>
|
||||
<div class="itemContent">
|
||||
<div class="titleType"> <span>保单号(中道物流)</span> </div>
|
||||
<van-field
|
||||
class="vanIpt"
|
||||
style="width: 65%"
|
||||
v-model="insuranceCodeZd"
|
||||
input-align="right"
|
||||
> </van-field>
|
||||
</div>
|
||||
<div class="lineBot"></div>-->
|
||||
</template>
|
||||
|
||||
<div class="itemContent">
|
||||
<div class="titleType">
|
||||
<img class="startImg" src="@/assets/start.png" />
|
||||
@@ -418,7 +344,7 @@
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
<two-common-btn class="btn" @cancelClick="back" @submitClick="submitBtn" />
|
||||
<two-common-btn class="btn" @cancelClick="h5GoBack" @submitClick="submitBtn" />
|
||||
<van-calendar v-model="showDatePicker" :min-date="minDate"
|
||||
:max-date="maxDate" type="range" @confirm="onConfirm" />
|
||||
|
||||
@@ -614,7 +540,6 @@ export default {
|
||||
name: '其他',
|
||||
value: 14
|
||||
}],
|
||||
liabilityQuotaOptions:[{value:10},{value:20},{value:30},{value:50},{value:70},{value:80},{value:100},{value:200}],
|
||||
approvalForm:{
|
||||
type:2,
|
||||
supplierId:'',
|
||||
@@ -632,10 +557,7 @@ export default {
|
||||
vehicleInfoChange:false,
|
||||
insuranceChange:false,
|
||||
loading: false,
|
||||
liabilityInsuranceAmount:'',
|
||||
liabilityInsuranceQuota:'',
|
||||
insuranceCode:'',
|
||||
insuranceCodeZd:'',
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -822,8 +744,7 @@ export default {
|
||||
clickPreview(){
|
||||
console.log(' this.insurancePicturePhoto', this.insurancePicturePhoto)
|
||||
if(this.insurancePicturePhoto && this.insurancePicturePhoto.indexOf('.pdf') !== -1){
|
||||
let url=this.insurancePicturePhoto?.split(',')[0]
|
||||
window.open(url.replace("http://", "https://"))
|
||||
window.open(this.insurancePicturePhoto.replace("http://", "https://"))
|
||||
}
|
||||
},
|
||||
async insurancePictureFilesHandler(file) {
|
||||
@@ -831,7 +752,6 @@ export default {
|
||||
formData.append("file" , file.file);
|
||||
let res = await uploadImage(formData);
|
||||
this.insurancePicturePhoto = res.data;
|
||||
console.log('insurancePictureFilesHandler',this.insurancePictureFiles)
|
||||
},
|
||||
async ocrCarFrontHandler() { // 车辆正面 orc 识别
|
||||
let res = await ocrHandler({
|
||||
@@ -981,9 +901,8 @@ export default {
|
||||
this.insuranceCorp = result.insuranceCorp;
|
||||
this.liabilityInsuranceAudit = result.liabilityInsuranceAudit
|
||||
if(this.insurancePicturePhoto) {
|
||||
this.insurancePictureFiles = [{url: this.insurancePicturePhoto?.split(',')[0]}]
|
||||
this.insurancePictureFiles = [{url: this.insurancePicturePhoto}]
|
||||
}
|
||||
console.log('this.insurancePictureFiles',this.insurancePictureFiles)
|
||||
if( this.vehicleLicenseFront ) {
|
||||
this.vehicleLicenseFrontList = [{ url : this.vehicleLicenseFront }];
|
||||
}
|
||||
@@ -1030,7 +949,7 @@ export default {
|
||||
isVehicleChange(e) {
|
||||
this.vehicleStatus=e
|
||||
},
|
||||
/* async submitAuditHandle(){//提交审核
|
||||
async submitAuditHandle(){//提交审核
|
||||
let urls=[]
|
||||
this.insurancePictureFiles?.forEach(item => urls.push(item.url))
|
||||
let time =this.dateVal ? this.formatDateTimeRange(this.dateVal) : ''
|
||||
@@ -1108,7 +1027,7 @@ export default {
|
||||
this.approvalDialogShow=false
|
||||
await this.submitBtn();
|
||||
}
|
||||
},*/
|
||||
},
|
||||
async submitApprovalHandle(){//提交审批-走接口
|
||||
if(this.vehicleInfoChange){
|
||||
if(!(this.selectedOption.length > 0)){
|
||||
@@ -1211,14 +1130,6 @@ export default {
|
||||
this.vehicleInfoChange=false
|
||||
this.insuranceChange=false
|
||||
},
|
||||
back() {
|
||||
this.$router.push({
|
||||
name:'vehicleManage',
|
||||
params:{
|
||||
id: this.id
|
||||
}
|
||||
})
|
||||
},
|
||||
async submitBtn(){
|
||||
if( !this.vehicleLicenseFront ) {
|
||||
this.$toast('行驶证主页照片不能为空')
|
||||
@@ -1280,26 +1191,12 @@ export default {
|
||||
this.$toast('保单有效期不能为空')
|
||||
return
|
||||
}
|
||||
if( this.hasLiabilityInsurance == 1){
|
||||
if(this.permissonList.includes('hasInsuranceAudit') && !this.liabilityInsuranceAmount && this.liabilityInsuranceAmount!=0){
|
||||
this.$toast('保费不能为空')
|
||||
return
|
||||
}
|
||||
if(!this.liabilityInsuranceQuota){
|
||||
this.$toast('保额不能为空')
|
||||
return
|
||||
}
|
||||
/* if(!this.insuranceCode){
|
||||
this.$toast('保单号(救援)不能为空')
|
||||
return
|
||||
}*/
|
||||
}
|
||||
let timeObj;
|
||||
if(this.dateVal) {
|
||||
timeObj = this.formatDateTimeRange(this.dateVal)
|
||||
}
|
||||
this.serviceIds = this.$refs.tree.getCheckedKeys(true)
|
||||
// console.log('1122',this.vehicleStatus)
|
||||
console.log('1122',this.vehicleStatus)
|
||||
// return
|
||||
await saveVehicle({
|
||||
vehicleId:this.id ? this.id : '',
|
||||
@@ -1321,11 +1218,7 @@ export default {
|
||||
liabilityInsuranceEndTime: this.hasLiabilityInsurance == 1 ? (timeObj?.endTime || '') : '',
|
||||
virtualVehicle: this.virtualVehicle,
|
||||
canSubmitApproval:true,
|
||||
vehicleStatus:this.vehicleStatus,
|
||||
liabilityInsuranceAmount:this.liabilityInsuranceAmount,
|
||||
liabilityInsuranceQuota:this.liabilityInsuranceQuota,
|
||||
insuranceCode:this.insuranceCode,
|
||||
insuranceCodeZd:this.insuranceCodeZd,
|
||||
vehicleStatus:this.vehicleStatus
|
||||
})
|
||||
if(this.id){
|
||||
this.$toast('修改成功')
|
||||
@@ -1531,12 +1424,4 @@ export default {
|
||||
transform: translate(-50%, -50%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
.vanIpt{
|
||||
width: 80%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.vanIpt1{
|
||||
width: 72%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<van-search
|
||||
v-model="searchVal"
|
||||
show-action
|
||||
placeholder="请输入车辆名称、车牌号、车架号"
|
||||
placeholder="车辆名称/车牌号/车架号"
|
||||
@search="resetHandler"
|
||||
>
|
||||
<template #action>
|
||||
@@ -39,14 +39,6 @@
|
||||
></i>
|
||||
</template>
|
||||
</el-input>-->
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="authStates" placeholder="认证状态" :class="{'customSel':true , 'has-value': authStates }" clearable>
|
||||
<el-option
|
||||
v-for="item in authStatesOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="inputStatusList" placeholder="录入状态" :class="{'customSel':true , 'has-value': inputStatusList }" clearable>
|
||||
<el-option
|
||||
v-for="item in inputStatusListOptions"
|
||||
@@ -57,6 +49,14 @@
|
||||
</el-select>
|
||||
<!-- </div>-->
|
||||
<!-- <div>-->
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="authStates" placeholder="认证状态" :class="{'customSel':true , 'has-value': authStates }" clearable>
|
||||
<el-option
|
||||
v-for="item in authStatesOptions"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select @change="resetHandler" multiple :collapse-tags="true" v-model="liabilityInsuranceAuditList" placeholder="职业责任险" :class="{'customSel':true , 'has-value': liabilityInsuranceAuditList }" clearable>
|
||||
<el-option
|
||||
v-for="item in insuresOptions"
|
||||
@@ -79,12 +79,11 @@
|
||||
<div class="carItem" v-for="(item,index) in vehicleList" :key="index" @click.stop="updateVehicle(item)">
|
||||
<div class="carCode">
|
||||
<div class="codeLeft">{{item.plateNumber}} / {{item.vehicleTypeString}}
|
||||
<span class="ml10" :class="{'insuranceSuccess': item.vehicleStatus == 1, 'insuranceDanger': item.vehicleStatus == 2 ,'insuranceGray': !item.vehicleStatus }">{{ item.vehicleStatus == 1 ? '启用' :( item.vehicleStatus == 2 ? '停用' : ( item.vehicleStatus == 12 ? '否-服务商停用' : '无状态')) }} </span>
|
||||
<span class="ml10" @click.stop="updateStatus(item)" :class="{'insuranceSuccess': item.vehicleStatus == 1, 'insuranceDanger': item.vehicleStatus == 2 ,'insuranceGray': !item.vehicleStatus }">{{ item.vehicleStatus == 1 ? '启用' :( item.vehicleStatus == 2 ? '停用' : ( item.vehicleStatus == 12 ? '否-服务商停用' : '无状态')) }} </span>
|
||||
</div>
|
||||
<div class="codeRight" v-if="item.vehicleStatus == 1" @click.stop="updateStatus(item)">停用</div>
|
||||
|
||||
</div>
|
||||
<div class="juhe flex-between">
|
||||
<span class="zdJuhe">核验认证</span>
|
||||
<span class="flex-right">
|
||||
<span class="common_cls" v-if="item.inputStatusString" :class="getClass(item.inputStatusString)?.className">{{item.inputStatusString}}</span>
|
||||
<span class="common_cls" v-if="item.authStateString" :class="getClass(item.authStateString)?.className">{{item.authStateString}}</span>
|
||||
@@ -96,12 +95,12 @@
|
||||
<span class="common_cls" @click.stop="showTip(item.liabilityInsuranceAuditMsg)" :class="getClass(item.rescueInsurance)?.className">{{item.rescueInsurance}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<!-- <div class="juhe flex-between">
|
||||
<div class="juhe flex-between">
|
||||
<span class="zdJuhe">车辆信息</span>
|
||||
<span class="flex-right" v-if="item.auditStatusStr">
|
||||
<span class="common_cls" @click.stop="showTip(item.auditMsg)" :class="getClass(item.auditStatusStr)?.className">{{item.auditStatusStr}}</span>
|
||||
</span>
|
||||
</div>-->
|
||||
</div>
|
||||
<div class="juhe flex-between">
|
||||
<span class="zdJuhe">最近登录时间</span>
|
||||
<span class="flex-right">{{item.lastLoginTime}}</span>
|
||||
@@ -250,9 +249,7 @@ export default {
|
||||
},
|
||||
async onLoad(){
|
||||
await this.getVehicleList()
|
||||
if(this.total>10){
|
||||
this.pageNum++;
|
||||
}
|
||||
// 加载状态结束
|
||||
this.loading = false;
|
||||
// 数据全部加载完成
|
||||
@@ -415,12 +412,6 @@ export default {
|
||||
.codeLeft{
|
||||
@include fontWeightSize(bold,14px)
|
||||
}
|
||||
.codeRight{
|
||||
padding: 2px 8px;
|
||||
border: 1px solid #DDDDDD;
|
||||
border-radius: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.twoBtn{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -74,7 +74,6 @@
|
||||
<div class="item">
|
||||
<span class="leftTitle fontColor">服务师傅:</span><span class="rightContent">{{ orderDetailInfo.driverName }} {{orderDetailInfo.drivePhone ? '/' : ''}} {{orderDetailInfo.drivePhone }}
|
||||
<span v-if="queryType == 5" class="driverPoiBtn" @click="noMultipleClicks(showMap)">查看司机位置</span>
|
||||
<span v-if="orderDetailInfo.driverName && orderDetailInfo.proprietary?.code==1" class="driverPoiBtn" @click="noMultipleClicks(createDriverInfo)">生成司机信息</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="item" v-if="queryType == 9 || queryType ==11 || queryType ==12">
|
||||
@@ -115,7 +114,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import {myMixins} from '@/utils/myMixins'
|
||||
import {getOrderDetail,showVehiclePositionInfo, getConfigByCode,getDriverInfo} from "@/api/order"
|
||||
import {getOrderDetail,showVehiclePositionInfo, getConfigByCode} from "@/api/order"
|
||||
import minePosition from '@/assets/minePosition.png';
|
||||
import vehiclePosition from '@/assets/vehiclePosition.png';
|
||||
import desitationPosition from '@/assets/desitationPosition.png'
|
||||
@@ -162,30 +161,6 @@ export default {
|
||||
});
|
||||
this.carTypeList = res?.data?.userVehicleType
|
||||
},
|
||||
async getDriverInfo(){
|
||||
let result=await getDriverInfo({
|
||||
driverId:this.orderDetailInfo.driverId
|
||||
})
|
||||
if(result.data){
|
||||
// console.log('--result--',result.data)
|
||||
let params={
|
||||
'姓名:':this.orderDetailInfo.driverName,
|
||||
'身份证:':result.data.identityCardNumber,
|
||||
'车牌:':this.orderDetailInfo.plateNumber,
|
||||
'手机:':this.orderDetailInfo.driverPhone,
|
||||
}
|
||||
let data = {"action":"copyToClipboard","params":JSON.stringify(params)}
|
||||
var u = navigator.userAgent;
|
||||
var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
|
||||
if(isiOS){
|
||||
window.webkit.messageHandlers.nativeObject.postMessage(data);
|
||||
}else {
|
||||
window.android.copyToClipboard(JSON.stringify(params));
|
||||
}
|
||||
}else {
|
||||
this.$toast('未获取到司机信息')
|
||||
}
|
||||
},
|
||||
async getDetail(){
|
||||
let result=await getOrderDetail({
|
||||
queryType:this.queryType,
|
||||
@@ -201,9 +176,6 @@ export default {
|
||||
this.showPopup = true;
|
||||
this.mapMarkers();
|
||||
},
|
||||
async createDriverInfo(){//生成司机信息
|
||||
await this.getDriverInfo()
|
||||
},
|
||||
checkPhoto(){
|
||||
let isAllowImage = this.queryType == 9 ? 0 : 1
|
||||
let data = {
|
||||
|
||||
@@ -1147,8 +1147,8 @@ export default {
|
||||
{label: '服务车辆', prop: 'vehicleName'},
|
||||
{label: '服务完成状况', prop: 'orderStatusString'},
|
||||
{label: '案件完成时间', prop: 'finishTime'},
|
||||
{label: '省(B)', prop: 'bprovince'},
|
||||
{label: '市(B)', prop: 'bcity'},
|
||||
{label: '省(B)', prop: 'bProvince'},
|
||||
{label: '市(B)', prop: 'bCity'},
|
||||
{label: '区(B)', prop: 'area'},
|
||||
]
|
||||
} else if (this.active === 6) {//投诉明细
|
||||
@@ -1626,13 +1626,13 @@ export default {
|
||||
getTitle(type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return '客户评价';
|
||||
return '接单时效';
|
||||
case 1:
|
||||
return 'APP使用';
|
||||
return '客户评价';
|
||||
case 2:
|
||||
return 'APP使用';
|
||||
case 3:
|
||||
return '时效';
|
||||
/* case 3:
|
||||
return '时效';*/
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,453 +0,0 @@
|
||||
<template>
|
||||
<div class="wrap">
|
||||
<div class="navBar">
|
||||
<van-nav-bar
|
||||
title="人员信息"
|
||||
:left-arrow="Boolean(!isWebFunc())"
|
||||
left-arrow-color="#FFFFFF"
|
||||
:border="false"
|
||||
:fixed="true"
|
||||
:safe-area-inset-top="true"
|
||||
@click-left="goBack"
|
||||
/>
|
||||
</div>
|
||||
<div :class="{'tipWrap':true,'yelBg':type==3,'greBg':type==4}">
|
||||
<img v-show="[1,2].includes(type)" src="@/assets/unpass.png" />
|
||||
<img v-show="[3].includes(type)" src="@/assets/yelTip.png" />
|
||||
<img v-show="[4].includes(type)" src="@/assets/greTip.png" />
|
||||
<span v-if="type==1">请立即核对或修改以下信息:姓名/身份/电话/微信号/邮箱</span>
|
||||
<span v-else-if="type==2">“角色”无法修改,如需修改“角色”请联系区域经理。提交审批后请到【管理人员】模块进行查看。</span>
|
||||
<span v-else-if="type==3">当前信息正在确认中,如需调整请联系区域经理。</span>
|
||||
<span v-else-if="type==4">当前信息已确认,如需调整请联系区域经理。</span>
|
||||
</div>
|
||||
<van-loading v-show="personList.length<=0" class="loadingWrap" type="spinner" color="#1989fa" />
|
||||
<div class="contentWrap" v-show="personList.length>0"
|
||||
:style="{'height':([1,2].includes(type) && isMaster) ? 'calc(100% - 160px)' : 'calc(100% - 90px)'}">
|
||||
<div class="itemWrap" v-for="(item,index) in personList" :key="index">
|
||||
<div class="opaCol">人员{{(index+1)}}:</div>
|
||||
<div class="line"></div>
|
||||
<div class="item">
|
||||
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>姓名:</span></div>
|
||||
<div class="right">
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model="item.name" placeholder="请输入" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="left opaCol"><span class="star" style="opacity: 0">*</span><span>角色:</span></div>
|
||||
<div class="right" :class="{'opaCol':type==2}">
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" readonly v-model="item.roleName" placeholder="请输入" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>电话1:</span></div>
|
||||
<div class="right">
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model.number="item.phone1" placeholder="请输入" @blur="blurHandle" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="left" :class="{'opaCol':type!=2}"><span class="star" style="opacity: 0">*</span><span>电话2:</span></div>
|
||||
<div class="right">
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model.number="item.phone2" @blur="blurHandle" placeholder="请输入" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="left" :class="{'opaCol':type!=2}"><span class="star">*</span><span>微信号:</span></div>
|
||||
<div class="right wechatRight">
|
||||
<span class="reviseBtn" v-show="type==2" @click="wechatRevise(item,index)">修改</span>
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" readonly v-model="item.wechatName" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="left" :class="{'opaCol':type!=2}"><span class="star" style="opacity: 0">*</span><span>邮箱:</span></div>
|
||||
<div class="right">
|
||||
<van-field :input-align="type==2 ? 'right' : 'left'" :readonly="type!=2" v-model="item.email" placeholder="请输入" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btnWrap" v-if="isMaster && [1,2].includes(type)">
|
||||
<div v-show="type==2" class="audit common" @click="auditHandle">提交审批</div>
|
||||
<div v-show="type==1" class="revise common" @click="reviseHandle">立即修改</div>
|
||||
<div v-show="type==1" class="confirm common" @click="confirmHandle">确认信息无误</div>
|
||||
</div>
|
||||
<van-dialog v-model="dialogShow" title="请将此二维码发送至相应人员进行添加,成功添加后将更新微信号。" show-cancel-button
|
||||
confirmButtonText="确认已添加" confirmButtonColor="#354E93" className="customDialog"
|
||||
@confirm="wechatConfirm" @cancel="cancelHandle">
|
||||
<img v-if="wechatInfo?.qrCode" :src="wechatInfo.qrCode" style="width: 83%"/>
|
||||
</van-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import {myMixins} from "@/utils/myMixins"
|
||||
import {getConfirmPerson,getConfirmStatus,getQrCode,confirmAddWechat,confirm,submitConfirm} from "@/api/authentication";
|
||||
import { Dialog } from 'vant';
|
||||
export default {
|
||||
name: "personList",
|
||||
mixins:[myMixins],
|
||||
data(){
|
||||
return{
|
||||
noClick:true,
|
||||
id:'',
|
||||
type:'',//1确认信息 2修改 3审批中 4已确认
|
||||
personList:[],
|
||||
dialogShow:false,
|
||||
reviseIndex:-1,
|
||||
supplierId:'',
|
||||
wechatInfo:'',
|
||||
personInfoId:'',
|
||||
personInfo:'',
|
||||
isMaster:false,
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data === 'dialogClosed') {
|
||||
// console.log('Dialog 已关闭 // 执行关闭后的逻辑');
|
||||
}
|
||||
});
|
||||
// console.log('isWebFunc()',this.isWebFunc())
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
this.id=this.$route.query.id || urlParams.get('id');
|
||||
this.supplierId=this.$route.query.supplierId || urlParams.get('supplierId');
|
||||
// this.supplierId=1128
|
||||
console.log('1111',this.supplierId)
|
||||
await this.getPersonList()
|
||||
},
|
||||
methods:{
|
||||
blurHandle(e){
|
||||
let val= e.target.value || ''
|
||||
let flag=this.validatePhone(val)
|
||||
// console.log('flag',flag)
|
||||
if(!flag){
|
||||
this.$toast('电话号码格式不正确')
|
||||
}
|
||||
},
|
||||
validatePhone(val) {
|
||||
console.log('val',val)
|
||||
if(!val){
|
||||
return true
|
||||
}
|
||||
const purePhone = String(val).trim()
|
||||
const mobileReg = /^1[3-9]\d{9}$/ // 大陆手机号正则表达式
|
||||
const hkMobileReg = /^[569]\d{3}[\s-]?\d{4}$/ // 香港手机号正则表达式,允许使用空格或 "-" 分隔
|
||||
const macauMobileReg = /^6\d{3}[\s-]?\d{4}$/ // 澳门手机号正则表达式,允许使用空格或 "-" 分隔
|
||||
const telReg = /^(0\d{2,3})([\s-])?\d{7,8}$/ // 大陆座机号正则表达式,允许区号和座机号用空格或 "-" 分开
|
||||
const hkTelReg = /^\(?\d{2,4}\)?[\s-]?\d{4}[\s-]?\d{4}$/ // 香港座机号正则表达式,允许使用空格或 "-" 分隔
|
||||
const macauTelReg = /^\(?\d{2,4}\)?[\s-]?\d{4}[\s-]?\d{4}$/ // 澳门座机号正则表达式,允许使用空格或 "-" 分隔
|
||||
const phone400Reg = /^400[\s-]?\d{3}[\s-]?\d{4}$/ // 以 "400" 开头的号码正则表达式,允许使用空格或 "-" 分隔
|
||||
// 情况1:12位且首位是0、第二位是1 → 去0后按大陆手机号校验
|
||||
if (/^01[0-9]{10}$/.test(purePhone)) {
|
||||
return true
|
||||
}
|
||||
// 匹配任意一种格式即为合法
|
||||
if (mobileReg.test(purePhone) || hkMobileReg.test(purePhone) || macauMobileReg.test(purePhone) ||
|
||||
telReg.test(purePhone) || hkTelReg.test(purePhone) || macauTelReg.test(purePhone) ||
|
||||
phone400Reg.test(purePhone)) {
|
||||
return true
|
||||
}
|
||||
// 其他情况 → 不合法
|
||||
return false
|
||||
},
|
||||
async getPersonList(){
|
||||
let result=await getConfirmStatus({supplierId:this.supplierId})
|
||||
if(result.data?.wechatConfirmStatus==2){
|
||||
this.type=3
|
||||
}else if(result.data?.wechatConfirmStatus==3){
|
||||
this.type=4
|
||||
}else if(!result.data?.wechatConfirmStatus || result.data?.wechatConfirmStatus==1){
|
||||
this.type=1
|
||||
}
|
||||
this.isMaster=result.data.isMaster
|
||||
// this.type=2
|
||||
let res=await getConfirmPerson({supplierId:this.supplierId})
|
||||
if(res.data && res.data.length>0){
|
||||
this.personList=res.data
|
||||
}else{
|
||||
this.personList=[]
|
||||
}
|
||||
},
|
||||
async wechatConfirm(){//确认已添加微信按钮
|
||||
Dialog.confirm({
|
||||
message:'请确认相关人员是否已添加该二维码。',
|
||||
confirmButtonText:'确认',
|
||||
cancelButtonText:'取消',
|
||||
confirmButtonColor:'#354E93',
|
||||
}).then(async() => {
|
||||
let res=await confirmAddWechat({supplierId:this.supplierId,supplierPersonInfoId:this.personInfoId})
|
||||
console.log('res',this.personInfo,res.data?.name,this.personInfo.wechatName)
|
||||
if((res.data?.name == this.personInfo.wechatName) || (!res.data && this.personInfo.wechatName)){
|
||||
console.log('11111111')
|
||||
this.$set(this.personList[this.reviseIndex],'isChange',false)
|
||||
}else {
|
||||
console.log('2222222')
|
||||
this.$set(this.personList[this.reviseIndex],'isChange',true)
|
||||
}
|
||||
console.log('this.personList',this.personList)
|
||||
let flagRevise=this.personList.some(item => 'isChange' in item && !item.isChange)
|
||||
console.log('存在未修改',flagRevise)
|
||||
if(res.data){
|
||||
this.personList[this.reviseIndex].wechatId=res.data?.externalUserId
|
||||
this.personList[this.reviseIndex].wechatName=res.data?.name
|
||||
}
|
||||
await this.cancelHandle()
|
||||
}).catch(async () => {
|
||||
await this.cancelHandle()
|
||||
|
||||
});
|
||||
},
|
||||
cancelHandle(){
|
||||
this.dialogShow=false
|
||||
this.wechatInfo=''
|
||||
this.reviseIndex=-1
|
||||
this.personInfoId=''
|
||||
},
|
||||
async wechatRevise(item,index){
|
||||
console.log('item,index',item,index)
|
||||
// console.log('item',item)
|
||||
this.personInfoId=item.id
|
||||
this.reviseIndex=index
|
||||
this.personInfo=item
|
||||
await this.getCode()
|
||||
this.dialogShow=true
|
||||
},
|
||||
async getCode(){//获取二维码
|
||||
let res = await getQrCode({supplierId:this.supplierId,supplierPersonInfoId:this.personInfoId})
|
||||
// console.log('res--getCode',res)
|
||||
this.wechatInfo=res.data || ''
|
||||
},
|
||||
async auditHandle(){//提交审批
|
||||
let flag=this.personList.every(item => item.name && item.phone1 && item.wechatId && item.wechatName)
|
||||
if(!flag){
|
||||
this.$toast('必填项不可为空')
|
||||
return
|
||||
}
|
||||
console.log('----',this.personList)
|
||||
let flagRevise=this.personList.some(item => 'isChange' in item && !item.isChange)
|
||||
console.log('存在未修改',flagRevise)
|
||||
if(flagRevise){
|
||||
this.$toast('您仍未修改微信号,请先修改再提交审批。')
|
||||
return
|
||||
}
|
||||
let phone1Flag= this.personList.every(item => this.validatePhone(item.phone1))
|
||||
let phone2Flag= this.personList.every(item => (item.phone2 && this.validatePhone(item.phone2) || !item.phone2))
|
||||
console.log('phone1Flag',phone1Flag)
|
||||
console.log('phone2Flag',phone2Flag)
|
||||
if(!phone1Flag || !phone2Flag){
|
||||
this.$toast('电话号码格式不正确')
|
||||
return
|
||||
}
|
||||
await submitConfirm({supplierId:this.supplierId,infos:this.personList})
|
||||
this.$toast('操作成功')
|
||||
if(this.isWebFunc()){
|
||||
setTimeout(()=>{
|
||||
this.closeParentDialog()
|
||||
},1500)
|
||||
}else{
|
||||
setTimeout(()=>{
|
||||
this.goBack()
|
||||
},1500)
|
||||
}
|
||||
},
|
||||
async reviseHandle(){//修改
|
||||
this.type=2
|
||||
},
|
||||
async confirmHandle(){//确认信息无误
|
||||
let flag=this.personList.every(item => item.name && item.phone1 && item.wechatId && item.wechatName)
|
||||
if(!flag){
|
||||
this.$toast('必填项不可为空,请点击“立即修改”将信息补充完整')
|
||||
return
|
||||
}
|
||||
Dialog.confirm({
|
||||
message:'请务必仔细确认信息是否无误。',
|
||||
confirmButtonText:'确认无误',
|
||||
cancelButtonText:'返回',
|
||||
confirmButtonColor:'#354E93',
|
||||
}).then(async() => {
|
||||
// console.log('确认无误')
|
||||
await confirm({supplierId:this.supplierId})
|
||||
this.$toast('操作成功')
|
||||
if(this.isWebFunc()){
|
||||
setTimeout(()=>{
|
||||
this.closeParentDialog()
|
||||
},1500)
|
||||
}else{
|
||||
setTimeout(()=>{
|
||||
this.goBack()
|
||||
},1500)
|
||||
}
|
||||
}).catch(() => {
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.customDialog {
|
||||
.van-dialog__content{
|
||||
text-align: center !important;
|
||||
}
|
||||
.van-dialog__header {
|
||||
box-sizing: border-box;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/common.scss";
|
||||
@import '@/styles/mixin.scss';
|
||||
.wrap {
|
||||
@include wh(100%, 100%);
|
||||
position: relative;
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.navBar{
|
||||
margin-bottom: 46px;
|
||||
}
|
||||
.tipWrap{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 8px 8px 18px;
|
||||
margin-bottom: 10px;
|
||||
display: flex;
|
||||
background-color: #FFF6F2;
|
||||
img{
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
//vertical-align: middle;
|
||||
margin-right: 5px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
span{
|
||||
color: #FC3C06;
|
||||
}
|
||||
}
|
||||
.yelBg{
|
||||
background-color: #FFFFED ;
|
||||
span{
|
||||
color: #F36708;
|
||||
}
|
||||
}
|
||||
.greBg{
|
||||
background-color: #E8FFF3;
|
||||
span{
|
||||
color: #19AC43;
|
||||
}
|
||||
}
|
||||
/*.headerWrap{
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 15px 16px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.back{
|
||||
@include wh(15px,15px);
|
||||
}
|
||||
span{
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
color: #203152;
|
||||
}
|
||||
}*/
|
||||
.loadingWrap{
|
||||
width: 100%;
|
||||
height: calc(100% - 90px);
|
||||
text-align: center;
|
||||
line-height: 200px;
|
||||
}
|
||||
.contentWrap{
|
||||
//height: calc(100% - 160px);
|
||||
//height: calc(100% - 90px);//没有按钮时
|
||||
overflow-y: auto;
|
||||
.itemWrap{
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: #FFFFFF;
|
||||
box-sizing: border-box;
|
||||
padding:10px 15px 10px 20px;
|
||||
.line{
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
border-bottom: 2px solid;
|
||||
opacity: 0.16;
|
||||
margin-top: 10px;
|
||||
border-image: linear-gradient(270deg, rgba(217, 217, 217, 0.6), rgba(178, 178, 178, 1), rgba(178, 178, 178, 1), rgba(217, 217, 217, 0.6)) 1 1;
|
||||
}
|
||||
.item{
|
||||
//line-height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.left{
|
||||
width: 66px;
|
||||
}
|
||||
.right{
|
||||
flex: 1;
|
||||
}
|
||||
.wechatRight{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.reviseBtn{
|
||||
display: inline-block;
|
||||
width: 60px;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
background-color: #354D93;
|
||||
color: #FFFFFF;
|
||||
box-sizing: border-box;
|
||||
padding: 2px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.opaCol{
|
||||
color: #323643;
|
||||
opacity: .65;
|
||||
}
|
||||
.star{
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
color: #FF0808;
|
||||
}
|
||||
}
|
||||
}
|
||||
.btnWrap{
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 10px 19px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background-color: #F6F6F6;
|
||||
.common{
|
||||
background: #354D93;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
.audit{
|
||||
width: 100%;
|
||||
}
|
||||
.revise{
|
||||
width: 30%;
|
||||
background-color: #FFFFFF;
|
||||
color: #354D93;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #354D93;
|
||||
}
|
||||
.confirm{
|
||||
width: 67%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -478,21 +478,6 @@ export default {
|
||||
otherPhoto:this.otherImgSrc?.join(',')
|
||||
})
|
||||
this.clearStorageFormInfo()
|
||||
if(res.code == 200 && !res.msg){
|
||||
this.$toast('发布成功')
|
||||
if(this.isWebFunc()){
|
||||
setTimeout(()=>{
|
||||
this.closeParentDialog()
|
||||
},1000)
|
||||
}else{
|
||||
setTimeout(()=>{
|
||||
this.$router.push({ name: "mineRelease"})
|
||||
sessionStorage.setItem('mineActiveTab',String(1) )
|
||||
},1000)
|
||||
}
|
||||
}else{
|
||||
this.$toast(res.msg)
|
||||
}
|
||||
console.log("车源发布publishCarInfo",res)
|
||||
} catch (e){
|
||||
console.log('e',e)
|
||||
|
||||
Reference in New Issue
Block a user