Browse Source

BUG修复

master
wxc 2 years ago
parent
commit
14ef2b727f
  1. 53
      index.html
  2. 6
      src/components/PoliceSelect.vue
  3. 8
      src/components/popup/details.vue
  4. 6
      src/components/popup/index.vue
  5. 1
      src/main.ts
  6. 4
      src/style/public.scss
  7. 39
      src/utils/util.ts
  8. 7
      src/views/Login.vue
  9. 4
      src/views/datascreen/assets/css/index.css
  10. 57
      src/views/datascreen/countyData.vue
  11. 1307
      src/views/datascreen/details.vue
  12. 292
      src/views/work/Done.vue
  13. 11
      src/views/work/Fav.vue
  14. 94
      src/views/work/Query.vue
  15. 300
      src/views/work/Todo.vue
  16. 172
      src/views/work/components/ConfirmedCompletion.vue
  17. 6
      src/views/work/components/MailCheck.vue
  18. 45
      src/views/work/components/MailDialog.vue
  19. 11
      src/views/work/components/MailTodoByChange.vue
  20. 22
      src/views/work/components/templates/CompletionDetail.vue
  21. 55
      src/views/work/components/templates/ThreeHandling.vue
  22. 4
      src/views/work/components/templates/ThreeHandlingDetail.vue
  23. 1
      vite.config.ts

53
index.html

@ -15,6 +15,59 @@
</div>
</div>
<script type="module" src="/src/main.ts"></script>
<script>
function getBrowse() {
var browser = {};
var userAgent = navigator.userAgent.toLowerCase();
var s;
(s = userAgent.match(/msie ([\d.]+)/)) ? browser.ie = s[1] : (s = userAgent.match(/firefox\/([\d.]+)/)) ? browser.firefox = s[1] : (s = userAgent.match(/chrome\/([\d.]+)/)) ? browser.chrome = s[1] : (s = userAgent.match(/opera.([\d.]+)/)) ? browser.opera = s[1] : (s = userAgent.match(/version\/([\d.]+).*safari/)) ? browser.safari = s[1] : 0;
var version = "";
if (browser.ie) {
version = 'IE ' + browser.ie;
}
else {
if (browser.firefox) {
version = 'firefox ' + browser.firefox;
}
else {
if (browser.chrome) {
version = 'chrome ' + browser.chrome;
}
else {
if (browser.opera) {
version = 'opera ' + browser.opera;
}
else {
if (browser.safari) {
version = 'safari ' + browser.safari;
}
else {
version = '未知浏览器';
}
}
}
}
}
return version;
}
function isWin64() {
var agent = navigator.userAgent.toLowerCase();// 获取window的CPU
return agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0;
}
var browseVersion = getBrowse();
console.log('浏览器版本', browseVersion)
var arr = browseVersion.split(' ')
var browse = arr[0];
var version = parseInt(arr[1].substr(0, arr[1].indexOf('.')));
if (browse === 'IE' || (browse === 'chrome' && version < 80)) {
var result = confirm(`系统检测到您的浏览器版本[${browseVersion}]太低可能会影响使用,是否需要下载新版本浏览器?`);
if (result) {
window.open(`${location.origin}/download/${isWin64() ? '109.0.5414.120_chrome_installer_64.exe' : '109.0.5414.120_chrome_installer_32.exe'}`)
}
}
</script>
</body>
<style>
.loader {

6
src/components/PoliceSelect.vue

@ -24,12 +24,8 @@ const props = defineProps({
default: null
}
})
console.log('props', props.data)
const value = ref(props.data ? props.data.empNo : '')
watch(() => props.data, () => {
console.log('watch', props.data)
})
const value = ref(props.data ? props.data.empNo : '')
const emit = defineEmits(['update:data', 'select'])

8
src/components/popup/details.vue

@ -56,11 +56,6 @@ export default defineComponent({
type: [String, Boolean],
default: '取消'
},
width: {
//
type: String,
default: '400px'
},
disabled: {
//
type: Boolean,
@ -123,7 +118,8 @@ export default defineComponent({
<style lang="scss">
.el-dialog{
margin-top: 60px
margin-top: 40px;
width: max-content;
}
.dialog-body {
white-space: pre-line;

6
src/components/popup/index.vue

@ -9,7 +9,6 @@
:custom-class="customClass"
:center="center"
:append-to-body="true"
:width="width"
:close-on-click-modal="clickModalClose"
@closed="close"
>
@ -60,11 +59,6 @@ export default defineComponent({
type: [String, Boolean],
default: '取消'
},
width: {
//
type: String,
default: '400px'
},
disabled: {
//
type: Boolean,

1
src/main.ts

@ -17,4 +17,3 @@ createApp(App)
.use(store)
.use(install)
.mount('#app')

4
src/style/public.scss

@ -229,6 +229,10 @@ svg+span {
margin-bottom: 40px;
}
.h100 {
height: 100%;
}
.step {
--setp-background-color: #fff;
--setp-font-color: #666;

39
src/utils/util.ts

@ -176,11 +176,11 @@ export const formatTimeText = (seconds: number) => {
// 小时
if (seconds < 86400) {
const remainder = seconds % 3600;
return `${Math.floor(seconds / 3600)}${parseInt(seconds % 3600 / 60)}`
return `${Math.floor(seconds / 3600)}${parseInt(seconds % 3600 / 60)}`
}
// 天
const remainder = seconds % 86400;
return `${Math.floor(seconds / 86400)}${parseInt(seconds % 86400 / 3600)}`
return `${Math.floor(seconds / 86400)}${parseInt(seconds % 86400 / 3600)}`
}
/**
@ -370,39 +370,4 @@ export function getAppealDept(handlingDept) {
});
});
}
}
export function browse() {
var browser = {};
var userAgent = navigator.userAgent.toLowerCase();
var s;
(s = userAgent.match(/msie ([\d.]+)/)) ? browser.ie = s[1] : (s = userAgent.match(/firefox\/([\d.]+)/)) ? browser.firefox = s[1] : (s = userAgent.match(/chrome\/([\d.]+)/)) ? browser.chrome = s[1] : (s = userAgent.match(/opera.([\d.]+)/)) ? browser.opera = s[1] : (s = userAgent.match(/version\/([\d.]+).*safari/)) ? browser.safari = s[1] : 0;
var version = "";
if (browser.ie) {
version = 'IE ' + browser.ie;
}
else {
if (browser.firefox) {
version = 'firefox ' + browser.firefox;
}
else {
if (browser.chrome) {
version = 'chrome ' + browser.chrome;
}
else {
if (browser.opera) {
version = 'opera ' + browser.opera;
}
else {
if (browser.safari) {
version = 'safari ' + browser.safari;
}
else {
version = '未知浏览器';
}
}
}
}
}
return version;
}

7
src/views/Login.vue

@ -76,9 +76,6 @@
数字证书登录
</el-button>
</el-form>
<div class="flex end mt-16">
<a target="_blank" href="/download/109.0.5414.120_chrome_installer_64.exe" style="color: var(--primary-color); text-decoration: none;">浏览器下载</a>
</div>
</div>
</div>
</div>
@ -88,7 +85,6 @@ import cache from "@/utils/cache";
import { ACCOUNT_KEY } from "@/enums/cacheEnums";
import { PageEnum } from "@/enums/pageEnum";
import useUserStore from "@/stores/modules/user";
import { browse } from "@/utils/util";
const router = useRouter();
const route = useRoute();
@ -159,9 +155,6 @@ function getUsername() {
return localStorage.getItem('username');
}
const browseVersion = browse();
console.log('浏览器版本:', browseVersion)
</script>
<style lang="scss" scoped>
.wrapper {

4
src/views/datascreen/assets/css/index.css

@ -232,7 +232,7 @@ a:active {
.col-6{width: 50%;}
.col-3{width: 25%;}
.col-4{width: 33.33333%;}
.h100{height: 100%;}
.pmbar{position: relative; display: flex;}
.pmbar span{ background: linear-gradient(to right,#14b6ff,#9cefff); display: inline-block;
@ -401,7 +401,7 @@ a:active {
.col-6{width: 50%;}
.col-3{width: 25%;}
.col-4{width: 33.33333%;}
.h100{height: 100%;}
.ratebar{position: relative; display: flex;width: 100% }
.ratebar span{ background: linear-gradient(to right,#14b6ff,#9cefff); display: inline-block; height: 10px; }

57
src/views/datascreen/countyData.vue

@ -293,7 +293,7 @@
title="办结率计算方式"
:width="200"
trigger="hover"
show-after="700"
:show-after="700"
:content="`办结率 = 已办结数 / 信件总数 \n ${consoleMap.completedrate} = ${consoleMap.completed} / ${consoleMap.completedsum}`"
popper-class="custom-popover-style"
>
@ -314,7 +314,7 @@
title="满意率计算方式"
:width="200"
trigger="hover"
show-after="700"
:show-after="700"
:content="`满意率 = 满意数 / 已办结数 \n ${consoleMap.satisfiedrate} = ${consoleMap.satisfied} / ${consoleMap.satisfiedSum}`"
popper-class="custom-popover-style"
>
@ -335,7 +335,7 @@
title="解决率计算方式"
:width="220"
trigger="hover"
show-after="700"
:show-after="700"
:content="`解决率 = 解决数 / 已办结数 \n ${consoleMap.resolvedrate} = ${consoleMap.resolved} / ${consoleMap.resolvedsum}`"
popper-class="custom-popover-style"
>
@ -546,7 +546,7 @@ let dutyList = ref([]);
let typeRankList = ref([]);
let rateMap = ref([]);
let mailTrendMap = ref([]);
let consoleMap = ref([]);
let consoleMap = ref({});
let mailTypeRankList = reactive([]) as any[];
let completeList = reactive([]) as any[];
let dutySjList = reactive([]) as any[];
@ -623,7 +623,7 @@ const selectYear = (year) => {
//console
const getConsoleDataMap = async () => {
consoleMap = await consoleData(currentParams);
consoleMap.value = await consoleData(currentParams);
};
const getCurrentMapJSON = async () => {
@ -731,6 +731,7 @@ const formatDate = (value) => {
return date.toLocaleString();
};
const startRateAutoSwitch = () => {
clearInterval(intervalIdRate);
intervalIdRate = setInterval(() => {
if (rateActiveName.value === "completionRate") {
rateActiveName.value = "resolutionRate";
@ -933,9 +934,7 @@ const changsMap = () => {
color: "white",
},
itemStyle: {
normal: {
areaColor: "#02215E", //
},
areaColor: "#02215E", //
},
data: mapDataList,
},
@ -1118,10 +1117,8 @@ const dayEcharts = () => {
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
color: "#0184d5",
width: 2,
},
color: "#0184d5",
width: 2,
},
areaStyle: {
normal: {
@ -1146,11 +1143,9 @@ const dayEcharts = () => {
},
},
itemStyle: {
normal: {
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
data: dayYList,
},
@ -1251,10 +1246,8 @@ const monthEcharts = () => {
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
color: "#0184d5",
width: 2,
},
color: "#0184d5",
width: 2,
},
areaStyle: {
normal: {
@ -1279,11 +1272,9 @@ const monthEcharts = () => {
},
},
itemStyle: {
normal: {
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
data: monthYList,
},
@ -1384,10 +1375,8 @@ const weekEcharts = () => {
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
color: "#0184d5",
width: 2,
},
color: "#0184d5",
width: 2,
},
areaStyle: {
normal: {
@ -1412,11 +1401,9 @@ const weekEcharts = () => {
},
},
itemStyle: {
normal: {
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
color: "#0184d5",
borderColor: "rgba(221, 220, 107, .1)",
borderWidth: 12,
},
data: weekYList,
},

1307
src/views/datascreen/details.vue

File diff suppressed because it is too large Load Diff

292
src/views/work/Done.vue

@ -5,36 +5,65 @@
<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-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
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" style="width: 180px">
<el-select
v-model="query.contactField"
style="width: 180px"
>
<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 />
<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
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>
@ -42,28 +71,53 @@
<el-row>
<el-col :span="6">
<el-form-item label="信件分类">
<el-tree-select v-model="query.mailCategory" :data="mailStore.mailCategorys" check-strictly
filterable />
<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
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="办理单位">
<DeptTreeSelect v-model="query.deptId" check-strictly />
<DeptTreeSelect
v-model="query.deptId"
check-strictly
/>
</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
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>
@ -77,76 +131,126 @@
<main>
<div class="table-container">
<el-table :data="dones" style="width: 100%" stripe>
<el-table-column prop="mailTime" label="来信时间" align="center" width="160" />
<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>
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="联系电话" width="120" align="center" />
<el-table-column prop="mailCategory" label="信件分类" align="center" width="120"/>
<el-table-column
prop="contactName"
label="姓名"
align="center"
width="80"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
width="120"
align="center"
/>
<el-table-column
prop="mailCategory"
label="信件分类"
align="center"
width="120"
/>
<el-table-column label="信件状态" width="90" align="center">
<template #default="{ row }">
<span>{{
getDictLable(dictData.mail_state, row.mailState)
}}</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 prop="currentOperator" label="当前处理对象" width="120" align="center"></el-table-column>
<el-table-column label="流程节点" class-name="text-no-ellipsis" align="center">
<el-table-column
prop="threeDeptName"
label="办理单位"
width="120"
align="center"
/>
<el-table-column
prop="currentOperator"
label="当前处理对象"
width="120"
align="center"
></el-table-column>
<el-table-column
label="流程节点"
class-name="text-no-ellipsis"
align="center"
>
<template #default="{ row }">
<el-tag :type="getFlowTagType(row.mailFlowName)">{{ row.mailFlowName }}</el-tag>
<el-tag :type="getFlowTagType(row.mailFlowName)">{{
row.mailFlowName
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="流程限时" align="center">
<el-table-column align="center">
<template #header>
<FlowLimitedExplanation />
</template>
<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>
<FlowLimited :time="row.flowLimitedRemainingTime" />
</template>
</el-table-column>
<el-table-column label="信件等级" width="100" align="center">
<el-table-column
label="信件等级"
width="100"
align="center"
>
<template #default="{ row }">
<mail-level :value="row.mailLevel" :list="dictData.mail_level" />
<mail-level
:value="row.mailLevel"
:list="dictData.mail_level"
/>
</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>
<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"
layout="total,sizes, prev, pager, next, jumper" :total="totalSize.total">
<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"
layout="total,sizes, prev, pager, next, jumper"
:total="totalSize.total"
>
</el-pagination>
</div>
</main>
</div>
<MailDialog v-model:show="showModel" :mail-id="activeMailId" :work-id="activeWorkId" :disabled="true"
@update="getList" />
<MailDialog
v-model:show="showModel"
:mail-id="activeMailId"
:work-id="activeWorkId"
:disabled="true"
@update="getList"
/>
</template>
<script lang="ts" setup>
import MailDialog from "./components/MailDialog.vue";
@ -154,58 +258,42 @@ import MailDialog from "./components/MailDialog.vue";
import { getDones } from "@/api/work";
import { getMailFlowDetail } from "@/api/mail";
import { useDictData } from "@/hooks/useDictOptions";
import { useDictOptions } from '@/hooks/useDictOptions'
import { onMounted, onUnmounted } from 'vue'
import { useDictOptions } from "@/hooks/useDictOptions";
import { onMounted, onUnmounted } from "vue";
import useMailStore from "@/stores/modules/mail";
import { getDictLable, formatTimeText, getFlowTagType } from "@/utils/util";
import { getDictLable, getFlowTagType } from "@/utils/util";
import { ref, reactive, watchEffect } from "vue";
import { getFlowNodes } from '@/api/org/flowNode'
import { getFlowNodes } from "@/api/org/flowNode";
const mailStore = useMailStore();
mailStore.getMailCategorys();
const { dictData } = useDictData(["mail_source", "mail_level", "mail_state"]);
const query = ref({
size: 10,
current: 1
current: 1,
});
const totalSize = reactive({
total: 0,
pages: 0
})
pages: 0,
});
const dones = ref([]);
const showModel = ref(false);
const activeMailId = ref("");
const activeWorkId = ref(0)
const activeWorkId = ref(0);
const { optionsData } = useDictOptions<{
flowNodes: any[]
flowNodes: any[];
}>({
flowNodes: {
api: getFlowNodes
}
})
api: getFlowNodes,
},
});
function handleMail(row) {
showModel.value = true;
activeMailId.value = row.mailId;
activeWorkId.value = row.id
activeWorkId.value = row.id;
}
let timeClock: any = null
const updateCountdown = (second: number) => {
dones.value.forEach((item: any) => {
if (item.flowLimitedRemainingTime > 0) {
item.flowLimitedRemainingTime -= 1;
}
});
};
onMounted(() => {
timeClock = setInterval(updateCountdown, 1000)
})
onUnmounted(() => {
clearInterval(timeClock);
});
function getList() {
getDones(query.value).then((data) => {
dones.value = data.records;
@ -215,42 +303,22 @@ function getList() {
}
function reset() {
query.value = {}
getList()
query.value = {};
getList();
}
getList()
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
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>

11
src/views/work/Fav.vue

@ -72,10 +72,8 @@
<el-table-column label="信件来源" align="center" width="90">
<template #default="{ row }">
<span>{{
dictData.mail_source.filter(
(item) => item.value === row.source
)[0].name
}}</span>
getDictLable(dictData.mail_source, row.source)
}}</span>
</template>
</el-table-column>
<el-table-column prop="contactName" label="姓名" align="center" width="80" />
@ -93,7 +91,10 @@
<el-table-column prop="threeDeptName" label="办理单位" width="120" align="center" />
<el-table-column label="信件等级" width="100" align="center">
<template #default="{ row }">
<mail-level :value="row.mailLevel" :list="dictData.mail_level" />
<mail-level
:value="row.mailLevel"
:list="dictData.mail_level"
/>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center">

94
src/views/work/Query.vue

@ -32,7 +32,7 @@
</el-col>
<el-col :span="6">
<el-form-item label="内容查询">
<el-input v-model="query.queryByContent" placeholder="请输入相关信件内容" clearable />
<el-input v-model="query.queryByContent" placeholder="请输入关键字" clearable />
</el-form-item>
</el-col>
</el-row>
@ -67,7 +67,7 @@
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-row v-if="!collapse">
<el-col :span="6">
<el-form-item label="信件标签">
<el-select v-model="query.mailLabels" placeholder="请选择标签" multiple clearable filterable>
@ -99,6 +99,17 @@
</el-form-item>
</el-col>
</el-row>
<el-row v-if="!collapse">
<el-col :span="6">
<el-form-item label="信件超时">
<el-select v-model="query.timeout" placeholder="请选择" clearable>
<el-option label="签收超时" value="1" />
<el-option label="联系群众超时" value="2" />
<el-option label="办结超时" value="3" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<div style="display: flex; justify-content: space-between; margin-bottom: 20px;">
<div>
<el-button type="primary" @click="checkMail">信件核对</el-button>
@ -112,6 +123,16 @@
<div>
<el-button type="primary" @click="getList">查询</el-button>
<el-button @click="reset">重置</el-button>
<el-button type="primary" text @click="collapse = !collapse">
<template v-if="collapse">
<span class="mr-4">展开</span>
<icon name="el-icon-ArrowDownBold" />
</template>
<template v-else>
<span class="mr-4">收起</span>
<icon name="el-icon-ArrowUpBold" />
</template>
</el-button>
</div>
</div>
</el-form>
@ -122,20 +143,19 @@
@selection-change="handleSelectionChange" :row-key="rowKey">
<el-table-column type="selection" width="30" :reserve-selection="true" />
<el-table-column prop="mailTime" label="来信时间" align="center" width="160" />
<el-table-column label="信件来源" align="center" width="100">
<el-table-column label="信件来源" align="center" width="100" show-overflow-tooltip>
<template #default="{ row }">
<span>{{
dictData.mail_source.filter(
(item) => item.value === row.source
)[0].name
}}</span>
<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="联系电话" width="120" align="center" />
<el-table-column prop="mailCategory" label="信件分类" width="120" align="center" />
<el-table-column prop="content" label="信件内容" show-overflow-tooltip align="center" />
<el-table-column prop="mailCategory" label="信件分类" show-overflow-tooltip width="120" align="center" />
<el-table-column prop="content" label="信件内容" show-overflow-tooltip align="center" min-width="90" />
<el-table-column label="信件状态" width="90" align="center">
<template #default="{ row }">
@ -152,18 +172,13 @@
<el-tag type="danger" v-else>未签收</el-tag>
</template>
</el-table-column>
<el-table-column label="流程限时" width="140" align="center">
<el-table-column width="140" align="center">
<template #header>
<FlowLimitedExplanation />
</template>
<template #default="{ row }">
<div v-if="row.flowName !== '已办结'">
<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>
<FlowLimited :time="row.flowLimitedRemainingTime" />
</div>
</template>
</el-table-column>
@ -176,9 +191,9 @@
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleMail(row.id)" size="small">详情</el-button>
<el-button type="primary" link @click="handleMailLabel(row.id)" size="small">标签</el-button>
<el-button type="primary" link @click="handleMailLabel(row.id)" size="small" v-show="!IsdeleteMail(row)">标签</el-button>
<el-button type="primary" link @click="handleTodoByChange(row.id)" v-show="handleMailCategory(row)" size="small">转为待办</el-button>
<el-button type="primary" link @click="handleDelete(row.id)" v-show="IsdeleteMail(row)" size="small">删除</el-button>
<el-button type="danger" link @click="handleDelete(row.id)" v-show="IsdeleteMail(row)" size="small">删除</el-button>
</template>
</el-table-column>
</el-table>
@ -257,21 +272,9 @@ watch(() => query.value.contactField, (val, prevVal) => {
}
});
let timeClock = null
const updateCountdown = (second: number) => {
form.value.forEach((item: any) => {
if (item.flowLimitedRemainingTime > 0) {
item.flowLimitedRemainingTime -= 1;
}
});
};
onMounted(() => {
timeClock = setInterval(updateCountdown, 1000)
getList()
})
onUnmounted(() => {
clearInterval(timeClock);
});
const route = useRoute()
const useRouterParams = useRouterParamsStore()
@ -378,7 +381,7 @@ const exportLedger = () => {
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'data.xlsx'); //
link.setAttribute('download', '局长信箱即接即办工作汇总台账.xlsx'); //
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
@ -537,28 +540,9 @@ const handleMailCategory = (row: any) => {
return allowChangeList.includes(row.mailCategory)
}
const collapse = ref(true)
</script>
<style lang="scss" scoped>
.table-container {
border: 1px solid rgba(198, 208, 251, 1);
}
.success .text {
color: #128009;
padding: 0 8px;
height: 24px;
line-height: 24px;
text-align: center;
}
.error {
background-color: #FF0000;
color: #fff;
padding: 0 8px;
height: 24px;
line-height: 24px;
border-radius: 20px;
text-align: center;
}
</style>

300
src/views/work/Todo.vue

@ -5,16 +5,30 @@
<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-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
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>
@ -26,15 +40,27 @@
<el-option label="身份证" value="idCard" />
<el-option label="联系电话" value="phone" />
</el-select>
<el-input v-model="query.contactFieldValue" placeholder="请输入关键字" clearable />
<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
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>
@ -42,38 +68,70 @@
<el-row>
<el-col :span="6">
<el-form-item label="信件分类">
<el-tree-select v-model="query.mailCategory" :data="mailStore.mailCategorys" check-strictly
filterable />
<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
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="办理单位">
<DeptTreeSelect v-model="query.deptId" check-strictly />
<DeptTreeSelect
v-model="query.deptId"
check-strictly
/>
</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
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>
<el-button
type="primary"
@click="createMail"
v-perms="['mail:add']"
>自建信件</el-button
>
</div>
<div>
<el-button type="primary" @click="getList">查询</el-button>
<el-button type="primary" @click="getList"
>查询</el-button
>
<el-button @click="reset">重置</el-button>
</div>
</div>
@ -82,73 +140,125 @@
<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
prop="mailTime"
label="来信时间"
align="center"
width="160"
/>
<el-table-column label="信件来源" align="center" width="90">
<template #default="{ row }">
<span>{{ getDictLable(dictData.mail_source, row.source) }}</span>
<span>{{
getDictLable(dictData.mail_source, row.source)
}}</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 prop="mailCategory" label="信件分类" align="center" width="120" />
<el-table-column prop="content" align="center" label="信件内容" show-overflow-tooltip width="150" />
<el-table-column
prop="contactName"
label="姓名"
align="center"
width="80"
/>
<el-table-column
prop="contactPhone"
label="联系电话"
align="center"
width="120"
/>
<el-table-column
prop="mailCategory"
label="信件分类"
align="center"
show-overflow-tooltip
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>
getDictLable(dictData.mail_state, row.mailState)
}}</span>
</template>
</el-table-column>
<el-table-column prop="threeDeptName" label="办理单位" width="120" align="center" />
<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>
<el-tag :type="getFlowTagType(row.flowName)">{{
row.flowName
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="流程限时" align="center">
<el-table-column align="center">
<template #header>
<FlowLimitedExplanation />
</template>
<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>
<FlowLimited :time="row.flowLimitedRemainingTime" />
</template>
</el-table-column>
<el-table-column label="信件等级" width="100" align="center">
<el-table-column
label="信件等级"
width="100"
align="center"
>
<template #default="{ row }">
<mail-level :value="row.mailLevel" :list="dictData.mail_level" />
<mail-level
:value="row.mailLevel"
:list="dictData.mail_level"
/>
</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>
<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
@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" />
<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";
@ -157,10 +267,10 @@ 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'
import { 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"]);
@ -168,12 +278,12 @@ const { dictData } = useDictData(["mail_source", "mail_level", "mail_state"]);
const query = ref({
size: 10,
current: 1,
contactField: 'name'
contactField: "name",
});
const totalSize = reactive({
total: 0,
pages: 0
})
pages: 0,
});
const addMailShow = ref(false);
@ -181,40 +291,25 @@ const todos = ref([]);
const showModel = ref(false);
const activeMailId = ref("");
const activeWorkId = ref(0);
const activeWorkType = ref("")
const activeWorkType = ref("");
const { optionsData } = useDictOptions<{
dept: any[],
flowNodes: any[]
dept: any[];
flowNodes: any[];
}>({
dept: {
api: deptLists
api: deptLists,
},
flowNodes: {
api: getFlowNodes
}
})
api: getFlowNodes,
},
});
function handleMail(row) {
showModel.value = true;
activeMailId.value = row.mailId;
activeWorkId.value = row.id;
activeWorkType.value = row.workType
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;
@ -223,52 +318,31 @@ function getList() {
});
}
function reset() {
query.value = {
size: 10,
current: 1,
contactField: 'name'
contactField: "name",
};
getList();
}
const createMail = () => {
addMailShow.value = true;
}
};
getList()
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
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>

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

@ -1,33 +1,47 @@
<template>
<el-dialog v-model="visible" width="55vw" top="2vh" title="认定办结">
<el-dialog width="55vw" top="2vh" title="认定办结">
<h2>办理反馈情况</h2>
<div class="flex mb-12">
<div class="col">
<div class="col" style="width: 33.33%">
<label>群众反应事项解决情况</label>
<span>{{ mail.verifyIsResolved ? "已解决" : "未解决" }}</span>
</div>
<div class="col">
<div class="col" style="width: 33.33%">
<label>办理反馈情况</label>
<span>{{ mail.verifyFeedback }}</span>
</div>
</div>
<div class="flex mb-12">
<div class="col">
<div class="col" style="width: 33.33%">
<label>回访人姓名</label>
<span>{{ mail.verifyFollowupPolice?.name }}</span>
</div>
<div class="col">
<div class="col" style="width: 33.33%">
<label>回访人警号</label>
<span>{{ mail.verifyFollowupPolice?.empNo }}</span>
</div>
</div>
<div class="flex mb-20">
<div class="col">
<div class="col" style="width: 33.33%">
<label>回访人电话</label>
<span>{{ mail.verifyFollowupPolice?.mobile }}</span>
</div>
</div>
<el-divider />
<template v-if="mail.verifyIsTrue === '属实' || mail.verifyIsTrue === '基本属实'">
<h2>查证属实问题</h2>
<div class="flex">
<el-form-item 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-group>
</el-form-item>
</div>
<el-divider />
</template>
<el-form :model="form" :rules="rules" ref="formRef" :label-width="244">
<h2>综合认定情况</h2>
<el-row>
@ -66,7 +80,10 @@
</el-col>
</el-row>
<el-form-item label="群众回复情况" prop="satisfactionStatus">
<el-radio-group v-model="form.satisfactionStatus" v-if="!mail.satisfaction">
<el-radio-group
v-model="form.satisfactionStatus"
v-if="!mail.satisfaction"
>
<el-radio
v-for="item in dictData.satisfaction_status"
:key="item.id"
@ -78,57 +95,67 @@
<span v-else>{{ getSatisfaction() }}</span>
</el-form-item>
<div class="tips" v-if="isSatisfactionNonConsistent()">
<span class="mr-16" style="color: red; font-weight: 700">重点审核</span>
<span class="mr-16" style="color: red; font-weight: 700"
>重点审核</span
>
<span>办理反馈情况 群众回复情况 不一致</span>
</div>
<el-divider />
<h2 class="relative">
<span>信件标签</span>
<el-button type="primary" plain @click="addLableShow = true" size="small" class="add-label-btn"
<el-button
type="primary"
plain
@click="addLableShow = true"
size="small"
class="add-label-btn"
>添加标签</el-button
>
</h2>
<el-form-item class="mb-40 label-position-top" prop="mailLabels">
<el-form-item class="mb-20 label-position-top" prop="mailLabels">
<el-checkbox-group v-model="form.mailLabels">
<el-checkbox
v-for="item in labels"
:key="item.id"
:label="item.id"
>{{ item.labelName }}</el-checkbox>
>{{ item.labelName }}</el-checkbox
>
</el-checkbox-group>
</el-form-item>
<el-divider />
<h2>认定办结意见<span style="color: red">*</span></h2>
<h2><span style="color: red">*</span>认定办结意见</h2>
<el-form-item
prop="completionComment"
class="mb-40 label-position-top"
class="mb-20 label-position-top"
>
<el-input
v-model="form.completionComment"
type="textarea"
:rows="4"
:rows="3"
placeholder="请输入认定办结意见"
></el-input>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button type="primary" size="large" @click="submit"
>认定办结</el-button
>
</footer>
</el-dialog>
<el-dialog v-model="addLableShow" width="30vw" title="添加标签">
<el-input type="textarea" v-model="labelName" placeholder="请输入标签内容" class="mb-10"/>
<footer class="flex end">
<el-button type="primary" @click="handleAddLabel"
>确定</el-button
>
<el-button @click="addLableShow = false"
>取消</el-button
>
</footer>
<el-dialog v-model="addLableShow" width="30vw" title="添加标签">
<el-input
type="textarea"
v-model="labelName"
placeholder="请输入标签内容"
class="mb-10"
/>
<footer class="flex end">
<el-button type="primary" @click="handleAddLabel"
>确定</el-button
>
<el-button @click="addLableShow = false">取消</el-button>
</footer>
</el-dialog>
</el-dialog>
</template>
<script setup>
@ -137,10 +164,9 @@ import { useDictData } from "@/hooks/useDictOptions";
const { dictData } = useDictData([
"satisfaction_status",
"qualified_processing_status",
"verify_problem"
]);
const visible = ref(false);
const rules = {
qualifiedProcessingStatus: [
{
@ -171,46 +197,34 @@ const formRef = ref();
const form = reactive({});
const props = defineProps({
show: {
type: Boolean,
default: false,
},
data: {
type: Object,
default: {},
},
mail: {
type: Object,
default: {},
},
flowKey: {
type: String,
default: "",
},
});
const mail = inject("mail");
watch(() => mail.value.verifyProblem, (val) => {
form.verifyProblem = val
})
const emits = defineEmits(["update:data", "submit", "close"]);
const emits = defineEmits(["update:show", "update:data", "submit"]);
watch(visible, (val) => {
emits("update:show", val);
});
watch(
() => props.show,
(val) => {
visible.value = val;
() => mail.value.satisfaction,
() => {
form.satisfactionStatus = getSatisfaction();
}
);
watch(() => props.mail.satisfaction, () => {
form.satisfactionStatus = getSatisfaction()
})
function submit() {
formRef.value.validate((valid) => {
if (valid) {
//
const data = { ...props.data, ...form};
const data = { ...props.data, ...form };
emits("update:data", data);
emits("submit", "confirmedCompletion");
visible.value = false;
emits("close");
}
});
}
@ -221,9 +235,9 @@ function getLables() {
labels.value = data;
});
}
getLables()
getLables();
const labelName = ref("");
const addLableShow = ref(false)
const addLableShow = ref(false);
function handleAddLabel() {
if (!labelName.value) {
return;
@ -231,32 +245,35 @@ function handleAddLabel() {
labelAdd({
labelName: labelName.value,
}).then((data) => {
addLableShow.value = false
labelName.value = ''
getLables()
addLableShow.value = false;
labelName.value = "";
getLables();
});
}
const SATISFACTION = {
not_satisfied: '不满意',
basically_satisfied: '基本满意',
satisfied: '非常满意'
}
const SATISFACTION = {
not_satisfied: "不满意",
basically_satisfied: "基本满意",
satisfied: "非常满意",
};
function getSatisfaction() {
if (!props.mail.satisfaction) {
return ''
if (!mail.value.satisfaction) {
return "";
}
return SATISFACTION[props.mail.satisfaction]
return SATISFACTION[mail.value.satisfaction];
}
function isSatisfactionNonConsistent() {
if (!props.mail.satisfaction || !props.mail.verifyFeedback) {
return false
if (!mail.value.satisfaction || !mail.value.verifyFeedback) {
return false;
}
if(getSatisfaction()!== props.mail.verifyFeedback){
if(getSatisfaction()=="满意"&&props.mail.verifyFeedback=="非常满意"){
if (getSatisfaction() !== mail.value.verifyFeedback) {
if (
getSatisfaction() == "满意" &&
mail.value.verifyFeedback == "非常满意"
) {
return false;
}else{
} else {
return true;
}
}
@ -265,16 +282,17 @@ function isSatisfactionNonConsistent() {
<style lang="scss" scoped>
h2 {
margin-top: 0;
font-size: 20px;
font-size: 18px;
margin-bottom: 16px;
color: #333;
}
.col {
label {
width: 244px;
width: 160px;
text-align: right;
}
}
.el-divider--horizontal {
.el-divider--horizontal {
margin: 10px 0;
}
.add-label-btn {
@ -283,7 +301,7 @@ h2 {
right: 0;
}
.tips {
border: 1px solid #FFE3E3;
border: 1px solid #ffe3e3;
padding: 12px 2em;
}
:deep() {

6
src/views/work/components/MailCheck.vue

@ -85,8 +85,10 @@
<el-tag type="danger" v-else>未签收</el-tag>
</template>
</el-table-column>
<el-table-column label="流程限时" width="140">
<el-table-column width="140">
<template #header>
<FlowLimitedExplanation />
</template>
<template #default="{ row }">
<div v-if="row.flowLimitedRemainingTime > 0" class="success">
<span class="mr-4">剩余</span>

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

@ -66,22 +66,22 @@
<el-row :gutter="20" style="height: 100%">
<el-col :span="5" style="height: 100%">
<div
style="height: 100%; padding: 0 20px 0 40px"
ref="leftContainerRef"
class="left-container h100"
>
<div
class="timer flex center"
v-if="flowNode.key !== 'completion'"
ref="timerRef"
>
<div
v-if="mail.flowRemainingTime > 0"
style="height: 210px"
class="timer-box"
>
<el-progress
type="dashboard"
:percentage="percentage"
:stroke-width="16"
:width="240"
:stroke-width="10"
:color="colors"
class="timer"
>
@ -91,7 +91,7 @@
<span
style="font-size: 12px; color: #ff0000"
v-if="mail.extensionFlag"
>已延期1{{ mail.extensionDays }}</span
>已延期{{ mail.extensionDays }}</span
>
</el-progress>
</div>
@ -142,13 +142,6 @@
getTotalTime()
}}</span>
</span>
<el-button
type="primary"
size="small"
plain
:disabled="true"
>节点流程图</el-button
>
</header>
<el-scrollbar :max-height="flowMaxHeight">
<div class="flow-container">
@ -176,9 +169,7 @@
</div>
<div
class="flow-time"
:danger="
item.consumingTime >
item.limitedTime
:danger="item.handlerDeptName !== '长沙市公安局' && item.consumingTime > item.limitedTime
"
>
<span class="second mr-8"
@ -343,7 +334,7 @@
webComponents.indexOf('CompletionDetail') > -1
"
>
<CompletionDetail :mail="mail" />
<CompletionDetail />
</template>
<div style="height: 20px"></div>
</el-scrollbar>
@ -444,10 +435,10 @@
@close="approvedShow = false"
/>
<ConfirmedCompletion
v-model:show="completionShow"
v-model="completionShow"
v-model:data="requestData"
:mail="mail"
@submit="(key) => handleAction(key)"
@close="completionShow = false"
/>
<InitiateCountersign
v-model="countersignShow"
@ -601,6 +592,7 @@ watch(
}
);
const timerRef = ref()
async function getDetail() {
loading.value = true;
//
@ -626,13 +618,13 @@ async function getDetail() {
.map((item) => item.trim());
}
actions.value = data.actions;
nextTick(() => {
flowMaxHeight.value =
leftContainerRef.value.offsetHeight -
(mailInfoRef.value?.offsetHeight || 0) -
flowHeaderRef.value.offsetHeight -
240;
flowHeaderRef.value.offsetHeight -
(timerRef.value?.offsetHeight || 0);
});
}
@ -933,7 +925,9 @@ function getFlowHandler(item) {
}
}
}
.left-container {
padding: 0 20px 0 40px;
}
.timer {
--large-font-color: var(--primary-color);
--default-font-color: #999;
@ -950,6 +944,9 @@ function getFlowHandler(item) {
width: 100%;
}
}
.timer-box {
height: 210px;
}
.flow {
.flow-header {
background: #f5f6ff;
@ -1053,5 +1050,9 @@ footer {
span[danger="true"] {
color: var(--danger-color);
}
.timer-box .el-progress-circle {
height: 240px !important;
width: 240px !important;
}
}
</style>

11
src/views/work/components/MailTodoByChange.vue

@ -136,12 +136,9 @@
</main>
<footer class="flex between mr-15 ml-15" style="background-color: #F9FAFF;">
<div></div>
<div>
<el-button type="primary" size="large" @click="handlePrint" plain :icon="Printer">打印</el-button>
<el-button type="primary" size="large" @click="handleExport" plain :icon="DocumentAdd">导出</el-button>
</div>
<div>
<el-button type="primary" size="large" @click="handleTodo">转为代办</el-button>
<el-button type="primary" size="large" @click="handleTodo">转为待办</el-button>
</div>
</footer>
</el-dialog>
@ -250,10 +247,10 @@ const handleTodo = () => {
mailChange({ mailId: props.mailId }).then(() => {
loading.value = false;
visible.value = false;
ElMessage.success('转为办成功')
ElMessage.success('转为办成功')
emits("update");
}).catch((err) => {
ElMessage.success('转为办失败')
ElMessage.success('转为办失败')
console.log(err)
})
}

22
src/views/work/components/templates/CompletionDetail.vue

@ -25,7 +25,7 @@
</div>
<div class="col">
<label>群众回复情况</label>
<span>{{ mail.satisfactionStatus }}</span>
<span>{{ getSatisfaction() }}</span>
</div>
</div>
<div class="flex mb-12" v-if="mail.completionComment">
@ -43,12 +43,20 @@
</template>
</template>
<script setup>
defineProps({
mail: {
type: Object,
default: () => {},
},
});
const mail = inject('mail');
const SATISFACTION = {
not_satisfied: '不满意',
basically_satisfied: '基本满意',
satisfied: '非常满意'
}
function getSatisfaction() {
if (mail.value.satisfaction) {
return SATISFACTION[mail.value.satisfaction] + "(群众)"
}
return mail.value.satisfactionStatus;
}
</script>
<style lang="scss" scoped>
.col {

55
src/views/work/components/templates/ThreeHandling.vue

@ -385,14 +385,14 @@
import CoHandlingPoliceEdit from "./CoHandlingPoliceEdit.vue";
import { listByThree, deptAll } from "@/api/org/department";
import { allLists } from "@/api/perms/admin";
import { timeDiffSeconds, formatTimeText } from "@/utils/util";
import { useDictData } from "@/hooks/useDictOptions";
import feedback from "@/utils/feedback";
const { VITE_API_URL } = process.env;
import { useDictData } from "@/hooks/useDictOptions";
const { dictData } = useDictData([
"interview_type",
"verify_problem",
@ -558,32 +558,43 @@ if (props.mail.simpleFlowFlag) {
];
}
const form = ref({});
const formRef = ref();
const step = ref(1);
watch(
() => props.mail.id,
() => {
formRef.value.resetFields();
initForm();
//
resetStep();
}
);
const activeStep = ref(step.value);
const depts = ref([]);
watch(step, (val) => {
activeStep.value = val
})
const resetStep = () => {
if (props.mail.flowKey === "interview_writer") {
step.value = 2;
} else if (props.mail.flowKey === "verify") {
step.value = 3;
getDepts(props.mail);
} else step.value = 1;
};
function init() {
console.log('init')
formRef.value?.resetFields();
initForm();
//
resetStep();
}
watch(
() => props.mail.flowKey,
() => props.mail.id + props.mail.flowKey,
() => {
updateStep();
init();
}
);
init()
watch(
() => props.mail.coHandlingPolices,
(val) => {
@ -602,23 +613,11 @@ function updateCoHandlingPolices() {
emits("update:data", data);
}
const depts = ref([]);
updateStep();
function updateStep() {
if (props.mail.flowKey === "interview_writer") {
step.value = 2;
}
if (props.mail.flowKey === "verify") {
step.value = 3;
getDepts(props.mail);
}
}
const activeStep = computed(() => step.value);
function handleChangeTab(index) {
if (props.mail.flowKey === "verify") {
step.value = index;
activeStep.value = index;
}
}
@ -680,8 +679,6 @@ function handleChangePolice(val, index) {
reportedPolices.value[index].name = police.name;
}
const form = ref({});
initForm();
function initForm() {
form.value = {
@ -712,7 +709,7 @@ function initForm() {
};
}
const reportedPolices = ref([]);
const formRef = ref();
function validate() {
return new Promise((resolve, reject) => {

4
src/views/work/components/templates/ThreeHandlingDetail.vue

@ -32,7 +32,7 @@
<div class="flex mb-12" v-if="mail.contactPoliceName">
<div class="col" v-if="mail.mainDeptSignTime">
<label>主单位签收时长</label>
<span :dnager="mail.mainDeptSignTime > 600">{{ formatTimeText(mail.mainDeptSignTime) }}</span>
<span :danger="mail.mainDeptSignTime > 600">{{ formatTimeText(mail.mainDeptSignTime) }}</span>
</div>
<div class="col">
<label>联系民警</label>
@ -40,7 +40,7 @@
</div>
<div class="col">
<label>主单位联系群众时长</label>
<span :dnager="mail.contactDuration > 1800">{{ formatTimeText(mail.contactDuration) }}</span>
<span :danger="mail.contactDuration > 1800">{{ formatTimeText(mail.contactDuration) }}</span>
</div>
</div>
<template v-if="mail.interviewType">

1
vite.config.ts

@ -21,6 +21,7 @@ export default ({ mode }) => {
},
server: {
host: '0.0.0.0',
port: 5172,
proxy: {
'/lan-api': {
target: 'http://127.0.0.1:8082',

Loading…
Cancel
Save