Browse Source

信件签收 240203

master
wxc 2 years ago
parent
commit
a47a3ac9a2
  1. 4
      src/api/org/department.ts
  2. 2
      src/components/PoliceSelect.vue
  3. 4
      src/utils/util.ts
  4. 232
      src/views/home/components/MailTable.vue
  5. 2
      src/views/work/Done.vue
  6. 15
      src/views/work/Todo.vue
  7. 182
      src/views/work/components/ApplicationCompleted.vue
  8. 19
      src/views/work/components/MailDialog.vue
  9. 144
      src/views/work/components/VerifyForm.vue

4
src/api/org/department.ts

@ -32,4 +32,8 @@ export function listSecond() {
export function listThree() {
return request.get({ url: '/system/dept/three/list'})
}
export function listByThree() {
return request.get({ url: '/system/dept/three/listByThree'})
}

2
src/components/PoliceSelect.vue

@ -3,7 +3,7 @@
v-model="value"
filterable
:remote-method="remoteMethod"
placeholder=""
placeholder="请输入姓名搜索"
:loading="loading"
remote-show-suffix
@change="handleChange">

4
src/utils/util.ts

@ -175,11 +175,11 @@ export const formatTimeText = (seconds: number) => {
// 小时
if (seconds < 86400) {
const remainder = seconds % 3600;
return `${ Math.floor(seconds / 3600) }小时${ formatTimeText(remainder) }`
return `${ Math.floor(seconds / 3600) }小时${ parseInt(seconds % 3600 / 60) }`
}
// 天
const remainder = seconds % 86400;
return `${ Math.floor(seconds / 86400) }${ formatTimeText(remainder) }`
return `${ Math.floor(seconds / 86400) }${ parseInt(seconds % 86400 / 3600) }小时`
}
/**

232
src/views/home/components/MailTable.vue

@ -1,67 +1,213 @@
<template>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="我的待办" name="todo">
<el-table :data="tableData" style="width: 100%" stripe >
<el-table-column prop="date" label="来信时间" width="180" />
<el-table-column prop="name" label="姓名" width="180" />
<el-table-column prop="address" label="联系电话" />
<el-table-column prop="address" label="信件内容" />
<el-table-column prop="address" label="办理单位" />
<el-table-column prop="address" label="信件状态" />
<el-table-column prop="address" label="流程节点" />
<el-table-column prop="address" label="操作" />
<el-table :data="todos" style="width: 100%" stripe>
<el-table-column
prop="mailTime"
label="来信时间"
align="center"
width="180"
/>
<el-table-column
prop="contactName"
label="姓名"
align="center"
width="120"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
width="120"
/>
<el-table-column
prop="contactIdCard"
label="身份证号"
width="120"
/>
<el-table-column
prop="content"
label="信件内容"
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column label="流程节点">
<template #default="{ row }"> </template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleMail(row.mailId)"
>立即处理</el-button
>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="即将到期" name="due">即将到期</el-tab-pane>
<el-tab-pane label="督办信件" name="supervise">
<el-table :data="superviseTodos" style="width: 100%" stripe>
<el-table-column
prop="mailTime"
label="来信时间"
align="center"
width="180"
/>
<el-table-column
prop="contactName"
label="姓名"
align="center"
width="120"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
width="120"
/>
<el-table-column
prop="contactIdCard"
label="身份证号"
width="120"
/>
<el-table-column
prop="content"
label="信件内容"
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column label="流程节点">
<template #default="{ row }"> </template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleMail(row.mailId)"
>立即处理</el-button
>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="高敏信件" name="high">
<el-table :data="highTodos" style="width: 100%" stripe>
<el-table-column
prop="mailTime"
label="来信时间"
align="center"
width="180"
/>
<el-table-column
prop="contactName"
label="姓名"
align="center"
width="120"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
width="120"
/>
<el-table-column
prop="contactIdCard"
label="身份证号"
width="120"
/>
<el-table-column
prop="content"
label="信件内容"
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column label="流程节点">
<template #default="{ row }"> </template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button
type="primary"
link
@click="handleMail(row.mailId)"
>立即处理</el-button
>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="即将到期" name="due">Config</el-tab-pane>
<el-tab-pane label="督办信件" name="supervise">Role</el-tab-pane>
<el-tab-pane label="高敏信件" name="highSensitivity">Task</el-tab-pane>
</el-tabs>
</template>
<script setup>
import { getTodos } from "@/api/work";
const activeName = ref("todo");
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
watch(activeName, (val) => {
if (val === "todo") {
}
if (val === "supervise") {
superviseTodoList();
}
if (val === "high") {
highTodoList();
}
});
const todos = ref([]);
const superviseTodos = ref([]);
const highTodos = ref([]);
todoList();
function todoList() {
getTodos({
size: 8,
current: 1,
}).then((data) => {
todos.value = data.records;
});
}
function superviseTodoList() {
getTodos({
size: 8,
current: 1,
mailLevel: "superintend",
}).then((data) => {
superviseTodos.value = data.records;
});
}
function highTodoList() {
getTodos({
size: 8,
current: 1,
mailLevel: "high_sensitivity",
}).then((data) => {
highTodos.value = data.records;
});
}
</script>
<style lang="scss" scoped>
.el-tabs {
--el-font-size-base: 24px;
--el-text-color-primary: #999;
:deep() {
.el-tabs__header {
margin: 0;
.el-tabs__nav {
padding-bottom: 16px;
.el-tabs__item {
font-weight: 700;
}
padding-bottom: 16px;
.el-tabs__item {
font-weight: 700;
}
}
}
.el-tabs__active-bar {
.el-tabs__active-bar {
height: 4px;
}
.el-tabs__item {
--el-font-size-base: 24px;
--el-text-color-primary: #999;
}
}
}
</style>

2
src/views/work/Done.vue

@ -182,7 +182,7 @@
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column prop="handlingDeptName" label="办理单位" />
<el-table-column prop="threeDeptName" label="办理单位" />
<el-table-column label="流程节点">
<template #default="{ row }">

15
src/views/work/Todo.vue

@ -182,14 +182,21 @@
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column prop="handlingDeptName" label="办理单位" />
<el-table-column prop="threeDeptName" label="办理单位" />
<el-table-column label="流程节点">
<template #default="{ row }">
<el-tag :type="getFlowTagType(row.flowKey)" v-if="row.flowBeforeName">{{ row.flowBeforeName }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="" label="流程限时" />
<el-table-column label="流程限时">
<template #default="{ row }">
<div v-if="row.flowLimitedRemainingTime" :class="row.flowLimitedRemainingTime > 0 ? 'success' : 'error'">
<span class="mr-8">{{ row.flowLimitedRemainingTime > 0 ? '剩余' : '超时' }}</span>
<span class="text">{{ formatTimeText(row.flowLimitedRemainingTime) }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="操作">
<template #default="{ row }">
<el-button
@ -214,6 +221,7 @@ import { getTodos } from "@/api/work";
import { getMailFlowDetail } from "@/api/mail";
import { useDictData } from "@/hooks/useDictOptions";
import useMailStore from "@/stores/modules/mail";
import { formatTimeText } from "@/utils/util";
const mailStore = useMailStore();
mailStore.getMailCategorys();
@ -264,4 +272,7 @@ function getFlowTagType(flowKey) {
.table-container {
border: 1px solid rgba(198, 208, 251, 1);
}
.success .text {
color: #128009;
}
</style>

182
src/views/work/components/ApplicationCompleted.vue

@ -0,0 +1,182 @@
<template>
<el-dialog
v-model="visible"
width="50vw"
title="申请办结"
>
<div>
<h2>选择办结方式</h2>
<el-form
label-position="top"
:model="form"
:rules="rules"
ref="formRef"
>
<el-form-item prop="completeMethod">
<el-radio-group v-model="form.completeMethod" style="">
<el-row :gutter="20">
<el-col :span="12">
<el-radio :label="'offline'"
>线下审批</el-radio
></el-col
>
<el-col :span="12">
<el-radio :label="'online'"
>线上呈批</el-radio
></el-col
>
</el-row>
</el-radio-group>
</el-form-item>
<p>线上呈批时由三级机构专班发起办结线上呈批流程经由</p>
<h3>
所队领导 二级机构专班 二级机构分管领导
二级机构正职领导 二级机构专班 市局专班
</h3>
<p style="margin-bottom: 40px">逐步上报审批</p>
<div style="margin-bottom: 60px">
<el-form-item
label="呈报上级,选择对应的二级机构专班"
prop="secondDeptId"
v-if="form.completeMethod === 'online'"
>
<el-select
v-model="form.secondDeptId"
@change="handleSelect"
>
<el-option
v-for="item in depts"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item
label="请选择上级领导"
prop="leaderEmpNo"
v-else
>
<el-select
v-model="form.leaderEmpNo"
@change="handleSelect"
>
<el-option
v-for="item in leaders"
:key="item.id"
:label="item.name"
:value="item.empNo"
/>
</el-select>
</el-form-item>
</div>
</el-form>
</div>
<footer class="flex end">
<el-button type="primary" size="large" @click="submit"
>提交办结</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { listSecond } from "@/api/org/department";
import { getLeaderList } from "@/api/perms/admin";
const visible = ref(false);
const props = defineProps({
show: {
type: Boolean,
default: false,
},
data: {
type: Object,
default: {}
},
});
const emits = defineEmits(["update:show", "update:data", "submit"]);
watch(visible, (val) => {
emits("update:show", val);
});
watch(
() => props.show,
(val) => {
visible.value = val;
if (val) {
}
}
);
const form = ref({});
const formRef = ref(null);
const rules = {
completeMethod: [
{
required: true,
message: "请选择办结方式",
},
],
secondDeptId: [
{
required: true,
message: "请选择二级机构",
},
],
leaderEmpNo: [
{
required: true,
message: "请选择上级领导",
},
],
};
const depts = ref([]);
listSecond().then((data) => {
depts.value = data;
});
const leaders = ref([]);
getLeaderList().then((data) => {
leaders.value = data;
});
function submit() {
formRef.value.validate((valid) => {
if (valid) {
const data = { ...props.data, ...form.value}
emits('update:data', data)
emits('submit', form.value.completeMethod)
visible.value = false
}
});
}
</script>
<style lang="scss" scoped>
h2 {
color: var(--primary-color);
font-size: 24px;
font-weight: 500;
margin-top: 0;
}
h3 {
color: var(--primary-color);
font-size: 20px;
}
.el-radio-group {
display: block;
width: 100%;
.el-radio {
--el-radio-font-size: 24px;
--el-radio-input-width: 22px;
--el-radio-input-height: 22px;
border: 1px solid #c3caf5;
display: flex;
padding: 16px;
&.is-checked {
background-color: #f1f2fc;
}
}
}
.el-col {
}
</style>

19
src/views/work/components/MailDialog.vue

@ -218,6 +218,7 @@
v-for="action in actions"
:key="action.key"
:type="action.btnType"
:plain="action.btnPlain"
size="large"
@click="handleAction(action.key)"
>{{ action.btnLabel }}</el-button
@ -227,6 +228,8 @@
</el-dialog>
<Message ref="messageRef" />
<ApplicationCompleted v-model:show="completeShow" v-model:data="requestData" @submit="handleAction" />
</template>
<script setup>
import MailTypeForm from "./MailTypeForm.vue";
@ -236,6 +239,8 @@ import ContactWriterFrom from "./ContactWriterFrom.vue";
import InterviewWriterFrom from "./InterviewWriterFrom.vue";
import VerifyForm from "./VerifyForm.vue";
import ApplicationCompleted from "./ApplicationCompleted.vue";
import { getMailFlowDetail, flowNext } from "@/api/mail";
import { addFav, delFav } from "@/api/work/fav";
import { useDictData } from "@/hooks/useDictOptions";
@ -366,6 +371,9 @@ const requestBody = ref({});
const requestData = ref({});
const messageRef = ref();
async function handleAction(key) {
if (!key) {
return
}
if (mailTypeFormRef.value) {
await mailTypeFormRef.value.validate();
}
@ -375,6 +383,14 @@ async function handleAction(key) {
if (contactWriterFromRef.value) {
await contactWriterFromRef.value.validate();
}
if (verifyFormRef.value) {
await verifyFormRef.value.validate();
}
//
if (key === 'applicationCompleted') {
completeShow.value = true;
return
}
requestBody.value = {
mailId: props.mailId,
nextActionKey: key,
@ -416,6 +432,9 @@ function handleFav() {
});
}
}
const completeShow = ref(false);
</script>
<style lang="scss" scoped>
.dialog-header {

144
src/views/work/components/VerifyForm.vue

@ -1,5 +1,5 @@
<template>
<el-form :label-width="140" :model="form" :rules="rules" ref="formRef">
<el-form :label-width="170" :model="form" :rules="rules" ref="formRef">
<el-row>
<el-form-item
label="核办结果"
@ -15,7 +15,7 @@
</el-form-item>
</el-row>
<el-row>
<el-form-item label="是否属实">
<el-form-item label="是否属实" prop="verifyIsTrue">
<el-radio-group v-model="form.verifyIsTrue">
<el-radio label="1" size="large">属实</el-radio>
<el-radio label="2" size="large">基本属实</el-radio>
@ -26,34 +26,75 @@
<el-row>
<el-form-item label="被举报对象">
<div>
<div class="flex gap mb-10">
<el-select></el-select>
<el-select></el-select>
<div></div>
<el-button type="darger" plain>删除</el-button>
</div>
<div class="flex gap">
<el-select></el-select>
<el-select></el-select>
<div></div>
<el-button type="darger" plain>删除</el-button>
<div
class="flex between gap mb-10"
v-for="(item, index) in reportedPolices"
:key="index"
>
<el-select
v-model="item.deptId"
@change="handleChangeDept"
style="width: 280px"
>
<el-option
v-for="item in threeDepts"
:key="item.id"
:value="item.id"
:label="item.name"
></el-option>
</el-select>
<el-select v-model="item.empNo" style="width: 280px">
<el-option
v-for="item in polices"
:key="item.id"
:value="item.empNo"
:label="item.name"
></el-option
></el-select>
<div style="font-size: 12px">
<span v-if="item.empNo">
<span class="mr-4">警号</span>
<span class="mr-4">{{ item.empNo }}</span>
</span>
<span v-if="item.gender">
<span class="mr-4">性别</span>
<span class="mr-4">{{ item.gender }}</span>
</span>
<span v-if="item.birthday">
<span class="mr-4">出生年月</span>
<span>{{ item.birthday }}</span>
</span>
</div>
<el-button
type="darger"
plain
@click="reportedPolices.splice(index, 1)"
>删除</el-button
>
</div>
</div>
</el-form-item>
</el-row>
<div class="text-center">
<el-button type="primary" plain>添加被举报对象</el-button>
<el-button type="primary" plain @click="reportedPolices.push({})"
>添加被举报对象</el-button
>
</div>
<el-divider />
<el-row>
<el-form-item label="查证属实问题">
<el-form-item label="查证属实问题" prop="verifyProblem">
<el-checkbox-group v-model="form.verifyProblem">
<el-checkbox v-for="item in dictData.verify_problem" :key="item.value" :label="item.name" :value="item.value" />
<el-checkbox
v-for="item in dictData.verify_problem"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-checkbox-group>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="是否需要问责">
<el-form-item label="是否需要问责" prop="verifyNeedAccountability">
<el-radio-group v-model="form.verifyNeedAccountability">
<el-radio label="1" size="large"></el-radio>
<el-radio label="2" size="large"></el-radio>
@ -63,8 +104,12 @@
<el-row>
<el-form-item label="责任追究">
<el-checkbox-group v-model="form.verifyPunish">
<el-checkbox v-for="item in dictData.verify_punish" :key="item.value" :label="item.name" :value="item.value" />
<el-checkbox
v-for="item in dictData.verify_punish"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-checkbox-group>
</el-form-item>
</el-row>
@ -77,7 +122,7 @@
</el-form-item>
</el-row>
<el-row>
<el-form-item label="办理反馈情况">
<el-form-item label="办理反馈情况" prop="verifyFeedback">
<el-radio-group v-model="form.verifyFeedback">
<el-radio label="1" size="large">满意</el-radio>
<el-radio label="2" size="large">基本满意</el-radio>
@ -87,19 +132,19 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="回访人姓名">
<el-input />
<el-form-item label="回访人姓名" prop="verifyFollowupPolice">
<police-select v-model:data="form.verifyFollowupPolice" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="回访人电话">
<el-input />
<span>{{ form.verifyFollowupPolice?.phone }}</span>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-form-item label="回访人警号">
<el-input />
<span>{{ form.verifyFollowupPolice?.empNo }}</span>
</el-form-item>
</el-row>
<el-row>
@ -112,7 +157,7 @@
</el-col>
<el-col :span="12">
<el-form-item label="佐证材料说明">
<div style="line-height: 1.5;">
<div style="line-height: 1.5">
请上传核查办理报告处理反馈表及相关的法律文件比如受案回执立案决定书不予立案决定书等和佐证材料比如谈话笔录调解协议等
</div>
<div>
@ -130,10 +175,16 @@
</template>
<script setup>
import { useDictData } from "@/hooks/useDictOptions";
import { listByThree } from "@/api/org/department";
import { allLists } from "@/api/perms/admin";
const { dictData } = useDictData(["verify_problem", "verify_punish"]);
const threeDepts = ref([]);
const polices = ref([]);
const form = ref({});
const formRef = ref();
const reportedPolices = ref([]);
const rules = {
verifyDetails: [
@ -172,18 +223,48 @@ const rules = {
message: "请选择办理反馈情况",
},
],
verifyFeedback: [
verifyFollowupPolice: [
{
required: true,
message: "请选择回访人姓名",
message: "请选择回访人",
},
],
};
listByThree().then((data) => {
threeDepts.value = data;
});
function handleChangeDept(deptId) {
allLists({
deptId,
}).then((data) => {
polices.value = data;
});
}
function handleChangePolice(empNo, index) {
const police = polices.value.filter(item => item.empNo === empNo)[0]
reportedPolices.value[index].sex = police.gender
reportedPolices.value[index].birthday = police.birthday
}
const props = defineProps({
data: {
type: Object,
default: {},
},
});
const emits = defineEmits(["update:data"]);
function validate() {
return new Promise((resolve, reject) => {
formRef.value.validate((valid) => {
if (valid) {
const verifyReportedPolices = reportedPolices.value.filter(item => item.empNo)
form.value.verifyReportedPolices = JSON.stringify(verifyReportedPolices)
form.value.verifyFollowupPolice = JSON.stringify(form.value.verifyFollowupPolice)
emits("update:data", form.value);
resolve(true);
} else {
@ -196,11 +277,4 @@ function validate() {
defineExpose({
validate,
});
</script>
<style lang="scss" scoped>
:deep() {
.el-form-item__label {
text-align: right;
}
}
</style>
</script>
Loading…
Cancel
Save