|
|
|
|
@ -23,6 +23,7 @@
|
|
|
|
|
:flow-id="$route.query.flow_id"
|
|
|
|
|
:collapsible="(!/\/detail/.test($route.path)) && (!$route.query.flow_id || isFirstNode)"
|
|
|
|
|
style="margin-bottom: 20px;"
|
|
|
|
|
@open-meeting-minute="openMeetingMinutesDrawer"
|
|
|
|
|
></RelatedFlows>
|
|
|
|
|
|
|
|
|
|
<!-- 关联的支付信息(查看/办理:只要有 flow_id 就展示,没数据时展示空态) -->
|
|
|
|
|
@ -136,16 +137,20 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 会议纪要:点击抽屉查看 -->
|
|
|
|
|
<!-- 会议纪要:点击抽屉查看(一对多,多条链接) -->
|
|
|
|
|
<div v-else-if="el.type === 'meeting_minutes'">
|
|
|
|
|
<el-link
|
|
|
|
|
v-if="extractMeetingMinuteId(getPaymentTemplateElementValue(el, payment))"
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
@click="openMeetingMinutesDrawer(extractMeetingMinuteId(getPaymentTemplateElementValue(el, payment)))"
|
|
|
|
|
>
|
|
|
|
|
{{ (getPaymentTemplateElementValue(el, payment) && getPaymentTemplateElementValue(el, payment).title) ? getPaymentTemplateElementValue(el, payment).title : '查看会议纪要' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
<template v-if="getPaymentMeetingMinutesList(el, payment).length">
|
|
|
|
|
<span v-for="(item, idx) in getPaymentMeetingMinutesList(el, payment)" :key="item.id">
|
|
|
|
|
<el-link
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
@click="openMeetingMinutesDrawer(item.id)"
|
|
|
|
|
>
|
|
|
|
|
{{ item.title || '查看会议纪要' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
<span v-if="idx < getPaymentMeetingMinutesList(el, payment).length - 1">、</span>
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@ -305,16 +310,20 @@
|
|
|
|
|
<span v-if="getPlannedFileItems(expId, f).length === 0">-</span>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- meeting_minutes:点击抽屉查看 -->
|
|
|
|
|
<!-- meeting_minutes:点击抽屉查看(一对多,多条链接) -->
|
|
|
|
|
<template v-else-if="f.element_type === 'meeting_minutes'">
|
|
|
|
|
<el-link
|
|
|
|
|
v-if="extractMeetingMinuteId(getIndirectFieldValue(expId, getTplFieldKey(f)))"
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
@click="openMeetingMinutesDrawer(extractMeetingMinuteId(getIndirectFieldValue(expId, getTplFieldKey(f))))"
|
|
|
|
|
>
|
|
|
|
|
查看会议纪要
|
|
|
|
|
</el-link>
|
|
|
|
|
<template v-if="getIndirectMeetingMinutesList(expId, getTplFieldKey(f)).length">
|
|
|
|
|
<span v-for="(item, idx) in getIndirectMeetingMinutesList(expId, getTplFieldKey(f))" :key="item.id">
|
|
|
|
|
<el-link
|
|
|
|
|
type="primary"
|
|
|
|
|
:underline="false"
|
|
|
|
|
@click="openMeetingMinutesDrawer(item.id)"
|
|
|
|
|
>
|
|
|
|
|
{{ item.title || '查看会议纪要' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
<span v-if="idx < getIndirectMeetingMinutesList(expId, getTplFieldKey(f)).length - 1">、</span>
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
<span v-else>-</span>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
@ -782,28 +791,54 @@
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 会议纪要:请求数据展示 -->
|
|
|
|
|
<!-- 会议纪要:请求数据展示(与会议纪要管理查看模式字段、顺序一致) -->
|
|
|
|
|
<div v-else-if="rightDrawerType === 'meetingMinutes'" v-loading="loadingMeetingMinutes">
|
|
|
|
|
<div v-if="meetingMinutesDetail">
|
|
|
|
|
<el-descriptions :column="1" border>
|
|
|
|
|
<el-descriptions-item label="标题">
|
|
|
|
|
{{ meetingMinutesDetail.title || '-' }}
|
|
|
|
|
<el-descriptions-item label="会议纪要标题">
|
|
|
|
|
<span style="font-weight: 500;">{{ meetingMinutesDetail.title || '-' }}</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="内容清单">
|
|
|
|
|
<div v-if="meetingMinutesDetail.items && meetingMinutesDetail.items.length">
|
|
|
|
|
<div v-for="(it, idx) in meetingMinutesDetail.items" :key="idx" style="margin-bottom: 8px;">
|
|
|
|
|
<span style="color:#409EFF;">{{ it.type || '类型' }}:</span>
|
|
|
|
|
<span>{{ it.content || '-' }}</span>
|
|
|
|
|
<el-descriptions-item label="关联上会审议流程">
|
|
|
|
|
<div v-if="meetingMinutesDetail.flows && meetingMinutesDetail.flows.length">
|
|
|
|
|
<el-tag
|
|
|
|
|
v-for="flow in meetingMinutesDetail.flows"
|
|
|
|
|
:key="flow.id"
|
|
|
|
|
type="info"
|
|
|
|
|
style="margin-right: 8px; margin-bottom: 4px;"
|
|
|
|
|
>
|
|
|
|
|
{{ flow.title || flow.no || ('流程' + flow.id) }}
|
|
|
|
|
<span v-if="flow.no" style="color: #909399; margin-left: 4px;">({{ flow.no }})</span>
|
|
|
|
|
</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else style="color: #909399;">未关联</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="附件">
|
|
|
|
|
<div v-if="meetingMinutesDetail.files_details && meetingMinutesDetail.files_details.length">
|
|
|
|
|
<div v-for="(f, idx) in meetingMinutesDetail.files_details" :key="idx" style="margin-bottom: 8px;">
|
|
|
|
|
<el-link type="primary" :underline="false" :href="f.url" target="_blank" style="margin-right: 10px;">
|
|
|
|
|
<i class="el-icon-view"></i> {{ f.original_name || f.name || '附件' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
<el-link type="primary" :underline="false" :href="f.url" target="_blank" download>
|
|
|
|
|
<i class="el-icon-download"></i> 下载
|
|
|
|
|
</el-link>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else>无</span>
|
|
|
|
|
<span v-else style="color: #909399;">无附件</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
<el-descriptions-item label="附件" v-if="meetingMinutesDetail.files_details && meetingMinutesDetail.files_details.length">
|
|
|
|
|
<div v-for="(f, idx) in meetingMinutesDetail.files_details" :key="idx" style="margin-bottom: 6px;">
|
|
|
|
|
<el-link type="primary" :underline="false" :href="f.url" target="_blank">
|
|
|
|
|
{{ f.original_name || f.name || '附件' }}
|
|
|
|
|
</el-link>
|
|
|
|
|
<el-descriptions-item label="内容清单">
|
|
|
|
|
<div v-if="meetingMinutesDetail.items && meetingMinutesDetail.items.length">
|
|
|
|
|
<div
|
|
|
|
|
v-for="(it, idx) in meetingMinutesDetail.items"
|
|
|
|
|
:key="idx"
|
|
|
|
|
style="margin-bottom: 12px; padding: 12px; background-color: #f5f7fa; border-radius: 4px;"
|
|
|
|
|
>
|
|
|
|
|
<div style="margin-bottom: 4px;">
|
|
|
|
|
<el-tag size="small" type="primary">{{ it.type || '未分类' }}</el-tag>
|
|
|
|
|
</div>
|
|
|
|
|
<div style="color: #606266; line-height: 1.6;">{{ it.content || '-' }}</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span v-else style="color: #909399;">无内容清单</span>
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
</div>
|
|
|
|
|
@ -962,12 +997,9 @@ export default {
|
|
|
|
|
return this.getOaCustomModelBindings(expenditureId, field).length > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// meeting_minutes 类型:仅当有会议纪要ID时才显示
|
|
|
|
|
// meeting_minutes 类型:有至少一条会议纪要时显示(一对多)
|
|
|
|
|
if (field.element_type === 'meeting_minutes') {
|
|
|
|
|
const meetingMinuteId = this.extractMeetingMinuteId(
|
|
|
|
|
this.getIndirectFieldValue(expenditureId, this.getTplFieldKey(field))
|
|
|
|
|
);
|
|
|
|
|
return meetingMinuteId !== null && meetingMinuteId !== undefined;
|
|
|
|
|
return this.getIndirectMeetingMinutesList(expenditureId, this.getTplFieldKey(field)).length > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// attachment/file 类型:仅当有文件项时才显示
|
|
|
|
|
@ -1049,6 +1081,9 @@ export default {
|
|
|
|
|
if (el.type === 'form_element' && el.field_type === 'attachment') {
|
|
|
|
|
return Array.isArray(val) && val.length > 0;
|
|
|
|
|
}
|
|
|
|
|
if (el.type === 'meeting_minutes') {
|
|
|
|
|
return this.normalizeMeetingMinutesValue(val).length > 0;
|
|
|
|
|
}
|
|
|
|
|
return !this.isEmptyValue(val);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
@ -1894,6 +1929,33 @@ export default {
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/** 将会议纪要值归一化为 [{ id, title }, ...],兼容单条与多条 */
|
|
|
|
|
normalizeMeetingMinutesValue(val) {
|
|
|
|
|
if (val === null || val === undefined) return [];
|
|
|
|
|
if (Array.isArray(val)) {
|
|
|
|
|
return val
|
|
|
|
|
.map((item) => {
|
|
|
|
|
const id = this.extractMeetingMinuteId(item);
|
|
|
|
|
if (!id) return null;
|
|
|
|
|
const title = (item && typeof item === 'object' && item.title) ? item.title : '';
|
|
|
|
|
return { id, title };
|
|
|
|
|
})
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
}
|
|
|
|
|
const id = this.extractMeetingMinuteId(val);
|
|
|
|
|
if (!id) return [];
|
|
|
|
|
const title = (val && typeof val === 'object' && val.title) ? val.title : '';
|
|
|
|
|
return [{ id, title }];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getPaymentMeetingMinutesList(el, payment) {
|
|
|
|
|
return this.normalizeMeetingMinutesValue(this.getPaymentTemplateElementValue(el, payment));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
getIndirectMeetingMinutesList(expenditureId, fieldKey) {
|
|
|
|
|
return this.normalizeMeetingMinutesValue(this.getIndirectFieldValue(expenditureId, fieldKey));
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async openFlowDrawer({ flowId, customModelId, title }) {
|
|
|
|
|
const fid = Number(flowId);
|
|
|
|
|
if (!fid || Number.isNaN(fid)) return;
|
|
|
|
|
@ -1934,7 +1996,7 @@ export default {
|
|
|
|
|
this.loadingMeetingMinutes = true;
|
|
|
|
|
try {
|
|
|
|
|
// meetingMinutesShow 成功时返回 res.data
|
|
|
|
|
const detail = await meetingMinutesShow({ id: meetingMinuteId });
|
|
|
|
|
const detail = await meetingMinutesShow({ id: meetingMinuteId, show_relation: ['flows', 'items'] });
|
|
|
|
|
this.meetingMinutesDetail = detail || null;
|
|
|
|
|
this.rightDrawerTitle = detail?.title || '查看会议纪要';
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|