Browse Source

信件签收

master
wxc 2 years ago
parent
commit
c5fe3ce454
  1. 9
      src/api/perms/admin.ts
  2. 42
      src/components/LeaderSelect.vue
  3. 37
      src/components/Upload.vue
  4. 2
      src/utils/request.ts
  5. 6
      src/utils/util.ts
  6. 2
      src/views/Login.vue
  7. 2
      src/views/home/components/MailTable.vue
  8. 9
      src/views/work/Done.vue
  9. 73
      src/views/work/Todo.vue
  10. 1
      src/views/work/components/ApplicationCompleted.vue
  11. 16
      src/views/work/components/ConfirmedCompletion.vue
  12. 3
      src/views/work/components/InitiateCountersign.vue
  13. 172
      src/views/work/components/MailDialog.vue
  14. 129
      src/views/work/components/RemainingTime.vue
  15. 13
      src/views/work/components/ReviewComments.vue
  16. 0
      src/views/work/components/templates/ContactWriterForm.vue
  17. 9
      src/views/work/components/templates/CountersignForm.vue
  18. 2
      src/views/work/components/templates/InterviewWriterForm.vue
  19. 88
      src/views/work/components/templates/MailApprovalDetail.vue
  20. 5
      src/views/work/components/templates/VerifyForm.vue

9
src/api/perms/admin.ts

@ -38,11 +38,6 @@ export function adminStatus(params: any) {
}
// 领导列表(正职)
export function getLeaderList() {
return request.get({ url: '/system/admin/leader/list'})
}
// 领导列表(副职)
export function getDeputyList() {
return request.get({ url: '/system/admin/leader/list'})
export function getLeaderList(type) {
return request.get({ url: '/system/admin/leader/list?type=' + type})
}

42
src/components/LeaderSelect.vue

@ -12,28 +12,42 @@
<script setup>
import { getLeaderList } from "@/api/perms/admin";
const selectVal = ref('');
defineProps({
value: {
const selectVal = ref("");
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:value', 'change']);
default: "",
},
leaderType: {
type: String,
default: 'all',
},
});
const emit = defineEmits(["update:modelValue", "change"]);
function handleSelect(val) {
emit('update:value', val);
const option = leaders.value.filter(
(item) => item.empNo === val
)[0];
emit('change', val, option);
emit("update:modelValue", val);
const option = leaders.value.filter((item) => item.empNo === val)[0];
emit("change", val, option);
}
const leaders = ref([]);
getLeaderList().then((data) => {
console.log('leaderType', props.leaderType)
function getLeaders() {
getLeaderList(props.leaderType).then((data) => {
leaders.value = data;
});
});
}
getLeaders();
watch(
() => props.leaderType,
() => {
console.log('watch leaderType', props.leaderType)
getLeaders();
}
);
</script>
<style lang="scss" scoped>
</style>

37
src/components/Upload.vue

@ -16,9 +16,12 @@
</template>
</el-button>
</el-upload>
<div class="flex wrap img-box mt-10">
<div class="flex v-center wrap img-box mt-10 gap">
<template v-for="(item, index) in files" :key="index">
<div class="relative">
<div
class="relative item"
v-if="item.type && item.type.indexOf('image') > -1"
>
<img
:src="`${VITE_API_URL}/api/file/stream/${item.filepath}`"
/>
@ -26,6 +29,13 @@
<icon name="el-icon-CircleCloseFilled" :size="20" />
</a>
</div>
<div class="relative item flex center v-center column" v-else>
<icon name="el-icon-Document" :size="20" />
<span>{{ item.orgiinFilename }}</span>
<a class="close-btn" @click="remove(index)">
<icon name="el-icon-CircleCloseFilled" :size="20" />
</a>
</div>
</template>
</div>
</div>
@ -35,13 +45,13 @@ import { getToken } from "@/utils/auth";
const { VITE_API_URL } = process.env;
const props = defineProps({
value: {
modelValue: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(["update:value"]);
const emit = defineEmits(["update:modelValue"]);
const files = ref([]);
@ -56,20 +66,33 @@ function handleSuccess(data, file) {
orgiinFilename: file.name,
type: file.raw.type,
});
emit("update:value", files.value);
emit("update:modelValue", files.value);
}
function remove(index) {
files.value.splice(index, 1);
emit("update:value", files.value);
emit("update:modelValue", files.value);
}
</script>
<style lang="scss" scoped>
.img-box {
img {
.item {
width: 80px;
height: 80px;
background-color: #edf0ff;
color: var(--primary-color);
img {
width: 100%;
height: 100%;
}
span {
line-height: 1.2;
height: 34px;
overflow: hidden;
}
}
.close-btn {
position: absolute;
top: -10px;

2
src/utils/request.ts

@ -82,7 +82,7 @@ function ajax(url: string, options: Options) {
if (res.code === 401) {
message = "未授权登陆"
}
feedback.msgError(message || '未知错误')
// feedback.msgError(message || '未知错误')
reject(res)
}

6
src/utils/util.ts

@ -209,7 +209,11 @@ export const getDictLable = (dictArr: any[], value: string) => {
if (!dictArr || !dictArr.length) {
return ''
}
return dictArr.filter(item => item.value === value)[0].name
const obj = dictArr.find(item => item.value === value)
if (!obj) {
return ''
}
return obj.name;
}
export function getFlowTagType(flowKey) {

2
src/views/Login.vue

@ -132,7 +132,7 @@ const handleLogin = async () => {
try {
await userStore.login(formData);
} catch (error) {
console.log(error);
isLock.value = false;
}
const {
query: { redirect },

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

@ -207,7 +207,7 @@
<MailDialog
v-model:show="showModel"
:mail-id="activeMailId"
@update="getList"
@update="todoList"
/>
</template>
<script setup>

9
src/views/work/Done.vue

@ -181,7 +181,13 @@
label="信件内容"
show-overflow-tooltip
/>
<el-table-column prop="mailState" label="信件状态" />
<el-table-column label="信件状态" width="90">
<template #default="{ row }">
<span>{{
getDictLable(dictData.mail_state, row.mailState)
}}</span>
</template>
</el-table-column>
<el-table-column prop="threeDeptName" label="办理单位" />
<el-table-column label="流程节点">
@ -220,6 +226,7 @@ import { getDones } from "@/api/work";
import { getMailFlowDetail } from "@/api/mail";
import { useDictData } from "@/hooks/useDictOptions";
import useMailStore from "@/stores/modules/mail";
import { getDictLable } from "@/utils/util";
const mailStore = useMailStore();
mailStore.getMailCategorys();

73
src/views/work/Todo.vue

@ -1,11 +1,7 @@
<template>
<div class="container">
<header>
<el-form
:inline="true"
class="demo-form-inline"
:label-width="120"
>
<el-form :inline="true" class="demo-form-inline" :label-width="120">
<el-row>
<el-col :span="6">
<el-form-item label="来信时间">
@ -147,11 +143,7 @@
align="center"
width="170"
/>
<el-table-column
label="信件来源"
align="center"
width="94"
>
<el-table-column label="信件来源" align="center" width="94">
<template #default="{ row }">
<span>{{
dictData.mail_source.filter(
@ -179,7 +171,11 @@
/>
</template>
</el-table-column>
<el-table-column prop="mailCategory" label="信件分类" width="160" />
<el-table-column
prop="mailCategory"
label="信件分类"
width="160"
/>
<el-table-column
prop="content"
label="信件内容"
@ -187,25 +183,47 @@
/>
<el-table-column label="信件状态" width="90">
<template #default="{ row }">
<span>{{ getDictLable(dictData.mail_state, row.mailState) }}</span>
<span>{{
getDictLable(dictData.mail_state, row.mailState)
}}</span>
</template>
</el-table-column>
<el-table-column prop="threeDeptName" label="办理单位" width="160" />
<el-table-column
prop="threeDeptName"
label="办理单位"
width="160"
/>
<el-table-column label="流程节点">
<template #default="{ row }">
<el-tag :type="getFlowTagType(row.flowKey)" v-if="row.flowBeforeName">{{ row.flowBeforeName }}</el-tag>
<el-tag
:type="getFlowTagType(row.flowKey)"
v-if="row.flowBeforeName"
>{{ row.flowBeforeName }}</el-tag
>
<el-tag type="danger" v-else>未签收</el-tag>
</template>
</el-table-column>
<el-table-column label="流程限时">
<template #default="{ row }">
<div v-if="row.flowLimitedRemainingTime > 0" class="success">
<div
v-if="row.flowLimitedRemainingTime > 0"
class="success"
>
<span class="mr-4">剩余</span>
<span class="text">{{ formatTimeText(row.flowLimitedRemainingTime) }}</span>
<span class="text">{{
formatTimeText(row.flowLimitedRemainingTime)
}}</span>
</div>
<div v-if="row.flowLimitedRemainingTime < 0" class="error">
<div
v-if="row.flowLimitedRemainingTime < 0"
class="error"
>
<span class="mr-4">超时</span>
<span class="text">{{ formatTimeText(-row.flowLimitedRemainingTime) }}</span>
<span class="text">{{
formatTimeText(
-row.flowLimitedRemainingTime
)
}}</span>
</div>
</template>
</el-table-column>
@ -223,15 +241,17 @@
</div>
<div class="flex mt-4 end">
<el-pagination @size-change="getList" @current-change="getList" :current-page="query.current"
:page-sizes="[10, 15, 20, 40, 50]" :page-size="query.size"
:page-sizes="[10, 15, 20, 40, 50]" :page-size="query.size" v-model:current-page="query.current"
layout="total,sizes, prev, pager, next, jumper" :total="totalSize.total">
</el-pagination>
</div>
</main>
</div>
<MailDialog v-model:show="showModel" :mail-id="activeMailId" @update="getList" />
<CreateMailSelfDialog v-model="showCreateMailSelf" @close="closeCreateMailSelf" />
</template>
<script setup>
import MailDialog from "./components/MailDialog.vue";
@ -248,7 +268,7 @@ const { dictData } = useDictData(["mail_source", "mail_level", "mail_state"]);
const query = ref({
size: 10,
current: 1
current: 1,
});
const totalSize = reactive({
total: 0,
@ -282,8 +302,8 @@ function getList() {
}
function reset() {
query.value = {}
getList()
query.value = {};
getList();
}
const createMail = () => {
@ -292,21 +312,22 @@ const createMail = () => {
getList()
</script>
<style lang="scss" scoped>
.table-container {
border: 1px solid rgba(198, 208, 251, 1);
}
.success .text {
color: #128009;
.success {
padding: 0 8px;
height: 24px;
line-height: 24px;
text-align: center;
.text {
color: #128009;
}
}
.error {
background-color: #FF0000;
background-color: #ff0000;
color: #fff;
padding: 0 8px;
height: 24px;

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

@ -51,6 +51,7 @@
<el-form-item label="请选择上级领导" prop="leaderEmpNo">
<LeaderSelect
v-model="form.leaderEmpNo"
leader-type="all"
/>
</el-form-item>
</template>

16
src/views/work/components/ConfirmedCompletion.vue

@ -4,27 +4,27 @@
<div class="flex mb-20">
<div class="col">
<label>群众反应事项解决情况</label>
<span></span>
<span>{{ mail.verifyIsResolved ? '已解决' : '未解决'}}</span>
</div>
<div class="col">
<label>办理反馈情况</label>
<span></span>
<span>{{ mail.verifyFeedback }}</span>
</div>
</div>
<div class="flex mb-20">
<div class="col">
<label>回访人姓名</label>
<span></span>
<span>{{ mail.verifyFollowupPolice?.name }}</span>
</div>
<div class="col">
<label>回访人警号</label>
<span></span>
<span>{{ mail.verifyFollowupPolice?.empNo }}</span>
</div>
</div>
<div class="flex mb-40">
<div class="col">
<label>回访人电话</label>
<span></span>
<span>{{ mail.verifyFollowupPolice?.phone }}</span>
</div>
</div>
<el-form
@ -77,7 +77,7 @@
</el-form>
<footer class="flex end">
<el-button type="primary" size="large" @click="submit"
>审批通过</el-button
>认定办结</el-button
>
</footer>
</el-dialog>
@ -125,6 +125,10 @@ const props = defineProps({
type: Object,
default: {},
},
mail : {
type: Object,
default: {}
},
flowKey: {
type: String,
default: "",

3
src/views/work/components/InitiateCountersign.vue

@ -145,10 +145,9 @@ function submit() {
formRef.value.validate((valid) => {
if (valid) {
//
const data = { ...props.data, ...form };
emits("update:data", data);
emits("submit", "confirmedCompletion");
emits("submit", "countersign");
visible.value = false;
}
});

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

@ -63,19 +63,28 @@
style="height: 100%; padding: 0 20px 0 40px"
ref="leftContainerRef"
>
<div class="timer flex center">
<el-progress
type="dashboard"
:percentage="percentage"
:stroke-width="16"
:width="240"
:width="210"
color="#2B45E5"
>
<div
class="mb-20"
v-html="percentageLableHtml"
></div>
<p v-if="flowRemainingTime > 0">剩余处理时间</p>
class="timer"
v-if="mail.flowRemainingTime > 0"
><RemainingTime
v-model:time="mail.flowRemainingTime"
/>
</el-progress>
<div
v-else
class="error flex column center v-center"
>
<RemainingTime
v-model:time="mail.flowRemainingTime"
/>
</div>
</div>
<div ref="mailInfoRef">
<div class="col mb-10" v-if="mail.mailCategory">
<label style="width: 56px">信件分类</label>
@ -97,7 +106,12 @@
style="padding-bottom: 20px"
>
<label>信件等级</label>
<span>{{ getDictLable(dictData.mail_level, mail.mailLevel) }}</span>
<span>{{
getDictLable(
dictData.mail_level,
mail.mailLevel
)
}}</span>
</div>
</div>
<div class="flow">
@ -192,25 +206,25 @@
</template>
<template
v-if="
webComponents.indexOf('ContactWriterFrom') > -1
webComponents.indexOf('ContactWriterForm') > -1
"
>
<ContactWriterFrom
<ContactWriterForm
v-model:data="requestData"
:time="mail.flowLimitedLastHandlerTime"
:limitedTime="flowNode.limitedTime"
ref="contactWriterFromRef"
ref="ContactWriterFormRef"
/>
</template>
<template
v-if="
webComponents.indexOf('InterviewWriterFrom') >
webComponents.indexOf('InterviewWriterForm') >
-1
"
>
<InterviewWriterFrom
<InterviewWriterForm
v-model:data="requestData"
ref="interviewWriterFromRef"
ref="InterviewWriterFormRef"
/>
</template>
<template
@ -231,6 +245,11 @@
<template v-if="webComponents.indexOf('Comments') > -1">
<Comments :approvals="approvals" />
</template>
<template
v-if="webComponents.indexOf('CountersignForm') > -1"
>
<CountersignForm />
</template>
</el-scrollbar>
</el-col>
</el-row>
@ -248,7 +267,9 @@
>{{ action.btnLabel }}</el-button
>
</div>
<el-button type="primary" size="large" v-if="completionBtnFlag">认定办结</el-button>
<el-button type="primary" size="large" v-if="completionBtnFlag"
>认定办结</el-button
>
</footer>
</el-dialog>
@ -269,6 +290,7 @@
<ConfirmedCompletion
v-model:show="completionShow"
v-model:data="requestData"
:mail="mail"
@submit="(key) => handleAction(key)"
/>
<InitiateCountersign
@ -283,17 +305,20 @@ import MainContactInfo from "./templates/MainContactInfo.vue";
import MailTypeForm from "./templates/MailTypeForm.vue";
import DeptSelectForm from "./templates/DeptSelectForm.vue";
import CoHandlingAndThreeFlow from "./templates/CoHandlingAndThreeFlow.vue";
import ContactWriterFrom from "./templates/ContactWriterFrom.vue";
import InterviewWriterFrom from "./templates/InterviewWriterFrom.vue";
import ContactWriterForm from "./templates/ContactWriterForm.vue";
import InterviewWriterForm from "./templates/InterviewWriterForm.vue";
import VerifyForm from "./templates/VerifyForm.vue";
import MailApprovalDetail from "./templates/MailApprovalDetail.vue";
import Comments from "./templates/Comments.vue";
import CountersignForm from "./templates/CountersignForm.vue";
import ApplicationCompleted from "./ApplicationCompleted.vue";
import ReviewComments from "./ReviewComments.vue";
import ConfirmedCompletion from "./ConfirmedCompletion.vue";
import InitiateCountersign from "./InitiateCountersign.vue";
import RemainingTime from "./RemainingTime.vue";
import { getMailFlowDetail, flowNext } from "@/api/mail";
import { addFav, delFav } from "@/api/work/fav";
import { useDictData } from "@/hooks/useDictOptions";
@ -304,11 +329,11 @@ const { dictData } = useDictData(["mail_level"]);
const mailTypeFormRef = ref();
const deptSelectFormRef = ref();
const contactWriterFromRef = ref();
const interviewWriterFromRef = ref();
const ContactWriterFormRef = ref();
const InterviewWriterFormRef = ref();
const verifyFormRef = ref();
const loading = ref(true)
const loading = ref(true);
const mail = ref({});
const flows = ref([]);
const flowNode = ref({});
@ -316,8 +341,6 @@ const webComponents = ref([]);
const actions = ref([]);
const percentage = ref(100);
const percentageLableHtml = ref("");
//
const flowRemainingTime = ref(0);
const approvals = ref([]);
const isFav = ref(false);
@ -382,12 +405,11 @@ watch(
}
);
let timer;
function getDetail() {
loading.value = true
loading.value = true;
//
getMailFlowDetail(props.mailId).then((data) => {
loading.value = false
loading.value = false;
mail.value = data.mail;
flows.value = data.flows;
isFav.value = data.isFav;
@ -399,17 +421,6 @@ function getDetail() {
.map((item) => item.trim());
}
actions.value = data.actions;
percentage.value = data.mail.flowRemainingTimePercentage;
flowRemainingTime.value = data.mail.flowRemainingTime;
if (flowRemainingTime.value > 0 && flowRemainingTime.value < 3600) {
clearInterval(timer);
timer = setInterval(() => {
flowRemainingTime.value -= 1;
if (flowRemainingTime.value <= 0) {
clearInterval(timer);
}
}, 1000);
}
nextTick(() => {
flowMaxHeight.value =
@ -428,60 +439,27 @@ watch(
}
);
watch(flowRemainingTime, (val) => {
if (val <= 0) {
percentageLableHtml.value = `<span class="error">已超时</span>`;
return;
}
if (val < 60) {
percentageLableHtml.value = `<span class="large">${val}</span><span>秒</span>`;
return;
}
if (val < 3600) {
percentageLableHtml.value = `<span class="large">${parseInt(
val / 60
)}</span><span></span><span class="large">${
val % 60
}</span><span></span>`;
return;
}
if (val < 86400) {
percentageLableHtml.value = `<span class="large">${parseInt(
val / 3600
)}</span><span>小时</span><span class="large">${parseInt(
(val % 3600) / 60
)}</span><span></span>`;
return;
}
const remainder = val % 86400;
if (remainder === 0) {
percentageLableHtml.value = `<span class="large">${parseInt(
val / 86400
)}</span><span></span>`;
return;
}
percentageLableHtml.value = `<span class="large">${parseInt(
val / 86400
)}</span><span></span><span class="large">${parseInt(
remainder / 3600
)}</span><span>小时</span>`;
});
const requestData = ref({});
const messageRef = ref();
const approvedShow = ref(false);
const completionShow = ref(false);
const countersignShow = ref(false);
//
const completionBtnFlag = ref(false)
const completionBtnFlag = ref(false);
//
watch(() => requestData.value.mailFirstCategory, () => {
if (requestData.value.mailFirstCategory === "无效类" || requestData.value.mailFirstCategory === "终止类") {
completionBtnFlag.value = true
watch(
() => requestData.value.mailFirstCategory,
() => {
if (
requestData.value.mailFirstCategory === "无效类" ||
requestData.value.mailFirstCategory === "终止类"
) {
completionBtnFlag.value = true;
} else {
completionBtnFlag.value = false
completionBtnFlag.value = false;
}
})
}
);
async function handleAction(key) {
if (!key) {
@ -508,11 +486,11 @@ async function handleAction(key) {
if (deptSelectFormRef.value) {
await deptSelectFormRef.value.validate();
}
if (contactWriterFromRef.value) {
await contactWriterFromRef.value.validate();
if (ContactWriterFormRef.value) {
await ContactWriterFormRef.value.validate();
}
if (interviewWriterFromRef.value) {
await interviewWriterFromRef.value.validate();
if (InterviewWriterFormRef.value) {
await InterviewWriterFormRef.value.validate();
}
if (verifyFormRef.value) {
await verifyFormRef.value.validate();
@ -528,7 +506,7 @@ async function handleAction(key) {
flowKey: flowNode.value.key,
data: requestData.value,
};
loading.value = true
loading.value = true;
flowNext(requestBody).then(() => {
//
emits("update");
@ -569,7 +547,6 @@ const flowMaxHeight = ref(200);
const leftContainerRef = ref();
const mailInfoRef = ref();
const flowHeaderRef = ref();
</script>
<style lang="scss" scoped>
.dialog-header {
@ -622,11 +599,24 @@ const flowHeaderRef = ref();
}
}
.el-progress {
.timer {
--large-font-color: var(--primary-color);
--default-font-color: #999;
color: var(--default-font-color);
.error {
--large-font-color: #fff;
--default-font-color: #fff;
background: linear-gradient(180deg, #ff7158 0%, #f40000 100%);
border: 4px solid #ffcdcd;
border-radius: 11px;
box-sizing: border-box;
margin-bottom: 20px;
height: 190px;
width: 100%;
}
div {
font-size: 18px;
vertical-align: bottom;
color: #999;
:deep() {
.error {
font-size: 50px;
@ -634,7 +624,7 @@ const flowHeaderRef = ref();
}
.large {
font-size: 56px;
color: var(--primary-color);
color: var(--large-font-color);
}
}
}
@ -685,7 +675,7 @@ const flowHeaderRef = ref();
transform: translateY(-50%);
}
}
&>div:first-child .flow-info::before {
& > div:first-child .flow-info::before {
width: 12px;
height: 12px;
background-color: var(--primary-color);

129
src/views/work/components/RemainingTime.vue

@ -0,0 +1,129 @@
<template>
<div class="remaining-container text-center" :countdown="countdownFlag">
<div class="time-val" >
<template v-if="state.day !== 0">
<span class="number">{{ state.day }}</span>
<span></span>
</template>
<template v-if="state.hour !== 0">
<span class="number">{{ state.hour }}</span>
<span>小时</span>
</template>
<template v-if="state.minute !== 0">
<span class="number">{{ state.minute }}</span>
<span>分钟</span>
</template>
<template v-if="state.second !== 0">
<span class="number">{{ state.second }}</span>
<span></span>
</template>
</div>
<div>
<span>{{ countdownFlag ? "剩余处理时间" : "已超时" }}</span>
</div>
</div>
</template>
<script setup>
const props = defineProps({
time: {
type: Number,
default: 0,
},
});
const emit = defineEmits(["update:time"]);
const countdownFlag = ref(true);
let timeVal = props.time;
debugger
const state = reactive({
day: 0,
hour: 0,
minute: 0,
second: 0,
});
updateState();
setRemainingTimeout();
function updateState() {
if (timeVal === 0) {
state.day = 0;
state.hour = 0;
state.minute = 0;
state.second = 0;
}
if (timeVal > 0) {
countdownFlag.value = true;
getState(timeVal);
}
// timeVal 0
if (timeVal < 0) {
countdownFlag.value = false;
getState(-timeVal);
}
function getState(val) {
state.day = Math.floor(val / (60 * 60 * 24));
state.hour = Math.floor(val / (60 * 60)) % 24;
if (state.day === 0) {
state.minute = Math.floor(val / 60) % 60;
} else {
state.minute = 0;
}
if (state.day === 0 && state.hour === 0) {
state.second = Math.floor(val) % 60;
} else {
state.second = 0;
}
}
}
watch(
() => props.time,
(newVal) => {
timeVal = props.time;
updateState();
setRemainingTimeout();
}
);
function setRemainingTimeout() {
//
if (props.time && props.time < 3600 && props.time > -3600) {
setTimeout(() => {
if (countdownFlag.value) {
timeVal--;
} else {
timeVal++;
}
emit("update:time", timeVal);
}, 1000);
}
}
</script>
<style lang="scss" scoped>
.remaining-container {
color: #fff;
span {
font-size: 18px;
line-height: 1;
}
.time-val {
vertical-align: bottom;
margin-bottom: 20px;
.number {
font-size: 56px;
}
}
&[countdown="true"] {
color: #333;
.time-val {
color: #666;
.number {
color: var(--primary-color);
}
}
}
}
</style>

13
src/views/work/components/ReviewComments.vue

@ -1,5 +1,5 @@
<template>
<el-dialog v-model="visible" width="50vw" title="提交审批">
<el-dialog v-model="visible" width="50vw" title="提交审批" v-if="visible">
<el-form
label-position="top"
:model="form"
@ -8,7 +8,7 @@
style="height: 50vh"
>
<el-form-item label="请选择上级领导" prop="leaderEmpNo" v-if="selectLeaderVisible">
<LeaderSelect v-model="form.leaderEmpNo" />
<LeaderSelect v-model="form.leaderEmpNo" :leader-type="leaderType" />
</el-form-item>
<el-form-item label="审批意见" prop="approvalComment">
<el-input
@ -60,9 +60,18 @@ const props = defineProps({
},
});
const selectLeaderVisible = ref(false)
const leaderType = ref('all')
watch(() => props.flowKey, (val) => {
if (val === 'second_approval' || val === 'second_deputy_approval') {
selectLeaderVisible.value = true
leaderType.value = val === 'second_deputy_approval' ? 'leader' : 'deputy'
}
if (val === 'second_approval') {
leaderType.value = 'deputy'
}
if (val === 'second_deputy_approval') {
leaderType.value = 'leader'
}
})

0
src/views/work/components/templates/ContactWriterFrom.vue → src/views/work/components/templates/ContactWriterForm.vue

9
src/views/work/components/templates/CountersignForm.vue

@ -0,0 +1,9 @@
<template>
<h2>部门会签</h2>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>

2
src/views/work/components/templates/InterviewWriterFrom.vue → src/views/work/components/templates/InterviewWriterForm.vue

@ -23,7 +23,7 @@
</el-col>
<el-col :span="12" prop="interviewPoliceEmpNo">
<el-form-item label="接访领导" prop="interviewPoliceEmpNo">
<LeaderSelect v-model="form.interviewPoliceEmpNo" @change="handleSelect" />
<LeaderSelect v-model="form.interviewPoliceEmpNo" @change="handleSelect" leader-type="all" />
</el-form-item>
</el-col>
</el-row>

88
src/views/work/components/templates/MailApprovalDetail.vue

@ -8,7 +8,7 @@
</div>
<div class="col">
<label>性别</label>
<span>{{ mail.contactSex === 'M' ? '男' : '女' }}</span>
<span>{{ mail.contactSex === "M" ? "男" : "女" }}</span>
</div>
<div class="col">
<label>证件号码</label>
@ -20,10 +20,18 @@
</div>
</div>
</el-collapse-item>
<el-collapse-item title="举报/投诉对象基本情况" name="2" v-if="mail.verifyReportedPolices.length">
<div class="flex" v-for="item in mail.verifyReportedPolices" :key="item.empNo">
<div class="col">
<label>被举报对象1</label>
<el-collapse-item
title="举报/投诉对象基本情况"
name="2"
v-if="mail.verifyReportedPolices.length"
>
<div
class="flex"
v-for="item in mail.verifyReportedPolices"
:key="item.empNo"
>
<div class="col">
<label>被举报人1</label>
<span>{{ item.name }}</span>
</div>
<div class="col">
@ -47,21 +55,26 @@
<div class="flex mb-10">
<div class="col">
<label>主单位签收时长</label>
<span>{{ }}</span>
<span>{{}}</span>
</div>
<div class="col">
<label>主单位联系群众时长</label>
<span>{{ }}</span>
<span>{{}}</span>
</div>
</div>
<div class="flex mb-10">
<div class="col">
<label>接访形式</label>
<span>{{ getDictLable(dictData.interview_type, mail.interviewType) }}</span>
<span>{{
getDictLable(
dictData.interview_type,
mail.interviewType
)
}}</span>
</div>
<div class="col">
<label>是否一把手接访</label>
<span>{{ mail.interviewIsLeader ? '是' : '否' }}</span>
<span>{{ mail.interviewIsLeader ? "是" : "否" }}</span>
</div>
<div class="col">
<label>接访领导</label>
@ -79,17 +92,25 @@
<div class="flex mb-10">
<div class="col">
<label>是否属实</label>
<span>{{ getDictLable(dictData.verifyIsTrue, mail.interviewType) }}</span>
<span>{{
getDictLable(dictData.verifyIsTrue, mail.interviewType)
}}</span>
</div>
<div class="col">
<label>是否需要问责</label>
<span>{{ mail.verifyNeedAccountability ? '是':'否' }}</span>
<span>{{
mail.verifyNeedAccountability ? "是" : "否"
}}</span>
</div>
</div>
<div class="flex mb-10">
<div class="col">
<div class="col" style="width: 100%">
<label>查证属实问题</label>
<span v-for="(item, index) in mail.verifyProblem" :key="index">{{ item }}</span>
<span
v-for="(item, index) in mail.verifyProblem"
:key="index" class="mr-8"
>{{ item }}</span
>
</div>
</div>
<div class="flex mb-10">
@ -103,7 +124,11 @@
<div class="flex">
<div class="col">
<label>责任追究</label>
<span v-for="(item, index) in mail.verifyPunish" :key="index">{{ getDictLable(dictData.verify_punish, item) }}</span>
<span
v-for="(item, index) in mail.verifyPunish"
:key="index"
>{{ getDictLable(dictData.verify_punish, item) }}</span
>
</div>
</div>
</el-collapse-item>
@ -111,11 +136,16 @@
<div class="flex mb-10">
<div class="col">
<label>群众反应事项解决情况</label>
<span>{{ mail.verifyIsResolved ? '已解决' : '' }}</span>
<span>{{ mail.verifyIsResolved ? "已解决" : "" }}</span>
</div>
<div class="col">
<label>办理反馈情况</label>
<span>{{ getDictLable(dictData.satisfaction_status, mail.verifyFeedback) }}</span>
<span>{{
getDictLable(
dictData.satisfaction_status,
mail.verifyFeedback
)
}}</span>
</div>
</div>
<div class="flex">
@ -134,14 +164,28 @@
</div>
</el-collapse-item>
<el-collapse-item title="办结佐证材料" name="8">
<div></div>
<div class="flex gap file-box">
<div v-for="(item, index) in mail.verifyAttachments" :key="index" class="item pointer">
<template v-if="item.type && item.type.indexOf('image') > -1">
<img
:src="`${VITE_API_URL}/api/file/stream/${item.filepath}`"
/>
</template>
</div>
</div>
</el-collapse-item>
</el-collapse>
</template>
<script setup>
import { getDictLable } from "@/utils/util";
import { useDictData } from "@/hooks/useDictOptions";
const { dictData } = useDictData(["interview_type", "satisfaction_status", "verify_is_true", "verify_punish"]);
const { dictData } = useDictData([
"interview_type",
"satisfaction_status",
"verify_is_true",
"verify_punish",
]);
const { VITE_API_URL } = process.env;
defineProps({
mail: {
@ -150,7 +194,7 @@ defineProps({
},
});
const activeNames = ref(['1', "2", "3", "4", "5", "6", "7", "8"])
const activeNames = ref(["1", "2", "3", "4", "5", "6", "7", "8"]);
</script>
<style lang="scss" scoped>
.el-collapse-item {
@ -168,4 +212,10 @@ const activeNames = ref(['1', "2", "3", "4", "5", "6", "7", "8"])
padding: 12px;
color: #333;
}
.file-box {
img {
width: 80px;
height: 80px;
}
}
</style>

5
src/views/work/components/templates/VerifyForm.vue

@ -22,7 +22,7 @@
</el-form-item>
</el-row>
<el-row>
<el-form-item label="被举报对象">
<el-form-item label="被举报">
<div>
<div
class="flex between gap mb-10"
@ -75,7 +75,7 @@
</el-row>
<div class="text-center">
<el-button type="primary" plain @click="reportedPolices.push({})"
>添加被举报对象</el-button
>添加被举报</el-button
>
</div>
<el-divider />
@ -262,6 +262,7 @@ 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)

Loading…
Cancel
Save