464 lines
18 KiB
Vue
464 lines
18 KiB
Vue
<template>
|
||
<browser :component-loading="componentLoading"
|
||
:api-config="apiConfig"
|
||
:table-config="tableConfig"
|
||
:permissions="permissions"
|
||
:dialog-config="dialogConfig"
|
||
:actions="actions"
|
||
@update:query-params="queryParams = $event"
|
||
@update:actions="actions = $event"
|
||
@update:dialog-config="dialogConfig = $event">
|
||
<template #extraButton v-if="isNotDialog">
|
||
<el-button type="success" @click="handleSms" :disabled="deliverys.length === 0">
|
||
<template #icon>
|
||
<font-awesome-icon icon="file-export"/>
|
||
</template>
|
||
短信推送 ({{ deliverys.length }})
|
||
</el-button>
|
||
</template>
|
||
<template #queryPanel="{ queryParams: qp }" v-if="isNotDialog">
|
||
<el-form ref="queryForm" :model="qp" label-width="80px">
|
||
|
||
</el-form>
|
||
</template>
|
||
|
||
<el-table-column prop="caseInfo.caseNum" label="案卷编号" min-width="200"/>
|
||
<el-table-column prop="caseInfo.caseName" label="案卷名称" min-width="350" show-overflow-tooltip/>
|
||
<el-table-column prop="documentInfo.documentName" label="文书名称" min-width="200"/>
|
||
<el-table-column prop="deliveryMethod.methodName" label="送达方式" min-width="100"/>
|
||
<el-table-column prop="recipientInfo.name" label="受送人" min-width="100"/>
|
||
<el-table-column prop="deliveryTime" label="实际送达时间" min-width="150"/>
|
||
<el-table-column prop="status" label="状态" min-width="100">
|
||
<template #default="{ row }">
|
||
<span v-if="row.status!=='1'">正常送达</span><span v-else>留置送达</span></template>
|
||
</el-table-column>
|
||
<template #tableControlColumn="{data: r}">
|
||
<el-link v-if="r.data.row.needCll && isNotDialog" type="primary" @click="handleVoicePush(r.data.row)"
|
||
title="语音推送">语音推送
|
||
</el-link>
|
||
</template>
|
||
<template #dialogContent="{ dialogConfig: dc }">
|
||
<el-row>
|
||
<el-col :span="24">
|
||
<el-form-item label="案卷名称" prop="caseId">
|
||
<SimpleEntitySelector :disabled="dc.mode === 'detail'" @change="ajxxChange" v-model="dc.data.caseId"
|
||
:simpleConfig="simpleConfigCase"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="执法文书" prop="documentId">
|
||
<SimpleEntitySelector :disabled="dc.mode === 'detail'" v-model="dc.data.documentId"
|
||
:simpleConfig="simpleConfigZfws" :caseId="dc.data.caseId"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="受送达人" prop="recipientId">
|
||
<SimpleEntitySelector :disabled="dc.mode === 'detail'" :simpleConfig="simpleConfigSdfs" :multiple="false"
|
||
v-model="dc.data.recipientId"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="送达方式" prop="deliveryMethodId">
|
||
<SimpleEntitySelector :disabled="dc.mode === 'detail'" @change="sdfsChange" :simpleConfig="simpleConfigSsr"
|
||
:multiple="false" v-model="dc.data.deliveryMethodId"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="实际送达时间" prop="deliveryTime">
|
||
<el-date-picker :disabled="dc.mode === 'detail'" v-model="dc.data.deliveryTime" type="datetime"
|
||
placeholder="选择实际送达时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
|
||
style="width: 100%;"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<!-- <el-col :span="8"><el-form-item label="送达回证" prop="receiptProof"><el-input :disabled="dc.mode === 'detail'" v-model="dc.data.receiptProof"/></el-form-item></el-col>-->
|
||
<el-col :span="8" v-if="methodName === '电话送达'">
|
||
<el-form-item label="通话录音" prop="callTape">
|
||
<el-input :disabled="dc.mode === 'detail'" v-model="dc.data.callTape"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName === '电子送达'">
|
||
<el-form-item label="送达类型" prop="deliveryType">
|
||
<el-select :disabled="dc.mode === 'detail'" v-model="dc.data.deliveryType" placeholder="请选择" clearable>
|
||
<el-option v-for="item in sdlxOptions" :key="item.value" :label="item.label"
|
||
:value="item.value"></el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName === '邮寄送达'">
|
||
<el-form-item label="快递单号" prop="trackingNo">
|
||
<el-input :disabled="dc.mode === 'detail'" v-model="dc.data.trackingNo"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName === '邮寄送达'">
|
||
<el-form-item label="物流信息" prop="logistics.info">
|
||
<el-input :disabled="dc.mode === 'detail'" v-model="dc.data.logistics.info"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName === '公告送达'">
|
||
<el-form-item label="刊登凭证" prop="appearedVoucher">
|
||
<el-input :disabled="dc.mode === 'detail'" v-model="dc.data.appearedVoucher"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName === '委托送达' || methodName === '转交送达'">
|
||
<el-form-item label="委托人姓名" prop="trusteeName">
|
||
<el-input :disabled="dc.mode === 'detail'" v-model="dc.data.trusteeName"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8" v-if="methodName !== '公告送达'">
|
||
<el-form-item label="状态" prop="status">
|
||
<el-radio-group v-model="dc.data.status" :disabled="dc.mode === 'detail'">
|
||
<el-radio :label="'0'" :value="'0'">正常送达</el-radio>
|
||
<el-radio :label="'1'" :value="'1'">留置送达</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24" v-if="methodName">
|
||
<!-- v-if="methodName && (methodName === '直接送达' || methodName === '转交送达' || methodName === '留置送达')"-->
|
||
<el-form-item label="送达回证">
|
||
<MultiplePicture ref="multiple_pictures"
|
||
:form-data="{urls: dc.data.picList}"
|
||
:parameters="{mode: dc.mode, autoUpload: true, limit: 20}"
|
||
@on-success="onSuccess"
|
||
@on-pic-view="onPicView"
|
||
@on-remove="onRemove"/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="送达人电子签名" prop="recipientSignature">
|
||
<el-button type="primary" size="small" @click="openSignatureOne" v-if="dc.mode !== 'detail'">送达人电子签名
|
||
</el-button>
|
||
<div v-if="dc.data.recipientSignature"
|
||
style="border: 1px solid #ccc; margin-left: 10px; display: inline-block; position: relative;">
|
||
<img :src="dc.data.recipientSignature" alt="签名" style="height: 100px;"/>
|
||
<el-button v-if="dc.mode !== 'detail'" type="danger" size="small"
|
||
style="position: absolute; top: 5px; right: 5px; transform: translate(50%, -50%); border-radius: 50%; width: 20px; height: 20px; padding: 0;"
|
||
@click="saveSignatureOne('')">×
|
||
</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="见证人电子签名" prop="witnessSignature">
|
||
<el-button type="primary" size="small" @click="openSignatureTwo" v-if="dc.mode !== 'detail'">见证人电子签名
|
||
</el-button>
|
||
<div v-if="dc.data.witnessSignature"
|
||
style="border: 1px solid #ccc; margin-left: 10px; display: inline-block; position: relative;">
|
||
<img :src="dc.data.witnessSignature" alt="签名" style="height: 100px;"/>
|
||
<el-button v-if="dc.mode !== 'detail'" type="danger" size="small"
|
||
style="position: absolute; top: 5px; right: 5px; transform: translate(50%, -50%); border-radius: 50%; width: 20px; height: 20px; padding: 0;"
|
||
@click="saveSignatureTwo('')">×
|
||
</el-button>
|
||
</div>
|
||
</el-form-item>
|
||
</el-col>
|
||
<PictureView ref="pictureViewRef"/>
|
||
</el-row>
|
||
</template>
|
||
</browser>
|
||
<SignatureComponent v-model="showSignatureOne" @save="saveSignatureOne"/>
|
||
<SignatureComponent v-model="showSignatureTwo" @save="saveSignatureTwo"/>
|
||
</template>
|
||
<script setup>
|
||
import {reactive, toRefs, ref, watch, onMounted} from 'vue'
|
||
import Browser from '@/components/Browser.vue'
|
||
import {ElButton, ElMessage} from "element-plus"
|
||
import deliveryRecords from "@/api/lawenforcement/DeliveryRecord.js"
|
||
import SimpleEntitySelector from "@/components/SimpleEntitySelector.vue"
|
||
import MultiplePicture from "@pages/common/MultiplePicture.vue"
|
||
import PictureView from "@pages/common/PictureView.vue"
|
||
import SignatureComponent from "@pages/common/SignatureComponent.vue"
|
||
|
||
const props = defineProps({
|
||
dialogData: {type: Object, default: () => ({})},
|
||
isNotDialog: {type: Boolean, default: true}
|
||
})
|
||
|
||
const state = reactive({
|
||
componentLoading: false,
|
||
permissions: {
|
||
query: props.isNotDialog,
|
||
add: props.isNotDialog,
|
||
modify: props.isNotDialog,
|
||
detail: true,
|
||
delete: props.isNotDialog,
|
||
deleteAll: props.isNotDialog,
|
||
importFile: false,
|
||
exportFile: false,
|
||
exportSelectFile: false,
|
||
downloadTemp: false,
|
||
},
|
||
tableConfig: {
|
||
tableData: {},
|
||
hasControlColumn: true,
|
||
controlWidth: props.isNotDialog ? '180' : '80',
|
||
multipleSelect: props.isNotDialog,
|
||
selectable: (row) => {
|
||
return row.deliveryMethod?.methodName === '电子送达' && row.deliveryType === '2'
|
||
}
|
||
},
|
||
apiConfig: {
|
||
api: deliveryRecords,
|
||
modelId: 'deliveryId',
|
||
},
|
||
dialogConfig: {
|
||
show: false,
|
||
mode: 'detail',
|
||
formLabelWidth: '110px',
|
||
loading: false,
|
||
baseTitle: '执法文书送达',
|
||
rules: {
|
||
caseId: [{required: true, message: '案卷不能为空', trigger: 'change'}],
|
||
documentIds: [{required: true, message: '执法文书不能为空', trigger: 'change'}],
|
||
recipientId: [{required: true, message: '受送达人不能为空', trigger: 'change'}],
|
||
deliveryMethodId: [{required: true, message: '送达方式不能为空', trigger: 'change'}],
|
||
deliveryTime: [{required: false, message: '实际送达时间不能为空', trigger: 'change'}],
|
||
receiptProof: [{required: false, message: '送达回证不能为空', trigger: 'change'}, {
|
||
min: 0,
|
||
max: 255,
|
||
message: '送达回证的长度不能超过255',
|
||
trigger: 'change'
|
||
}],
|
||
callTape: [{required: false, message: '通话录音不能为空', trigger: 'change'}, {
|
||
min: 0,
|
||
max: 100,
|
||
message: '通话录音的长度不能超过100',
|
||
trigger: 'change'
|
||
}],
|
||
deliveryType: [{required: true, message: '送达类型不能为空', trigger: 'change'}],
|
||
trackingNo: [{required: false, message: '快递单号不能为空', trigger: 'change'}, {
|
||
min: 0,
|
||
max: 100,
|
||
message: '快递单号的长度不能超过100',
|
||
trigger: 'change'
|
||
}],
|
||
logistics: [{required: false, message: '物流信息不能为空', trigger: 'change'}],
|
||
appearedVoucher: [{required: false, message: '刊登凭证不能为空', trigger: 'change'}, {
|
||
min: 0,
|
||
max: 100,
|
||
message: '刊登凭证的长度不能超过100',
|
||
trigger: 'change'
|
||
}],
|
||
trusteeName: [{required: false, message: '委托人姓名不能为空', trigger: 'change'}, {
|
||
min: 0,
|
||
max: 20,
|
||
message: '委托人姓名的长度不能超过20',
|
||
trigger: 'change'
|
||
}]
|
||
},
|
||
data: {},
|
||
actions: {
|
||
handleDialogOk: handleDialogOk
|
||
}
|
||
},
|
||
actions: {
|
||
add: handleAdd,
|
||
modify: handleModify,
|
||
detail: handleDetail,
|
||
query: handleQuery,
|
||
handleSelectionChange
|
||
},
|
||
simpleConfigCase: {confName: 'case', parmas: {tag: 'Y'}},
|
||
simpleConfigZfws: {confName: 'document'},
|
||
simpleConfigSdfs: {confName: 'recipient'},
|
||
simpleConfigSsr: {confName: 'method'},
|
||
deliverys: [],
|
||
queryParams: {}
|
||
})
|
||
|
||
const {
|
||
componentLoading,
|
||
permissions,
|
||
tableConfig,
|
||
apiConfig,
|
||
dialogConfig,
|
||
actions,
|
||
simpleConfigCase,
|
||
simpleConfigZfws,
|
||
simpleConfigSdfs,
|
||
simpleConfigSsr,
|
||
deliverys,
|
||
queryParams
|
||
} = toRefs(state)
|
||
|
||
const sdlxOptions = reactive([{value: '1', label: '网站'}, {value: '2', label: '短信'}, {
|
||
value: '3',
|
||
label: '邮件'
|
||
}, {value: '4', label: '手机APP'}, {value: '5', label: '微信'}])
|
||
|
||
const methodName = ref('')
|
||
const caseId = ref('')
|
||
|
||
function sdfsChange(row) {
|
||
methodName.value = row?.methodName
|
||
if (methodName.value === '公告送达') {
|
||
dialogConfig.value.data.status = 0
|
||
}
|
||
}
|
||
|
||
function ajxxChange(row) {
|
||
caseId.value = row?.caseId
|
||
}
|
||
|
||
function handleQuery() {
|
||
tableConfig.value.tableLoading = true
|
||
apiConfig.value.api.query(props.isNotDialog ? queryParams.value : props.dialogData).then(res => {
|
||
if (res.success) {
|
||
tableConfig.value.tableData = res
|
||
}
|
||
tableConfig.value.tableLoading = false
|
||
}).catch(() => tableConfig.value.tableLoading = false)
|
||
}
|
||
|
||
function handleAdd() {
|
||
dialogConfig.value.show = true
|
||
methodName.value = null
|
||
dialogConfig.value.mode = 'add'
|
||
dialogConfig.value.title = '新增执法文书送达'
|
||
dialogConfig.value.data = Object.assign({}, {documentIds: [], materials: [], picList: [], logistics: {}, status: '0'})
|
||
}
|
||
|
||
function handleModify(row) {
|
||
dialogConfig.value.show = true
|
||
methodName.value = null
|
||
dialogConfig.value.mode = 'modify'
|
||
dialogConfig.value.title = '修改执法文书送达'
|
||
dialogConfig.value.data.documentIds = []
|
||
findOne(row)
|
||
}
|
||
|
||
function handleDetail(row) {
|
||
dialogConfig.value.show = true
|
||
methodName.value = null
|
||
dialogConfig.value.mode = 'detail'
|
||
dialogConfig.value.title = '执法文书送达详情'
|
||
dialogConfig.value.showFooter = false
|
||
findOne(row)
|
||
}
|
||
|
||
function findOne(row) {
|
||
dialogConfig.value.loading = true
|
||
apiConfig.value.api.findOne(row[apiConfig.value.modelId]).then(res => {
|
||
if (res.success) {
|
||
dialogConfig.value.loading = false
|
||
let data = res.data
|
||
caseId.value = data.caseId
|
||
methodName.value = data.deliveryMethod?.methodName
|
||
data.logistics = data.logistics ? data.logistics : {}
|
||
data.documentIds = data.documentIds?.split(',') || []
|
||
if (data.materials) data.materials.forEach(item => item.uid = item.materialsId)
|
||
dialogConfig.value.data = Object.assign({}, data, {picList: data.materials})
|
||
} else {
|
||
dialogConfig.value.loading = false
|
||
throw new Error('查询失败')
|
||
}
|
||
}).catch(() => {
|
||
dialogConfig.value.loading = false
|
||
})
|
||
}
|
||
|
||
function handleDialogOk(formRef) {
|
||
let _event = actions.value
|
||
formRef.validate(valid => {
|
||
if (valid) {
|
||
dialogConfig.value.loading = true
|
||
let data = Object.assign({}, dialogConfig.value.data)
|
||
if (dialogConfig.value.mode === 'add') {
|
||
apiConfig.value.api.add(data).then(res => {
|
||
dialogConfig.value.show = false
|
||
if (res.success) {
|
||
ElMessage.success('操作成功')
|
||
_event.query()
|
||
} else {
|
||
throw new Error('操作失败')
|
||
}
|
||
dialogConfig.value.loading = false
|
||
}).catch(() => {
|
||
dialogConfig.value.loading = false
|
||
})
|
||
} else if (dialogConfig.value.mode === 'modify') {
|
||
apiConfig.value.api.modify(dialogConfig.value.data[apiConfig.value.modelId], data).then(res => {
|
||
dialogConfig.value.show = false
|
||
if (res.success) {
|
||
ElMessage.success('操作成功')
|
||
_event.query()
|
||
} else {
|
||
throw new Error('操作失败')
|
||
}
|
||
dialogConfig.value.loading = false
|
||
}).catch(() => {
|
||
dialogConfig.value.loading = false
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
function handleSelectionChange(selectedData) {
|
||
deliverys.value = [...selectedData]
|
||
}
|
||
|
||
function handleVoicePush(row) {
|
||
tableConfig.value.tableLoading = true
|
||
apiConfig.value.api.voicePush(row).then(res => {
|
||
if (res.success) {
|
||
ElMessage.success('操作成功')
|
||
} else {
|
||
throw new Error('操作失败')
|
||
}
|
||
tableConfig.value.tableLoading = false
|
||
}).catch(() => {
|
||
tableConfig.value.tableLoading = false
|
||
})
|
||
}
|
||
|
||
function handleSms() {
|
||
let ids = deliverys.value.map((item) => item[apiConfig.value.modelId])
|
||
tableConfig.value.tableLoading = true
|
||
apiConfig.value.api.smsCall(ids).then(res => {
|
||
if (res.success) {
|
||
ElMessage.success('操作成功')
|
||
} else {
|
||
throw new Error('操作失败')
|
||
}
|
||
tableConfig.value.tableLoading = false
|
||
}).catch(() => {
|
||
tableConfig.value.tableLoading = false
|
||
})
|
||
}
|
||
|
||
function onSuccess(data, file, row) {
|
||
let obj = {materialsId: file.uid, name: data.fileName, savePath: data.savePathName, url: data.url}
|
||
dialogConfig.value.data.materials.push(obj)
|
||
}
|
||
|
||
function onRemove(file, row) {
|
||
const idx = dialogConfig.value.data.materials.findIndex((item) => item.uid === file.uid)
|
||
if (idx > -1) dialogConfig.value.data.materials.splice(idx, 1)
|
||
}
|
||
|
||
const pictureViewRef = ref(null)
|
||
|
||
function onPicView(url) {
|
||
pictureViewRef.value.viewPicture(url)
|
||
}
|
||
|
||
const showSignatureOne = ref(false)
|
||
const openSignatureOne = () => {
|
||
showSignatureOne.value = true
|
||
}
|
||
const saveSignatureOne = (data) => {
|
||
dialogConfig.value.data.recipientSignature = data
|
||
}
|
||
const showSignatureTwo = ref(false)
|
||
const openSignatureTwo = () => {
|
||
showSignatureTwo.value = true
|
||
}
|
||
const saveSignatureTwo = (data) => {
|
||
dialogConfig.value.data.witnessSignature = data
|
||
}
|
||
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
|
||
</style>
|