Browse Source

fit: 新增流程单位会签

main
wxc 1 year ago
parent
commit
203866421b
  1. 3
      src/components/file/list.vue
  2. 2
      src/components/home/work/my-todo.vue
  3. 88
      src/components/negative/apply-countersign.vue
  4. 2
      src/components/negative/approve-description.vue
  5. 143
      src/components/negative/confirmation-completion.vue
  6. 82
      src/components/negative/countersign-description.vue
  7. 33
      src/components/negative/countersign.vue
  8. 23
      src/components/negative/dialog.vue
  9. 7
      src/components/negative/verify-description.vue
  10. 1
      src/enums/flowEnums.ts
  11. 2
      src/utils/flow.ts

3
src/components/file/list.vue

@ -129,8 +129,7 @@
</template>
<template
v-else-if="
getFileType(activeFile.fileName) === FileType.WORD &&
activeFile.fileName.toLocaleLowerCase().endsWith('.docx')
getFileType(activeFile.fileName) === FileType.WORD
"
>
<vue-office-docx

2
src/components/home/work/my-todo.vue

@ -123,6 +123,8 @@
)
}}{{
row.extensionApplyFlag ? "" : "(延期申请)"
}}{{
row.workFlowKey === 'countersign' ? "(单位会签)" : ""
}}</el-tag
>
</template>

88
src/components/negative/apply-countersign.vue

@ -0,0 +1,88 @@
<template>
<el-dialog width="50vw" title="发起单位会签" v-model="show">
<el-form :model="formData" ref="formRef">
<el-form-item
label="会签具体要求"
:rules="{
required: true,
message: '请输入会签具体要求',
trigger: ['blur'],
}"
label-position="top"
prop="requirement"
>
<el-input
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入单位会签提议,如对问题处理结果存疑的地方,希望哪些单位提供专业意见等。"
v-model="formData.requirement"
/>
</el-form-item>
<el-form-item
label="参与会签单位"
:rules="{
required: true,
message: '请选择参与会签单位'
}"
label-position="top"
prop="countersignDeparts"
>
<div style="min-height: 200px">
<div class="flex gap-20 mb-10" v-for="(item, index) in formData.countersignDeparts" :key="index">
<div style="width: 280px">
<depart-tree-select v-model="item.id" />
</div>
<el-button type="primary" plain v-if="index === 0" @click="handleAddDepart">
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加单位</el-button
>
<el-button type="danger" plain v-else @click="handleRemoveDepart">
<template #icon>
<icon name="el-icon-Delete" />
</template>
删除单位</el-button
>
</div>
</div>
</el-form-item>
</el-form>
<footer class="flex end">
<el-button type="primary" size="large" @click="submit"
>发起会签</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
const emit = defineEmits(["submit"]);
const show = ref(false);
const formData = ref({
countersignDeparts: [{}]
})
const formRef = ref()
function handleAddDepart() {
formData.value.countersignDeparts.push({})
}
function handleRemoveDepart(index) {
formData.value.countersignDeparts.splice(index, 1)
}
async function submit() {
await formRef.value.validate();
show.value = false;
emit("submit", formData.value);
}
async function open() {
show.value = true;
}
defineExpose({
open,
});
</script>

2
src/components/negative/approve-description.vue

@ -60,7 +60,7 @@ console.log("approves", approves);
</script>
<style lang="scss" scoped>
header {
font-size: 20px;
font-size: 16px;
color: var(--primary-color);
padding: 20px 0;
}

143
src/components/negative/confirmation-completion.vue

@ -11,8 +11,9 @@
<span>查看文档</span>
</a>
</p> -->
<el-form :label-width="120" ref="formRef" :model="formData">
<!-- <div v-for="(item, index) in blames" :key="index">
<div style="min-height: 350px">
<el-form :label-width="120" ref="formRef" :model="formData">
<!-- <div v-for="(item, index) in blames" :key="index">
<h5>涉及人员{{ index + 1 }}</h5>
<div class="row">
<div class="col col-6">
@ -132,72 +133,75 @@
50%
</p>
</div> -->
<h3>认定办结情况</h3>
<el-row>
<el-col :span="12">
<el-form-item
label="核查办理情况"
prop="verifySituation"
:rules="{
required: true,
message: '请选择核查办理情况',
trigger: ['blur'],
}"
>
<el-radio-group v-model="formData.verifySituation">
<el-radio
v-for="item in dict.verifySituation"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="佐证材料情况"
prop="verifyFileSituation"
:rules="{
required: true,
message: '请选择佐证材料情况',
trigger: ['blur'],
}"
>
<el-radio-group v-model="formData.verifyFileSituation">
<el-radio
v-for="item in dict.verifyFileSituation"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
<h3>认定办结情况</h3>
<el-row>
<el-col :span="12">
<el-form-item
label="核查办理情况"
prop="verifySituation"
:rules="{
required: true,
message: '请选择核查办理情况',
trigger: ['blur'],
}"
>
<el-radio-group v-model="formData.verifySituation">
<el-radio
v-for="item in dict.verifySituation"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="佐证材料情况"
prop="verifyFileSituation"
:rules="{
required: true,
message: '请选择佐证材料情况',
trigger: ['blur'],
}"
>
<el-radio-group
v-model="formData.verifyFileSituation"
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item
label="认定办结意见"
prop="completionComment"
:rules="{
required: true,
message: '请输入认定办结意见',
trigger: ['blur'],
}"
>
<el-input
type="textarea"
v-model="formData.completionComment"
placeholder="请输入"
:autosize="{ minRows: 4 }"
/>
</el-form-item>
</el-form>
<el-radio
v-for="item in dict.verifyFileSituation"
:key="item.dictCode"
:value="item.dictValue"
>{{ item.dictLabel
}}{{
item.remark ? `(${item.remark})` : ""
}}</el-radio
>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item
label="认定办结意见"
prop="completionComment"
:rules="{
required: true,
message: '请输入认定办结意见',
trigger: ['blur'],
}"
>
<el-input
type="textarea"
v-model="formData.completionComment"
placeholder="请输入"
:autosize="{ minRows: 4 }"
/>
</el-form-item>
</el-form>
</div>
<footer class="flex end mt-40">
<el-button size="large">取消</el-button>
<el-button type="primary" size="large" @click="submit"
@ -270,9 +274,8 @@ function getNegativeLevelScore(val) {
function getScore(item, index) {
return (
item.baseScore +
(1 *
getNegativeLevelScore(formData.value.blames[index].negativeLevel)) +
(1 * item.frequencyScore)
1 * getNegativeLevelScore(formData.value.blames[index].negativeLevel) +
1 * item.frequencyScore
).toFixed(2);
}

82
src/components/negative/countersign-description.vue

@ -0,0 +1,82 @@
<template>
<el-collapse v-model="activeNames">
<el-collapse-item
v-for="(item, index) in countersignApplys"
:key="index"
:title="`单位会签${index + 1}`"
:name="`countersign${index}`"
>
<div class="row">
<div class="col col-6">
<label>会签发起人</label>
<span>{{ item.creatorName }}</span>
</div>
<div class="col col-6">
<label>发起时间</label>
<span>{{ item.createTime }}</span>
</div>
<div class="col col-12">
<label>会签单位</label>
<span>
<div
v-for="depart in item.countersigns"
:key="depart"
class="flex gap wrap"
>
<span>{{ depart.departName }}</span>
<span
>({{
depart.state === "uncompleted"
? "未提交"
: "已提交"
}})</span
>
</div>
</span>
</div>
<div class="col col-24">
<label>会签具体要求</label>
<span>{{ item.requirement }}</span>
</div>
</div>
<div
v-for="countersign in item.countersigns.filter(
(obj) => obj.state !== 'uncompleted'
)"
:key="countersign"
>
<div class="text-primary mb-8">
{{ countersign.departName }}的会签意见
</div>
<div class="text-wrap mb-10">{{ countersign.comments }}</div>
<div class="row" v-if="countersign.files">
<div class="col col-24">
<label>附件</label>
<span>
<file-list :files="JSON.parse(countersign.files)" />
</span>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</template>
<script setup>
import { onMounted } from "vue";
const countersignApplys = inject("countersignApplys");
const activeNames = ref([]);
watch(countersignApplys, () => {
for (let i = 0; i < countersignApplys.value.length; i++) {
console.log(i)
activeNames.value.push(`countersign${i}`);
}
});
</script>
<style lang="scss" scoped>
.el-collapse {
--el-collapse-header-text-color: var(--primary-color);
--el-collapse-header-font-size: 16px;
}
</style>

33
src/components/negative/countersign.vue

@ -0,0 +1,33 @@
<template>
<el-form :model="formData" ref="formRef" label-width="108" class="mt-10">
<el-form-item label="会签意见" prop="comments" :rules="{
required: true,
message: '请输入会签意见',
trigger: ['blur']}">
<el-input
type="textarea"
placeholder="请输入会签意见"
:autosize="{ minRows: 4 }"
v-model="formData.comments"
/>
</el-form-item>
<el-form-item label="附件">
<file-upload v-model:files="formData.files" />
</el-form-item>
</el-form>
</template>
<script setup>
const formData = ref({});
const formRef = ref();
async function validate() {
await formRef.value.validate();
return formData.value;
}
defineExpose({
validate
});
</script>
<style lang="scss" scoped>
</style>

23
src/components/negative/dialog.vue

@ -138,6 +138,17 @@
<template v-if="approves.length">
<negative-approve-description />
</template>
<negative-countersign-description />
<template
v-if="
components.indexOf(
'negative-countersign'
) > -1
"
>
<negative-countersign ref="componentRef"
@submit="handleSubmitExecute" />
</template>
</el-scrollbar>
</el-col>
</el-row>
@ -193,6 +204,12 @@
@submit="handleSubmitExecute"
/>
</template>
<template v-if="item.actionKey.includes('apply_countersign')">
<negative-apply-countersign
:ref="(el) => setActionItemRef(item.actionKey, el)"
@submit="handleSubmitExecute"
/>
</template>
</template>
<template v-if="confirmationCompletionFlag && flowActions.length">
<negative-confirmation-completion
@ -241,11 +258,13 @@ const actionHistory = ref([]);
const signReturns = ref([]);
const approves = ref([]);
const extensionApply = ref({});
const countersignApplys = ref([])
provide("negative", negative);
provide("actionHistory", actionHistory);
provide("signReturns", signReturns);
provide("approves", approves);
provide("extensionApply", extensionApply);
provide("countersignApplys", countersignApplys);
const isFav = ref(false);
const remainingDuration = ref(0);
@ -269,6 +288,7 @@ function getDetails() {
signReturns.value = data.signReturns;
approves.value = data.approves;
extensionApply.value = data.extensionApply || {};
countersignApplys.value = data.countersignApplys
isFav.value = data.isFav;
remainingDuration.value = data.remainingDuration;
maxDuration.value = data.maxDuration;
@ -306,7 +326,8 @@ async function handleExecute(action, data) {
if (action.openDialog) {
if (
confirmationCompletionFlag.value &&
!action.actionKey.includes("_return")
!action.actionKey.includes("_return") &&
action.actionKey !== "apply_countersign"
) {
confirmationCompletionRef.value.open();
activeAction.value = {

7
src/components/negative/verify-description.vue

@ -34,6 +34,12 @@
<span>{{ negative.checkStatusDesc }}</span>
</div>
</div>
<div class="row" v-if="negative.rectifyDesc">
<div class="col col-24">
<label>问题整改情况</label>
<span>{{ negative.rectifyDesc }}</span>
</div>
</div>
</el-collapse-item>
<el-collapse-item
v-for="(blame, index) in negative.blames.filter(
@ -268,5 +274,6 @@ for (
<style lang="scss" scoped>
.el-collapse {
--el-collapse-header-text-color: var(--primary-color);
--el-collapse-header-font-size: 16px;
}
</style>

1
src/enums/flowEnums.ts

@ -9,6 +9,7 @@ export enum FlowNodeEnum {
FIRST_APPROVE = 'first_approve',
SECOND_EXTENSION_APPROVE = 'second_extension_approve',
FIRST_EXTENSION_APPROVE = 'first_extension_approve',
COUNTERSIGN = 'countersign',
COMPLETED = 'completed'
}

2
src/utils/flow.ts

@ -21,6 +21,8 @@ export function getComponents(flowKey:string) {
return ['negative-verify-description'];
case FlowNodeEnum.COMPLETED:
return ['negative-verify-description'];
case FlowNodeEnum.COUNTERSIGN:
return ['negative-verify-description', 'negative-countersign'];
}
return []
}
Loading…
Cancel
Save