Conflicts:
	src/main/java/com/budwk/app/zhgh/democratic/teachercongress/institution/controller/TeacherCongressInstitutionController.java
	src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/basicTable.js
	src/main/resources/views/platform/zhgh/democratic/teachercongress/institution/index.html
This commit is contained in:
zhouhefeng
2026-07-15 11:49:49 +08:00
204 changed files with 5657 additions and 1459 deletions
@@ -419,6 +419,25 @@ layout("/layouts/v4/baseLayout.html"){
},
defaultSelect() {
// 应用中心点击根菜单时会缓存完整应用信息,根菜单配置了href则应优先进入根菜单页面。
try {
const rootApp = JSON.parse(window.sessionStorage.getItem("zhgh_sub_app"))
const currentAppId = GetQueryString("appId")
const hasRootHref = rootApp && typeof rootApp.href === "string" && rootApp.href.trim() !== ""
// 校验缓存应用与当前URL一致,避免复用旧标签页缓存时跳转到其他应用。
if (hasRootHref && String(rootApp.id) === currentAppId) {
this.activeMenuIndex = rootApp.id
this.openedMenus = []
this.$nextTick(() => {
this.menuSelect(this.activeMenuIndex, this.openedMenus)
commonUtil.pjaxPush(getBaseSubAppPath(rootApp.href))
})
return
}
} catch (e) {
// 根菜单缓存缺失或格式异常时,继续使用子菜单href作为默认入口。
}
// 查找第一个有href的子菜单
function findFirstChildWithHref(menus) {
for (const menu of menus) {
@@ -276,11 +276,12 @@ layout("/layouts/platform.html"){
if (resp.code === 0) {
this.$message.success(resp.msg)
this.updateDialog = false
this.pageData()
}
})
})
.finally(() => {
this.updateLoading = false
.finally(() => {
this.updateLoading = false
})
})
},
listUnit() {
@@ -19,7 +19,7 @@ const branchUnionGroupManage = {
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter); margin-top: 10px">
<el-table :data="tableData" border>
<el-table :data="tableData" :height="table_height ? Math.max(200, table_height - 90) : null" border>
<el-table-column type="index" width="50" label="序号"></el-table-column>
<el-table-column prop="code" label="小组编码" width="120px"></el-table-column>
<el-table-column prop="name" label="小组名称" width="200px"></el-table-column>
@@ -85,6 +85,11 @@ const branchUnionGroupManage = {
union_id: {
type: String,
required: true
},
// 工会小组列表包含分页,父页面传入高度后预留分页区域。
table_height: {
type: Number,
default: null
}
},
data() {
@@ -16,7 +16,7 @@ const branchUnionPartUnitManage = {
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter); margin-top: 10px">
<el-table :data="tableData" border>
<el-table :data="tableData" :height="table_height ? Math.max(200, table_height - 40) : null" border>
<el-table-column type="index" width="50" label="序号"></el-table-column>
<el-table-column prop="unitcode" label="单位编码"></el-table-column>
<el-table-column prop="name" label="单位名称"></el-table-column>
@@ -48,6 +48,11 @@ const branchUnionPartUnitManage = {
union_id: {
type: String,
required: true
},
// 父页面可传入可用高度;默认值保持组件在其他页面的原有展示能力。
table_height: {
type: Number,
default: null
}
},
data() {
@@ -45,7 +45,7 @@ const branchUnionUserManage = {
</el-row>
</el-card>
<el-card shadow="never" style="border: 1px solid var(--border-color-lighter); margin-top: 10px">
<el-table :data="tableData" border size="small">
<el-table :data="tableData" :height="table_height ? Math.max(200, table_height - 40) : null" border size="small">
<el-table-column prop="loginName" label="工号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="mobile" label="联系方式"></el-table-column>
@@ -123,6 +123,11 @@ const branchUnionUserManage = {
union_id: {
type: String,
required: true
},
// 父页面可传入可用高度;默认值保持组件在其他页面的原有展示能力。
table_height: {
type: Number,
default: null
}
},
data() {
@@ -38,6 +38,13 @@ layout("/layouts/platform.html"){
<el-table-column label="身份" prop="roleName" show-overflow-tooltip></el-table-column>
<el-table-column label="入会时间" prop="joinTime" show-overflow-tooltip></el-table-column>
<el-table-column label="退会时间" prop="exitTime" show-overflow-tooltip></el-table-column>
<el-table-column label="退出方式" width="110">
<template v-slot="{row}">
<el-tag :type="row.exitType === 'AUDIT_EXIT' ? 'success' : 'info'" size="mini">
{{ exitTypeName(row) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template v-slot="{row}">
<el-button size="mini" type="primary" @click="onView(row)">查看</el-button>
@@ -76,14 +83,17 @@ layout("/layouts/platform.html"){
async getClubList() {
const resp = await this.$axios.post("/platform/club/infoManage/exitManage/getClubList")
if (resp.code === 0) {
this.clubList = resp.data
this.$set(this, "clubList", resp.data)
}
},
exitTypeName(row) {
return row.exitType === "AUDIT_EXIT" ? "审核退会" : "直接移出"
},
async pageData() {
const resp = await this.$axios.post("/platform/club/infoManage/exitManage/pageData", this.pageForm)
if (resp.code === 0) {
this.tableData = resp.data.list
this.pageForm.totalCount = resp.data.totalCount
this.$set(this, "tableData", resp.data.list)
this.$set(this.pageForm, "totalCount", resp.data.totalCount)
} else {
this.$message.warning(resp.msg)
}
@@ -1,58 +1,60 @@
const clubExitInfo = {
template:
/*language=HTML*/
`
<div>
<div class="process-title">
退会信息
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
</div>
<el-descriptions border>
<el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
<el-descriptions-item label="性别">{{viewData.sex}}</el-descriptions-item>
<el-descriptions-item label="出生年月">{{$moment(viewData.birthday).format('YYYY-MM-DD')}}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{viewData.mobile}}</el-descriptions-item>
<el-descriptions-item label="电子信箱">{{viewData.email}}</el-descriptions-item>
<el-descriptions-item label="分工会">{{viewData.unionName}}</el-descriptions-item>
<el-descriptions-item label="部门" :span="2">{{viewData.unitName}}</el-descriptions-item>
<el-descriptions-item label="职务">{{viewData.position}}</el-descriptions-item>
<el-descriptions-item label="职称" :span="2">{{viewData.technicalTitle}}</el-descriptions-item>
<el-descriptions-item label="学历">{{viewData.education}}</el-descriptions-item>
<el-descriptions-item label="学位" :span="2">{{viewData.academicDegree}}</el-descriptions-item>
<el-descriptions-item label="同时参加其他社团情况" :span="3">{{viewData.sameTimeJoinOtherClubSituation}}</el-descriptions-item>
<el-descriptions-item label="文化、体育方面的活动经历、获奖情况" :span="3">{{viewData.awardsExperience}}</el-descriptions-item>
<el-descriptions-item label="照片" :span="3">
<img :src="viewData.avatar" alt="" style="width: 120px;height: 150px" v-if="viewData.avatar">
</el-descriptions-item>
<el-descriptions-item label="签字" :span="3">
<el-image v-if="viewData.signature" :src="viewData.signature" class="signature-image"></el-image>
<span v-else>暂无</span>
</el-descriptions-item>
</el-descriptions>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})</el-descriptions-item>
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
`,
[
'<div>',
' <div class="process-title">',
' 退会信息',
' <el-link v-if="row.instanceId" type="primary" @click="openChart">点击查看流程图</el-link>',
' </div>',
' <el-descriptions border>',
' <el-descriptions-item label="姓名">{{viewData.userName}}</el-descriptions-item>',
' <el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>',
' <el-descriptions-item label="退出方式">{{getExitTypeName()}}</el-descriptions-item>',
' <el-descriptions-item label="性别">{{viewData.sex}}</el-descriptions-item>',
' <el-descriptions-item label="出生年月">{{$moment(viewData.birthday).format(\'YYYY-MM-DD\')}}</el-descriptions-item>',
' <el-descriptions-item label="联系电话">{{viewData.mobile}}</el-descriptions-item>',
' <el-descriptions-item label="电子信箱">{{viewData.email}}</el-descriptions-item>',
' <el-descriptions-item label="分工会">{{viewData.unionName}}</el-descriptions-item>',
' <el-descriptions-item label="部门" :span="2">{{viewData.unitName}}</el-descriptions-item>',
' <el-descriptions-item label="职务">{{viewData.position}}</el-descriptions-item>',
' <el-descriptions-item label="职称" :span="2">{{viewData.technicalTitle}}</el-descriptions-item>',
' <el-descriptions-item label="学历">{{viewData.education}}</el-descriptions-item>',
' <el-descriptions-item label="学位" :span="2">{{viewData.academicDegree}}</el-descriptions-item>',
' <el-descriptions-item label="同时参加其他社团情况" :span="3">{{viewData.sameTimeJoinOtherClubSituation}}</el-descriptions-item>',
' <el-descriptions-item label="文化、体育方面的活动经历、获奖情况" :span="3">{{viewData.awardsExperience}}</el-descriptions-item>',
' <el-descriptions-item label="照片" :span="3">',
' <img :src="viewData.avatar" alt="" style="width: 120px;height: 150px" v-if="viewData.avatar">',
' </el-descriptions-item>',
' <el-descriptions-item label="签字" :span="3">',
' <el-image v-if="viewData.signature" :src="viewData.signature" class="signature-image"></el-image>',
' <span v-else>暂无</span>',
' </el-descriptions-item>',
' </el-descriptions>',
' <template v-for="task in doneTasks">',
' <div class="mt10">',
' <div class="process-title">{{ task.displayName }}</div>',
' <el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-if="task.ext.isFirstTaskNode">',
' <el-descriptions-item label="申请用户">{{ task.ext.initiatorName }}({{task.ext.initiatorAccount}})</el-descriptions-item>',
' <el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>',
' <el-descriptions-item label="办理结果">',
' <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>',
' </el-descriptions-item>',
' </el-descriptions>',
' <el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>',
' <el-descriptions-item label="办理用户">{{ task.taskFormData.userName }}({{task.taskFormData.loginName}})</el-descriptions-item>',
' <el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>',
' <el-descriptions-item label="办理结果">',
' <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" :value="task.ext.submitType"></dict-tag>',
' </el-descriptions-item>',
' <el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{ task.taskFormData.opinion }}</el-descriptions-item>',
' </el-descriptions>',
' </div>',
' </template>',
' <snaker-chart ref="snakerChartRef"></snaker-chart>',
' <slot></slot>',
'</div>'
].join(''),
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
@@ -63,33 +65,43 @@ const clubExitInfo = {
},
methods: {
onOpen(row) {
this.row = row
this.$set(this, "row", row || {})
this.$set(this, "viewData", {})
this.$set(this, "doneTasks", [])
this.$axios.post("/platform/club/infoManage/exitManage/info", { id: row.id }).then((res) => {
if (res.code === 0) {
this.viewData = res.data
this.$set(this, "viewData", res.data || {})
}
})
this.getDoneTasks()
if (row.instanceId) {
this.getDoneTasks()
}
},
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
this.$set(this, "doneTasks", res.data || [])
}
})
},
openChart(){
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
getExitTypeName() {
const exitType = this.row.exitType || this.viewData.exitType
return exitType === "AUDIT_EXIT" ? "审核退会" : "直接移出"
},
openChart() {
if (this.row.instanceId) {
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
}
}
},
style: /*language=CSS*/ `
.el-descriptions-item__label {
width: 200px;
min-width: 200px;
max-width: 200px;
}
.el-tabs__header {
margin: 0;
}
`
style: /*language=CSS*/ [
'.el-descriptions-item__label {',
' width: 200px;',
' min-width: 200px;',
' max-width: 200px;',
'}',
'.el-tabs__header {',
' margin: 0;',
'}'
].join('')
}
@@ -20,7 +20,12 @@ layout("/layouts/platform.html"){
</el-select>
</search-item>
<search-item label="人员状态:">
<dict-select clearable code="USER_STATE" placeholder="请选择人员状态" v-model="pageForm.userState"></dict-select>
<el-select clearable placeholder="请选择人员状态" v-model="pageForm.userState">
<el-option label="在职" value="在职"></el-option>
<el-option label="在岗" value="在岗"></el-option>
<el-option label="退休" value="退休"></el-option>
<el-option label="不在岗" value="不在岗"></el-option>
</el-select>
</search-item>
<search-item label="性别:">
<el-select clearable filterable placeholder="请选择性别" v-model="pageForm.sex">
@@ -174,7 +174,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名服务单位">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
@@ -114,7 +114,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名服务单位">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
<el-descriptions-item v-if="detailFillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
<el-descriptions-item v-if="detailFillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
@@ -255,7 +255,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="报名旅行社">
<el-form-item label="报名服务单位">
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
</el-form-item>
</el-col>
@@ -112,8 +112,8 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="旅行社名称" prop="travelAgencyId">
<el-select v-model="formData.travelAgencyId" clearable filterable placeholder="请选择旅行社" style="width: 100%">
<el-form-item label="服务单位名称" prop="travelAgencyId">
<el-select v-model="formData.travelAgencyId" clearable filterable placeholder="请选择服务单位" style="width: 100%">
<el-option v-for="item in travelAgencyOptions" :key="item.id" :label="item.agencyName" :value="item.id"></el-option>
</el-select>
</el-form-item>
@@ -187,7 +187,7 @@ layout("/layouts/platform.html"){
<text-editor v-model="formData.lineContent"></text-editor>
</el-form-item>
<el-form-item label="移动端缩略图" prop="mobileThumb">
<!-- 与旅行社管理保持一致:移动端缩略图使用单图上传并保存URL。 -->
<!-- 与服务单位管理保持一致:移动端缩略图使用单图上传并保存URL。 -->
<file-upload
style="--upload-width: 200px;--upload-height:108px"
:upload_number="1"
@@ -191,7 +191,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
<el-descriptions-item label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="服务单位">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="是否携带家属">
{{ familyText() }}
</el-descriptions-item>
@@ -83,6 +83,7 @@ layout("/layouts/platform.html"){
:visible.sync="dialogVisible"
:close-on-click-modal="false"
width="64.8%"
custom-class="tour-setting-dialog"
@closed="destroyEditor">
<el-form :model="formData" :rules="formRules" label-width="120px" ref="form">
<div v-if="title === '新建疗休养配置'" class="tour-setting-inherit">
@@ -145,6 +146,19 @@ layout("/layouts/platform.html"){
<el-input-number v-model="formData.maxGroupPeople" :controls="false" :min="0" :precision="0" placeholder="请输入最多成团人数" style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出行人数指标" prop="travelPeopleQuota">
<el-input-number v-model="formData.travelPeopleQuota" :controls="false" :min="0" :precision="0" placeholder="请输入出行人数指标" style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="24">
<div class="tour-setting-basic-divider"></div>
</el-col>
<el-col :span="12">
<el-form-item label="省内几年去一次" prop="inProvinceYears">
<el-input-number v-model="formData.inProvinceYears" :controls="false" :min="0" :precision="0" placeholder="请输入省内间隔年限" style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="24">
<div class="tour-setting-basic-divider"></div>
</el-col>
@@ -267,6 +281,47 @@ layout("/layouts/platform.html"){
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="人员分配" name="unionQuota">
<div class="tour-tab-fill">
<div class="tour-quota-toolbar">
<div class="tour-quota-stat">
<span>出行人数指标</span>
<strong>{{ travelPeopleQuota }}</strong>
</div>
<div class="tour-quota-stat">
<span>分工会总人数</span>
<strong>{{ branchTotalPersonCount }}</strong>
</div>
<el-input-number
v-model="quotaAllocate.ratio"
:controls="false"
:min="0"
:precision="2"
placeholder="比例"
class="tour-quota-input">
</el-input-number>
<el-button type="primary" size="medium" @click="allocateQuotaByRatio">按比例分配</el-button>
</div>
<el-table
:data="formData.unionQuotas"
border
class="vi-table tour-quota-table tour-tab-table"
empty-text="暂无分工会"
height="100%"
show-summary
:summary-method="unionQuotaSummary"
style="width: 100%">
<el-table-column label="序号" type="index" width="70" align="center" header-align="center"></el-table-column>
<el-table-column label="分工会" prop="unionName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="当前人数" prop="personCount" width="140" align="center" header-align="center"></el-table-column>
<el-table-column label="人员数量" width="180" align="center" header-align="center">
<template slot-scope="{row}">
<el-input-number v-model="row.peopleQuota" :controls="false" :min="0" :precision="0" style="width: 100%"></el-input-number>
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="服务须知" name="notice">
<el-form-item prop="serviceNotice" label-width="0">
<text-editor v-model="formData.serviceNotice"></text-editor>
@@ -317,6 +372,14 @@ layout("/layouts/platform.html"){
callback()
}
}
const checkInProvinceYears = (rule, value, callback) => {
if (value !== null && value !== undefined && value !== ""
&& (!Number.isInteger(Number(value)) || Number(value) < 0)) {
callback(new Error("省内间隔年限必须为非负整数"))
} else {
callback()
}
}
return {
title: "",
dialogVisible: false,
@@ -331,12 +394,17 @@ layout("/layouts/platform.html"){
activityGroupList: [],
formData: {},
lotDeleteList: [],
quotaAllocate: {
ratio: null
},
inheritLoading: false,
formRules: {
year: [{required: true, message: "必填", trigger: ["blur", "change"]}],
configName: [{required: true, message: "必填", trigger: ["blur", "change"]}],
travelPeopleQuota: [{required: true, message: "必填", trigger: ["blur", "change"]}],
minGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
maxGroupPeople: [{validator: checkGroupPeople, trigger: ["blur", "change"]}],
inProvinceYears: [{validator: checkInProvinceYears, trigger: ["blur", "change"]}],
outProvinceRatioType: [{required: true, message: "必填", trigger: ["blur", "change"]}],
outProvinceFixedPeople: [{validator: checkOutProvinceFixedPeople, trigger: ["blur", "change"]}],
cycleStartYear: [{validator: checkCycleYear, trigger: ["blur", "change"]}],
@@ -347,12 +415,117 @@ layout("/layouts/platform.html"){
components: {
"drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue")
},
computed: {
// 出行人数指标统一按非负整数参与页面统计和分配上限校验。
travelPeopleQuota() {
return this.toNonNegativeInteger(this.formData.travelPeopleQuota)
},
// 人员总数使用后端实时统计结果,仅作为按比例分配的计算基数。
branchTotalPersonCount() {
const rows = this.formData.unionQuotas || []
return rows.reduce((sum, row) => sum + this.toNonNegativeInteger(row.personCount), 0)
}
},
watch: {
"formData.travelPeopleQuota": function() {
this.refreshQuotaRatio()
}
},
methods: {
async getActivityGroup() {
const {data} = await this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup")
this.activityGroupList = (data || []).map((item) => {
// 加载分工会人员分配行;新增时传空配置ID,编辑时合并已保存数量。
loadUnionQuotaRows(settingId) {
this.$axios.post(loc() + "/unionQuotaRows", {settingId: settingId || ""}).then((res) => {
if (res.code === 0) {
this.$set(this.formData, "unionQuotas", this.normalizeUnionQuotaRows(res.data || []))
this.refreshQuotaRatio()
} else {
this.$message.warning(res.msg || "查询人员分配失败")
}
})
},
// 将接口和历史数据中的空值规范为非负整数,避免合计结果出现 NaN。
normalizeUnionQuotaRows(rows) {
return (rows || []).map(item => {
return Object.assign({}, item, {
groupId: item.groupId === null || item.groupId === undefined ? "" : String(item.groupId)
peopleQuota: this.toNonNegativeInteger(item.peopleQuota),
personCount: this.toNonNegativeInteger(item.personCount)
})
})
},
toNonNegativeInteger(value) {
const numberValue = parseInt(value, 10)
if (isNaN(numberValue) || numberValue < 0) {
return 0
}
return numberValue
},
toNumber(value) {
const numberValue = parseFloat(value)
return isNaN(numberValue) ? null : numberValue
},
truncateDecimal(value, precision) {
const times = Math.pow(10, precision)
return Math.floor(value * times) / times
},
// 默认比例为出行人数指标除以分工会总人数,并按参考项目保留两位后直接截断。
refreshQuotaRatio() {
if (this.branchTotalPersonCount <= 0 || this.travelPeopleQuota <= 0) {
this.quotaAllocate.ratio = null
return
}
this.quotaAllocate.ratio = this.truncateDecimal(this.travelPeopleQuota / this.branchTotalPersonCount, 2)
},
unionQuotaSummary(param) {
const columns = param.columns || []
const rows = this.formData.unionQuotas || []
return columns.map((column, index) => {
if (index === 0) {
return "合计"
}
if (column.property === "personCount") {
return rows.reduce((sum, row) => sum + this.toNonNegativeInteger(row.personCount), 0)
}
if (column.label === "人员数量") {
return rows.reduce((sum, row) => sum + this.toNonNegativeInteger(row.peopleQuota), 0)
}
return ""
})
},
allocateQuotaByRatio() {
const rows = this.formData.unionQuotas || []
const ratio = this.toNumber(this.quotaAllocate.ratio)
if (!rows.length) {
this.$message.warning("暂无分工会数据")
return
}
if (ratio === null || this.quotaAllocate.ratio === "" || this.quotaAllocate.ratio === undefined) {
this.$message.warning("比例为空,未分配")
return
}
if (ratio < 0) {
this.$message.warning("比例不能为负数")
return
}
// 按比例分配时小数直接舍去,不补余数,保持与参考项目一致。
const nextQuotas = rows.map(row => {
return Math.floor(ratio * this.toNonNegativeInteger(row.personCount))
})
const quotaTotal = nextQuotas.reduce((sum, value) => sum + value, 0)
if (quotaTotal > this.travelPeopleQuota) {
this.$message.warning("当前人员数量合计 " + quotaTotal + ",不能超过出行人数指标 " + this.travelPeopleQuota)
return
}
nextQuotas.forEach((peopleQuota, index) => {
this.$set(rows[index], "peopleQuota", peopleQuota)
})
},
getActivityGroup() {
return this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup").then((res) => {
const data = res.data
this.activityGroupList = (data || []).map((item) => {
return Object.assign({}, item, {
groupId: item.groupId === null || item.groupId === undefined ? "" : String(item.groupId)
})
})
})
},
@@ -378,10 +551,12 @@ layout("/layouts/platform.html"){
year: moment().format("YYYY"),
configName: "",
tourType: "",
travelPeopleQuota: 0,
activityGroupId: "",
sortNo: 0,
minGroupPeople: 0,
maxGroupPeople: 0,
inProvinceYears: 0,
outProvinceYears: 0,
outProvinceRatio: 0,
outProvinceRatioType: "当年报名人数",
@@ -394,6 +569,7 @@ layout("/layouts/platform.html"){
fillBedInfo: true,
enabled: true,
lots: [],
unionQuotas: [],
serviceNotice: ""
}
},
@@ -404,6 +580,7 @@ layout("/layouts/platform.html"){
// 新建时给出默认年度和开关值,减少校工会管理员录入成本。
this.formData = this.defaultFormData()
this.dialogVisible = true
this.loadUnionQuotaRows("")
this.$nextTick(() => this.$refs.form && this.$refs.form.clearValidate())
},
inheritPreviousYearInfo() {
@@ -428,11 +605,19 @@ layout("/layouts/platform.html"){
allowOverReimbursement: !!item.allowOverReimbursement
}
})
// 延用上一年分配数量,但清除原配置和子表ID,保存时生成当前年度数据。
const inheritedUnionQuotas = this.normalizeUnionQuotaRows(previous.unionQuotas || []).map(item => {
return Object.assign({}, item, {
id: "",
settingId: ""
})
})
this.formData = Object.assign(this.defaultFormData(), previous, {
year: String(currentYear),
cycleStartYear: previous.cycleStartYear ? String(previous.cycleStartYear) : "",
cycleEndYear: previous.cycleEndYear ? String(previous.cycleEndYear) : "",
lots: inheritedLots
lots: inheritedLots,
unionQuotas: inheritedUnionQuotas
})
delete this.formData.id
delete this.formData.createdAt
@@ -463,7 +648,9 @@ layout("/layouts/platform.html"){
this.$axios.post(loc() + "/detail", {id: row.id}).then((res) => {
if (res.code === 0) {
this.formData = Object.assign({
travelPeopleQuota: 0,
activityGroupId: "",
inProvinceYears: 0,
outProvinceRatioType: "当年报名人数",
outProvinceFixedPeople: 0,
cycleStartYear: "",
@@ -474,6 +661,7 @@ layout("/layouts/platform.html"){
fillBedInfo: true,
enabled: true,
lots: [],
unionQuotas: [],
serviceNotice: ""
}, res.data || {})
this.formData.year = this.formData.year ? String(this.formData.year) : ""
@@ -491,6 +679,7 @@ layout("/layouts/platform.html"){
this.formData.lots = (this.formData.lots || []).map(item => Object.assign({}, item, {
allowOverReimbursement: !!item.allowOverReimbursement
}))
this.formData.unionQuotas = this.normalizeUnionQuotaRows(this.formData.unionQuotas || [])
this.dialogVisible = true
this.$nextTick(() => this.$refs.form && this.$refs.form.clearValidate())
} else {
@@ -502,6 +691,7 @@ layout("/layouts/platform.html"){
this.$refs.form.validate((valid) => {
if (!valid) return
if (!this.validateLots()) return
if (!this.validateUnionQuotas()) return
this.submitLoading = true
// Nutz 对子表集合按字符串化 JSON 绑定更稳定,和体检项目维护的提交方式保持一致。
const submitData = JSON.parse(JSON.stringify(this.formData))
@@ -509,6 +699,7 @@ layout("/layouts/platform.html"){
submitData.outProvinceFixedPeople = 0
}
submitData.lots = JSON.stringify(this.formData.lots || [])
submitData.unionQuotas = JSON.stringify(this.formData.unionQuotas || [])
submitData.lotDeleteList = JSON.stringify(this.lotDeleteList)
this.$axios.post(loc() + "/doSubmit", submitData).then((res) => {
this.submitLoading = false
@@ -562,6 +753,29 @@ layout("/layouts/platform.html"){
}
return true
},
// 提交前统一人员数量格式,并校验分配合计不超过出行人数指标。
validateUnionQuotas() {
const rows = this.formData.unionQuotas || []
for (let i = 0; i < rows.length; i++) {
const row = rows[i]
if (row.peopleQuota === null || row.peopleQuota === undefined || row.peopleQuota === "") {
row.peopleQuota = 0
}
if (!/^\d+$/.test(String(row.peopleQuota))) {
this.$message.warning("第" + (i + 1) + "行人员数量必须为非负整数")
return false
}
this.$set(row, "peopleQuota", this.toNonNegativeInteger(row.peopleQuota))
}
const quotaTotal = rows.reduce((sum, row) => {
return sum + this.toNonNegativeInteger(row.peopleQuota)
}, 0)
if (quotaTotal > this.travelPeopleQuota) {
this.$message.warning("当前人员数量合计 " + quotaTotal + ",不能超过出行人数指标 " + this.travelPeopleQuota)
return false
}
return true
},
deleteLot(index, row) {
this.$confirm("确定删除该标段吗?", "提示", {
confirmButtonText: "确定",
@@ -593,6 +807,9 @@ layout("/layouts/platform.html"){
destroyEditor() {
this.formData = {}
this.lotDeleteList = []
this.quotaAllocate = {
ratio: null
}
this.inheritLoading = false
this.activeTab = "basic"
}
@@ -627,6 +844,94 @@ layout("/layouts/platform.html"){
border-top: 1px dashed #dcdfe6;
margin: 2px 0 18px;
}
.tour-quota-toolbar {
align-items: center;
display: flex;
flex-shrink: 0;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 10px;
}
.tour-quota-input {
width: 160px;
}
.tour-quota-stat {
align-items: center;
border: 1px solid #dcdfe6;
border-radius: 4px;
display: inline-flex;
gap: 8px;
height: 36px;
padding: 0 10px;
}
.tour-quota-stat span {
color: #606266;
}
.tour-quota-stat strong {
color: #303133;
font-weight: 600;
}
.tour-tab-fill {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.tour-tab-table {
flex: 1;
min-height: 0;
}
.tour-setting-dialog {
display: flex;
flex-direction: column;
height: 85vh;
max-height: 85vh;
}
.tour-setting-dialog .el-dialog__header,
.tour-setting-dialog .el-dialog__footer,
.tour-setting-dialog .el-tabs__header {
flex-shrink: 0;
}
.tour-setting-dialog .el-dialog__body {
flex: 1;
min-height: 0;
overflow: hidden;
padding-bottom: 0;
}
.tour-setting-dialog .el-form,
.tour-setting-dialog .el-tabs {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.tour-setting-dialog .el-tabs {
flex: 1;
}
.tour-setting-dialog .el-tabs__content {
flex: 1;
min-height: 0;
overflow-x: hidden;
overflow-y: auto;
padding: 0 6px 18px 0;
}
.tour-setting-dialog .el-tab-pane {
height: 100%;
}
</style>
<!--#
@@ -154,7 +154,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="报名旅行社">
<el-form-item label="报名服务单位">
<el-input v-model="signupForm.travelAgencyName" :disabled="isDirectFamilyLine(signupForm)" readonly></el-input>
</el-form-item>
</el-col>
@@ -360,7 +360,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="时间标段">{{ lineDetail.lotName || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ lineDetail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="直系亲属线路">{{ isDirectFamilyLine(lineDetail) ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="旅行社">{{ lineDetail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="服务单位">{{ lineDetail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="创建人">{{ lineDetail.creatorName || '' }}</el-descriptions-item>
<el-descriptions-item label="所在单位">{{ lineDetail.unitName || '' }}</el-descriptions-item>
<el-descriptions-item label="是否对外开放">{{ lineDetail.openFlag ? '是' : '否' }}</el-descriptions-item>
@@ -15,11 +15,11 @@ layout("/layouts/platform.html"){
style="width: 100%">
</el-date-picker>
</search-item>
<search-item label="旅行社名称">
<search-item label="服务单位名称">
<el-input
v-model="pageForm.agencyName"
clearable
placeholder="请输入旅行社名称"
placeholder="请输入服务单位名称"
style="width: 100%"
@keyup.enter.native="doSearch">
</el-input>
@@ -50,7 +50,7 @@ layout("/layouts/platform.html"){
</el-card>
<el-card class="mt10" shadow="never">
<table-tool :app="this" label="旅行社列表">
<table-tool :app="this" label="服务单位列表">
<el-button @click="openAdd" size="medium" type="primary">
<i class="el-icon-plus"></i>
新增
@@ -65,8 +65,8 @@ layout("/layouts/platform.html"){
@sort-change="pageOrder">
<el-table-column label="序号" type="index" :index="indexMethod" width="80" align="center" header-align="center"></el-table-column>
<el-table-column label="年度" prop="year" width="110" sortable="custom" align="center" header-align="center"></el-table-column>
<el-table-column label="旅行社编号" prop="agencyCode" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="旅行社名称" prop="agencyName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="服务单位编号" prop="agencyCode" width="120" sortable="custom" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="服务单位名称" prop="agencyName" min-width="220" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="联系人" prop="contactName" width="130" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="联系电话" prop="contactPhone" width="150" align="center" header-align="center" show-overflow-tooltip></el-table-column>
<el-table-column label="激活状态" prop="enabled" width="160" align="center" header-align="center">
@@ -111,15 +111,15 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="旅行社名称" prop="agencyName">
<el-input v-model="formData.agencyName" maxlength="30" show-word-limit placeholder="请输入旅行社名称"></el-input>
<el-form-item label="服务单位名称" prop="agencyName">
<el-input v-model="formData.agencyName" maxlength="30" show-word-limit placeholder="请输入服务单位名称"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="旅行社编号" prop="agencyCode">
<el-input v-model="formData.agencyCode" maxlength="50" placeholder="请输入旅行社编号"></el-input>
<el-form-item label="服务单位编号" prop="agencyCode">
<el-input v-model="formData.agencyCode" maxlength="50" placeholder="请输入服务单位编号"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -248,19 +248,19 @@ layout("/layouts/platform.html"){
}
},
openAdd() {
this.title = "新增旅行社信息"
this.title = "新增服务单位信息"
this.viewMode = false
this.formData = this.emptyForm()
this.dialogVisible = true
this.$nextTick(() => this.$refs.form && this.$refs.form.clearValidate())
},
openEdit(row) {
this.title = "编辑旅行社信息"
this.title = "编辑服务单位信息"
this.viewMode = false
this.loadDetail(row.id)
},
openView(row) {
this.title = "查看旅行社信息"
this.title = "查看服务单位信息"
this.viewMode = true
this.loadDetail(row.id)
},
@@ -191,7 +191,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="出行时段">{{ detail.travelPeriod || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
<el-descriptions-item label="旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="服务单位">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="是否携带家属">
{{ familyText() }}
</el-descriptions-item>
@@ -164,7 +164,7 @@ layout("/layouts/platform.html"){
<el-descriptions-item label="报名线路">{{ detail.lineName || '' }}</el-descriptions-item>
<el-descriptions-item label="线路类型">{{ detail.lineType || '' }}</el-descriptions-item>
<el-descriptions-item label="报名酒店">{{ detail.hotelName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名旅行社">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="报名服务单位">{{ detail.travelAgencyName || '' }}</el-descriptions-item>
<el-descriptions-item label="出行时间">{{ detail.travelPeriod || '' }}</el-descriptions-item>
<el-descriptions-item v-if="fillBedInfo" label="床型">{{ detail.bedType || '' }}</el-descriptions-item>
<el-descriptions-item v-if="fillBedInfo" label="床位信息">{{ detail.bedInfo || '' }}</el-descriptions-item>
@@ -27,8 +27,8 @@ layout("/layouts/platform.html"){
:value="o.id"></el-option>
</el-select>
</search-item>
<search-item label="荣誉级别">
<el-select v-model="pageForm.honorLevel" placeholder="请选择荣誉级别" clearable>
<search-item label="荣誉类别">
<el-select v-model="pageForm.honorLevel" placeholder="请选择荣誉类别" clearable>
<el-option v-for="o in honorLevelList" :key="o.id" :label="o.name" :value="o.id"></el-option>
</el-select>
</search-item>
@@ -77,7 +77,7 @@ layout("/layouts/platform.html"){
sortable></el-table-column>
<!--<el-table-column prop="prizeDesc" label="奖项说明" ></el-table-column>-->
<el-table-column prop="typeName" label="荣誉类型"></el-table-column>
<el-table-column prop="levelName" label="级别"
<el-table-column prop="levelName" label="荣誉类别"
sortable></el-table-column>
<el-table-column prop="grantUnit" label="授予单位"
show-overflow-tooltip></el-table-column>
@@ -185,7 +185,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-col>-->
<el-col :span="6">
<el-form-item label="级别">{{ viewData.levelName }}</el-form-item>
<el-form-item label="荣誉类别">{{ viewData.levelName }}</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="授予单位">{{ viewData.grantUnit }}</el-form-item>
@@ -303,9 +303,9 @@ layout("/layouts/platform.html"){
prize +
"&honorLevel=" +
honorLevel +
"&userName" +
"&userName=" +
userName +
"&unitName" +
"&unitName=" +
unitName
},
openEdit(row) {
@@ -96,6 +96,9 @@ layout("/layouts/platform.html"){
{{item.name}}
</el-radio>
</el-radio-group>
<span class="ml10 text-danger" v-if="getProjectTipByProject(formData.reimburseProject)">
{{getProjectTipByProject(formData.reimburseProject)}}
</span>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="经办人">{{formData.userName}}({{formData.loginName}})</el-descriptions-item>
@@ -400,145 +403,6 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="支付信息" :span="3">
<div class="mb10">
<el-button type="primary" size="mini" @click="addPaymentInfo">新增支付信息</el-button>
</div>
<el-table class="payment-info-table" :data="paymentInfoRows" border empty-text="暂无支付信息" style="width: 100%">
<el-table-column label="支付方式" min-width="160">
<template slot-scope="scope">
<el-form-item :prop="'paymentDetails.' + scope.$index + '.paymentWay'"
:rules="paymentDetailRules.paymentWay">
<el-select v-model="scope.row.paymentWay"
clearable
placeholder="请选择支付方式"
style="width: 100%"
@change="handlePaymentWayChange(scope.row)">
<el-option
v-for="item in dict.type.UNION_REIMBURSE_PAYMENT_WAY"
:key="item.code"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="金额" min-width="140">
<template slot-scope="scope">
<el-form-item :prop="'paymentDetails.' + scope.$index + '.money'"
:rules="paymentDetailRules.money">
<el-input v-model="scope.row.money" placeholder="请输入金额"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="付款人" min-width="240">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.payer'"
:rules="paymentDetailRules.payer">
<el-select style="width: 100%"
v-model="scope.row.payer"
@change="payerUserChange(scope.row)"
filterable
clearable
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethodForPayer(scope.row)">
<el-option
v-for="item in scope.row.payerOptions"
:key="item.id"
:label="item.userName+'('+item.loginName+')'+'('+item.unitName+')'"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="户名" min-width="180">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankUserName'"
:rules="paymentDetailRules.bankUserName">
<el-select
v-model="scope.row.bankUserName"
@change="handleBankUserNameChange(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入户名"
style="width: 100%">
<el-option
v-for="(item, index) in getBankHistoryUserNames(scope.row)"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="开户行" min-width="220">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankOfDeposit'"
:rules="paymentDetailRules.bankOfDeposit">
<el-select
v-model="scope.row.bankOfDeposit"
@change="fillBankInfoFromHistory(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入开户行名称"
style="width: 100%">
<el-option
v-for="(item, index) in scope.row.historyData"
:key="index"
:label="item.bankOfDeposit"
:value="item.bankOfDeposit">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="银行卡号" min-width="220">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankCardNumber'"
:rules="paymentDetailRules.bankCardNumber">
<el-select
v-model="scope.row.bankCardNumber"
@change="fillBankInfoFromHistory(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入银行卡号"
style="width: 100%">
<el-option
v-for="(item, index) in scope.row.historyData"
:key="index"
:label="item.bankCardNumber"
:value="item.bankCardNumber">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="120">
<template slot-scope="scope">
<el-button type="text" style="color: #f56c6c;" @click="deletePaymentInfo(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="参加随行人员" :span="3"
v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-form-item prop="participants" label="参加随行人员">
@@ -563,7 +427,8 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-descriptions-item>
<el-descriptions-item :span="3">
<el-descriptions-item :span="3"
v-if="formData.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'">
<template slot="label">
附件
</template>
@@ -619,6 +484,148 @@ layout("/layouts/platform.html"){
type="textarea" :autosize="{ minRows: 4, maxRows: 8}"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<div class="invoice-field-title">支付信息</div>
<div>
<div class="mb10">
<el-button type="primary" size="mini" @click="addPaymentInfo">新增支付信息</el-button>
</div>
<el-table class="payment-info-table" :data="paymentInfoRows" border empty-text="暂无支付信息" style="width: 100%">
<el-table-column label="支付方式" min-width="160">
<template slot-scope="scope">
<el-form-item :prop="'paymentDetails.' + scope.$index + '.paymentWay'"
:rules="paymentDetailRules.paymentWay">
<el-select v-model="scope.row.paymentWay"
clearable
placeholder="请选择支付方式"
style="width: 100%"
@change="handlePaymentWayChange(scope.row)">
<el-option
v-for="item in dict.type.UNION_REIMBURSE_PAYMENT_WAY"
:key="item.code"
:label="item.name"
:value="item.code">
</el-option>
</el-select>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="金额" min-width="140">
<template slot-scope="scope">
<el-form-item :prop="'paymentDetails.' + scope.$index + '.money'"
:rules="paymentDetailRules.money">
<el-input v-model="scope.row.money" placeholder="请输入金额"></el-input>
</el-form-item>
</template>
</el-table-column>
<el-table-column label="付款人" min-width="240">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.payer'"
:rules="paymentDetailRules.payer">
<el-select style="width: 100%"
v-model="scope.row.payer"
@change="payerUserChange(scope.row)"
filterable
clearable
remote
reserve-keyword
placeholder="请输入姓名或工号查询"
:remote-method="createRemoteMethodForPayer(scope.row)">
<el-option
v-for="item in scope.row.payerOptions"
:key="item.id"
:label="item.userName+'('+item.loginName+')'+'('+item.unitName+')'"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="户名" min-width="180">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankUserName'"
:rules="paymentDetailRules.bankUserName">
<el-select
v-model="scope.row.bankUserName"
@change="handleBankUserNameChange(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入户名"
style="width: 100%">
<el-option
v-for="(item, index) in getBankHistoryUserNames(scope.row)"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="开户行" min-width="220">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankOfDeposit'"
:rules="paymentDetailRules.bankOfDeposit">
<el-select
v-model="scope.row.bankOfDeposit"
@change="fillBankInfoFromHistory(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入开户行名称"
style="width: 100%">
<el-option
v-for="(item, index) in scope.row.historyData"
:key="index"
:label="item.bankOfDeposit"
:value="item.bankOfDeposit">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="银行卡号" min-width="220">
<template slot-scope="scope">
<el-form-item v-if="isPrivatePayment(scope.row)"
:prop="'paymentDetails.' + scope.$index + '.bankCardNumber'"
:rules="paymentDetailRules.bankCardNumber">
<el-select
v-model="scope.row.bankCardNumber"
@change="fillBankInfoFromHistory(scope.row)"
clearable
filterable
allow-create
default-first-option
placeholder="请输入银行卡号"
style="width: 100%">
<el-option
v-for="(item, index) in scope.row.historyData"
:key="index"
:label="item.bankCardNumber"
:value="item.bankCardNumber">
</el-option>
</el-select>
</el-form-item>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="120">
<template slot-scope="scope">
<el-button type="text" style="color: #f56c6c;" @click="deletePaymentInfo(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-col>
<el-col :span="24">
<div class="invoice-toolbar">
<div>
@@ -819,7 +826,21 @@ layout("/layouts/platform.html"){
{required: true, message: "请填写联系方式", trigger: ["change", "blur"]},
{pattern: /^(1[3-9]\d{9}|0\d{2,3}-?\d{7,8})$/, message: "请输入正确的联系方式", trigger: "blur"}
],
files: [{required: true, message: "请上传附件", trigger: ["change", "blur"]}],
files: [{
validator: (rule, value, callback) => {
// 慰问项目不展示附件上传,提交时无需校验附件。
if (this.formData.reimburseProject === "UNION_REIMBURSE_PROJECT_1") {
callback()
return
}
if (!value || value.length === 0) {
callback(new Error("请上传附件"))
return
}
callback()
},
trigger: ["change", "blur"]
}],
userSign: [{required: true, message: "请签名", trigger: ["change", "blur"]}],
// certifierUserId: [{required: true, message: "请填写认证人", trigger: ["change", "blur"]}],
@@ -1205,6 +1226,11 @@ layout("/layouts/platform.html"){
this.rebuildInvoiceSummary()
this.normalizeFundBalance()
}
this.$nextTick(() => {
if (this.$refs.formRef) {
this.$refs.formRef.clearValidate("files")
}
})
},
openInvoiceDialog(mode, row, index) {
this.invoiceDialogMode = mode
@@ -1561,10 +1587,10 @@ layout("/layouts/platform.html"){
return new Promise((resolve) => {
this.rebuildInvoiceSummary()
const paymentDetails = this.preparePaymentDetailsForSubmit()
this.$refs.formRef.validate((valid) => {
this.$refs.formRef.validate((valid, invalidFields) => {
if (valid) {
if (!this.validatePaymentDetailsBeforeSubmit(paymentDetails)) {
this.$set(this, "activeTabName", "basic")
this.$set(this, "activeTabName", "invoice")
resolve(false)
return
}
@@ -1581,6 +1607,12 @@ layout("/layouts/platform.html"){
this.normalizeFundBalance()
resolve(true)
} else {
// 支付信息已移至发票信息页,支付明细校验失败时跳转到对应页签。
const paymentDetailInvalid = Object.keys(invalidFields || {})
.some((field) => field.indexOf("paymentDetails.") === 0)
if (paymentDetailInvalid) {
this.$set(this, "activeTabName", "invoice")
}
this.$message.warning("请完善必填信息")
resolve(false)
}
@@ -1592,7 +1624,7 @@ layout("/layouts/platform.html"){
const isValid = await this.validateBeforeSubmit()
if (!isValid) return
this.$confirm("您确定要提交吗?", "提示", {
this.$confirm("您确定要提交吗?审核通过后可前往我的报销打印!", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
@@ -1612,7 +1644,7 @@ layout("/layouts/platform.html"){
const isValid = await this.validateBeforeSubmit()
if (!isValid) return
this.$confirm("您确定要提交吗?", "提示", {
this.$confirm("您确定要提交吗?审核通过后可前往我的报销打印!", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
@@ -1650,6 +1682,14 @@ layout("/layouts/platform.html"){
const project = this.descOptions.find(item => item.reimburseProject === projectCode);
return project ? project.fileDesc : '';
},
// 根据当前选择的报销项目获取管理端配置的提示内容。
getProjectTipByProject(projectCode) {
if (!this.descOptions || !Array.isArray(this.descOptions)) {
return '';
}
const project = this.descOptions.find(item => item.reimburseProject === projectCode);
return project ? project.projectTip : '';
},
// 新建申请默认优先选择分工会经费;若当前用户没有对应权限,则按页面可见权限回退到其它经费来源。
getDefaultFundSource() {
if (this.$auth.hasPermission("unionReimburse.fgh")) {
@@ -62,11 +62,17 @@ layout("/layouts/platform.html"){
</el-table-column>
<el-table-column prop="reimburseProject" label="报销项目" sortable="custom">
<template slot-scope="{row}">
<span v-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">慰问</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_2'">文体活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_3'">日常活动</span>
<span v-else-if="row.reimburseProject === 'UNION_REIMBURSE_PROJECT_4'">专项活动</span>
<span v-else>{{ row.reimburseProject }}</span>
<el-select v-if="isAdmin && row.reimburseProject !== 'UNION_REIMBURSE_PROJECT_1'"
:value="row.reimburseProject"
size="mini"
style="width: 120px"
@change="updateReimburseProject(row, $event)">
<el-option v-for="item in activityReimburseProjectOptions"
:key="item.code"
:label="item.name"
:value="item.code"></el-option>
</el-select>
<span v-else>{{ getReimburseProjectName(row.reimburseProject) }}</span>
</template>
</el-table-column>
<el-table-column label="备注">
@@ -106,6 +112,7 @@ layout("/layouts/platform.html"){
<el-form :model="editFormData" :rules="editFormRules" ref="editForm" label-width="120px">
<el-form-item label="实际报销金额" prop="realMoney">
<el-input v-model="editFormData.realMoney" placeholder="请输入实际报销金额"></el-input>
<div class="text-muted mt5">申请金额:{{ editFormData.maxMoney }}</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -137,7 +144,8 @@ layout("/layouts/platform.html"){
editDialogVisible: false,
editFormData: {
realMoney: '',
id: '' // 报销记录ID
id: '', // 报销记录ID
maxMoney: '0.00' // 申请金额上限
},
editFormRules: {
realMoney: [
@@ -151,12 +159,50 @@ layout("/layouts/platform.html"){
computed: {
isAdmin() {
return this.$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])
},
activityReimburseProjectOptions() {
const activityProjectCodes = [
"UNION_REIMBURSE_PROJECT_2",
"UNION_REIMBURSE_PROJECT_3",
"UNION_REIMBURSE_PROJECT_4"
]
return (this.dict.type.UNION_REIMBURSE_PROJECT || [])
.filter((item) => activityProjectCodes.includes(item.code))
}
},
methods: {
formatCreateTime(value) {
return value && this.$moment(value).isValid() ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : ""
},
getReimburseProjectName(reimburseProject) {
const project = (this.dict.type.UNION_REIMBURSE_PROJECT || [])
.find((item) => item.code === reimburseProject)
return project ? project.name : reimburseProject
},
async updateReimburseProject(row, reimburseProject) {
if (reimburseProject === row.reimburseProject) {
return
}
try {
await this.$confirm("确定修改该记录的报销项目吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
const res = await this.$axios.post("/platform/unionReimburse/collect/updateReimburseProject", {
id: row.id,
reimburseProject: reimburseProject
})
if (res.code === 0) {
this.$set(row, "reimburseProject", reimburseProject)
this.$message.success("报销项目修改成功")
} else {
this.$message.error(res.msg)
}
} catch (error) {
// 取消确认时保持列表原项目,不修改页面数据。
}
},
onView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
@@ -179,8 +225,10 @@ layout("/layouts/platform.html"){
},
openEdit(row) {
// 初始化编辑表单数据
this.editFormData.id = row.id;
this.editFormData.realMoney = row.realMoney || '';
const applyMoney = row.money != null ? row.money : row.condolenceMoney
this.$set(this.editFormData, "id", row.id)
this.$set(this.editFormData, "realMoney", row.realMoney || '')
this.$set(this.editFormData, "maxMoney", Number(applyMoney || 0).toFixed(2))
this.editDialogVisible = true;
},
@@ -195,6 +243,10 @@ layout("/layouts/platform.html"){
saveFinallyMoney() {
this.$refs.editForm.validate((valid) => {
if (valid) {
if (Number(this.editFormData.realMoney) > Number(this.editFormData.maxMoney)) {
this.$message.error("实际报销金额不能超过申请金额:" + this.editFormData.maxMoney)
return
}
this.$axios.post("/platform/unionReimburse/collect/updateActuallyAmount", {
id: this.editFormData.id,
realMoney: this.editFormData.realMoney
@@ -14,6 +14,10 @@ const basicForm = {
<el-input type="text" v-model="formData.fileDesc" maxlength="50"
placeholder="请填写附件说明"></el-input>
</el-form-item>
<el-form-item label="报销项目提示" prop="projectTip">
<el-input type="textarea" v-model="formData.projectTip" maxlength="500" show-word-limit
placeholder="请填写报销项目提示"></el-input>
</el-form-item>
</el-form-item>
</el-form>
@@ -84,6 +84,7 @@ layout("/layouts/platform.html"){
{prop: 'code', label: '项目编码'},
{prop: 'name', label: '项目名称'},
{prop: 'fileDesc', label: '附件说明'},
{prop: 'projectTip', label: '报销项目提示'},
// {prop: 'isUploadFile', label: '是否上传附件'},
],
}
@@ -12,6 +12,7 @@ const PROPOSAL_INFO = {
</h3>
<el-descriptions :column="3" border>
<el-descriptions-item label="提案编号">{{ viewData.code }}</el-descriptions-item>
<el-descriptions-item label="立案编号">{{ viewData.caseFilingCode || '暂无' }}</el-descriptions-item>
<el-descriptions-item label="提案人">{{viewData.createUserName }}</el-descriptions-item>
<el-descriptions-item label="提案时间">{{ viewData.createTime }}</el-descriptions-item>
<el-descriptions-item label="教代会届次"> {{ viewData.sessionName || '暂无' }}</el-descriptions-item>
@@ -87,7 +88,8 @@ const PROPOSAL_INFO = {
<div style="display: flex;justify-content: center">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
<template v-if="row.caseFilingType">
<!-- 普通提案/重点提案暂不展示,历史数据仍保留。 -->
<template v-if="false">
(
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
@@ -107,9 +109,22 @@ const PROPOSAL_INFO = {
</div>
</el-dialog>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
<!--审核信息采用手风琴展示,同一时间最多展开一条记录,避免流程较长时页面内容一次性全部铺开。-->
<template v-if="doneTasks.length">
<div class="process-title">审核信息</div>
<el-collapse v-model="activeTaskId" accordion>
<el-collapse-item v-for="task in doneTasks" :key="task.id" :name="task.id">
<template slot="title">
<!--折叠标题使用独立的单行布局,避免复用 process-title 后产生外边距和高度冲突。-->
<div style="display: flex;align-items: center;justify-content: space-between;width: 100%;min-width: 0;padding-left: 10px">
<span style="overflow: hidden;text-overflow: ellipsis;white-space: nowrap;font-size: 15px;font-weight: 600">
{{ task.displayName }}
</span>
<span style="flex-shrink: 0;margin-right: 8px;color: var(--color-primary);font-weight: 400">
{{ activeTaskId === task.id ? '收起' : '展开' }}
</span>
</div>
</template>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
@@ -154,7 +169,8 @@ const PROPOSAL_INFO = {
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.ext.tf_caseFilingResult"></dict-tag>
<template v-if="task.ext.tf_caseFilingType">
<!-- 普通提案/重点提案暂不展示,历史流程变量仍保留。 -->
<template v-if="false">
(
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="task.ext.tf_caseFilingType"></dict-tag>
@@ -200,7 +216,8 @@ const PROPOSAL_INFO = {
<div v-html="task.taskFormData.tf_opinion"></div>
</el-descriptions-item>
</el-descriptions>
</div>
</el-collapse-item>
</el-collapse>
</template>
<slot></slot>
@@ -215,6 +232,7 @@ const PROPOSAL_INFO = {
return {
viewData: {},
doneTasks: [],
activeTaskId: null,
row: null,
viewDialogVisible: false
}
@@ -224,6 +242,9 @@ const PROPOSAL_INFO = {
onOpen(row) {
this.row = row
this.visible = true
// 切换提案时先清空上一条提案的审核记录和展开状态,避免异步加载期间展示旧数据。
this.doneTasks = []
this.activeTaskId = null
this.getInfo()
this.getDoneTasks()
},
@@ -249,9 +270,12 @@ const PROPOSAL_INFO = {
getDoneTasks() {
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
if (res.code === 0) {
this.doneTasks = res.data
const tasks = res.data || []
this.doneTasks = tasks
// 审核记录加载完成后默认全部折叠,由用户按需展开查看。
this.activeTaskId = null
// 通知外层页面已办节点数据已加载完成,便于当前环节做表单回显。
this.$emit("done-tasks", res.data)
this.$emit("done-tasks", tasks)
}
})
},
@@ -15,10 +15,10 @@ layout("/layouts/platform.html"){
<table-tool>
<el-button type="primary" size="mini" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" border stripe>
<el-table :data="tableData" border stripe @sort-change="pageOrder">
<el-table-column label="序号" type="index" :index="indexMethod" width="50px"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="code" label="编码"></el-table-column>
<el-table-column prop="name" label="名称" sortable="custom"></el-table-column>
<el-table-column prop="code" label="编码" sortable="custom"></el-table-column>
<el-table-column label="操作" width="150px">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
@@ -23,12 +23,12 @@ layout("/layouts/platform.html"){
<table-tool>
<el-button type="primary" size="small" icon="el-icon-refresh" @click="syncSysUnit">同步系统单位</el-button>
</table-tool>
<el-table :data="tableData" border ref="tableRef" height="100%">
<el-table :data="tableData" border ref="tableRef" height="100%" @sort-change="pageOrder">
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></el-table-column>
<el-table-column prop="name" label="单位名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="code" label="单位编码" width="150px"></el-table-column>
<el-table-column prop="name" label="单位名称" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column prop="code" label="单位编码" sortable="custom" width="150px"></el-table-column>
<!-- <el-table-column prop="branchSchoolLeader" label="分管校领导及联系方式" width="180px"></el-table-column>-->
<el-table-column prop="unitLeader" label="单位领导及联系方式" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column prop="unitLeader" label="单位领导及联系方式" sortable="custom" width="180px" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="350px">
<template slot-scope="{row}">
<!-- <el-button size="mini" type="primary" @click="$refs.userRef.onOpen(row.id,true)">设置分管校领导</el-button>-->
@@ -196,26 +196,26 @@ layout("/layouts/platform.html"){
</div>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="danger">否</el-tag>
</template>
</el-table-column>
<el-table-column label="主办单位" prop="masterUnitName" show-overflow-tooltip></el-table-column>
<el-table-column label="协办单位" prop="slaveUnitNames" show-overflow-tooltip></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column label="主办单位" prop="masterUnitName" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="协办单位" prop="slaveUnitNames" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
@@ -88,7 +88,7 @@ layout("/layouts/platform.html"){
<div style="flex: 1;display: flex;gap: 5px;">
<el-tag
v-for="item in typeOptions"
:key="item.code"
:key="item.id"
:effect="pageForm.typeIds && pageForm.typeIds.includes(item.id) ? 'dark':'plain'"
@click="tagToggle('typeIds',item.id)"
>
@@ -125,6 +125,7 @@ layout("/layouts/platform.html"){
<el-button type="primary" size="small" @click="exportAllProposalFeedBackAsZip">导出反馈表压缩包
</el-button>
<el-button type="primary" size="small" @click="exportSummaryAsExcel">导出汇总表</el-button>
<el-button type="primary" size="small" @click="exportUndertakeUnitTablesAsZip">导出承办单位表压缩包</el-button>
<!-- <el-button type="primary" size="small" @click="exportProposalRegisterSummaryAsExcel">导出立案汇总表-->
<el-button type="primary" size="small" @click="exportCustomAsExcel">自定义导出</el-button>
</table-tool>
@@ -137,6 +138,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -204,6 +206,7 @@ layout("/layouts/platform.html"){
},
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name"},
{label: "提案人", prop: "createUserName"},
{label: "提案类别", prop: "typeName"},
@@ -289,6 +292,15 @@ layout("/layouts/platform.html"){
pageForm: JSON.stringify(this.pageForm)
})
},
exportUndertakeUnitTablesAsZip() {
if (!this.pageForm.sessionId) {
this.$message.warning("请选择教代会")
return
}
this.$downLoad(loc() + "/exportUndertakeUnitTablesAsZip", {
pageForm: JSON.stringify(this.pageForm)
})
},
exportProposalRegisterSummaryAsExcel() {
this.$downLoad("/platform/proposal/export/comprehensive/exportProposalRegisterSummaryAsExcel", {
pageForm: JSON.stringify(this.pageForm)
@@ -312,15 +324,25 @@ layout("/layouts/platform.html"){
},
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (!this.pageForm.sessionId) {
this.$set(this, "typeOptions", [])
return Promise.resolve()
}
return this.$axios.post(loc() + "/listSessionProposalTypes", {
sessionId: this.pageForm.sessionId
}).then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
this.$set(this, "typeOptions", res.data)
}
})
},
async meetingChange(val) {
this.pageForm.delegationId = null
meetingChange(val) {
// 切换届次后旧类别不再适用,需清空选择并加载当前届次类别
this.$set(this.pageForm, "typeIds", [])
this.$set(this, "typeOptions", [])
this.listProposalType()
this.$set(this.pageForm, "delegationId", null)
this.listDelegation()
},
listDelegation() {
@@ -333,9 +355,10 @@ layout("/layouts/platform.html"){
listSession() {
this.$axios.post("/platform/proposal/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this, "sessionOptions", res.data)
if (this.sessionOptions && this.sessionOptions.length > 0) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.listProposalType()
this.listDelegation()
this.pageData()
}
@@ -378,7 +401,6 @@ layout("/layouts/platform.html"){
this.listUnderTake()
this.listUnion()
this.listUnit()
this.listProposalType()
}
})
</script>
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
@@ -31,7 +31,8 @@ layout("/layouts/platform.html"){
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<style>
@@ -204,11 +204,12 @@ layout("/layouts/platform.html"){
</div>
<el-button size="mini" type="primary" @click="exportStatistics">导出统计数据</el-button>
</div>
<el-table :data="statisticsRows" border stripe style="width: 100%" v-loading="tableLoading">
<el-table-column prop="dimension" label="统计维度" width="180"></el-table-column>
<el-table-column prop="itemName" label="分类项" min-width="260" show-overflow-tooltip></el-table-column>
<el-table-column prop="count" label="数量" width="120"></el-table-column>
<el-table-column prop="rate" label="占比" width="120"></el-table-column>
<el-table :data="statisticsRows" border stripe style="width: 100%" v-loading="tableLoading"
@sort-change="statisticsOrder">
<el-table-column prop="dimension" label="统计维度" sortable="custom" width="180"></el-table-column>
<el-table-column prop="itemName" label="分类项" sortable="custom" min-width="260" show-overflow-tooltip></el-table-column>
<el-table-column prop="count" label="数量" sortable="custom" width="120"></el-table-column>
<el-table-column prop="rate" label="占比" sortable="custom" width="120"></el-table-column>
</el-table>
</el-card>
@@ -220,14 +221,15 @@ layout("/layouts/platform.html"){
</div>
<el-button size="mini" type="primary" @click="exportAnalysis">导出分析数据</el-button>
</div>
<el-table :data="analysisRows" border stripe style="width: 100%" v-loading="tableLoading">
<el-table-column prop="dimension" label="统计维度" width="160"></el-table-column>
<el-table-column prop="total" label="总量" width="100"></el-table-column>
<el-table-column prop="categoryCount" label="分类数量" width="120"></el-table-column>
<el-table-column prop="topItem" label="最高项" min-width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="topCount" label="最高数量" width="120"></el-table-column>
<el-table-column prop="topRate" label="最高占比" width="120"></el-table-column>
<el-table-column prop="analysis" label="分析结论" min-width="320" show-overflow-tooltip></el-table-column>
<el-table :data="analysisRows" border stripe style="width: 100%" v-loading="tableLoading"
@sort-change="analysisOrder">
<el-table-column prop="dimension" label="统计维度" sortable="custom" width="160"></el-table-column>
<el-table-column prop="total" label="总量" sortable="custom" width="100"></el-table-column>
<el-table-column prop="categoryCount" label="分类数量" sortable="custom" width="120"></el-table-column>
<el-table-column prop="topItem" label="最高项" sortable="custom" min-width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="topCount" label="最高数量" sortable="custom" width="120"></el-table-column>
<el-table-column prop="topRate" label="最高占比" sortable="custom" width="120"></el-table-column>
<el-table-column prop="analysis" label="分析结论" sortable="custom" min-width="320" show-overflow-tooltip></el-table-column>
</el-table>
</el-card>
@@ -283,7 +285,11 @@ layout("/layouts/platform.html"){
return {
pageForm: {
sessionId: "",
dimension: ""
dimension: "",
statisticsOrderName: "",
statisticsOrderBy: "",
analysisOrderName: "",
analysisOrderBy: ""
},
dimensionOptions: [
{label: "提案人单位", value: "提案人单位"},
@@ -320,6 +326,18 @@ layout("/layouts/platform.html"){
this.listSession()
},
methods: {
// 统计数据表使用独立排序参数,避免与分析数据表的排序状态相互覆盖。
statisticsOrder(column) {
this.pageForm.statisticsOrderName = column.prop
this.pageForm.statisticsOrderBy = column.order
this.doSearch()
},
// 分析数据表使用独立排序参数,两个接口刷新时分别应用各自白名单。
analysisOrder(column) {
this.pageForm.analysisOrderName = column.prop
this.pageForm.analysisOrderBy = column.order
this.doSearch()
},
toggleChartView() {
this.showChart = !this.showChart
if (this.showChart) {
@@ -89,6 +89,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -206,6 +206,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -214,6 +215,11 @@ layout("/layouts/platform.html"){
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
<!-- 立案类型在数据库中保存字典编码,列表统一转换为中文名称展示。 -->
<template v-else-if="column.prop === 'caseFilingType'" scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
</template>
<template v-else-if="column.prop === 'merge'" scope="{row}">
<el-tag v-if="row.merge" size="small">是</el-tag>
<el-tag v-else type="warning" size="small">否</el-tag>
@@ -14,7 +14,8 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10">
<table-tool label="代表团列表" :columns.sync="tableColumns"></table-tool>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id" show-summary>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id"
show-summary @sort-change="pageOrder">
<el-table-column
:index="indexMethod"
label="序号"
@@ -28,6 +29,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -61,6 +63,30 @@ layout("/layouts/platform.html"){
</div>
</el-dialog>
</div>
<!-- 提案明细组件模板独立放在页面中,避免在JavaScript中使用模板字符串。 -->
<script type="text/x-template" id="proposal-table-template" nonce="${cspNonce!}">
<div>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id"
@sort-change="pageOrder">
<el-table-column label="序号" width="50px" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable="custom" width="200px"></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom"></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="届次" prop="sessionName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="当前节点" prop="curTaskName" sortable="custom"></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="$emit('view-single-proposal',row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
</script>
<script nonce="${cspNonce!}">
<!--#include("proposalTable.js"){}#-->
<!--#include("../../common/info.js"){}#-->
@@ -128,7 +154,9 @@ layout("/layouts/platform.html"){
pageData() {
this.$axios
.post(loc() + "/pageData", {
sessionId: this.sessionId
sessionId: this.sessionId,
pageOrderName: this.pageForm.pageOrderName,
pageOrderBy: this.pageForm.pageOrderBy
})
.then((res) => {
if (res.code === 0) {
@@ -1,24 +1,6 @@
const PROPOSAL_TABLE = {
template: `
<div>
<el-table :data="tableData" ref="tableRef" header-align="center" style="width: 100%" row-key="id" @sort-change="pageOrder">
<el-table-column label="序号" width="50px" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="200px"></el-table-column>
<el-table-column label="提案名称" prop="name"></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="当前节点" prop="curTaskName"></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="{row}">
<el-button size="mini" type="primary" @click="$emit('view-single-proposal',row)">查看</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
`,
// 组件模板由页面中的text/x-template节点提供,避免使用JavaScript模板字符串。
template: "#proposal-table-template",
props: {
sessionId: {
type: String,
@@ -94,35 +94,35 @@ layout("/layouts/platform.html"){
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="120px" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" width="120px" sortable="custom"></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="届次" prop="sessionName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="立案类型" prop="caseFilingType">
<el-table-column label="立案类型" prop="caseFilingType" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="merge">
<el-table-column label="是否并案" prop="merge" sortable="custom">
<template slot-scope="{row}">
<el-tag v-if="row.merge" size="small">是</el-tag>
<el-tag v-else type="warning" size="small">否</el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="undertakeUnits" show-overflow-tooltip>
<el-table-column label="承办单位" prop="undertakeUnits" sortable="custom" show-overflow-tooltip>
<template slot-scope="{row}">
{{ getUndertakeDisplay(row) }}
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
@@ -24,19 +24,19 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<el-table :data="tableData">
<el-table :data="tableData" @sort-change="pageOrder">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable="custom"></el-table-column>
<el-table-column label="主办提案">
<el-table-column label="提案数量" prop="masterSum" sortable></el-table-column>
<el-table-column label="已答复" prop="masterReplySum" sortable></el-table-column>
<el-table-column label="未答复" prop="masterNoReplySum" sortable></el-table-column>
<el-table-column label="提案数量" prop="masterSum" sortable="custom"></el-table-column>
<el-table-column label="已答复" prop="masterReplySum" sortable="custom"></el-table-column>
<el-table-column label="未答复" prop="masterNoReplySum" sortable="custom"></el-table-column>
</el-table-column>
<el-table-column label="协办提案">
<el-table-column label="提案数量" prop="slaveSum" sortable></el-table-column>
<el-table-column label="已答复" prop="slaveReplySum" sortable v-if="slaveNeedReply"></el-table-column>
<el-table-column label="未答复" prop="slaveNoReplySum" sortable v-if="slaveNeedReply"></el-table-column>
<el-table-column label="提案数量" prop="slaveSum" sortable="custom"></el-table-column>
<el-table-column label="已答复" prop="slaveReplySum" sortable="custom" v-if="slaveNeedReply"></el-table-column>
<el-table-column label="未答复" prop="slaveNoReplySum" sortable="custom" v-if="slaveNeedReply"></el-table-column>
</el-table-column>
</el-table>
</el-card>
@@ -22,14 +22,14 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<el-table :data="tableData">
<el-table :data="tableData" @sort-change="pageOrder">
<el-table-column label="序号" type="index" width="50"></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable></el-table-column>
<el-table-column label="主办提案数" prop="masterSum" sortable></el-table-column>
<el-table-column label="协办提案数" prop="slaveSum" sortable></el-table-column>
<el-table-column label="单位名称" prop="unitName" width="400" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案总数" prop="sum" sortable="custom"></el-table-column>
<el-table-column label="主办提案数" prop="masterSum" sortable="custom"></el-table-column>
<el-table-column label="协办提案数" prop="slaveSum" sortable="custom"></el-table-column>
<template v-for="dict in dict.type.PROPOSAL_FEEDBACK">
<el-table-column :label="dict.label" :prop="dict.code" sortable></el-table-column>
<el-table-column :label="dict.label" :prop="dict.code" sortable="custom"></el-table-column>
</template>
</el-table>
</el-card>
@@ -96,29 +96,29 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="danger">否</el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="undertakeUnits" show-overflow-tooltip>
<el-table-column label="承办单位" prop="undertakeUnits" sortable="custom" show-overflow-tooltip>
<template slot-scope="{row}">
{{ getUndertakeDisplay(row) }}
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
@@ -76,25 +76,25 @@ layout("/layouts/platform.html"){
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="warning">否</el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
@@ -9,7 +9,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<search @search="doSearch">
<search-item label="教代会">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.sessionId">
<el-select @change="meetingChange" clearable filterable placeholder="所属教代会" v-model="pageForm.searchSessionId">
<el-option :key="item.id" :label="item.fullName" :value="item.id" v-for="item in sessionOptions"></el-option>
</el-select>
</search-item>
@@ -70,24 +70,24 @@ layout("/layouts/platform.html"){
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="danger">否</el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
@@ -157,7 +157,7 @@ layout("/layouts/platform.html"){
this.listDelegation()
},
listDelegation() {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.sessionId }).then((res) => {
this.$axios.post("/platform/proposal/common/listDelegation", { sessionId: this.pageForm.searchSessionId }).then((res) => {
if (res.code === 0) {
this.delegationOptions = res.data
}
@@ -168,7 +168,7 @@ layout("/layouts/platform.html"){
if (res.code === 0) {
this.sessionOptions = res.data
if (this.sessionOptions) {
this.$set(this.pageForm, "sessionId", this.sessionOptions[0].id)
this.$set(this.pageForm, "searchSessionId", this.sessionOptions[0].id)
this.listDelegation()
this.pageData()
}
@@ -58,7 +58,7 @@ layout("/layouts/platform.html"){
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
sortable="custom"
align="center"
header-align="center"
show-overflow-tooltip
@@ -95,7 +95,7 @@ layout("/layouts/platform.html"){
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
sortable="custom"
align="center"
header-align="center"
show-overflow-tooltip
@@ -76,31 +76,31 @@ layout("/layouts/platform.html"){
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="warning">否</el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="反馈评价" prop="tf_feedback" width="150px">
<el-table-column label="反馈评价" prop="tf_feedback" sortable="custom" width="150px">
<template slot-scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK" :value="row.tf_feedback"></dict-tag>
</template>
@@ -70,24 +70,24 @@ layout("/layouts/platform.html"){
<table-tool></table-tool>
<el-table :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom" width="100px" show-overflow-tooltip></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="danger">否</el-tag>
</template>
</el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
@@ -34,6 +34,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -35,6 +35,7 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -48,6 +49,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -99,14 +101,14 @@ layout("/layouts/platform.html"){
</el-radio>
</el-radio-group>
<span class="text-primary ml10" v-if="formData.tf_caseCheckNeedSecondReply">
(请选择需要进入二次答复的承办单位,可多选)
(请选择需要进入二次答复的办理单位,可多选)
</span>
</el-form-item>
<el-form-item
label="答复单位"
prop="tf_secondReplyUnitIds"
v-if="formData.tf_caseCheckNeedSecondReply"
:rules="[{required:formData.tf_caseCheckNeedSecondReply === 1,message:'请选择需要二次答复的承办单位',trigger:['change','blur']}]"
:rules="[{required:formData.tf_caseCheckNeedSecondReply === 1,message:'请选择需要二次答复的办理单位',trigger:['change','blur']}]"
>
<el-select v-model="formData.tf_secondReplyUnitIds" clearable filterable multiple style="width: 100%">
<el-option
@@ -123,7 +125,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<!-- <el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>-->
<!-- <el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>-->
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
@@ -146,6 +148,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -171,6 +174,15 @@ layout("/layouts/platform.html"){
this.listUnion()
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
@@ -242,7 +254,7 @@ layout("/layouts/platform.html"){
})
},
// 二次答复只能选择当前提案已配置的承办单位,避免误选到别的单位。
// 二次答复只能选择当前提案已配置的办理单位,避免误选到别的单位。
loadReplyUnits(proposalId) {
this.$axios.post("/platform/proposal/case/check/listReplyUnits", { proposalId: proposalId }).then((res) => {
if (res.code === 0) {
@@ -44,6 +44,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -100,7 +101,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="doSubmit" size="small" type="primary">提交</el-button>
</el-row>
</div>
@@ -59,6 +59,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
@@ -75,6 +76,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -120,7 +122,8 @@ layout("/layouts/platform.html"){
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
<!-- 普通提案/重点提案暂不展示,保留原字段和处理逻辑,便于兼容历史流程数据。 -->
<el-form-item v-if="false" label="立案类型"
prop="tf_caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingType" size="small">
@@ -130,9 +133,9 @@ layout("/layouts/platform.html"){
</el-radio-group>
</el-form-item>
<el-form-item
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '承办单位' : '主办单位'"
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '办理单位' : '主办单位'"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择承办单位' : '请选择主办单位',trigger:['change','blur']}]"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择办理单位' : '请选择主办单位',trigger:['change','blur']}]"
prop="tf_masterUnitIds"
>
<el-select v-model="formData.tf_masterUnitIds" filterable clearable multiple
@@ -167,7 +170,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
@@ -198,6 +201,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{ label: "提案编号", prop: "code" },
{ label: "立案编号", prop: "caseFilingCode" },
{ label: "提案名称", prop: "name", width: "200px" },
{ label: "提案类别", prop: "typeName" },
{ label: "届次", prop: "sessionName" },
@@ -227,8 +231,17 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
/**
* “作为建议”不再区分主办/协办,只保留承办单位;
* “作为建议”不再区分主办/协办,只保留办理单位;
* 切到“不予立案”等结果时,同时清空已选单位,避免旧值被误提交。
*/
handleCaseFilingResultChange(caseFilingResult) {
@@ -271,7 +284,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(() => {
// “作为建议”统一按承办单位处理,提交时不再携带协办单位数据。
// “作为建议”统一按办理单位处理,提交时不再携带协办单位数据。
const masterUnitIds = this.formData.tf_masterUnitIds || []
const slaveUnitIds = this.formData.tf_caseFilingResult === "CONFIRM_FILING" ? (this.formData.tf_slaveUnitIds || []) : []
// 是否有协办单位
@@ -411,7 +424,7 @@ layout("/layouts/platform.html"){
})
},
// 查询承办单位
// 查询办理单位
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
@@ -31,7 +31,8 @@ const merge = {
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
<!-- 普通提案/重点提案暂不展示,保留原字段和处理逻辑,便于兼容历史流程数据。 -->
<el-form-item v-if="false" label="立案类型"
prop="tf_caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingType" size="small">
@@ -41,9 +42,9 @@ const merge = {
</el-radio-group>
</el-form-item>
<el-form-item
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '承办单位' : '主办单位'"
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '办理单位' : '主办单位'"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择承办单位' : '请选择主办单位',trigger:['change','blur']}]"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择办理单位' : '请选择主办单位',trigger:['change','blur']}]"
prop="tf_masterUnitIds"
>
<el-select v-model="formData.tf_masterUnitIds" filterable clearable multiple style="width: 100%">
@@ -77,7 +78,7 @@ const merge = {
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$emit('close')" size="small">取消</el-button>
<el-button @click="$emit('close')" size="small">返回</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
@@ -104,7 +105,7 @@ const merge = {
methods: {
/**
* 并案审核与单案审核保持同一口径:
* “作为建议”只录入承办单位,不再区分协办单位。
* “作为建议”只录入办理单位,不再区分协办单位。
*/
handleCaseFilingResultChange(caseFilingResult) {
if (caseFilingResult !== "CONFIRM_FILING") {
@@ -132,7 +133,7 @@ const merge = {
}
this.selection.splice(index, 1)
},
// 查询承办单位
// 查询办理单位
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
@@ -59,6 +59,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>-->
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="doUpData">更新</el-button>-->
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
@@ -76,6 +77,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -121,7 +123,15 @@ layout("/layouts/platform.html"){
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
<!-- 立案编号由审核人手工填写,仅确定立案时参与校验和保存。 -->
<el-form-item v-if="formData.tf_caseFilingResult === 'CONFIRM_FILING'"
label="立案编号"
prop="tf_caseFilingCode"
:rules="[{required:true,message:'请填写立案编号',trigger:['change','blur']}]">
<el-input v-model="formData.tf_caseFilingCode" clearable maxlength="20"
show-word-limit placeholder="请输入立案编号"></el-input>
</el-form-item>
<!-- <el-form-item v-if="['CONFIRM_FILING'].includes(formData.tf_caseFilingResult)" label="立案类型"
prop="tf_caseFilingType"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<el-radio-group v-model="formData.tf_caseFilingType" size="small">
@@ -129,11 +139,11 @@ layout("/layouts/platform.html"){
{{item.label}}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form-item>-->
<el-form-item
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '承办单位' : '主办单位'"
:label="formData.tf_caseFilingResult === 'SUGGESTION' ? '办理单位' : '主办单位'"
v-if="['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult)"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择承办单位' : '请选择主办单位',trigger:['change','blur']}]"
:rules="[{required:['CONFIRM_FILING','SUGGESTION'].includes(formData.tf_caseFilingResult),message:formData.tf_caseFilingResult === 'SUGGESTION' ? '请选择办理单位' : '请选择主办单位',trigger:['change','blur']}]"
prop="tf_masterUnitIds"
>
<el-select v-model="formData.tf_masterUnitIds" filterable clearable multiple
@@ -168,7 +178,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
@@ -199,6 +209,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
@@ -222,12 +233,22 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
/**
* “作为建议”场景下只保留承办单位,协办单位和立案类型都要及时清空,
* “作为建议”场景下只保留办理单位,协办单位和立案类型都要及时清空,
* 避免旧表单值跟着一起提交到流程里。
*/
handleCaseFilingResultChange(caseFilingResult) {
if (caseFilingResult !== "CONFIRM_FILING") {
this.$set(this.formData, "tf_caseFilingCode", "")
this.$set(this.formData, "tf_caseFilingType", "")
}
if (caseFilingResult === "SUGGESTION") {
@@ -281,9 +302,10 @@ layout("/layouts/platform.html"){
if (!val || !val.length) {
return
}
// 当前页面需要回显上一环节“提案委员会立案”保存的主办/协办单位或承办单位。
// 当前页面需要回显上一环节“提案委员会立案”保存的主办/协办单位或办理单位。
var data = val[val.length - 1]
this.$set(this.formData, "tf_caseFilingResult", data.ext.tf_caseFilingResult)
this.$set(this.formData, "tf_caseFilingCode", data.ext.tf_caseFilingCode || "")
this.$set(this.formData, "tf_caseFilingType", data.ext.tf_caseFilingType)
this.$set(this.formData, "tf_masterUnitIds", this.normalizeUnitIds(data.ext.tf_masterUnitIds))
this.$set(this.formData, "tf_slaveUnitIds", this.normalizeUnitIds(data.ext.tf_slaveUnitIds))
@@ -296,6 +318,7 @@ layout("/layouts/platform.html"){
proposalId: row.id,
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_caseFilingCode: "",
tf_masterUnitIds: [],
tf_slaveUnitIds: []
}
@@ -311,7 +334,7 @@ layout("/layouts/platform.html"){
cancelButtonText: "取消",
type: "warning"
}).then(() => {
// “作为建议”统一按承办单位处理,提交时不再携带协办单位数据。
// “作为建议”统一按办理单位处理,提交时不再携带协办单位数据。
const masterUnitIds = this.formData.tf_masterUnitIds || []
const slaveUnitIds = this.formData.tf_caseFilingResult === "CONFIRM_FILING" ? (this.formData.tf_slaveUnitIds || []) : []
// 是否有协办单位
@@ -436,7 +459,7 @@ layout("/layouts/platform.html"){
})
},
// 查询承办单位
// 查询办理单位
listUnderTake() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
@@ -28,7 +28,8 @@ layout("/layouts/platform.html"){
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -64,7 +65,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<span slot="footer">
<el-button size="small" @click="jumpDialogVisible = false">取消</el-button>
<el-button size="small" @click="jumpDialogVisible = false">返回</el-button>
<el-button size="small" type="primary" @click="doJump">确定</el-button>
</span>
</el-dialog>
@@ -25,6 +25,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -38,6 +39,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -81,7 +83,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
@@ -106,6 +108,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -121,6 +124,15 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
@@ -25,7 +25,8 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<table-tool>
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -39,6 +40,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -94,7 +96,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
</div>
@@ -118,6 +120,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "是否并案", prop: "merge"},
@@ -134,6 +137,15 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
@@ -196,15 +208,13 @@ layout("/layouts/platform.html"){
})
},
// 获取立案信息
async getCaseInfo(instId) {
const {
data,
code
} = await this.$axios.post('/platform/proposal/feedbackEvaluation/caseInfo', {instId})
if (code === 0) {
return data
}
// 获取立案信息并返回 Promise,供表单初始化按原顺序等待结果。
getCaseInfo(instId) {
return this.$axios.post('/platform/proposal/feedbackEvaluation/caseInfo', {instId}).then((res) => {
if (res.code === 0) {
return res.data
}
})
},
// 教代会
@@ -24,13 +24,13 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code"></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案类别" prop="typeName"></el-table-column>
<el-table-column label="届次" prop="sessionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<el-table-column label="提案编号" prop="code" sortable="custom"></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案类别" prop="typeName" sortable="custom"></el-table-column>
<el-table-column label="届次" prop="sessionName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column prop="curTaskName" label="当前节点" sortable="custom"></el-table-column>
<el-table-column prop="instanceState" label="流程状态" sortable="custom">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
@@ -35,6 +35,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -147,6 +148,74 @@ layout("/layouts/platform.html"){
</guava>
</div>
<script type="text/x-template" id="proposal-invite-seconder-template">
<div>
<search @search="doSearch">
<search-item label="关键字">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入工号或者姓名查询"
clearable></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId"
style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
</search>
<div style="display: flex;column-gap: 50px;">
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div>
<table-tool label="代表数据">
<el-radio-group v-model="pageForm.isInvite" @change="doSearch" size="small"
style="margin-left: 5px;">
<el-radio-button :label="true">已邀请</el-radio-button>
<el-radio-button :label="false">可邀请</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" ref="tableRef" @sort-change="pageOrder" header-align="center"
style="width: 100%" :row-key="getRowKey">
<el-table-column type="selection" reserve-selection
v-if="!pageForm.isInvite"></el-table-column>
<el-table-column label="序号" width="50px" type="index"
:index="indexMethod"></el-table-column>
<el-table-column label="工号" prop="loginName" sortable="custom"></el-table-column>
<el-table-column label="姓名" prop="userName" sortable="custom"></el-table-column>
<el-table-column label="性别" prop="sex" sortable="custom"></el-table-column>
<el-table-column label="单位" prop="unitName" sortable="custom"></el-table-column>
<el-table-column label="分工会" prop="unionName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
</div>
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div v-if="$refs.tableRef">
<table-tool label="当前已选择"></table-tool>
<el-table :data="$refs.tableRef.selection">
<el-table-column label="序号" width="50px" type="index"></el-table-column>
<el-table-column label="工号" prop="loginName" sortable></el-table-column>
<el-table-column label="姓名" prop="userName" sortable></el-table-column>
<el-table-column label="性别" prop="sex" sortable></el-table-column>
<el-table-column label="单位" prop="unitName" sortable></el-table-column>
<el-table-column label="分工会" prop="unionName" sortable></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable></el-table-column>
</el-table>
<el-row type="flex" justify="center" class="p10">
<el-button @click="">取消</el-button>
<el-button @click="invite" type="primary">邀请</el-button>
</el-row>
</div>
</div>
</div>
</div>
</script>
<script nonce="${cspNonce!}">
<!--#include("../../common/info.js"){}#-->
<!--#include("inviteSeconder.js"){}#-->
@@ -1,81 +1,5 @@
const PROPOSAL_INVITE_SECONDER_COMPONENT = {
/*language=HTML*/
template: `
<div>
<search @search="doSearch">
<search-item label="关键字">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入工号或者姓名查询"
clearable></el-input>
</search-item>
<search-item label="代表团">
<el-select clearable filterable placeholder="所属代表团" v-model="pageForm.delegationId"
style="width: 100%">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in delegationOptions"></el-option>
</el-select>
</search-item>
</search>
<div style="display: flex;column-gap: 50px;">
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div>
<table-tool label="代表数据">
<!-- <el-button size="small" @click="invite" type="primary" icon="el-icon-plus"-->
<!-- :disabled="pageForm.isInvite">邀请-->
<!-- </el-button>-->
<el-radio-group v-model="pageForm.isInvite" @change="doSearch" size="small"
style="margin-left: 5px;">
<el-radio-button :label="true">已邀请</el-radio-button>
<el-radio-button :label="false">可邀请</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" ref="tableRef" @sort-change="pageOrder" header-align="center"
style="width: 100%" :row-key="getRowKey">
<el-table-column type="selection" reserve-selection
v-if="!pageForm.isInvite"></el-table-column>
<el-table-column label="序号" width="50px" type="index"
:index="indexMethod"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<!-- <el-table-column label="操作" width="150px">-->
<!-- <template scope="{row}">-->
<!-- <el-button size="mini" type="primary" @click="invite(row)">邀请</el-button>-->
<!-- </template>-->
<!-- </el-table-column>-->
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
</div>
<div style="flex: 1">
<el-divider class="mt10 mb10"></el-divider>
<div v-if="$refs.tableRef">
<table-tool label="当前已选择"></table-tool>
<el-table :data="$refs.tableRef.selection">
<el-table-column label="序号" width="50px" type="index"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
<el-row type="flex" justify="center" class="p10">
<el-button @click="">取消</el-button>
<el-button @click="invite" type="primary">邀请</el-button>
</el-row>
</div>
</div>
</div>
</div>
`,
template: "#proposal-invite-seconder-template",
mixins: [initTableMixins],
data() {
return {
@@ -173,11 +97,13 @@ const PROPOSAL_INVITE_SECONDER_COMPONENT = {
})
},
async getConfig() {
const {code, data} = await this.$axios.post("/platform/proposal/common/config")
if (code === 0) {
this.config = data
}
// 加载附议人数配置,并返回 Promise 保证弹窗按原顺序初始化。
getConfig() {
return this.$axios.post("/platform/proposal/common/config").then((res) => {
if (res.code === 0) {
this.config = res.data
}
})
}
}
}
@@ -36,6 +36,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -49,6 +50,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -85,7 +87,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(4)" size="small" type="info">退回到提案人(不审核)</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人(审核)</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>
@@ -110,6 +112,7 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案人", prop: "createUserName", width: "80px"},
{label: "提案类别", prop: "typeName"},
@@ -133,6 +136,15 @@ layout("/layouts/platform.html"){
this.listUnion()
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
@@ -58,7 +58,8 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never">
<table-tool>
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -72,6 +73,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -119,7 +121,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction('back')" size="small" type="danger">退回提委会立案</el-button>
<el-button @click="handleTaskAction('agree')" size="small" type="primary">同意</el-button>
</el-row>
@@ -144,9 +146,10 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "承办单位", prop: "undertakeUnits", width: "260px"},
{label: "办理单位", prop: "undertakeUnits", width: "260px"},
{label: "是否并案", prop: "merge"},
{label: "当前节点", prop: "curTaskName"},
{label: "审核人", prop: "auditUser"},
@@ -163,9 +166,18 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
/**
* 校领导审批列表需要按立案结果切换承办单位展示口径:
* 确定立案显示主办/协办,作为建议只显示承办单位。
* 校领导审批列表需要按立案结果切换办理单位展示口径:
* 确定立案显示主办/协办,作为建议只显示办理单位。
*/
getUndertakeDisplay(row) {
var masterUnitNames = this.formatUnitNames(row.masterUnitName)
@@ -36,6 +36,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -81,12 +82,12 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end" v-if="row.curTaskCode ==='second'">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回返回</el-button>
<el-button @click="handleTaskAction(20)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
</el-row>
<el-row type="flex" justify="end" v-else>
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="updateSecond(2)" size="small" type="danger">不同意</el-button>
<el-button @click="updateSecond(1)" size="small" type="primary">同意</el-button>
</el-row>
@@ -109,7 +109,8 @@ layout("/layouts/platform.html"){
:prop="column.prop"
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -143,7 +144,7 @@ layout("/layouts/platform.html"){
<proposal-info ref="proposalInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
承办单位意见
办理单位意见
</div>
<el-form :model="formData" ref="formRef" label-width="80px" :rules="formRules" label-suffix="">
<el-form-item label="承办意向" prop="result"
@@ -160,7 +161,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="onAudit()" size="small" type="primary">提交</el-button>
</el-row>
</div>
@@ -208,7 +209,7 @@ layout("/layouts/platform.html"){
{label: "提案类别", prop: "typeName"},
{label: "届次", prop: "sessionName"},
{label: "代表团", prop: "delegationName"},
{label: "建议承办单位", prop: "suggestUnits"},
{label: "建议办理单位", prop: "suggestUnits"},
{label: "意见数", prop: "count"},
{label: "当前节点", prop: "curTaskName"},
{label: "流程状态", prop: "instanceState"}
@@ -45,6 +45,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -83,7 +84,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到提案人</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">不同意</el-button>
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意</el-button>
@@ -54,28 +54,28 @@ layout("/layouts/platform.html"){
:row-key="(val)=>{val.id + val.processInstanceTaskId}"
>
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
<el-table-column label="提案编号" prop="code" sortable></el-table-column>
<el-table-column label="提案名称" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult">
<el-table-column label="提案编号" prop="code" sortable="custom"></el-table-column>
<el-table-column label="提案名称" prop="name" sortable="custom" show-overflow-tooltip></el-table-column>
<el-table-column label="提案人" prop="createUserName" sortable="custom"></el-table-column>
<el-table-column label="代表团" prop="delegationName" sortable="custom"></el-table-column>
<el-table-column label="立案结果" prop="caseFilingResult" sortable="custom">
<template scope="{row}">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" :value="row.caseFilingResult"></dict-tag>
</template>
</el-table-column>
<el-table-column label="是否并案" prop="isConsolidation" width="100">
<el-table-column label="是否并案" prop="isConsolidation" sortable="custom" width="100">
<template scope="{row}">
<el-tag size="mini" v-if="row.isConsolidation" type="success">是</el-tag>
<el-tag size="mini" v-else type="danger">否</el-tag>
</template>
</el-table-column>
<el-table-column label="是否主办" prop="isMasterUnderTake" width="100">
<el-table-column label="是否主办" prop="isMasterUnderTake" sortable="custom" width="100">
<template scope="{row}">
<el-tag v-if="row.isMasterUnderTake" size="mini" type="success">是</el-tag>
<el-tag v-else size="mini" type="info">否</el-tag>
</template>
</el-table-column>
<el-table-column label="承办单位" prop="underTakeName" show-overflow-tooltip></el-table-column>
<el-table-column label="办理单位" prop="underTakeName" show-overflow-tooltip></el-table-column>
<el-table-column label="当前节点" prop="processInstanceNodeName" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" fixed="right" width="100px">
<template scope="{row}">
@@ -105,7 +105,7 @@ layout("/layouts/platform.html"){
<el-divider></el-divider>
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
<el-form-item label="承办单位">
<el-form-item label="办理单位">
<el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item>
<el-form-item label="能否承办" prop="canTake" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
@@ -128,7 +128,7 @@ layout("/layouts/platform.html"){
<!-- </el-form-item>-->
</el-form>
<el-row type="flex" justify="end">
<el-button plain @click="$refs.guava.index()">取消</el-button>
<el-button plain @click="$refs.guava.index()">返回</el-button>
<el-button type="primary" @click="doApproval('DYNAMIC')">提交</el-button>
</el-row>
</div>
@@ -97,6 +97,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool :columns.sync="tableColumns">
<el-button type="primary" size="small" @click="exportList">导出</el-button>
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
@@ -110,6 +111,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -131,7 +133,7 @@ layout("/layouts/platform.html"){
size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="转交" prop="transfer"
<el-table-column label="转交" prop="transfer" sortable="custom"
v-if="pageForm.approval && $auth.hasRoleOr('SYSADMIN,PROPOSAL_UNIT_LEADER')">
<template slot-scope="{row}">
{{row.transferUserName}}
@@ -148,7 +150,7 @@ layout("/layouts/platform.html"){
</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回
</el-button>
<!--承办单位领导、超级管理员才能转办-->
<!--办理单位领导、超级管理员才能转办-->
<el-button v-if="!pageForm.approval && $auth.hasRoleOr('SYSADMIN,PROPOSAL_UNIT_LEADER')"
@click="openTransfer(row)" size="mini" type="primary">转交
</el-button>
@@ -165,7 +167,7 @@ layout("/layouts/platform.html"){
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" label-width="80px" :rules="formRules" label-suffix="">
<el-form-item label="承办单位">
<el-form-item label="办理单位">
<el-input :value="formData.underTakeName" disabled></el-input>
</el-form-item>
<el-form-item label="落实情况" prop="tf_implementState"
@@ -200,7 +202,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
<el-button @click="$refs.guava.index()" size="small">返回</el-button>
<!-- <el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>-->
<el-button @click="handleTaskAction(1)" size="small" type="primary">提交</el-button>
</el-row>
@@ -246,7 +248,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="showTransferDialog = false" size="small">取消</el-button>
<el-button @click="showTransferDialog = false" size="small">返回</el-button>
<el-button @click="handleTransfer" size="small" type="primary">提交</el-button>
</el-row>
</el-dialog>
@@ -265,7 +267,7 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="showReplyEditDialog = false" size="small">取消</el-button>
<el-button @click="showReplyEditDialog = false" size="small">返回</el-button>
<el-button @click="handleReplyEdit" size="small" type="primary">保存</el-button>
</el-row>
</el-dialog>
@@ -287,11 +289,12 @@ layout("/layouts/platform.html"){
return {
tableColumns: [
{label: "提案编号", prop: "code"},
{label: "立案编号", prop: "caseFilingCode"},
{label: "提案名称", prop: "name", width: "200px"},
{label: "提案类别", prop: "typeName"},
{label: "立案结果", prop: "caseFilingResult"},
{label: "是否并案", prop: "merge"},
{label: "承办单位", prop: "underTakeName"},
{label: "办理单位", prop: "underTakeName"},
{label: "承办类型", prop: "underTakeIsMaster"},
{label: "当前节点", prop: "curTaskName"},
{label: "审核人", prop: "auditUser"},
@@ -318,6 +321,15 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportList() {
this.$downLoad(loc() + "/exportList", {
pageForm: JSON.stringify(this.pageForm),
approval: this.pageForm.approval,
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
return item.visible !== false
}))
})
},
openView(row) {
this.$refs.guava.edit(() => {
this.showApprovalForm = false
@@ -37,6 +37,7 @@ layout("/layouts/platform.html"){
:key="column.key"
:min-width="column.width"
:fixed="column.fixed"
sortable="custom"
show-overflow-tooltip
v-for="column in tableColumns"
v-if="column.visible !== false"
@@ -101,7 +101,7 @@ layout("/layouts/platform.html"){
<el-col :span="12">
<el-form-item label="提案类型" prop="typeId">
<el-select v-model="formData.typeId" style="width: 100%">
<el-option :key="item.code" :label="item.name" :value="item.id"
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in typeOptions"></el-option>
</el-select>
</el-form-item>
@@ -134,19 +134,19 @@ layout("/layouts/platform.html"){
<!-- ></el-input>-->
<!-- </el-form-item>-->
<el-form-item label="建议承办单位" prop="suggestUnits" v-if="false">
<el-form-item label="建议办理单位" prop="suggestUnits" v-if="false">
<el-select v-model="formData.suggestUnits" multiple filterable style="width: 100%"
placeholder="请选择建议承办单位">
placeholder="请选择建议办理单位">
<el-option :key="item.id" :label="item.name" :value="item.name"
v-for="item in suggestUnitOptions"></el-option>
</el-select>
</el-form-item>
<el-form-item label="案由" prop="brief">
<text-editor v-model="formData.brief" key="brief" placeholder="案由"></text-editor>
<text-editor v-model="formData.brief" key="brief" top-tip="(提案内容已进入深入调研,具备真实性、广泛性、代表性)"></text-editor>
</el-form-item>
<el-form-item label="建议措施" prop="measures">
<text-editor v-model="formData.measures" key="measures"
placeholder="建议措施"></text-editor>
top-tip="(建议措施内容具体,具备科学性,可执行性)"></text-editor>
</el-form-item>
<el-form-item label="附件上传" prop="files">
<file-upload
@@ -154,6 +154,7 @@ layout("/layouts/platform.html"){
:upload_number="5"
upload_result_category="array"
upload_mode="drag"
:limit_upload_size="false"
complete_result
></file-upload>
</el-form-item>
@@ -269,8 +270,8 @@ layout("/layouts/platform.html"){
delegationId: [{required: true, message: "请选择所属代表团", trigger: ["blur", "change"]}],
sessionId: [{required: true, message: "请选择所属教代会", trigger: ["blur", "change"]}],
committeeId: [{required: true, message: "请选择所属委员会", trigger: ["blur", "change"]}],
typeId: [{required: true, message: "请选择提案类别", trigger: ["blur", "change"]}],
suggestUnits: [{required: true, message: "请选择建议承办单位", trigger: ["blur", "change"]}],
typeId: [{required: true, message: "请选择提案类型", trigger: ["blur", "change"]}],
suggestUnits: [{required: true, message: "请选择建议办理单位", trigger: ["blur", "change"]}],
sign: [{required: true, message: "请扫描二维码进行签字", trigger: ["blur", "change"]}],
excerpt: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
researchFindings: [{required: true, message: "请填写", trigger: ["blur", "change"]}],
@@ -285,7 +286,7 @@ layout("/layouts/platform.html"){
isWriteTime: true,
// 建议承办单位
// 建议办理单位
suggestUnitOptions: []
}
},
@@ -445,9 +446,15 @@ layout("/layouts/platform.html"){
}
},
// 获取提案类别
// 根据当前教代会届次获取允许撰写的提案类型
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (!this.formData.sessionId) {
this.typeOptions = []
return Promise.resolve()
}
return this.$axios.post("/platform/proposal/write/listSessionProposalTypes", {
sessionId: this.formData.sessionId
}).then((res) => {
if (res.code === 0) {
this.typeOptions = res.data
}
@@ -465,6 +472,10 @@ layout("/layouts/platform.html"){
//教代会change
async meetingChange(val) {
// 切换届次后,原提案类型不再有效,需按新届次重新选择
this.$set(this.formData, "typeId", null)
this.typeOptions = []
this.listProposalType()
this.formData.delegationId = null
this.formData.committeeId = null
this.listDelegation()
@@ -474,7 +485,7 @@ layout("/layouts/platform.html"){
},
// 建议承办单位
// 建议办理单位
listSuggestUnit() {
this.$axios.post("/platform/proposal/common/listUnderTake").then((res) => {
if (res.code === 0) {
@@ -505,6 +516,7 @@ layout("/layouts/platform.html"){
this.checkWriteTime()
}
await this.listDelegation()
this.listProposalType()
// await this.listSource()
}
})
@@ -577,7 +589,6 @@ layout("/layouts/platform.html"){
created() {
this.init()
this.listSuggestUnit()
this.listProposalType()
this.getProposalConfig()
}
})
@@ -49,13 +49,13 @@ layout("/layouts/platform.html"){
<el-table-column prop="unionName" label="所属工会"></el-table-column>
<el-table-column prop="unitName" label="所属单位"></el-table-column>
<!-- <el-table-column prop="submitTime" label="投稿时间"></el-table-column>-->
<el-table-column prop="curTaskName" label="当前节点"></el-table-column>
<el-table-column prop="instanceState" label="流程状态">
<template slot-scope="{row}">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</template>
</el-table-column>
<!-- <el-table-column prop="curTaskName" label="当前节点"></el-table-column>-->
<!-- <el-table-column prop="instanceState" label="流程状态">-->
<!-- <template slot-scope="{row}">-->
<!-- <enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"-->
<!-- size="small"></enum-tag>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="操作" fixed="right" width="200px">
<template slot-scope="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
@@ -25,13 +25,14 @@ const HEAD_FORM_TEMPLATE = {
placeholder="请输入工号或者姓名"
style="width: 100%"></user-select>
</el-form-item>
<el-form-item prop="viceUserId" label="副团长">
<user-select v-model="formData.viceUserId"
<el-form-item prop="viceUserIds" label="副团长">
<user-select v-model="formData.viceUserIds"
v-if="headDialogFormVisible"
api="/platform/teacherCongress/delegation/notHeadUser"
:api_params="{sessionId:formData.sessionId,delegationId:formData.delegationId}"
api_input_key_name="keyWord"
:option_list="viceHeadOptions"
:multiple="true"
option_value="userId"
:option_label_func="(item)=>{return item.userName + item.loginName + '(' + item.unitName + ')'}"
placeholder="请输入工号或者姓名"
@@ -70,7 +71,7 @@ const HEAD_FORM_TEMPLATE = {
name: [{required: true, message: "必填", trigger: ["change", "blur"]}],
code: [{required: true, message: "必填", trigger: ["change", "blur"]}],
userId: [{required: true, message: "必填", trigger: ["change", "blur"]}],
//viceUserId: [{required: true, message: "必填", trigger: ["change", "blur"]}],
//viceUserIds: [{required: true, message: "必填", trigger: ["change", "blur"]}],
//contactUserId: [{required: true, message: "必填", trigger: ["change", "blur"]}]
}
}
@@ -84,7 +85,8 @@ const HEAD_FORM_TEMPLATE = {
this.listSession()
this.formData = {
sessionId,
delegationId
delegationId,
viceUserIds: []
}
this.findHeadUser()
},
@@ -97,8 +99,8 @@ const HEAD_FORM_TEMPLATE = {
}).then((res) => {
if (res.code === 0) {
if (res.data) {
this.headOptions = [res.data]
this.$set(this.formData, "userId", res.data.userId)
this.headOptions = res.data
this.$set(this.formData, "userId", res.data.length > 0 ? res.data[0].userId : null)
}
}
})
@@ -108,8 +110,8 @@ const HEAD_FORM_TEMPLATE = {
}).then((res) => {
if (res.code === 0) {
if (res.data) {
this.viceHeadOptions = [res.data]
this.$set(this.formData, "viceUserId", res.data.userId)
this.viceHeadOptions = res.data
this.$set(this.formData, "viceUserIds", res.data.map((item) => item.userId))
}
}
})
@@ -119,8 +121,8 @@ const HEAD_FORM_TEMPLATE = {
}).then((res) => {
if (res.code === 0) {
if (res.data) {
this.contactOptions = [res.data]
this.$set(this.formData, "contactUserId", res.data.userId)
this.contactOptions = res.data
this.$set(this.formData, "contactUserId", res.data.length > 0 ? res.data[0].userId : null)
}
}
})
@@ -6,12 +6,13 @@ const HEAD_TABLE_TEMPLATE = {
</table-tool>
<el-table :data="tableData" border>
<el-table-column type="index" label="序号" width="100px"></el-table-column>
<el-table-column prop="roleName" label="类型"></el-table-column>
<el-table-column prop="loginName" label="工号"></el-table-column>
<el-table-column prop="userName" label="姓名"></el-table-column>
<el-table-column prop="mobile" label="电话"></el-table-column>
<el-table-column label="操作" width="100px">
<template scope="scope">
<el-link type="danger" @click="doDelete(scope.row.userId)">删除</el-link>
<el-link type="danger" @click="doDelete(scope.row.userId, scope.row.roleType)">删除</el-link>
</template>
</el-table-column>
</el-table>
@@ -52,27 +53,33 @@ const HEAD_TABLE_TEMPLATE = {
}
},
methods: {
// 查询团长和副团长,副团长可能存在多人,需要完整展示。
pageData() {
this.$axios
const headRequest = this.listHeadUser("TEACHER_CONGRESS_DELEGATION_HEAD", "团长")
const viceHeadRequest = this.listHeadUser("TEACHER_CONGRESS_VICE_DELEGATION_HEAD", "副团长")
Promise.all([headRequest, viceHeadRequest]).then((values) => {
this.tableData = values[0].concat(values[1])
})
},
// 按角色查询负责人,并补充表格展示所需的角色名称和角色编码。
listHeadUser(roleType, roleName) {
return this.$axios
.post("/platform/teacherCongress/delegation/headUser", {
...this.pageForm,
sessionId: this.session_id,
delegationId: this.delegation_id
delegationId: this.delegation_id,
type: roleType
})
.then((res) => {
if (res.code === 0) {
if (res.data) {
this.tableData = [res.data]
} else {
this.tableData = []
}
if (res.code === 0 && res.data) {
return res.data.map((item) => Object.assign({roleName, roleType}, item))
}
return []
})
},
open() {
this.$emit("open", this.delegation_id, this.session_id)
},
doDelete(userId) {
doDelete(userId, roleType) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
@@ -82,7 +89,8 @@ const HEAD_TABLE_TEMPLATE = {
.post("/platform/teacherCongress/delegation/deleteHead", {
userId,
sessionId: this.session_id,
delegationId: this.delegation_id
delegationId: this.delegation_id,
type: roleType
})
.then((res) => {
if (res.code === 0) {
@@ -35,6 +35,12 @@ layout("/layouts/platform.html"){
<el-table-column prop="year" label="年份" sortable></el-table-column>
<el-table-column prop="j" label="届数" sortable></el-table-column>
<el-table-column prop="c" label="次数" sortable></el-table-column>
<el-table-column prop="proposalType" label="提案类型" min-width="180">
<template slot-scope="{row}">
<el-tag v-for="item in parseProposalTypes(row.proposalType)" :key="item" size="small"
style="margin-right: 5px">{{item}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="description" label="描述"></el-table-column>
<el-table-column prop="startDate" label="开启时间"></el-table-column>
<el-table-column prop="enable" label="开启状态">
@@ -78,6 +84,15 @@ layout("/layouts/platform.html"){
<dict-select v-model="formData.c" code="TEACHER_CONGRESS_C"></dict-select>
</el-form-item>
<!-- 支持多选历史类型,也允许直接输入并创建新的届次提案类型。 -->
<el-form-item prop="proposalType" label="提案类型">
<el-select v-model="formData.proposalType" multiple clearable filterable allow-create default-first-option
placeholder="请选择或输入提案类型" style="width: 100%">
<el-option v-for="item in proposalTypeOptions" :key="item.proposalType"
:label="item.proposalType" :value="item.proposalType"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input type="textarea" :rows="2" style="width: 100%" placeholder="请输入教代会描述"
v-model="formData.description"></el-input>
@@ -133,18 +148,39 @@ layout("/layouts/platform.html"){
el: "#app",
mixins: [initTableMixins],
data() {
// 多选项至少保留一项,单个自定义类型最多 50 个字符,序列化后总长度不超过数据库字段限制。
const validateProposalTypes = (rule, value, callback) => {
const proposalTypes = value || []
if (!proposalTypes.length) {
callback(new Error("请至少选择或输入一个提案类型"))
return
}
if (proposalTypes.some((item) => item && item.trim().length > 50)) {
callback(new Error("单个提案类型最多50个字符"))
return
}
if (JSON.stringify(proposalTypes).length > 1000) {
callback(new Error("提案类型数据不能超过1000个字符"))
return
}
callback()
}
return {
dialogFormVisible: false,
formRules: {
year: [{required: true, message: "必填", trigger: ["change", "blur"]}],
j: [{required: true, message: "必填", trigger: ["change", "blur"]}],
c: [{required: true, message: "必填", trigger: ["change", "blur"]}],
proposalType: [
{validator: validateProposalTypes, trigger: ["change", "blur"]}
],
enable: [{required: true, message: "必填", trigger: ["change", "blur"]}],
description: [{required: true, message: "必填", trigger: ["change", "blur"]}],
isExtend: [{required: true, message: "必填", trigger: ["change", "blur"]}],
collectStartTime: [{required: true, message: "必填", trigger: ["change", "blur"]}],
collectEndTime: [{required: true, message: "必填", trigger: ["change", "blur"]}]
}
},
proposalTypeOptions: []
}
},
methods: {
@@ -152,6 +188,7 @@ layout("/layouts/platform.html"){
this.dialogFormVisible = true
this.$nextTick(() => {
this.formData = {}
this.$set(this.formData, "proposalType", [])
})
},
openEdit(id) {
@@ -159,6 +196,7 @@ layout("/layouts/platform.html"){
this.$axios.post(loc() + "/findOne", {id}).then((res) => {
if (res.code === 0) {
res.data.year = res.data.year.toString()
this.$set(res.data, "proposalType", this.parseProposalTypes(res.data.proposalType))
this.formData = res.data
}
})
@@ -168,11 +206,16 @@ layout("/layouts/platform.html"){
this.$refs.formRef.validate((valid) => {
if (valid) {
const loading = createLoading()
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), this.formData).then((res) => {
const submitData = {
...this.formData,
proposalType: JSON.stringify(this.formData.proposalType || [])
}
this.$axios.post(loc() + (this.formData.id ? "/update" : "/insert"), submitData).then((res) => {
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.doSearch()
this.listProposalTypes()
}
}).finally(() => {
loading.close()
@@ -181,6 +224,22 @@ layout("/layouts/platform.html"){
})
},
// 数据库存储 JSON 数组;同时兼容字段调整前可能存在的单值内容。
parseProposalTypes(proposalType) {
if (Array.isArray(proposalType)) {
return proposalType
}
if (!proposalType) {
return []
}
try {
const values = JSON.parse(proposalType)
return Array.isArray(values) ? values : [proposalType]
} catch (e) {
return [proposalType]
}
},
doDelete(id) {
this.$confirm("您确定要删除吗?", "提示", {
confirmButtonText: "确定",
@@ -194,10 +253,20 @@ layout("/layouts/platform.html"){
}
})
})
},
// 查询历史届次已保存的提案类型,作为可输入下拉框的候选项。
listProposalTypes() {
this.$axios.post(loc() + "/listProposalTypes").then((res) => {
if (res.code === 0) {
this.proposalTypeOptions = res.data || []
}
})
}
},
created() {
this.pageData()
this.listProposalTypes()
}
})
</script>
@@ -65,6 +65,7 @@ layout("/layouts/platform.html"){
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
ref="table" row-key="id" style="width: 100%"
v-loading="tableLoading"
:summary-method="getSummaries" :show-summary="showSummary">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"
fixed="left"></el-table-column>
@@ -1,10 +1,10 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="申请列表">
@@ -86,6 +86,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -0,0 +1,51 @@
<script type="text/x-template" id="member-apply-common-query-template">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN', 'BRANCH_UNION_CHAIRMAN'])">
<search-item label="所属工会">
<el-select
@change="flushUnits"
@clear="flushUnits"
clearable
filterable
placeholder="请选择所属工会"
style="width: 100%"
v-model="pageForm.unionId"
>
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<!--
<search-item label="编制类别">
<dict-select v-model="pageForm.preparedBys" placeholder="请选择编制类别" @change="doSearch"
code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>
</search-item>
-->
<search-item label="人员分类">
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
style="width: 100%"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes" code="USER_ATTRIBUTE"
multiple collapse-tags clearable style="width: 100%"></dict-select>
<dict-select v-else v-model="pageForm.userAttribute" code="USER_ATTRIBUTE"
clearable style="width: 100%"></dict-select>
</search-item>
</template>
</search>
</script>
@@ -1,51 +1,12 @@
const COMMON_QUERY = {
template: /*language=HTML*/ `
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<template v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN', 'BRANCH_UNION_CHAIRMAN'])">
<search-item label="所属工会">
<el-select
@change="flushUnits"
@clear="flushUnits"
clearable
filterable
placeholder="请选择所属工会"
style="width: 100%"
v-model="pageForm.unionId"
>
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<!-- <search-item label="编制类别">-->
<!-- <dict-select v-model="pageForm.preparedBys" placeholder="请选择编制类别" @change="doSearch"-->
<!-- code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>-->
<!-- </search-item>-->
<search-item label="人员分类" v-if="false">
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
style="width: 100%"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" code="USER_ATTRIBUTE"
style="width: 100%"></dict-select>
</search-item>
</template>
</search>
`,
const COMMON_QUERY = {
template: "#member-apply-common-query-template",
props: {
// 默认保持原单选行为,仅由明确传参的页面开启人员属性多选。
userAttributeMultiple: {
type: Boolean,
default: false
}
},
store,
mixins: [initTableMixins],
data() {
@@ -59,6 +20,9 @@
userStates: [],
personTypes: [],
preparedBys: [],
aidFundMemberUserType: '',
userAttribute: '',
userAttributes: [],
}
}
},
@@ -68,6 +32,7 @@
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
this.$emit('search', pageForm)
},
async initData(){
@@ -1,10 +1,10 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
@@ -71,6 +71,8 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -1,10 +1,10 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
@@ -104,6 +104,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -87,6 +87,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -1,11 +1,11 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
@@ -75,6 +75,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
@@ -0,0 +1,40 @@
<script type="text/x-template" id="member-change-common-query-template">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable filterable
placeholder="请选择所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%"
v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员分类">
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes"
placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"
multiple collapse-tags clearable></dict-select>
<dict-select v-else v-model="pageForm.userAttribute" placeholder="请选择人员属性"
@change="doSearch" code="USER_ATTRIBUTE"></dict-select>
</search-item>
</search>
</script>
@@ -1,45 +1,12 @@
const COMMON_QUERY = {
template: /*language=HTML*/ `
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
</search-item>
<search-item label="所属工会">
<el-select @change="flushUnits" @clear="flushUnits" clearable filterable
placeholder="请选择所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%"
v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<!-- <search-item label="编制类别">-->
<!-- <dict-select v-model="pageForm.preparedBys" placeholder="请选择编制类别" @change="doSearch"-->
<!-- code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>-->
<!-- </search-item>-->
<search-item label="人员分类" v-if="false">
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE"></dict-select>
</search-item>
</search>
`,
const COMMON_QUERY = {
template: "#member-change-common-query-template",
props: {
// 未显式开启时保持原单选行为,避免影响未列入本次范围的页面。
userAttributeMultiple: {
type: Boolean,
default: false
}
},
store,
mixins: [initTableMixins],
data() {
@@ -55,6 +22,7 @@
preparedBys: [],
aidFundMemberUserType: '',
userAttribute: '',
userAttributes: [],
}
}
},
@@ -64,6 +32,8 @@
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
// 多选人员属性沿用现有数组查询参数的JSON提交方式。
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
this.$emit('search', pageForm)
},
async initData(){
@@ -44,8 +44,8 @@ layout("/layouts/platform.html"){
<!-- code="AIDFUND_MEMBER_USER_TYPE"></dict-select>-->
<!-- </search-item>-->
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE"></dict-select>
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
</search-item>
<search-item label="更新日期">
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
@@ -515,7 +515,7 @@ layout("/layouts/platform.html"){
isMember: 1,
changeTypes: [],
aidFundMemberUserType: "",
userAttribute: "",
userAttributes: [],
},
unions: [],
units: [],
@@ -588,6 +588,16 @@ layout("/layouts/platform.html"){
"member-all-change": MEMBER_ALL_CHANGE_INFO,
},
methods: {
// 分页和导出共用该参数构建方法,保证人员属性多选值始终按 JSON 数组提交。
buildQueryPageForm(source = this.pageForm) {
const pageForm = clone(source)
pageForm.userAttributes = JSON.stringify(source.userAttributes || [])
return pageForm
},
// 覆盖公共分页方法,使后端按人员属性集合执行查询。
pageData(data = null) {
return initTableMixins.methods.pageData.call(this, this.buildQueryPageForm(data || this.pageForm))
},
dropdownCommand(command) {
const {type, data} = command
if (type === 'view') {
@@ -648,7 +658,7 @@ layout("/layouts/platform.html"){
* 导出会员名单
*/
exportExcel() {
const pageForm = clone(this.pageForm)
const pageForm = this.buildQueryPageForm()
const data = this.tableColumns.filter(item => this.checkedFields.includes(item.prop)).map(item => {
return {prop: item.prop, label: item.label}
})
@@ -1,10 +1,10 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
@@ -54,6 +54,7 @@ layout("/layouts/platform.html"){
</template>
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -43,8 +43,8 @@ layout("/layouts/platform.html"){
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE"></dict-select>
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
</search-item>
</search>
</el-card>
@@ -151,7 +151,7 @@ layout("/layouts/platform.html"){
personType: "",
changeType: "",
aidFundMemberUserType: "",
userAttribute: ""
userAttributes: []
}
}
},
@@ -198,6 +198,8 @@ layout("/layouts/platform.html"){
pageForm.personTypes = JSON.stringify(pageForm.personTypes)
pageForm.changeTypes = JSON.stringify(pageForm.changeTypes)
pageForm.changeOrigins = JSON.stringify(pageForm.changeOrigins)
// 人员属性为多选条件,提交前转换为后端可解析的 JSON 数组。
pageForm.userAttributes = JSON.stringify(pageForm.userAttributes)
this.$axios.post(loc() + '/pageData', pageForm)
.then(res => {
@@ -1,11 +1,11 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<el-card shadow="never">
<common-query ref="commonQueryRef" @search="search"></common-query>
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
</el-card>
<el-card shadow="never" class="mt10">
@@ -77,6 +77,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
@@ -75,6 +75,7 @@ layout("/layouts/platform.html"){
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../common/info.js"){}#-->
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
@@ -42,6 +42,7 @@ layout("/layouts/platform.html"){
</template>
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../../common/info/memberInfo.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -0,0 +1,51 @@
<script type="text/x-template" id="member-info-common-query-template">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-select
clearable
v-model="pageForm.userIds"
filterable
remote
collapse-tags
placeholder="请输入姓名或工号"
:remote-method="queryUser"
@change="doSearch"
style="width: 100%"
multiple
>
<el-option v-for="o in userList" :label="o.username + '(' + o.loginname + ')'" :value="o.id"
:key="o.id"></el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select @change="handleUnionChange" @clear="handleUnionClear" clearable filterable
placeholder="请选择所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%"
v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态" v-if="!query_disable">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型" v-if="!query_disable">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员分类">
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
</search-item>
</search>
</script>
@@ -1,60 +1,5 @@
const COMMON_QUERY = {
template: /*language=HTML*/ `
<search @search="doSearch">
<search-item label="姓名/工号">
<el-select
clearable
v-model="pageForm.userIds"
filterable
remote
collapse-tags
placeholder="请输入姓名或工号"
:remote-method="queryUser"
@change="doSearch"
style="width: 100%"
multiple
>
<el-option v-for="o in userList" :label="o.username + '(' + o.loginname + ')'" :value="o.id"
:key="o.id"></el-option>
</el-select>
<!-- <el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>-->
</search-item>
<search-item label="所属工会">
<el-select @change="handleUnionChange" @clear="handleUnionClear" clearable filterable
placeholder="请选择所属工会" style="width: 100%;" v-model="pageForm.unionId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in unions"></el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select clearable filterable placeholder="请选择所属单位" style="width: 100%"
v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id"
v-for="item in units"></el-option>
</el-select>
</search-item>
<search-item label="在职状态" v-if="!query_disable">
<dict-select v-model="pageForm.userStates" placeholder="请选择在职状态" @change="doSearch"
code="USER_STATE" multiple collapse-tags></dict-select>
</search-item>
<search-item label="人员类型" v-if="!query_disable">
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
</search-item>
<!-- <search-item label="编制类别">-->
<!-- <dict-select v-model="pageForm.preparedBys" placeholder="请选择编制类别" @change="doSearch"-->
<!-- code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>-->
<!-- </search-item>-->
<search-item label="人员分类" v-if="false">
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE"></dict-select>
</search-item>
</search>
`,
const COMMON_QUERY = {
template: "#member-info-common-query-template",
store,
props: {
query_disable: {
@@ -77,7 +22,7 @@
personTypes: [],
preparedBys: [],
aidFundMemberUserType: '',
userAttribute: '',
userAttributes: [],
}
}
},
@@ -92,6 +37,8 @@
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
// 人员属性多选值按现有数组查询参数口径提交。
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
this.$emit('search', pageForm)
},
handleUnionChange() {
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
@@ -183,6 +183,7 @@ layout("/layouts/platform.html"){
</template>
</guava>
</div>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("../../common/info/memberInfo.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -1,44 +1,54 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<guava ref="guava">
<template>
<el-row type="flex" :gutter="20" style="height: calc(100vh - 126px)">
<el-col :span="5">
<el-card shadow="never" style="height: 100%" :body-style="{ height: '100%' }">
<el-input placeholder="请输入关键字进行查找" v-model="filterText" clearable></el-input>
<div style="max-height: calc(100vh - 205px); overflow-y: auto; margin-top: 10px;">
<el-tree
:data="treeData"
ref="treeRef"
node-key="id"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
:filter-node-method="filterNode"
highlight-current
@node-click="treeNodeClick"
>
<template slot-scope="{ node, data }">
<span class="el-tree-node__label">
<i class="el-icon-folder-opened" v-if="node.level===1"></i>
<i class="el-icon-folder" v-else></i>
{{node.label}}
</span>
</template>
</el-tree>
</div>
</el-card>
</el-col>
<el-col :span="19">
<el-card shadow="never" v-show="tabActive === 'memberList'">
<div class="member-group-layout" :class="{ 'is-tree-collapsed': treeCollapsed }">
<aside class="member-group-tree-panel">
<div class="member-group-tree-content" v-show="!treeCollapsed">
<el-card shadow="never" class="member-group-tree-card" :body-style="{ height: '100%' }">
<el-input placeholder="请输入关键字进行查找" v-model="filterText" clearable></el-input>
<div class="member-group-tree-scroll">
<el-tree
:data="treeData"
ref="treeRef"
node-key="id"
:expand-on-click-node="false"
:props="{
children: 'children',
label: 'name'
}"
default-expand-all
:filter-node-method="filterNode"
highlight-current
@node-click="treeNodeClick"
>
<template slot-scope="{ node, data }">
<span class="el-tree-node__label">
<i class="el-icon-folder-opened" v-if="node.level===1"></i>
<i class="el-icon-folder" v-else></i>
{{node.label}}
</span>
</template>
</el-tree>
</div>
</el-card>
</div>
<el-tooltip :content="treeCollapsed ? '展开组织树' : '收起组织树'" placement="right">
<el-button
class="member-group-tree-toggle"
size="mini"
:icon="treeCollapsed ? 'el-icon-arrow-right' : 'el-icon-arrow-left'"
@click="toggleTree"
></el-button>
</el-tooltip>
</aside>
<main class="member-group-content">
<el-card shadow="never" class="member-group-query-card" v-show="tabActive === 'memberList'">
<common-query ref="commonQueryRef" @search="search" @union-change="queryUnionChange"></common-query>
</el-card>
<el-card shadow="never" v-show="tabActive !== 'memberList' && currentUnionId">
<el-card shadow="never" class="member-group-overview-card" v-show="tabActive !== 'memberList' && currentUnionId">
<div style="display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 600; color: #303133;">
<i class="el-icon-office-building"></i>
<span>{{ unionOverview.unionName || '-' }}</span>
@@ -61,13 +71,14 @@ layout("/layouts/platform.html"){
</el-row>
</el-card>
<el-card shadow="never" class="mt10">
<el-card shadow="never" class="mt10 member-group-list-card">
<el-tabs v-model="tabActive" type="card" @tab-click="tabChange">
<el-tab-pane name="memberList">
<span slot="label">
<i class="el-icon-user"></i>
会员列表
</span>
<div ref="memberListPaneRef" class="member-group-member-list">
<table-tool label="会员列表">
<el-button type="primary" size="small" icon="el-icon-upload2" @click="openImport">导入会员</el-button>
<el-button
@@ -113,7 +124,7 @@ layout("/layouts/platform.html"){
</el-popover>
</table-tool>
<el-table :data="tableData" style="width: 100%" row-key="id" @sort-change="pageOrder" :size="tableSize" class="vi-table">
<el-table ref="memberTableRef" :height="tableHeight" :data="tableData" style="width: 100%" row-key="id" @sort-change="pageOrder" :size="tableSize" class="vi-table">
<el-table-column
align="center"
header-align="center"
@@ -144,6 +155,7 @@ layout("/layouts/platform.html"){
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</div>
</el-tab-pane>
<el-tab-pane name="branchUnionUserManage">
<span slot="label">
@@ -154,6 +166,7 @@ layout("/layouts/platform.html"){
v-if="currentUnionId"
ref="branchUnionUserManageRef"
:union_id="currentUnionId"
:table_height="tableHeight"
></sys-union-branch-union-user-manage>
<el-empty v-else description="请选择一个分工会"></el-empty>
</el-tab-pane>
@@ -166,6 +179,7 @@ layout("/layouts/platform.html"){
v-if="currentUnionId"
ref="branchUnionPartUnitManageRef"
:union_id="currentUnionId"
:table_height="tableHeight"
></sys-union-branch-union-part-unit-manage>
<el-empty v-else description="请选择一个分工会"></el-empty>
</el-tab-pane>
@@ -178,13 +192,14 @@ layout("/layouts/platform.html"){
v-if="currentUnionId"
ref="branchUnionGroupRef"
:union_id="currentUnionId"
:table_height="tableHeight"
></sys-union-branch-union-group-manage>
<el-empty v-else description="请选择一个分工会"></el-empty>
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
</main>
</div>
</template>
<template #view>
@@ -204,6 +219,205 @@ layout("/layouts/platform.html"){
></file-import>
</el-dialog>
</div>
<style>
/* 会员档案页独立布局:树折叠时仅保留切换按钮占用的窄轨道。 */
#app .member-group-layout {
display: flex;
align-items: stretch;
gap: 16px;
min-width: 0;
height: calc(100vh - 82px);
overflow: hidden;
box-sizing: border-box;
}
#app .member-group-tree-panel {
position: relative;
flex: 0 0 clamp(280px, 20vw, 340px);
min-width: 0;
}
#app .member-group-tree-panel::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
z-index: 1;
width: 1px;
content: "";
background: #dcdfe6;
}
#app .member-group-tree-content,
#app .member-group-tree-card {
height: 100%;
}
#app .member-group-tree-card > .el-card__body {
display: flex;
flex-direction: column;
height: 100%;
box-sizing: border-box;
overflow: hidden;
}
#app .member-group-tree-scroll {
flex: 1 1 auto;
min-height: 0;
margin-top: 10px;
overflow-y: auto;
}
#app .member-group-tree-toggle {
position: absolute;
top: 50%;
right: -9px;
z-index: 3;
width: 18px;
height: 34px;
padding: 0;
transform: translateY(-50%);
color: #409eff;
background: #ffffff;
border-color: #dcdfe6;
border-radius: 0 3px 3px 0;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.1);
}
#app .member-group-tree-toggle:hover,
#app .member-group-tree-toggle:focus {
color: #409eff;
background: #ecf5ff;
border-color: #409eff;
}
#app .member-group-tree-toggle i {
margin: 0;
font-size: 12px;
}
#app .member-group-content {
display: flex;
flex-direction: column;
flex: 1 1 auto;
min-width: 0;
height: 100%;
overflow: hidden;
}
#app .member-group-layout.is-tree-collapsed .member-group-tree-panel {
flex-basis: 18px;
}
#app .member-group-layout.is-tree-collapsed .member-group-tree-toggle {
right: 0;
}
/* 查询项按可用宽度自动调整列数,减少固定比例布局造成的空白。 */
#app .member-group-query-card .search {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 12px 18px;
align-items: center;
}
#app .member-group-query-card .search .search-item {
width: auto;
min-width: 0;
}
#app .member-group-query-card .search .search-query {
display: flex;
align-items: center;
min-height: 40px;
}
#app .member-group-query-card,
#app .member-group-overview-card {
flex: 0 0 auto;
}
/* 四个页签共用剩余高度,内容超出时仅在页签内容区域滚动。 */
#app .member-group-list-card {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
#app .member-group-list-card > .el-card__body {
height: 100%;
box-sizing: border-box;
overflow: hidden;
}
#app .member-group-list-card .el-tabs {
display: flex;
flex-direction: column;
height: 100%;
}
#app .member-group-list-card .el-tabs__header {
flex: 0 0 auto;
}
#app .member-group-list-card .el-tabs__content {
flex: 1 1 auto;
min-height: 0;
overflow-x: hidden;
overflow-y: hidden;
}
#app .member-group-list-card .el-tab-pane,
#app .member-group-member-list,
#app .member-group-list-card .el-tab-pane > div {
height: 100%;
min-height: 0;
overflow: hidden;
}
#app .member-group-member-list,
#app .member-group-list-card .el-tab-pane > div {
display: flex;
flex-direction: column;
}
#app .member-group-member-list > .ele-table-tool,
#app .member-group-member-list > .el-pagination-container,
#app .member-group-list-card .el-tab-pane > div > .el-card:first-child {
flex: 0 0 auto;
}
#app .member-group-list-card .el-tab-pane > div > .el-card:last-of-type {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
#app .member-group-list-card .el-tab-pane > div > .el-card:last-of-type > .el-card__body {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
box-sizing: border-box;
overflow: hidden;
}
#app .member-group-member-list > .el-table,
#app .member-group-list-card .el-tab-pane > div > .el-card:last-of-type > .el-card__body > .el-table {
flex: 0 0 auto;
}
@media screen and (max-width: 1200px) {
#app .member-group-tree-panel {
flex-basis: 260px;
}
#app .member-group-query-card .search {
grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
}
</style>
<!--#include("../common/commonQuery.html"){}#-->
<script nonce="${cspNonce!}">
<!--#include("archiveMember.js"){}#-->
<!--#include("../common/commonQuery.js"){}#-->
@@ -218,6 +432,9 @@ layout("/layouts/platform.html"){
data() {
return {
filterText: null,
treeCollapsed: false,
tableHeight: 400,
tableResizeObserver: null,
unionRootId: "member-union-root",
treeData: [],
currentTreeData: null,
@@ -237,8 +454,8 @@ layout("/layouts/platform.html"){
{ prop: "personType", label: "人员类型", width: 120, sortable: true, checked: 0 },
// { prop: "preparedBy", label: "编制类别", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true, checked: 0 },
{ prop: "unionName", label: "所属工会", width: 120, sortable: true },
{ prop: "unitName", label: "所属单位", width: 120, sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位",sortable: true },
// { prop: "aidFundMemberUserType", label: "人员分类", width: 120, sortable: true },
// { prop: "userAttribute", label: "人员属性", width: 120, sortable: true },
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
@@ -277,6 +494,53 @@ layout("/layouts/platform.html"){
"sys-union-branch-union-group-manage": branchUnionGroupManage,
},
methods: {
// 切换组织树显示状态,并在内容宽度变化后重新计算固定列表格布局。
toggleTree() {
this.treeCollapsed = !this.treeCollapsed
this.$nextTick(() => {
this.updateTableHeight()
if (this.$refs.memberTableRef) {
this.$refs.memberTableRef.doLayout()
}
})
},
// 根据页签内容区的实际高度计算表格高度,由 Element Table 管理表头和表体滚动。
updateTableHeight() {
this.$nextTick(() => {
const tabsContent = this.$el.querySelector(".member-group-list-card .el-tabs__content")
if (!tabsContent || tabsContent.clientHeight <= 0) {
return
}
let availableHeight = tabsContent.clientHeight
let reservedHeight = 100
const memberPane = this.$refs.memberListPaneRef
if (memberPane && memberPane.clientHeight > 0) {
const tool = memberPane.querySelector(".ele-table-tool")
const pagination = memberPane.querySelector(".el-pagination-container")
// offsetHeight 不包含外边距,分页的 margin-top 需要一并扣除。
const getOuterHeight = (element) => {
if (!element) {
return 0
}
const style = window.getComputedStyle(element)
return element.offsetHeight
+ (parseFloat(style.marginTop) || 0)
+ (parseFloat(style.marginBottom) || 0)
}
availableHeight = memberPane.clientHeight
reservedHeight = getOuterHeight(tool) + getOuterHeight(pagination)
}
const nextHeight = Math.max(240, Math.floor(availableHeight - reservedHeight))
if (this.tableHeight !== nextHeight) {
this.tableHeight = nextHeight
}
this.$nextTick(() => {
if (this.$refs.memberTableRef) {
this.$refs.memberTableRef.doLayout()
}
})
})
},
openImport() {
this.importDialog = true
},
@@ -402,6 +666,7 @@ layout("/layouts/platform.html"){
},
tabChange(tab) {
this.$nextTick(() => {
this.updateTableHeight()
if (tab.name === "memberList") {
if (this.$refs.commonQueryRef) {
this.$refs.commonQueryRef.doSearch()
@@ -422,6 +687,7 @@ layout("/layouts/platform.html"){
this.$axios.post(loc() + "/unionOverview", { unionId: this.currentUnionId }).then((data) => {
if (data.code === 0) {
this.unionOverview = data.data || {}
this.updateTableHeight()
} else {
this.$message.error(data.msg)
}
@@ -492,6 +758,25 @@ layout("/layouts/platform.html"){
this.initDefaultView()
this.getTreeData()
this.pageData()
},
mounted() {
const tabsContent = this.$el.querySelector(".member-group-list-card .el-tabs__content")
if (tabsContent && window.ResizeObserver) {
// 查询区换行或页面尺寸变化时,自动重新分配表格数据区域高度。
this.tableResizeObserver = new ResizeObserver(this.updateTableHeight)
this.tableResizeObserver.observe(tabsContent)
}
this.$nextTick(() => {
this.updateTableHeight()
})
window.addEventListener("resize", this.updateTableHeight)
},
beforeDestroy() {
if (this.tableResizeObserver) {
this.tableResizeObserver.disconnect()
this.tableResizeObserver = null
}
window.removeEventListener("resize", this.updateTableHeight)
}
})
</script>
@@ -50,7 +50,8 @@ layout("/layouts/platform.html"){
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch" code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"></dict-select>
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
</search-item>
</search>
</el-card>
@@ -109,7 +110,7 @@ layout("/layouts/platform.html"){
memberSearchName: "",
memberSearchKeyWord: "",
aidFundMemberUserType: "",
userAttribute: ""
userAttributes: []
},
userId: "",
unions: [],
@@ -132,6 +133,16 @@ layout("/layouts/platform.html"){
"member-info": MEMBER_INFO
},
methods: {
// 分页和导出共用该参数构建方法,保证人员属性多选值始终按 JSON 数组提交。
buildQueryPageForm() {
const pageForm = clone(this.pageForm)
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes || [])
return pageForm
},
// 覆盖公共分页方法,使后端按人员属性集合执行查询。
pageData() {
return initTableMixins.methods.pageData.call(this, this.buildQueryPageForm())
},
openView(row) {
this.$refs.guava.view(() => {
this.$refs.memberInfoRef.onOpen(row.id)
@@ -141,7 +152,7 @@ layout("/layouts/platform.html"){
this.$downLoad("/platform/member/info/history/doExportByUnion", { year: this.pageForm.year })
},
doExport() {
this.$downLoad("/platform/member/info/history/doExport", this.pageForm)
this.$downLoad("/platform/member/info/history/doExport", this.buildQueryPageForm())
},
async initData() {
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
@@ -50,7 +50,8 @@ layout("/layouts/platform.html"){
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch" code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
</search-item>
<search-item label="人员属性">
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"></dict-select>
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
</search-item>
</search>
</el-card>
@@ -112,6 +113,7 @@ layout("/layouts/platform.html"){
data() {
return {
pageForm: {
userAttributes: [],
year: new Date().getFullYear() + "",
memberSearchName: "",
memberSearchKeyWord: ""
@@ -139,6 +141,12 @@ layout("/layouts/platform.html"){
"member-add-form": MEMBER_ADD_FORM
},
methods: {
// 人员属性为多选条件,分页查询前统一转换为后端可接收的 JSON 数组。
pageData(data = null) {
const pageForm = clone(data || this.pageForm)
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes || [])
return initTableMixins.methods.pageData.call(this, pageForm)
},
openAdd() {
this.$refs.guava.edit(() => {
this.$refs.memberAddFormRef.onOpen()
@@ -84,6 +84,13 @@ const filterUser = {
v-model="pageForm.personTypes"></dict-select>
</search-item>
<search-item label="人员属性:">
<dict-select clearable code="USER_ATTRIBUTE"
multiple
collapse-tags
placeholder="请选择人员属性"
v-model="pageForm.userAttributes"></dict-select>
</search-item>
<search-item label="在职状态:">
<dict-select clearable code="USER_STATE"
@@ -152,6 +159,7 @@ const filterUser = {
userStates: [],
personTypes: [],
preparedBys: [],
userAttributes: [],
unitIds: []
},
sexOptions: ["男", "女"],
@@ -165,7 +173,8 @@ const filterUser = {
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true }
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "threeUnitName", label: "三级单位", sortable: true }
]
}
},
@@ -186,9 +195,10 @@ const filterUser = {
this.$set(this.pageForm, "birthday", null)
this.$set(this.pageForm, "birthMonths", [])
this.$set(this.pageForm, "unionId", null)
this.$set(this.pageForm, "unitId", null)
this.$set(this.pageForm, "unitIds", [])
this.$set(this.pageForm, "personTypes", [])
this.$set(this.pageForm, "preparedBys", [])
this.$set(this.pageForm, "userAttributes", [])
this.$set(this.pageForm, "userStates", [])
this.$set(this.pageForm, "isMember", null)
},
@@ -425,7 +425,7 @@ layout("/layouts/platform_h5.html"){
<van-cell title="线路类型" :value="detail.lineType || ''"></van-cell>
<van-cell title="出行时间" :value="detail.travelPeriod || ''"></van-cell>
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell title="服务单位" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell v-if="detailFillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
<van-cell v-if="detailFillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
<van-cell v-if="detailFillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
@@ -216,7 +216,7 @@ layout("/layouts/platform_h5.html"){
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell title="服务单位" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
@@ -3,10 +3,11 @@ layout("/layouts/platform_tour_signup_h5.html"){
#-->
<style scoped>
.tour-signup-h5 {
#app.tour-signup-h5 {
/* 覆盖公共 #app 固定高度,确保长须知内容和底部占位共同参与页面滚动。 */
height: auto;
min-height: 100vh;
background: #f5f7fb;
padding-bottom: 80px;
box-sizing: border-box;
}
@@ -143,15 +144,24 @@ layout("/layouts/platform_tour_signup_h5.html"){
padding: 34px 0 26px;
}
.tour-signup-footer-spacer {
/* 占位元素位于正文流末尾,保证最后一行可完整滚动到固定按钮栏上方。 */
height: 110px;
height: calc(110px + env(safe-area-inset-bottom));
}
.tour-signup-footer {
position: fixed;
right: 0;
bottom: 0;
left: 0;
/* 不支持安全区变量时使用固定内边距,避免整条 padding 声明失效。 */
padding: 10px 12px;
padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
background: rgba(255, 255, 255, 0.96);
box-shadow: 0 -6px 18px rgba(15, 23, 42, 0.08);
box-sizing: border-box;
z-index: 20;
}
</style>
@@ -196,8 +206,18 @@ layout("/layouts/platform_tour_signup_h5.html"){
</van-skeleton>
</div>
<div class="tour-signup-footer-spacer" aria-hidden="true"></div>
<div class="tour-signup-footer">
<van-button block type="info" color="#0f74bc" round @click="confirmRead">我已阅读</van-button>
<van-button
block
type="info"
color="#0f74bc"
round
:disabled="readCountdown > 0"
@click="confirmRead">
{{ readButtonText }}
</van-button>
</div>
</div>
@@ -217,6 +237,8 @@ layout("/layouts/platform_tour_signup_h5.html"){
pdfPageCount: 0,
pdfRenderedPages: 0,
pdfRenderToken: 0,
readCountdown: 10,
readCountdownTimer: null,
bannerList: [
"/assets/platform/images/tour/tour-h5-banner-1.jpg",
"/assets/platform/images/tour/tour-h5-banner-2.jpg"
@@ -228,7 +250,33 @@ layout("/layouts/platform_tour_signup_h5.html"){
}
}
},
computed: {
// 倒计时期间在按钮中展示剩余秒数,结束后恢复原确认文案。
readButtonText() {
return this.readCountdown > 0 ? "我已阅读(" + this.readCountdown + "秒)" : "我已阅读"
}
},
methods: {
// 启动十秒阅读倒计时,重复调用前先清理旧计时器,避免并发计时。
startReadCountdown() {
this.clearReadCountdown()
this.readCountdown = 10
this.readCountdownTimer = window.setInterval(() => {
if (this.readCountdown <= 1) {
this.readCountdown = 0
this.clearReadCountdown()
return
}
this.readCountdown -= 1
}, 1000)
},
// 页面离开或倒计时结束时释放计时器,避免页面销毁后继续更新状态。
clearReadCountdown() {
if (this.readCountdownTimer !== null) {
window.clearInterval(this.readCountdownTimer)
this.readCountdownTimer = null
}
},
parseContentHref(content) {
if (!content) {
return ""
@@ -386,13 +434,19 @@ layout("/layouts/platform_tour_signup_h5.html"){
})
},
confirmRead() {
// 方法内再次校验倒计时,防止通过脚本触发禁用按钮的点击事件。
if (this.readCountdown > 0) {
return
}
window.location.href = "/platform/tour/signup/h5/signup"
}
},
created() {
this.startReadCountdown()
this.loadServiceNotice()
},
beforeDestroy() {
this.clearReadCountdown()
this.clearPdfPreview()
}
})
@@ -470,8 +470,8 @@ layout("/layouts/platform_tour_signup_h5.html"){
<div class="tour-line-info">
<div><span>出行开始时间:</span>{{ row.travelStartTime || '暂无' }}</div>
<div><span>出行结束时间:</span>{{ row.travelEndTime || '暂无' }}</div>
<!-- 临时屏蔽旅行社信息,保留字段和接口便于后续恢复。
<div><span>旅行社:</span>{{ row.travelAgencyName || '暂无' }}</div>
<!-- 临时屏蔽服务单位信息,保留字段和接口便于后续恢复。
<div><span>服务单位:</span>{{ row.travelAgencyName || '暂无' }}</div>
-->
</div>
<div class="tour-line-actions">
@@ -214,7 +214,7 @@ layout("/layouts/platform_h5.html"){
<van-cell title="出行时段" :value="detail.travelPeriod || ''"></van-cell>
<van-cell title="报名时间" :value="detail.signupTime || ''"></van-cell>
<van-cell title="报名酒店" :value="detail.hotelName || ''"></van-cell>
<van-cell title="旅行社" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell title="服务单位" :value="detail.travelAgencyName || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="床型" :value="detail.bedType || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="床位信息" :value="detail.bedInfo || ''"></van-cell>
<van-cell v-if="fillBedInfo" title="意向拼床人" :value="detail.intendedRoommate || ''"></van-cell>
@@ -439,6 +439,11 @@ layout("/layouts/platform_h5.html"){
required
is-link
></van-field>
<van-cell v-if="getProjectTipByProject(formData.reimburseProject)">
<template #title>
<span style="color: #ee0a24; text-align: left;">报销提示:{{getProjectTipByProject(formData.reimburseProject)}}</span>
</template>
</van-cell>
<van-popup position="bottom" round v-model:show="showReimburseProjectPicker">
<van-picker :columns="reimburseProjectColumns" @cancel="closePopup('showReimburseProjectPicker')"
@confirm="onReimburseProjectConfirm" show-toolbar></van-picker>
@@ -528,120 +533,6 @@ layout("/layouts/platform_h5.html"){
-->
</van-cell-group>
<van-cell-group class="form-section">
<div class="payment-section">
<div class="payment-toolbar">
<span>支付信息</span>
<van-button native-type="button" size="small" type="primary" icon="plus" @click="addPaymentInfo">新增</van-button>
</div>
<div class="invoice-tip" v-if="!paymentInfoRows.length">请至少维护一条支付信息。</div>
<van-swipe
ref="paymentSwipe"
class="payment-swipe"
:loop="false"
:show-indicators="false"
@change="handlePaymentSwipeChange"
v-if="paymentInfoRows.length">
<van-swipe-item v-for="(item, index) in paymentInfoRows" :key="index">
<div class="payment-detail-item">
<div class="payment-detail-title">
<div class="payment-title-left">
<span>支付信息{{index + 1}}</span>
<span class="payment-index-text">{{index + 1}} / {{paymentInfoRows.length}}</span>
</div>
<van-tag v-if="item.paymentWayName" type="primary">{{item.paymentWayName}}</van-tag>
</div>
<van-field
v-model="item.paymentWayName"
label="支付方式"
readonly
placeholder="请选择支付方式"
@click="openPaymentWayPicker(item, index)"
clickable
required
is-link
></van-field>
<van-field
label="金额"
v-model="item.money"
placeholder="请输入金额"
type="number"
required
></van-field>
<template v-if="isPrivatePayment(item)">
<van-field
v-model="item.payerName"
label="付款人"
readonly
placeholder="请选择付款人"
@click="openPayerSelect(item, index)"
clickable
required
is-link
></van-field>
<van-field
label="户名"
v-model="item.bankUserName"
placeholder="请输入户名"
required
></van-field>
<van-field
label="开户行"
v-model="item.bankOfDeposit"
placeholder="请输入开户行"
required
></van-field>
<van-field
label="银行卡号"
v-model="item.bankCardNumber"
placeholder="请输入银行卡号"
required
></van-field>
</template>
<div class="payment-detail-actions">
<div class="payment-nav-buttons">
<span class="payment-nav-btn" :class="{active: currentPaymentIndex > 0}" @click="showPrevPayment">
<van-icon name="arrow-left"></van-icon>
</span>
<span class="payment-nav-btn" :class="{active: currentPaymentIndex < paymentInfoRows.length - 1}" @click="showNextPayment">
<van-icon name="arrow"></van-icon>
</span>
</div>
<van-button class="payment-delete-btn" native-type="button" size="small" plain type="danger" icon="delete-o" @click="deletePaymentInfo(index)">删除</van-button>
</div>
</div>
</van-swipe-item>
</van-swipe>
<div class="payment-dots" v-if="paymentInfoRows.length > 1">
<span class="payment-dot" :class="{active: index === currentPaymentIndex}" v-for="(item, index) in paymentInfoRows"></span>
</div>
</div>
<van-popup position="bottom" round v-model:show="showPaymentWayPicker">
<van-picker :columns="paymentWayColumns" @cancel="closePopup('showPaymentWayPicker')"
@confirm="onPaymentWayConfirm" show-toolbar></van-picker>
</van-popup>
<van-action-sheet v-model="payerSelectShow" title="付款人" class="height100">
<van-search
v-model="payerSearchKeyword"
:show-action="false"
:reverse-color="false"
input-align="left"
placeholder="请输入工号或姓名选择付款人"
@input="payerRemoteMethod"
@clear="payerRemoteMethod"
shape="round"
></van-search>
<div class="van-action-sheet__content mt5" v-if="payerOptions && payerOptions.length>0">
<template v-for="item in payerOptions">
<van-button native-type="button" @click="payerUserChange(item)"
class="van-action-sheet__item van-hairline--bottom">
<span class="van-action-sheet__name">{{item.userName}}({{item.loginName}})</span>
</van-button>
</template>
</div>
<van-empty description="暂无数据" v-else></van-empty>
</van-action-sheet>
</van-cell-group>
<van-cell-group :title="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1' ? '慰问信息' : '活动信息'" class="form-section">
<template v-if="formData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
@@ -921,6 +812,120 @@ layout("/layouts/platform_h5.html"){
</template>
</van-field>
</van-cell-group>
<van-cell-group class="form-section">
<div class="payment-section">
<div class="payment-toolbar">
<span>支付信息</span>
<van-button native-type="button" size="small" type="primary" icon="plus" @click="addPaymentInfo">新增</van-button>
</div>
<div class="invoice-tip" v-if="!paymentInfoRows.length">请至少维护一条支付信息。</div>
<van-swipe
ref="paymentSwipe"
class="payment-swipe"
:loop="false"
:show-indicators="false"
@change="handlePaymentSwipeChange"
v-if="paymentInfoRows.length">
<van-swipe-item v-for="(item, index) in paymentInfoRows" :key="index">
<div class="payment-detail-item">
<div class="payment-detail-title">
<div class="payment-title-left">
<span>支付信息{{index + 1}}</span>
<span class="payment-index-text">{{index + 1}} / {{paymentInfoRows.length}}</span>
</div>
<van-tag v-if="item.paymentWayName" type="primary">{{item.paymentWayName}}</van-tag>
</div>
<van-field
v-model="item.paymentWayName"
label="支付方式"
readonly
placeholder="请选择支付方式"
@click="openPaymentWayPicker(item, index)"
clickable
required
is-link
></van-field>
<van-field
label="金额"
v-model="item.money"
placeholder="请输入金额"
type="number"
required
></van-field>
<template v-if="isPrivatePayment(item)">
<van-field
v-model="item.payerName"
label="付款人"
readonly
placeholder="请选择付款人"
@click="openPayerSelect(item, index)"
clickable
required
is-link
></van-field>
<van-field
label="户名"
v-model="item.bankUserName"
placeholder="请输入户名"
required
></van-field>
<van-field
label="开户行"
v-model="item.bankOfDeposit"
placeholder="请输入开户行"
required
></van-field>
<van-field
label="银行卡号"
v-model="item.bankCardNumber"
placeholder="请输入银行卡号"
required
></van-field>
</template>
<div class="payment-detail-actions">
<div class="payment-nav-buttons">
<span class="payment-nav-btn" :class="{active: currentPaymentIndex > 0}" @click="showPrevPayment">
<van-icon name="arrow-left"></van-icon>
</span>
<span class="payment-nav-btn" :class="{active: currentPaymentIndex < paymentInfoRows.length - 1}" @click="showNextPayment">
<van-icon name="arrow"></van-icon>
</span>
</div>
<van-button class="payment-delete-btn" native-type="button" size="small" plain type="danger" icon="delete-o" @click="deletePaymentInfo(index)">删除</van-button>
</div>
</div>
</van-swipe-item>
</van-swipe>
<div class="payment-dots" v-if="paymentInfoRows.length > 1">
<span class="payment-dot" :class="{active: index === currentPaymentIndex}" v-for="(item, index) in paymentInfoRows"></span>
</div>
</div>
<van-popup position="bottom" round v-model:show="showPaymentWayPicker">
<van-picker :columns="paymentWayColumns" @cancel="closePopup('showPaymentWayPicker')"
@confirm="onPaymentWayConfirm" show-toolbar></van-picker>
</van-popup>
<van-action-sheet v-model="payerSelectShow" title="付款人" class="height100">
<van-search
v-model="payerSearchKeyword"
:show-action="false"
:reverse-color="false"
input-align="left"
placeholder="请输入工号或姓名选择付款人"
@input="payerRemoteMethod"
@clear="payerRemoteMethod"
shape="round"
></van-search>
<div class="van-action-sheet__content mt5" v-if="payerOptions && payerOptions.length>0">
<template v-for="item in payerOptions">
<van-button native-type="button" @click="payerUserChange(item)"
class="van-action-sheet__item van-hairline--bottom">
<span class="van-action-sheet__name">{{item.userName}}({{item.loginName}})</span>
</van-button>
</template>
</div>
<van-empty description="暂无数据" v-else></van-empty>
</van-action-sheet>
</van-cell-group>
<van-cell-group title="电子发票" class="form-section" v-if="formData.reimburseProject">
<van-field label="报销金额"
v-model="formData.money"
@@ -1186,6 +1191,7 @@ layout("/layouts/platform_h5.html"){
clubOptions: [],
condolenceOptions: [],
typeOptions: [],
descOptions: [],
// 添加报销项目原始数据列表
reimburseProjectList: [],
// 添加日期选择器相关变量
@@ -2025,7 +2031,7 @@ layout("/layouts/platform_h5.html"){
}
this.$dialog.confirm({
title: "温馨提示",
message: "您确定要提交吗?"
message: "您确定要提交吗?审核通过后可前往pc端我的报销打印!"
}).then(() => {
this.$axios.post("/platform/unionReimburse/apply/submit", { data: JSON.stringify(this.buildSubmitFormData(paymentDetails)) })
.then(res => {
@@ -2064,7 +2070,7 @@ layout("/layouts/platform_h5.html"){
}
this.$dialog.confirm({
title: "温馨提示",
message: "您确定要提交吗?"
message: "您确定要提交吗?审核通过后可前往pc端我的报销打印!"
}).then(() => {
this.$axios.post("/platform/unionReimburse/apply/submitAgain", {
data: JSON.stringify(this.buildSubmitFormData(paymentDetails)),
@@ -2195,6 +2201,23 @@ layout("/layouts/platform_h5.html"){
const matchedFundSource = this.reimburseFundSourceColumns.find(item => item.value === code)
return matchedFundSource ? matchedFundSource.text : ""
},
// 查询管理端配置的报销项目提示。
queryProjectDesc() {
return this.$axios.post("/platform/unionReimburse/desc/queryFileDesc")
.then((resp) => {
if (resp.code === 0) {
this.$set(this, "descOptions", resp.data || [])
}
})
},
// 根据当前选择的报销项目获取管理端配置的提示内容。
getProjectTipByProject(projectCode) {
if (!this.descOptions || !Array.isArray(this.descOptions)) {
return ""
}
const project = this.descOptions.find(item => item.reimburseProject === projectCode)
return project ? project.projectTip : ""
},
async initDictOptions() {
// 报销类别
const reimburseTypeData = await this.$businessTool.getDictOptions("UNION_REIMBURSE_TYPE")
@@ -2558,6 +2581,7 @@ layout("/layouts/platform_h5.html"){
async created() {
await this.initDictOptions()
await this.queryProjectDesc()
await this.queryCondolenceType()
await this.queryClubs()
await this.init()
@@ -10,6 +10,7 @@ const PROPOSAL_INFO = {
</div>
</van-cell>
<van-cell title="提案编号">{{ viewData.code }}</van-cell>
<van-cell title="立案编号">{{ viewData.caseFilingCode || '暂无' }}</van-cell>
<van-cell title="提案人">{{ viewData.createUserName }}</van-cell>
<van-cell title="提案时间">{{ viewData.createTime }}</van-cell>
<van-cell title="教代会届次">{{ viewData.fullName }}</van-cell>
@@ -210,10 +210,10 @@ layout("/layouts/platform_h5.html"){
is-link
readonly
name="typeName"
label="提案类别"
placeholder="请选择提案类别"
label="提案类型"
placeholder="请选择提案类型"
@click="showTypePicker = true"
:rules="[{ required: true, message: '请选择提案类别' }]"
:rules="[{ required: true, message: '请选择提案类型' }]"
required
></van-field>
<van-popup v-model="showTypePicker" position="bottom">
@@ -411,7 +411,7 @@ layout("/layouts/platform_h5.html"){
},
onTypeConfirm(value) {
this.formData.typeId = value.value;
this.$set(this.formData, 'typeId', value.value);
this.$set(this.formData, 'typeName', value.text);
this.showTypePicker = false;
},
@@ -589,9 +589,15 @@ layout("/layouts/platform_h5.html"){
}
},
// 获取提案类别
// 根据当前教代会届次获取允许撰写的提案类型
listProposalType() {
this.$axios.post("/platform/proposal/common/listProposalType").then((res) => {
if (!this.formData.sessionId) {
this.typeOptions = [];
return Promise.resolve();
}
return this.$axios.post("/platform/proposal/write/listSessionProposalTypes", {
sessionId: this.formData.sessionId
}).then((res) => {
if (res.code === 0) {
this.typeOptions = res.data;
}
@@ -609,6 +615,11 @@ layout("/layouts/platform_h5.html"){
//教代会change
async meetingChange(val) {
// 切换届次后清空旧值,并加载新届次允许选择的提案类型
this.$set(this.formData, "typeId", null);
this.$set(this.formData, "typeName", "");
this.typeOptions = [];
this.listProposalType();
this.formData.delegationId = null;
this.formData.committeeId = null;
this.formData.delegationName = '';
@@ -646,6 +657,7 @@ layout("/layouts/platform_h5.html"){
if (!isModify && this.sessionOptions && this.sessionOptions.length > 0) {
this.$set(this.formData, "sessionId", this.sessionOptions[0].id);
this.$set(this.formData, "sessionName", this.sessionOptions[0].fullName);
this.listProposalType();
await this.listDelegation();
await this.listSource();
// 获取代表团
@@ -655,7 +667,9 @@ layout("/layouts/platform_h5.html"){
} else {
await this.listDelegation();
await this.listSource();
this.echoPicker()
this.listProposalType().then(() => {
this.echoPicker();
});
}
}
});
@@ -742,7 +756,6 @@ layout("/layouts/platform_h5.html"){
created() {
this.init();
this.listSuggestUnit();
this.listProposalType();
this.getProposalConfig();
},
watch: {