You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
11 KiB
279 lines
11 KiB
<template> |
|
<div class="container"> |
|
<header> |
|
<el-form class="demo-form-inline" :label-width="120"> |
|
<el-row> |
|
<el-col :span="6"> |
|
<el-form-item label="来信时间"> |
|
<el-date-picker v-model="query.mailTime" value-format="YYYY-MM-DD" type="daterange" |
|
range-separator="~" start-placeholder="开始日期" end-placeholder="结束日期" |
|
@change="handleMailTimeQuery" /> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="信件来源"> |
|
<el-select v-model="query.source" placeholder="请选择信件来源" clearable> |
|
<el-option v-for="item in dictData.mail_source" :key="item.value" :label="item.name" |
|
:value="item.value" /> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="来信人员"> |
|
<div class="flex gap"> |
|
<el-select v-model="query.contactField"> |
|
<el-option label="姓名" value="name" /> |
|
<el-option label="身份证" value="idCard" /> |
|
<el-option label="联系电话" value="phone" /> |
|
</el-select> |
|
<el-input v-model="query.contactFieldValue" placeholder="请输入" clearable /> |
|
</div> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="信件等级"> |
|
<el-select v-model="query.mailLevel" placeholder="请选择信件等级" clearable> |
|
<el-option v-for="item in dictData.mail_level" :key="item.value" :label="item.name" |
|
:value="item.value" /> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
</el-row> |
|
<el-row> |
|
<el-col :span="6"> |
|
<el-form-item label="信件分类"> |
|
<el-tree-select v-model="query.mailCategory" :data="mailStore.mailCategorys" check-strictly |
|
filterable /> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="信件状态"> |
|
<el-select v-model="query.mailState" placeholder="请选择信件状态" clearable> |
|
<el-option v-for="item in dictData.mail_state" :key="item.value" :label="item.name" |
|
:value="item.value" /> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="办理单位"> |
|
<el-tree-select class="flex-1" v-model="query.deptId" :data="optionsData.dept" clearable |
|
node-key="id" filterable :props="{ |
|
value: 'id', |
|
label: 'name', |
|
disabled(data: any) { |
|
return !!data.isStop |
|
} |
|
}" check-strictly placeholder="请选择上级部门" /> |
|
</el-form-item> |
|
</el-col> |
|
<el-col :span="6"> |
|
<el-form-item label="流程阶段"> |
|
<el-select v-model="query.flowKey" placeholder="" clearable multiple :collapse-tags="true"> |
|
<el-option v-for="item in optionsData.flowNodes" :key="item.key" :label="item.fullName" |
|
:value="item.key" /> |
|
</el-select> |
|
</el-form-item> |
|
</el-col> |
|
</el-row> |
|
<div class="flex between mb-20"> |
|
<div> |
|
<el-button type="primary" @click="createMail" v-perms="['mail:add']">自建信件</el-button> |
|
</div> |
|
<div> |
|
<el-button type="primary" @click="getList">查询</el-button> |
|
<el-button @click="reset">重置</el-button> |
|
</div> |
|
</div> |
|
</el-form> |
|
</header> |
|
<main> |
|
<div class="table-container"> |
|
<el-table :data="todos" style="width: 100%" stripe> |
|
<el-table-column prop="mailTime" label="来信时间" align="center" width="160" /> |
|
<el-table-column label="信件来源" align="center" width="90"> |
|
<template #default="{ row }"> |
|
<span>{{ |
|
dictData.mail_source.filter( |
|
(item) => item.value === row.source |
|
)[0].name |
|
}}</span> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="contactName" label="姓名" align="center" width="80" /> |
|
<el-table-column prop="contactPhone" label="联系电话" align="center" width="120" /> |
|
<el-table-column label="信件等级" width="100" align="center"> |
|
<template #default="{ row }"> |
|
<mail-level :value="row.mailLevel" :list="dictData.mail_level" /> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="mailCategory" label="信件分类" align="center" width="120" /> |
|
<el-table-column prop="content" align="center" label="信件内容" show-overflow-tooltip width="150" /> |
|
<el-table-column label="信件状态" width="90" align="center"> |
|
<template #default="{ row }"> |
|
<span>{{ |
|
getDictLable(dictData.mail_state, row.mailState) |
|
}}</span> |
|
</template> |
|
</el-table-column> |
|
<el-table-column prop="threeDeptName" label="办理单位" width="120" align="center" /> |
|
<el-table-column label="流程节点" align="center"> |
|
<template #default="{ row }"> |
|
<el-tag :type="getFlowTagType(row.flowName)">{{ row.flowName }}</el-tag> |
|
</template> |
|
</el-table-column> |
|
<el-table-column label="流程限时" align="center"> |
|
<template #default="{ row }"> |
|
<div v-if="row.flowLimitedRemainingTime > 0" class="success"> |
|
<span class="mr-4">剩余</span> |
|
<span class="text">{{ |
|
formatTimeText(row.flowLimitedRemainingTime) |
|
}}</span> |
|
</div> |
|
<div v-if="row.flowLimitedRemainingTime < 0" class="error"> |
|
<span class="mr-4">超时</span> |
|
<span class="text">{{ |
|
formatTimeText( |
|
-row.flowLimitedRemainingTime |
|
) |
|
}}</span> |
|
</div> |
|
</template> |
|
</el-table-column> |
|
<el-table-column label="操作" fixed="right" align="center"> |
|
<template #default="{ row }"> |
|
<el-button type="primary" link @click="handleMail(row)">立即处理</el-button> |
|
</template> |
|
</el-table-column> |
|
</el-table> |
|
</div> |
|
<div class="flex mt-4 end"> |
|
<el-pagination @size-change="getList" @current-change="getList" :current-page="query.current" |
|
:page-sizes="[10, 20, 50]" :page-size="query.size" v-model:current-page="query.current" |
|
:total="totalSize.total"> |
|
</el-pagination> |
|
</div> |
|
</main> |
|
</div> |
|
|
|
<MailDialog v-model:show="showModel" :mail-id="activeMailId" :work-id="activeWorkId" :work-type="activeWorkType" |
|
@update="getList" /> |
|
<AddMail v-model="addMailShow" @close="addMailShow = false" @success="getList" /> |
|
|
|
</template> |
|
<script lang="ts" setup> |
|
import MailDialog from "./components/MailDialog.vue"; |
|
import AddMail from "./components/AddMail.vue"; |
|
import { getTodos } from "@/api/work"; |
|
import { getMailFlowDetail } from "@/api/mail"; |
|
import { useDictData, useDictOptions } from "@/hooks/useDictOptions"; |
|
import useMailStore from "@/stores/modules/mail"; |
|
import { formatTimeText, getDictLable, getFlowTagType } from "@/utils/util"; |
|
import { deptLists } from '@/api/org/department' |
|
import { getFlowNodes } from '@/api/org/flowNode' |
|
import { onMounted, onUnmounted } from 'vue' |
|
const mailStore = useMailStore(); |
|
mailStore.getMailCategorys(); |
|
const { dictData } = useDictData(["mail_source", "mail_level", "mail_state"]); |
|
|
|
const query = ref({ |
|
size: 10, |
|
current: 1, |
|
}); |
|
const totalSize = reactive({ |
|
total: 0, |
|
pages: 0 |
|
}) |
|
|
|
const addMailShow = ref(false); |
|
|
|
const todos = ref([]); |
|
const showModel = ref(false); |
|
const activeMailId = ref(""); |
|
const activeWorkId = ref(0); |
|
const activeWorkType = ref("") |
|
const { optionsData } = useDictOptions<{ |
|
dept: any[], |
|
flowNodes: any[] |
|
}>({ |
|
dept: { |
|
api: deptLists |
|
}, |
|
flowNodes: { |
|
api: getFlowNodes |
|
} |
|
}) |
|
function handleMail(row) { |
|
showModel.value = true; |
|
activeMailId.value = row.mailId; |
|
activeWorkId.value = row.id; |
|
activeWorkType.value = row.workType |
|
} |
|
|
|
let timeClock: any = null |
|
const updateCountdown = (second: number) => { |
|
todos.value.forEach((item: any) => { |
|
if (item.flowLimitedRemainingTime > 0) { |
|
item.flowLimitedRemainingTime -= 1; |
|
} |
|
}); |
|
}; |
|
onMounted(() => { |
|
timeClock = setInterval(updateCountdown, 1000) |
|
}) |
|
onUnmounted(() => { |
|
clearInterval(timeClock); |
|
}); |
|
|
|
function getList() { |
|
getTodos(query.value).then((data) => { |
|
todos.value = data.records; |
|
totalSize.total = data.total; |
|
totalSize.pages = data.pages; |
|
}); |
|
} |
|
|
|
|
|
|
|
function reset() { |
|
query.value = {}; |
|
getList(); |
|
} |
|
|
|
const createMail = () => { |
|
addMailShow.value = true; |
|
} |
|
|
|
getList() |
|
|
|
function handleMailTimeQuery(val) { |
|
if (val) { |
|
query.value.mailTimeStart = val[0]; |
|
query.value.mailTimeEnd = val[1]; |
|
} else { |
|
delete query.value.mailTimeStart |
|
delete query.value.mailTimeEnd |
|
} |
|
} |
|
</script> |
|
<style lang="scss" scoped> |
|
.success { |
|
padding: 0 8px; |
|
height: 24px; |
|
line-height: 24px; |
|
text-align: center; |
|
|
|
.text { |
|
color: #128009; |
|
} |
|
} |
|
|
|
.error { |
|
background-color: #ff0000; |
|
color: #fff; |
|
padding: 0 8px; |
|
height: 24px; |
|
line-height: 24px; |
|
border-radius: 20px; |
|
text-align: center; |
|
} |
|
</style> |