| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
- <template>
- <ContentWrap>
- <!-- 搜索工作栏 -->
- <el-form
- class="-mb-15px"
- :model="queryParams"
- ref="queryFormRef"
- :inline="true"
- label-width="100px"
- >
- <!-- 约检单号 -->
- <el-form-item label="约检单号" prop="appointmentNo">
- <el-input v-model="queryParams.appointmentNo" placeholder="请输入约检单号" clearable class="!w-240px" />
- </el-form-item>
- <el-form-item label="检测日期" prop="appointmentDate">
- <el-date-picker
- v-model="queryParams.appointmentDate"
- value-format="YYYY-MM-DD"
- type="daterange"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
- class="!w-240px"
- />
- </el-form-item>
-
- <el-form-item label="申请单位" prop="unitName">
- <el-input v-model="queryParams.unitName" placeholder="请输入申请单位" clearable class="!w-240px" />
- </el-form-item>
- <el-form-item label="使用单位" prop="useUnitName">
- <el-input v-model="queryParams.useUnitName" placeholder="请输入使用单位" clearable class="!w-240px" />
- </el-form-item>
- <!-- <el-form-item label="单位地址" prop="unitAddress">
- <el-input v-model="queryParams.unitAddress" placeholder="请输入单位地址" clearable class="!w-240px" />
- </el-form-item> -->
- <el-form-item label="部门" prop="deptId">
- <DeptSelect v-model="queryParams.deptId" placeholder="请选择部门" clearable class="!w-240px" />
- </el-form-item>
- <el-form-item label="区域" prop="equipDistrict">
- <AreaSelect
- v-model="queryParams.equipDistrict"
- placeholder="请选择区域"
- class="!w-[240px]"
- collapse-tags
- collapse-tags-tooltip
- :clearable="true"
- @clear="handleAreaClear"
- @change="handleAreaChange"
- />
- </el-form-item>
- <el-form-item label="街道" prop="equipStreet">
- <StreetSelect
- v-model="queryParams.equipStreet"
- :district-ids="queryParams.equipDistrict ? [queryParams.equipDistrict] : []"
- placeholder="请选择街道"
- class="!w-[240px]"
- collapse-tags
- collapse-tags-tooltip
- :clearable="true"
- @clear="handleStreetClear"
- @change="handleStreetChange"
- />
- </el-form-item>
- <el-form-item label="设备" prop="equipType">
- <el-select v-model="queryParams.equipType" placeholder="请选择设备" clearable class="!w-240px">
- <el-option v-for="(item, key) in equipTypeMap" :key="key" :label="item" :value="key" />
- </el-select>
- </el-form-item>
- <el-form-item label="设备代码" prop="equipCode">
- <el-input v-model="queryParams.equipCode" placeholder="请输入设备注册代码" clearable class="!w-240px" />
- </el-form-item>
- <el-form-item label="检验性质" prop="checkType">
- <el-select v-model="queryParams.checkType" placeholder="请选择检验性质" clearable class="!w-240px">
- <el-option v-for="(item, key) in checkTypeMap" :key="key" :label="item" :value="key" />
- </el-select>
- </el-form-item>
- <el-form-item label="约检状态" prop="status">
- <el-select multiple v-model="queryParams.status" placeholder="请选择约检状态" clearable class="!w-240px">
- <el-option v-for="(item, key) in statusMap" :key="key" :label="item" :value="key" />
- </el-select>
- </el-form-item>
- <el-form-item label="预警时间" prop="warningDay">
- <el-input
- v-model="queryParams.warningDay[0]"
- :min="0"
- :max="365"
- placeholder="最小天数"
- class="!w-[110px]"
- />
- <span class="mx-2">至</span>
- <el-input
- v-model="queryParams.warningDay[1]"
- :min="0"
- :max="365"
- placeholder="最大天数"
- class="!w-[110px]"
- />
- </el-form-item>
- <el-form-item label="生成受理单" prop="createAcceptOrder">
- <el-select v-model="queryParams.createAcceptOrder" placeholder="请选择是否生成受理单" clearable class="!w-240px">
- <el-option label="是" :value="true" />
- <el-option label="否" :value="false" />
- </el-select>
- </el-form-item>
-
- <el-form-item>
- <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
- <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
- <el-button type="warning" @click="handleWarningSettings">
- <Icon icon="ep:bell" class="mr-5px" /> 预警设置
- </el-button>
- </el-form-item>
- </el-form>
- </ContentWrap>
-
- <!-- 列表 -->
- <ContentWrap>
- <el-table
- class="cursor-pointer"
- v-loading="loading"
- :data="list"
- stripe
- border
- :cell-style="cellStyle"
- @selection-change="handleSelectionChange"
- @row-dblclick="handleAppointment"
- show-overflow-tooltip
- tooltip-effect="dark"
- >
- <el-table-column label="操作" width="150" align="center">
- <template #default="scope">
- <!-- <el-button
- link
- type="primary"
- @click="handleAppointment(scope.row)"
- >
- 约检
- </el-button> -->
- <el-button
- v-if="scope.row.status === 100"
- link
- type="success"
- @click="handleSendConfirm(scope.row)"
- >
- 发送确认
- </el-button>
- </template>
- </el-table-column>
- <el-table-column label="约检状态" prop="status" align="center" width="100">
- <template #default="scope">
- {{ statusMap[scope.row.status] }}
- </template>
- </el-table-column>
- <el-table-column label="推送情况" prop="tempSendStatus" align="center" width="130">
- <template #default="scope">
- <el-tag v-if="!isEmpty(scope.row.tempSendStatus)" :type=getTypeColor(scope.row.tempSendStatus)>
- {{ tempSendStatusMap[scope.row.tempSendStatus] }}
- </el-tag>
- </template>
- </el-table-column>
- <!-- <el-table-column type="selection" width="30" align="center" /> -->
- <!-- 约检单号 -->
- <el-table-column label="约检单号" prop="appointmentNo" align="center" width="150">
- <template #default="{ row }">
- <el-button
- link
- type="primary"
- @click="handleAppointment(row)">{{ row.appointmentNo }}</el-button>
- </template>
- </el-table-column>
- <!-- 检验性质 -->
- <el-table-column label="检验性质" prop="checkType" align="center" width="100">
- <template #default="scope">
- {{ checkTypeMap[scope.row.checkType] }}
- </template>
- </el-table-column>
- <!-- 约检时间 -->
- <el-table-column label="检测日期" prop="appointmentDate" sortable align="center" width="140">
- <template #default="scope">
- {{ formatArrayDate(scope.row.appointmentDate) }}
- </template>
- </el-table-column>
- <!-- 预警剩余时间 -->
- <el-table-column label="预警时间" prop="warningDay" sortable align="center" width="110">
- <template #default="scope">
- {{ scope.row.warningDay }} 天
- </template>
- </el-table-column>
- <!-- 单位名称 -->
- <el-table-column label="使用单位" prop="useUnitName" align="center" width="150" />
- <!-- 单位名称 -->
- <el-table-column label="申请单位" prop="unitName" align="center" width="150" :show-overflow-tooltip="false">
- <template #default="{row}">
- <div style="color: #015293; cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" @click="handleUnitCodeFn(row.useUnitId)">{{row.unitName}}</div>
- </template>
- </el-table-column>
- <!-- 单位地址 -->
- <!-- <el-table-column label="使用单位地址" prop="unitAddress" align="center" width="150" /> -->
- <!-- 使用单位联系人 -->
- <el-table-column label="联系人" prop="unitContact" align="center" width="140" />
- <!-- 使用单位联系电话 -->
- <el-table-column label="手机" prop="unitPhone" align="center" width="140" />
- <!-- 设备 -->
- <el-table-column label="设备" prop="equipType" align="center" width="100">
- <template #default="scope">
- {{ equipTypeMap[scope.row.equipType] }}
- </template>
- </el-table-column>
- <!-- 设备数量 -->
- <el-table-column label="台数" prop="equipNum" sortable align="center" width="100" />
- <!-- 部门 -->
- <el-table-column label="部门" prop="deptId" sortable align="center" width="130">
- <template #default="scope">
- {{ scope.row.dept ? scope.row.dept.name : '' }}
- </template>
- </el-table-column>
- <!-- 区域 -->
- <el-table-column label="所属区" prop="equipDistrictName" align="center" sortable width="100" />
- <!-- 街道 -->
- <el-table-column label="街道" prop="equipStreetName" align="center" sortable width="100" />
- <!-- 备注 -->
- <el-table-column label="备注" prop="remark" align="center" width="150" />
- <!-- 是否受理 -->
- <el-table-column label="是否受理" prop="createAcceptOrder" align="center" width="100">
- <template #default="scope">
- {{ scope.row.createAcceptOrder ? '是' : '否' }}
- </template>
- </el-table-column>
- <!-- 受理时间 -->
- <el-table-column label="受理时间" prop="schedulingTime" align="center" sortable width="180">
- <template #default="scope">
- {{ scope.row.schedulingTime ? dayjs(scope.row.schedulingTime).format('YYYY-MM-DD HH:mm:ss') : ''}}
- </template>
- </el-table-column>
- <!-- 客户确认时间 -->
- <el-table-column label="客户确认时间" prop="confirmDate" align="center" sortable width="180">
- <template #default="scope">
- {{ scope.row.confirmDate ? formatArrayDate(scope.row.confirmDate) : '-'}}
- </template>
- </el-table-column>
- </el-table>
- <!-- 分页 -->
- <Pagination
- :total="total"
- v-model:page="queryParams.pageNo"
- v-model:limit="queryParams.pageSize"
- @pagination="getList"
- />
- </ContentWrap>
-
- <!-- 短信确认弹窗 -->
- <el-dialog
- v-model="smsDialogVisible"
- title="推送约检确认信息"
- width="500px"
- append-to-body
- destroy-on-close
- >
- <el-form
- ref="smsFormRef"
- :model="smsForm"
- :rules="smsRules"
- label-width="80px"
- >
- <!-- <el-form-item label="手机号" prop="mobile">
- <el-input
- v-model="smsForm.mobile"
- placeholder="请输入手机号"
- maxlength="11"
- show-word-limit
- />
- </el-form-item> -->
- </el-form>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="smsDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="submitSmsConfirm">发送短信</el-button>
- <!-- <el-button type="success" @click="handleCopyConfirmLink">复制链接</el-button> -->
- <el-button type="success" @click="handleSendWechatConfirm">微信推送</el-button>
- </div>
- </template>
- </el-dialog>
- <!-- 预警设置弹窗 -->
- <el-dialog
- v-model="warningDialogVisible"
- title="预警设置"
- width="400px"
- destroy-on-close
- append-to-body
- >
- <el-form
- ref="warningFormRef"
- :model="warningForm"
- :rules="warningRules"
- label-width="100px"
- >
- <el-form-item label="预警天数" prop="warningDays">
- <el-input-number
- v-model="warningForm.warningDays"
- :min="1"
- :max="365"
- placeholder="请输入预警天数"
- class="!w-full"
- :precision="0"
- :step="1"
- />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="warningDialogVisible = false">取 消</el-button>
- <el-button type="primary" @click="submitWarningSettings">确 定</el-button>
- </template>
- </el-dialog>
- <unitContainerForm ref="unitContainerFormRef" />
- </template>
-
- <script setup lang="ts">
- import { formatArrayDate } from '@/utils/formatTime'
- import { AppointmentConfirmOrderApi, AppointmentConfirmOrderVO } from '@/api/pressure/appointmentconfirmorder'
- import { ElMessage } from 'element-plus'
- import AreaSelect from '../../system/equipcontainer/components/AreaSelect.vue'
- import StreetSelect from '../../system/equipcontainer/components/StreetSelect.vue'
- import DeptSelect from '../plan/components/DeptSelect.vue'
- import { useRouter, useRoute } from 'vue-router'
- import dayjs from 'dayjs'
- import unitContainerForm from '@/components/unitContainerForm/index.vue'
- import { useEmitt } from '@/hooks/web/useEmitt'
- import { computed } from 'vue'
- import { cloneDeep } from 'lodash'
- import { isEmpty } from '@/utils/is'
- /** 约检确认 列表 */
- defineOptions({ name: 'OrderConfirm' })
-
- const cellStyle = ()=> {
- return {
- 'padding': '30px 0'
- }
- }
- const unitContainerFormRef = ref<InstanceType<typeof unitContainerForm>>()
- const router = useRouter()
- const route = useRoute()
-
- // 检验性质映射
- const checkTypeMap = {
- 100: '定期检验',
- 200: '年度检查',
- 300: '超年限检验'
- }
- const tempSendStatusMap: { [key: string]: string } = {
- '0': '推送成功',
- '1': '用户拒绝',
- '2': '其他原因失败',
- '3': '找不到平台用户'
- }
- const getTypeColor = computed(() => {
- return (status) => {
- const statusMap = {
- '1': 'warning',
- '0': 'success',
- '2': 'danger',
- '3': 'info',
- }
- return statusMap[status]
- }
- })
- // 设备类型
- const equipTypeMap = {
- 100: '容器',
- 200: '管道',
- 300: '锅炉'
- }
- // 确认状态
- const statusMap = {
- 100: '待确认',
- 200: '已确认',
- 300: '约检调整',
- 500: '已作废'
- }
-
- const loading = ref(true) // 列表的加载中
- const list = ref<AppointmentConfirmOrderVO[]>([]) // 列表的数据
- const total = ref(0) // 列表的总页数
- const queryParams = ref<Record<string, any>>({
- pageNo: 1,
- pageSize: 10,
- appointmentDate: [],
- unitName: '',
- useUnitName: '',
- unitAddress: '',
- equipCode: '',
- equipDistrict: undefined as number | undefined,
- equipStreet: undefined as number | undefined,
- deptId: '',
- equipType: '',
- checkType: '',
- status: ['100', '200', '300'],
- warningDay: [] as number[],
- createAcceptOrder: false,
- appointmentNo: ''
- })
- const queryFormRef = ref() // 搜索的表单
-
- // 短信确认相关
- const smsDialogVisible = ref(false)
- const smsFormRef = ref()
- const smsForm = reactive({
- mobile: ''
- })
- const smsRules = {
- mobile: [
- { required: true, message: '请输入手机号', trigger: 'blur' },
- { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
- ]
- }
- const currentRow = ref<AppointmentConfirmOrderVO>()
- const areaStreetMap = ref<Map<number, number[]>>(new Map())
- const handleAreaClear = () => {
- queryParams.value.equipStreet = undefined
- areaStreetMap.value.clear()
- }
- const handleAreaChange = (_areas: number[]) => {
- queryParams.value.equipStreet = undefined
- areaStreetMap.value.clear()
- return
- }
- const handleStreetClear = () => {
- areaStreetMap.value.clear()
- }
- const handleStreetChange = (streets: number[], areaId: number) => {
- if (queryParams.value.equipDistrict && areaId === queryParams.value.equipDistrict) {
- areaStreetMap.value.set(areaId, streets)
- }
- }
- const getPaginationList = async (page) => {
- queryParams.value.pageNo = page.page
- queryParams.value.pageSize = page.limit
- const { ids } = route.query as Recordable
- if(ids){
- queryParams.value.status = []
- queryParams.value.createAcceptOrder = undefined
- }
- await getList()
- }
- /** 查询列表 */
- const getList = async () => {
- loading.value = true
- try {
- const params = cloneDeep(queryParams.value)
- for (const key in params) {
- if (isEmpty(params[key])) {
- delete params[key]
- }
- }
- const data = await AppointmentConfirmOrderApi.getAppointmentConfirmOrderPage(params)
- list.value = data.list
- total.value = data.total
- } finally {
- loading.value = false
- }
- }
-
- /** 搜索按钮操作 */
- const handleQuery = () => {
- queryParams.value.pageNo = 1
- getList()
- }
-
- /** 重置按钮操作 */
- const resetQuery = () => {
- // queryFormRef.value.resetFields()
- queryParams.value = {
- pageNo: 1,
- pageSize: 10,
- warningDay: [] as number[],
- }
- handleQuery()
- }
-
- /** 约检按钮操作 */
- const handleAppointment = (row: AppointmentConfirmOrderVO) => {
- // 根据不同设备类型跳转不同页面
- switch (row.equipMainType){
- case 200:
- router.push({
- name: 'OrderBoilerDetail',
- query: {
- id: row.id
- }
- })
- break;
- case 300:
- router.push({
- name: 'OrderPipeDetail',
- query: {
- id: row.id
- }
- })
- break
- case 100:
- default:
- router.push({
- name: 'OrderConfirmDetail',
- query: {
- id: row.id
- }
- })
- break;
- }
- // router.push({
- // name: 'OrderConfirmDetail',
- // query: {
- // id: row.id
- // }
- // })
- }
- /** 选择框操作 */
- const handleSelectionChange = (selection: AppointmentConfirmOrderVO[]) => {
- console.log(selection)
- }
-
- /** 打开发送确认弹窗 */
- const handleSendConfirm = (row: AppointmentConfirmOrderVO) => {
- const {unitPhone = ''} = row
- if(!new RegExp(/^1[3-9]\d{9}$/).test(unitPhone)){
- ElMessage.error('发送失败,请修正约检联系人电话格式')
- return
- }
- currentRow.value = row
- smsForm.mobile = row.unitPhone || '' // 默认填入单位联系电话
- smsDialogVisible.value = true
- }
- /** 提交短信确认 */
- const submitSmsConfirm = async () => {
- if (!smsFormRef.value) return
- await smsFormRef.value.validate(async (valid: boolean) => {
- if (valid) {
- try {
- // 调用发送短信的API
- await AppointmentConfirmOrderApi.sendSmsConfirm({
- id: currentRow.value?.id,
- mobile: smsForm.mobile
- })
- ElMessage.success('短信发送成功')
- smsDialogVisible.value = false
- } catch (error) {
- console.error('发送短信失败:', error)
- } finally {
- getList();
- }
- }
- })
- }
- const handleUnitCodeFn = (id) => {
- if (!id) {
- return ElMessage.warning('该单位信息异常!')
- }
- unitContainerFormRef.value?.open(id)
- }
- /** 发送微信推送 */
- const handleSendWechatConfirm = async () => {
- try {
- // 调用发送短信的API
- await AppointmentConfirmOrderApi.sendWechatConfirm({
- id: currentRow.value?.id,
- })
- ElMessage.success('微信推送发送成功')
- smsDialogVisible.value = false
- } catch (error) {
- console.error('发送微信推送失败:', error)
- } finally {
- getList();
- }
- }
- // 预警设置相关
- const warningDialogVisible = ref(false)
- const warningFormRef = ref()
- const warningForm = reactive({
- warningDays: 30
- })
- const warningRules = {
- warningDays: [
- { required: true, message: '请输入预警天数', trigger: 'blur' },
- { validator: (_rule, value, callback) => {
- if (value < 1 || value > 365) {
- callback(new Error('预警天数必须在1-365之间'))
- } else {
- callback()
- }
- }, trigger: 'blur' }
- ]
- }
- /** 打开预警设置弹窗 */
- const handleWarningSettings = () => {
- warningDialogVisible.value = true
- }
- /** 提交预警设置 */
- const submitWarningSettings = async () => {
- if (!warningFormRef.value) return
- await warningFormRef.value.validate(async (valid: boolean) => {
- if (valid) {
- // 调用保存预警设置的API
- await AppointmentConfirmOrderApi.putWarningSettings({
- warningDay: warningForm.warningDays
- })
- ElMessage.success('预警设置保存成功')
- warningDialogVisible.value = false
- }
- })
- }
- /** 复制约检确认链接 */
- const handleCopyConfirmLink = () => {
- if (!currentRow.value?.id) {
- ElMessage.warning('获取约检ID失败')
- return
- }
-
- const url = `https://tjt.gzsei.cn/mp/pages/appointment-confirm/index?id=${currentRow.value.id}`
-
- // 使用 Clipboard API
- navigator.clipboard.writeText(url)
- .then(() => {
- ElMessage.success('约检确认链接已复制到剪贴板')
- })
- .catch(err => {
- console.error('复制失败: ', err)
- ElMessage.error('复制失败,请手动复制')
-
- // 兼容性处理:创建临时输入框
- const textArea = document.createElement('textarea')
- textArea.value = url
- document.body.appendChild(textArea)
- textArea.select()
-
- try {
- document.execCommand('copy')
- ElMessage.success('约检确认链接已复制到剪贴板')
- } catch (err) {
- ElMessage.error('复制失败,请手动复制')
- }
-
- document.body.removeChild(textArea)
- })
- }
- const { emitter } = useEmitt()
- emitter.on('refresh-list', ()=> {
- getList();
- })
- /** 初始化 **/
- onMounted(() => {
- // const { unitName } = route.query as Recordable
- // if(unitName){
- // queryParams.value.status = []
- // queryParams.value.createAcceptOrder = undefined
- // queryParams.value.unitName = unitName
- // }
- getList()
- })
- </script>
- <style lang="scss" scoped>
- .cursor-pointer .el-table__row {
- cursor: pointer;
- }
- .cursor-pointer .el-table__body-wrapper{
- padding-bottom: 16px;
- }
- </style>
|