zhzf/client/src/views/zfwssd/zfwsxx.vue

464 lines
18 KiB
Vue
Raw Normal View History

<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">
2025-04-11 17:48:39 +08:00
</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'
2025-05-09 18:18:32 +08:00
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>