✨ 异常处置新增编辑功能
列表操作列新增「编辑」,弹窗内只呈现运单信息与可编辑项, 按项目既有习惯用 section-card 分组、el-descriptions 展示只读信息、 el-row/el-col 排可编辑字段。 异常类型与异常原因的下拉值改为中文原文:库里 exception_type 存大类中文名、 exception_reason 存子类中文名(小程序上报即如此)。原先一级 value 是英文码 (traffic),而查询按该值做精确匹配,导致按异常类型筛选一行都查不到。 现场照片支持增删,上传走与我方 OSS 端点一致的 put-file 接口。
This commit is contained in:
@@ -9,6 +9,8 @@ export const getDetail = id => request({ url: `${baseUrl}/detail`, method: 'get'
|
|||||||
|
|
||||||
export const follow = data => request({ url: `${baseUrl}/follow`, method: 'post', data });
|
export const follow = data => request({ url: `${baseUrl}/follow`, method: 'post', data });
|
||||||
|
|
||||||
|
export const update = data => request({ url: `${baseUrl}/update`, method: 'post', data });
|
||||||
|
|
||||||
export const complete = data => request({ url: `${baseUrl}/complete`, method: 'post', data });
|
export const complete = data => request({ url: `${baseUrl}/complete`, method: 'post', data });
|
||||||
|
|
||||||
export const batchComplete = ids =>
|
export const batchComplete = ids =>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
// 一级 value 与二级 value 都用中文原文:库里 exception_type 存的是大类中文名、
|
||||||
|
// exception_reason 存子类中文名(小程序上报即如此),此处必须与之一致,
|
||||||
|
// 否则按异常类型做精确匹配的查询会一行都查不到。
|
||||||
export const exceptionCategoryOptions = [
|
export const exceptionCategoryOptions = [
|
||||||
{
|
{
|
||||||
label: '交通异常',
|
label: '交通异常',
|
||||||
value: 'traffic',
|
value: '交通异常',
|
||||||
children: [
|
children: [
|
||||||
{ label: '道路拥堵', value: '道路拥堵' },
|
{ label: '道路拥堵', value: '道路拥堵' },
|
||||||
{ label: '交通事故', value: '交通事故' },
|
{ label: '交通事故', value: '交通事故' },
|
||||||
@@ -12,7 +15,7 @@ export const exceptionCategoryOptions = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '车辆异常',
|
label: '车辆异常',
|
||||||
value: 'vehicle',
|
value: '车辆异常',
|
||||||
children: [
|
children: [
|
||||||
{ label: '车辆故障维修', value: '车辆故障维修' },
|
{ label: '车辆故障维修', value: '车辆故障维修' },
|
||||||
{ label: '车辆事故', value: '车辆事故' },
|
{ label: '车辆事故', value: '车辆事故' },
|
||||||
@@ -24,7 +27,7 @@ export const exceptionCategoryOptions = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '货物异常',
|
label: '货物异常',
|
||||||
value: 'cargo',
|
value: '货物异常',
|
||||||
children: [
|
children: [
|
||||||
{ label: '货损', value: '货损' },
|
{ label: '货损', value: '货损' },
|
||||||
{ label: '货差', value: '货差' },
|
{ label: '货差', value: '货差' },
|
||||||
@@ -35,7 +38,7 @@ export const exceptionCategoryOptions = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '其他异常',
|
label: '其他异常',
|
||||||
value: 'other',
|
value: '其他异常',
|
||||||
children: [
|
children: [
|
||||||
{ label: '变更路线地址', value: '变更路线地址' },
|
{ label: '变更路线地址', value: '变更路线地址' },
|
||||||
{ label: '其他', value: '其他异常-其他' },
|
{ label: '其他', value: '其他异常-其他' },
|
||||||
@@ -43,6 +46,16 @@ export const exceptionCategoryOptions = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** 一级类型的中文名列表,供编辑表单的级联选择使用 */
|
||||||
|
export const exceptionTypeOptions = exceptionCategoryOptions.map(item => ({
|
||||||
|
label: item.label,
|
||||||
|
value: item.value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
/** 按一级类型取二级选项 */
|
||||||
|
export const exceptionReasonOptions = typeValue =>
|
||||||
|
exceptionCategoryOptions.find(item => item.value === typeValue)?.children || [];
|
||||||
|
|
||||||
export const disposalStatusOptions = [
|
export const disposalStatusOptions = [
|
||||||
{ label: '待处理', value: 'pending' },
|
{ label: '待处理', value: 'pending' },
|
||||||
{ label: '处理中', value: 'processing' },
|
{ label: '处理中', value: 'processing' },
|
||||||
@@ -89,3 +102,21 @@ export const followColumns = [
|
|||||||
{ label: '跟进人', prop: 'followUserName', minWidth: 130 },
|
{ label: '跟进人', prop: 'followUserName', minWidth: 130 },
|
||||||
{ label: '跟进时间', prop: 'followTime', minWidth: 170 },
|
{ label: '跟进时间', prop: 'followTime', minWidth: 170 },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// 编辑表单只开放上报四件套。车牌、项目、承运商、配载单号由上报时从运单回填,
|
||||||
|
// 允许手改会让记录与运单脱钩;处置状态由跟进与完成流转,不在此处。
|
||||||
|
export const editFormFields = [
|
||||||
|
{ label: '异常类型', prop: 'exceptionType', type: 'select', required: true },
|
||||||
|
{ label: '异常原因', prop: 'exceptionReason', type: 'select' },
|
||||||
|
{ label: '上报说明', prop: 'reportDescription', type: 'textarea', required: true, span: 2 },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 编辑弹窗顶部的运单信息,只读展示,帮助运管员确认改的是哪一单
|
||||||
|
export const editWaybillFields = [
|
||||||
|
{ label: '运单号', prop: 'waybillNo' },
|
||||||
|
{ label: '配载单号/总单号', prop: 'loadingOrMasterNo' },
|
||||||
|
{ label: '车牌号', prop: 'vehicleNo' },
|
||||||
|
{ label: '项目', prop: 'projectName' },
|
||||||
|
{ label: '承运商', prop: 'carrierName' },
|
||||||
|
{ label: '上报人', prop: 'reporterName' },
|
||||||
|
];
|
||||||
|
|||||||
@@ -93,7 +93,11 @@
|
|||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-link v-if="column.link && row[column.prop]" type="primary" @click="openWaybill(row)">
|
<el-link
|
||||||
|
v-if="column.link && row[column.prop]"
|
||||||
|
type="primary"
|
||||||
|
@click="openWaybill(row)"
|
||||||
|
>
|
||||||
{{ row[column.prop] }}
|
{{ row[column.prop] }}
|
||||||
</el-link>
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
@@ -106,7 +110,7 @@
|
|||||||
<span v-else>{{ row[column.prop] || '-' }}</span>
|
<span v-else>{{ row[column.prop] || '-' }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="180" fixed="right" align="center">
|
<el-table-column label="操作" width="220" fixed="right" align="center">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="exception-disposal-page__actions">
|
<div class="exception-disposal-page__actions">
|
||||||
<template v-if="row.disposalStatus !== 'completed'">
|
<template v-if="row.disposalStatus !== 'completed'">
|
||||||
@@ -117,6 +121,13 @@
|
|||||||
>
|
>
|
||||||
跟进
|
跟进
|
||||||
</el-link>
|
</el-link>
|
||||||
|
<el-link
|
||||||
|
v-if="permission.exception_disposal_edit"
|
||||||
|
type="primary"
|
||||||
|
@click="openDisposal(row, 'edit')"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-link>
|
||||||
<el-link
|
<el-link
|
||||||
v-if="permission.exception_disposal_complete"
|
v-if="permission.exception_disposal_complete"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -125,13 +136,22 @@
|
|||||||
完成
|
完成
|
||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
<el-link
|
<template v-else>
|
||||||
v-else-if="permission.exception_disposal_view"
|
<el-link
|
||||||
type="primary"
|
v-if="permission.exception_disposal_view"
|
||||||
@click="openDisposal(row, 'detail')"
|
type="primary"
|
||||||
>
|
@click="openDisposal(row, 'detail')"
|
||||||
详情
|
>
|
||||||
</el-link>
|
详情
|
||||||
|
</el-link>
|
||||||
|
<el-link
|
||||||
|
v-if="permission.exception_disposal_edit"
|
||||||
|
type="primary"
|
||||||
|
@click="openDisposal(row, 'edit')"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -151,76 +171,191 @@
|
|||||||
|
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="dialog.visible"
|
v-model="dialog.visible"
|
||||||
:title="dialog.mode === 'detail' ? '异常详情' : '异常跟进'"
|
:title="dialogTitle"
|
||||||
width="960px"
|
:width="dialog.mode === 'edit' ? '1080px' : '960px'"
|
||||||
|
top="6vh"
|
||||||
append-to-body
|
append-to-body
|
||||||
destroy-on-close
|
destroy-on-close
|
||||||
>
|
>
|
||||||
<div v-loading="dialog.loading" class="exception-disposal-page__dialog">
|
<div v-loading="dialog.loading" class="exception-disposal-page__dialog">
|
||||||
<div class="dialog-section-title">异常信息</div>
|
<!-- 编辑态:只呈现运单信息与可编辑项,不再重复详情页的只读信息 -->
|
||||||
<dl class="exception-disposal-page__detail-grid">
|
|
||||||
<template v-for="field in detailFields" :key="field.prop">
|
|
||||||
<div :class="{ 'is-wide': field.span === 2 }">
|
|
||||||
<dt>{{ field.label }}</dt>
|
|
||||||
<dd>
|
|
||||||
<el-link v-if="field.link && detail[field.prop]" type="primary">
|
|
||||||
{{ detail[field.prop] }}
|
|
||||||
</el-link>
|
|
||||||
<span v-else>{{ detail[field.prop] || '-' }}</span>
|
|
||||||
</dd>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<div class="dialog-section-title">现场照片</div>
|
|
||||||
<div class="exception-disposal-page__photos">
|
|
||||||
<el-image
|
|
||||||
v-for="(url, index) in photoUrls"
|
|
||||||
:key="url"
|
|
||||||
:src="url"
|
|
||||||
:preview-src-list="photoUrls"
|
|
||||||
:initial-index="index"
|
|
||||||
fit="cover"
|
|
||||||
/>
|
|
||||||
<el-empty v-if="!photoUrls.length" description="暂无现场照片" :image-size="56" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-form
|
<el-form
|
||||||
v-if="dialog.mode === 'follow'"
|
v-if="dialog.mode === 'edit'"
|
||||||
ref="followFormRef"
|
ref="editFormRef"
|
||||||
:model="followForm"
|
:model="editForm"
|
||||||
:rules="followRules"
|
:rules="editRules"
|
||||||
label-position="right"
|
label-position="right"
|
||||||
label-width="auto"
|
label-width="96px"
|
||||||
class="exception-disposal-page__follow-form"
|
|
||||||
>
|
>
|
||||||
<el-form-item label="跟进说明" prop="followContent">
|
<section-card title="运单信息">
|
||||||
<el-input
|
<el-descriptions :column="3" border size="small">
|
||||||
v-model="followForm.followContent"
|
<el-descriptions-item
|
||||||
type="textarea"
|
v-for="field in editWaybillFields"
|
||||||
maxlength="500"
|
:key="field.prop"
|
||||||
show-word-limit
|
:label="field.label"
|
||||||
:rows="2"
|
>
|
||||||
placeholder="请输入"
|
{{ detailValue(field.prop) }}
|
||||||
/>
|
</el-descriptions-item>
|
||||||
</el-form-item>
|
</el-descriptions>
|
||||||
|
</section-card>
|
||||||
|
|
||||||
|
<section-card title="异常信息">
|
||||||
|
<el-row :gutter="18">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="异常类型" prop="exceptionType">
|
||||||
|
<el-select
|
||||||
|
v-model="editForm.exceptionType"
|
||||||
|
placeholder="请选择"
|
||||||
|
@change="handleEditTypeChange"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in exceptionTypeOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="异常原因" prop="exceptionReason">
|
||||||
|
<el-select
|
||||||
|
v-model="editForm.exceptionReason"
|
||||||
|
clearable
|
||||||
|
placeholder="请选择"
|
||||||
|
:disabled="!editForm.exceptionType"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in editReasonOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="上报说明" prop="reportDescription">
|
||||||
|
<el-input
|
||||||
|
v-model="editForm.reportDescription"
|
||||||
|
type="textarea"
|
||||||
|
maxlength="500"
|
||||||
|
show-word-limit
|
||||||
|
:rows="3"
|
||||||
|
placeholder="请输入"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="现场照片">
|
||||||
|
<div class="exception-disposal-page__edit-photos">
|
||||||
|
<div
|
||||||
|
v-for="(url, index) in editForm.scenePhotoList"
|
||||||
|
:key="url"
|
||||||
|
class="exception-disposal-page__edit-photo"
|
||||||
|
>
|
||||||
|
<el-image
|
||||||
|
:src="url"
|
||||||
|
:preview-src-list="editForm.scenePhotoList"
|
||||||
|
:initial-index="index"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<el-link type="danger" :underline="false" @click="removeEditPhoto(index)"
|
||||||
|
>删除</el-link
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<el-upload
|
||||||
|
action="/api/blade-resource/oss/endpoint/put-file"
|
||||||
|
name="file"
|
||||||
|
:headers="uploadHeaders"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="beforePhotoUpload"
|
||||||
|
:on-success="handlePhotoSuccess"
|
||||||
|
:on-error="handlePhotoError"
|
||||||
|
>
|
||||||
|
<div class="exception-disposal-page__edit-photo-add">+ 添加</div>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</section-card>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="dialog-section-title">历史跟进</div>
|
<template v-else>
|
||||||
<el-table :data="detail.followRecords || []" border>
|
<div class="dialog-section-title">异常信息</div>
|
||||||
<el-table-column type="index" label="序号" width="70" align="center" />
|
<dl class="exception-disposal-page__detail-grid">
|
||||||
<el-table-column
|
<template v-for="field in detailFields" :key="field.prop">
|
||||||
v-for="column in followColumns"
|
<div :class="{ 'is-wide': field.span === 2 }">
|
||||||
:key="column.prop"
|
<dt>{{ field.label }}</dt>
|
||||||
:prop="column.prop"
|
<dd>
|
||||||
:label="column.label"
|
<el-link v-if="field.link && detail[field.prop]" type="primary">
|
||||||
:min-width="column.minWidth"
|
{{ detail[field.prop] }}
|
||||||
align="center"
|
</el-link>
|
||||||
show-overflow-tooltip
|
<span v-else>{{ detail[field.prop] || '-' }}</span>
|
||||||
/>
|
</dd>
|
||||||
</el-table>
|
</div>
|
||||||
|
</template>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
<div class="dialog-section-title">现场照片</div>
|
||||||
|
<div class="exception-disposal-page__photos">
|
||||||
|
<el-image
|
||||||
|
v-for="(url, index) in photoUrls"
|
||||||
|
:key="url"
|
||||||
|
:src="url"
|
||||||
|
:preview-src-list="photoUrls"
|
||||||
|
:initial-index="index"
|
||||||
|
fit="cover"
|
||||||
|
/>
|
||||||
|
<el-empty v-if="!photoUrls.length" description="暂无现场照片" :image-size="56" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-form
|
||||||
|
v-if="dialog.mode === 'follow'"
|
||||||
|
ref="followFormRef"
|
||||||
|
:model="followForm"
|
||||||
|
:rules="followRules"
|
||||||
|
label-position="right"
|
||||||
|
label-width="auto"
|
||||||
|
class="exception-disposal-page__follow-form"
|
||||||
|
>
|
||||||
|
<el-form-item label="跟进说明" prop="followContent">
|
||||||
|
<el-input
|
||||||
|
v-model="followForm.followContent"
|
||||||
|
type="textarea"
|
||||||
|
maxlength="500"
|
||||||
|
show-word-limit
|
||||||
|
:rows="2"
|
||||||
|
placeholder="请输入"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div class="dialog-section-title">历史跟进</div>
|
||||||
|
<el-table :data="detail.followRecords || []" border>
|
||||||
|
<el-table-column type="index" label="序号" width="70" align="center" />
|
||||||
|
<el-table-column
|
||||||
|
v-for="column in followColumns"
|
||||||
|
:key="column.prop"
|
||||||
|
:prop="column.prop"
|
||||||
|
:label="column.label"
|
||||||
|
:min-width="column.minWidth"
|
||||||
|
align="center"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
<el-button
|
||||||
|
v-if="dialog.mode === 'edit' && permission.exception_disposal_edit"
|
||||||
|
type="primary"
|
||||||
|
:loading="dialog.submitting"
|
||||||
|
@click="submitEdit"
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
v-if="dialog.mode === 'follow' && permission.exception_disposal_follow"
|
v-if="dialog.mode === 'follow' && permission.exception_disposal_follow"
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -249,11 +384,15 @@ import { mapGetters } from 'vuex';
|
|||||||
import {
|
import {
|
||||||
detailFields,
|
detailFields,
|
||||||
disposalStatusOptions,
|
disposalStatusOptions,
|
||||||
|
editWaybillFields,
|
||||||
exceptionCategoryOptions,
|
exceptionCategoryOptions,
|
||||||
|
exceptionReasonOptions,
|
||||||
|
exceptionTypeOptions,
|
||||||
followColumns,
|
followColumns,
|
||||||
searchFields,
|
searchFields,
|
||||||
tableColumns,
|
tableColumns,
|
||||||
} from '@/option/transit/exception-disposal';
|
} from '@/option/transit/exception-disposal';
|
||||||
|
import { getUploadHeaders } from '@/utils/upload';
|
||||||
import * as api from '@/api/transit/exception-disposal';
|
import * as api from '@/api/transit/exception-disposal';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -268,6 +407,8 @@ export default {
|
|||||||
tableColumns,
|
tableColumns,
|
||||||
detailFields,
|
detailFields,
|
||||||
followColumns,
|
followColumns,
|
||||||
|
exceptionTypeOptions,
|
||||||
|
editWaybillFields,
|
||||||
loading: false,
|
loading: false,
|
||||||
query: {},
|
query: {},
|
||||||
rows: [],
|
rows: [],
|
||||||
@@ -283,10 +424,34 @@ export default {
|
|||||||
{ max: 500, message: '跟进说明不能超过500个字符', trigger: 'blur' },
|
{ max: 500, message: '跟进说明不能超过500个字符', trigger: 'blur' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
editForm: {
|
||||||
|
exceptionType: '',
|
||||||
|
exceptionReason: '',
|
||||||
|
reportDescription: '',
|
||||||
|
scenePhotoList: [],
|
||||||
|
},
|
||||||
|
editRules: {
|
||||||
|
exceptionType: [{ required: true, message: '请选择异常类型', trigger: 'change' }],
|
||||||
|
reportDescription: [
|
||||||
|
{ required: true, message: '请输入上报说明', trigger: 'blur' },
|
||||||
|
{ max: 500, message: '上报说明不能超过500个字符', trigger: 'blur' },
|
||||||
|
],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['permission']),
|
...mapGetters(['permission']),
|
||||||
|
dialogTitle() {
|
||||||
|
return (
|
||||||
|
{ detail: '异常详情', follow: '异常跟进', edit: '编辑异常' }[this.dialog.mode] || '异常详情'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
editReasonOptions() {
|
||||||
|
return exceptionReasonOptions(this.editForm.exceptionType);
|
||||||
|
},
|
||||||
|
uploadHeaders() {
|
||||||
|
return getUploadHeaders();
|
||||||
|
},
|
||||||
visibleSearchFields() {
|
visibleSearchFields() {
|
||||||
return this.searchExpanded ? this.searchFields : this.searchFields.slice(0, 4);
|
return this.searchExpanded ? this.searchFields : this.searchFields.slice(0, 4);
|
||||||
},
|
},
|
||||||
@@ -342,10 +507,79 @@ export default {
|
|||||||
try {
|
try {
|
||||||
const res = await api.getDetail(row.id);
|
const res = await api.getDetail(row.id);
|
||||||
this.detail = this.decorateRow(res.data?.data || res.data || res || {});
|
this.detail = this.decorateRow(res.data?.data || res.data || res || {});
|
||||||
|
if (mode === 'edit') {
|
||||||
|
this.editForm = {
|
||||||
|
exceptionType: this.detail.exceptionType || '',
|
||||||
|
exceptionReason: this.detail.exceptionReason || '',
|
||||||
|
reportDescription: this.detail.reportDescription || '',
|
||||||
|
scenePhotoList: this.parsePhotos(this.detail.scenePhotos),
|
||||||
|
};
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
this.dialog.loading = false;
|
this.dialog.loading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
detailValue(prop) {
|
||||||
|
const value = this.detail[prop];
|
||||||
|
return value === null || value === undefined || value === '' ? '-' : value;
|
||||||
|
},
|
||||||
|
handleEditTypeChange() {
|
||||||
|
// 一级类型变了,旧二级可能不属于新类型
|
||||||
|
const stillValid = this.editReasonOptions.some(
|
||||||
|
item => item.value === this.editForm.exceptionReason
|
||||||
|
);
|
||||||
|
if (!stillValid) {
|
||||||
|
this.editForm.exceptionReason = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforePhotoUpload(file) {
|
||||||
|
const validType = ['image/jpeg', 'image/png', 'image/jpg', 'image/bmp'].includes(file.type);
|
||||||
|
if (!validType) {
|
||||||
|
this.$message.error('仅支持 JPG、PNG、BMP 图片');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (file.size / 1024 / 1024 >= 5) {
|
||||||
|
this.$message.error('图片大小不能超过 5MB');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
handlePhotoSuccess(res) {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const url = res.data.link || res.data.url || res.data.domain || '';
|
||||||
|
if (url) {
|
||||||
|
this.editForm.scenePhotoList = [...this.editForm.scenePhotoList, url];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg || '上传失败');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlePhotoError() {
|
||||||
|
this.$message.error('上传失败');
|
||||||
|
},
|
||||||
|
removeEditPhoto(index) {
|
||||||
|
const list = [...this.editForm.scenePhotoList];
|
||||||
|
list.splice(index, 1);
|
||||||
|
this.editForm.scenePhotoList = list;
|
||||||
|
},
|
||||||
|
async submitEdit() {
|
||||||
|
await this.$refs.editFormRef.validate();
|
||||||
|
this.dialog.submitting = true;
|
||||||
|
try {
|
||||||
|
await api.update({
|
||||||
|
id: this.detail.id,
|
||||||
|
exceptionType: this.editForm.exceptionType,
|
||||||
|
exceptionReason: this.editForm.exceptionReason,
|
||||||
|
reportDescription: this.editForm.reportDescription,
|
||||||
|
scenePhotos: this.editForm.scenePhotoList.join(','),
|
||||||
|
});
|
||||||
|
this.$message.success('编辑成功');
|
||||||
|
this.dialog.visible = false;
|
||||||
|
this.loadTable();
|
||||||
|
} finally {
|
||||||
|
this.dialog.submitting = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
async submitFollow() {
|
async submitFollow() {
|
||||||
await this.$refs.followFormRef.validate();
|
await this.$refs.followFormRef.validate();
|
||||||
this.dialog.submitting = true;
|
this.dialog.submitting = true;
|
||||||
@@ -400,11 +634,15 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
exceptionName(value) {
|
exceptionName(value) {
|
||||||
for (const group of exceptionCategoryOptions) {
|
if (!value) return '-';
|
||||||
const match = group.children.find(item => item.value === value);
|
// 一级存中文大类名(如「交通异常」),二级存子类名(如「货损」),两级都查
|
||||||
|
const group = exceptionCategoryOptions.find(item => item.value === value);
|
||||||
|
if (group) return group.label;
|
||||||
|
for (const item of exceptionCategoryOptions) {
|
||||||
|
const match = item.children.find(child => child.value === value);
|
||||||
if (match) return match.label;
|
if (match) return match.label;
|
||||||
}
|
}
|
||||||
return value || '-';
|
return value;
|
||||||
},
|
},
|
||||||
statusLinkType(status) {
|
statusLinkType(status) {
|
||||||
return status === 'completed' ? 'info' : 'primary';
|
return status === 'completed' ? 'info' : 'primary';
|
||||||
@@ -565,6 +803,47 @@ export default {
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.exception-disposal-page__dialog :deep(.section-card + .section-card) {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exception-disposal-page__edit-photos {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exception-disposal-page__edit-photo {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
:deep(.el-image) {
|
||||||
|
width: 96px;
|
||||||
|
height: 96px;
|
||||||
|
border: 1px solid #eff1f7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exception-disposal-page__edit-photo-add {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 96px;
|
||||||
|
height: 96px;
|
||||||
|
border: 1px dashed #dcdfe6;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #909399;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1200px) {
|
@media screen and (max-width: 1200px) {
|
||||||
.exception-disposal-page__search-grid {
|
.exception-disposal-page__search-grid {
|
||||||
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
grid-template-columns: repeat(2, minmax(220px, 1fr));
|
||||||
|
|||||||
Reference in New Issue
Block a user