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
@@ -0,0 +1,4 @@
-- 评优评先申请表新增历史导入来源和类型名称字段。
ALTER TABLE `evaluate_apply`
ADD COLUMN `source` int(2) DEFAULT 0 COMMENT '来源 0.流程申请 1.历史导入' AFTER `honorTypeId`,
ADD COLUMN `typeName` varchar(200) DEFAULT NULL COMMENT '类型名称' AFTER `source`;
@@ -0,0 +1,122 @@
-- 普惠疗休养平台电脑端菜单。
-- 使用 permission 做幂等判断,避免同一环境重复执行时插入重复菜单。
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'b7c63f0c73a44a9a8c4f3d3bb1a10001',
'',
LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'),
'普惠疗休养',
'Tour',
'menu',
'',
'',
'ti-map-alt',
1,
0,
'tour',
NULL,
991,
1,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
NULL,
NULL,
'p',
0,
0
FROM sys_menu
WHERE (parentId = '' OR parentId IS NULL)
AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10002', p.id, CONCAT(p.path, '0001'), '疗休养设置', 'Tour Setting', 'menu', '/platform/tour/setting', 'data-pjax', '', 1, 0, 'tour.setting', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.setting') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10003', p.id, CONCAT(p.path, '0002'), '服务单位管理', 'Service Unit', 'menu', '/platform/tour/travelAgency', 'data-pjax', '', 1, 0, 'tour.travelAgency', NULL, 2, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'f', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.travelAgency') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10004', p.id, CONCAT(p.path, '0003'), '线路管理', 'Route Manage', 'menu', '/platform/tour/route', 'data-pjax', '', 1, 0, 'tour.route', NULL, 3, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.route') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10005', p.id, CONCAT(p.path, '0004'), '疗休养事项', 'Tour Matter', 'menu', '/platform/tour/matter', 'data-pjax', '', 1, 0, 'tour.matter', NULL, 4, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.matter') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10006', p.id, CONCAT(p.path, '0005'), '疗休养报名', 'Tour Signup', 'menu', '/platform/tour/signup', 'data-pjax', '', 1, 0, 'tour.signup', NULL, 5, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.signup') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10008', p.id, CONCAT(p.path, '0006'), '我的报名', 'My Signup', 'menu', '/platform/tour/mysignup', 'data-pjax', '', 1, 0, 'tour.mysignup', NULL, 6, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'w', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.mysignup') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10009', p.id, CONCAT(p.path, '0007'), '分工会查询', 'Union Ledger', 'menu', '/platform/tour/unionledger', 'data-pjax', '', 1, 0, 'tour.unionledger', NULL, 7, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'f', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.unionledger') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10011', p.id, CONCAT(p.path, '0010'), '分工会审核', 'Union Approval', 'menu', '/platform/tour/unionApproval', 'data-pjax', '', 1, 0, 'tour.unionApproval', NULL, 8, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'f', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.unionApproval') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10012', p.id, CONCAT(p.path, '0011'), '校工会审核', 'School Union Approval', 'menu', '/platform/tour/schoolUnionApproval', 'data-pjax', '', 1, 0, 'tour.schoolUnionApproval', NULL, 9, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.schoolUnionApproval') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10007', p.id, CONCAT(p.path, '0008'), '疗休养台账', 'Tour Ledger', 'menu', '/platform/tour/ledger', 'data-pjax', '', 1, 0, 'tour.ledger', NULL, 10, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.ledger') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10010', p.id, CONCAT(p.path, '0009'), '线路成团', 'Tour Group', 'menu', '/platform/tour/group', 'data-pjax', '', 1, 0, 'tour.group', NULL, 11, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.group') t);
-- 给系统管理员默认授权,其他角色可在角色管理中按需分配。
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission IN (
'tour',
'tour.setting',
'tour.travelAgency',
'tour.route',
'tour.matter',
'tour.signup',
'tour.group',
'tour.mysignup',
'tour.unionledger',
'tour.unionApproval',
'tour.schoolUnionApproval',
'tour.ledger'
)
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
WHERE r.code = 'SYSADMIN'
AND rm.roleId IS NULL;
@@ -0,0 +1,3 @@
-- 疗休养配置增加出行人数指标,历史配置默认按 0 处理。
ALTER TABLE `tour_setting`
ADD COLUMN `travelPeopleQuota` int DEFAULT 0 COMMENT '出行人数指标' AFTER `tourType`;
@@ -0,0 +1,184 @@
-- 普惠疗休养基础配置表。
-- 若生产环境未开启 Nutz 自动建表,请先执行本脚本再使用“疗休养设置”菜单。
CREATE TABLE IF NOT EXISTS `tour_setting` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`configName` varchar(100) DEFAULT NULL COMMENT '疗休养配置名称',
`tourType` varchar(50) DEFAULT NULL COMMENT '疗休养类型',
`activityGroupId` varchar(32) DEFAULT NULL COMMENT '可参加人员范围ID',
`sortNo` int DEFAULT NULL COMMENT '排序编号',
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
`inProvinceYears` int DEFAULT 0 COMMENT '省内几年去一次',
`outProvinceYears` int DEFAULT NULL COMMENT '省外几年去一次',
`outProvinceRatio` decimal(10,2) DEFAULT NULL COMMENT '省外人数占比',
`outProvinceRatioType` varchar(50) DEFAULT '当年报名人数' COMMENT '省外人数占比类型',
`outProvinceFixedPeople` int DEFAULT 0 COMMENT '省外固定人数',
`cycleStartYear` int DEFAULT NULL COMMENT '周期开始年度',
`cycleEndYear` int DEFAULT NULL COMMENT '周期结束年度',
`cycleTotalCost` int DEFAULT NULL COMMENT '周期内总费用',
`cycleAllowedTimes` int DEFAULT NULL COMMENT '周期允许次数',
`allowFamily` tinyint(1) DEFAULT 0 COMMENT '是否允许携带家属',
`fillBedInfo` tinyint(1) DEFAULT 1 COMMENT '是否填报床位信息',
`enabled` tinyint(1) DEFAULT 1 COMMENT '是否启用',
`serviceNotice` text COMMENT '服务须知',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_setting_year` (`year`),
KEY `idx_tour_setting_activity_group` (`activityGroupId`),
KEY `idx_tour_setting_sort` (`sortNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养配置';
-- 疗休养配置标段表。
-- 标段先挂在配置上维护,后续线路、旅行社、报名等模块可继续通过 lotId 做业务关联。
CREATE TABLE IF NOT EXISTS `tour_setting_lot` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`settingId` varchar(32) DEFAULT NULL COMMENT '所属配置ID',
`lotName` varchar(50) DEFAULT NULL COMMENT '标段名称',
`lotValue` varchar(50) DEFAULT NULL COMMENT '标段值',
`activityCost` int DEFAULT NULL COMMENT '标段费用',
`allowOverReimbursement` tinyint(1) DEFAULT 0 COMMENT '允许超出报销',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_setting_lot_setting` (`settingId`),
KEY `idx_tour_setting_lot_value` (`lotValue`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养配置标段';
-- 旅行社管理表。
CREATE TABLE IF NOT EXISTS `tour_travel_agency` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`agencyCode` varchar(50) DEFAULT NULL COMMENT '旅行社编号',
`agencyName` varchar(100) DEFAULT NULL COMMENT '旅行社名称',
`contactName` varchar(30) DEFAULT NULL COMMENT '联系人',
`contactPhone` varchar(30) DEFAULT NULL COMMENT '联系人手机',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`remark` text COMMENT '备注',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`enabled` tinyint(1) DEFAULT 1 COMMENT '激活状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_travel_agency_year_code` (`year`, `agencyCode`),
KEY `idx_tour_travel_agency_name` (`agencyName`),
KEY `idx_tour_travel_agency_contact` (`contactName`, `contactPhone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养旅行社';
-- 线路管理表。
CREATE TABLE IF NOT EXISTS `tour_line` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '创建年度',
`lineCode` varchar(50) DEFAULT NULL COMMENT '线路编号',
`lineName` varchar(100) DEFAULT NULL COMMENT '线路名称',
`travelAgencyId` varchar(32) DEFAULT NULL COMMENT '旅行社ID',
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
`unitId` varchar(32) DEFAULT NULL COMMENT '所在单位ID',
`unitName` varchar(100) DEFAULT NULL COMMENT '所在单位',
`lineType` varchar(50) DEFAULT NULL COMMENT '线路类型',
`lotId` varchar(32) DEFAULT NULL COMMENT '时间标段ID',
`lineContent` text COMMENT '线路内容',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`openFlag` tinyint(1) DEFAULT 1 COMMENT '是否对外开放',
`directFamilyUnitLine` tinyint(1) DEFAULT 0 COMMENT '是否直系亲属线路',
`enabled` tinyint(1) DEFAULT 1 COMMENT '激活状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_line_year_code` (`year`, `lineCode`),
KEY `idx_tour_line_year` (`year`),
KEY `idx_tour_line_name` (`lineName`),
KEY `idx_tour_line_agency` (`travelAgencyId`),
KEY `idx_tour_line_creator` (`creatorUserId`),
KEY `idx_tour_line_unit` (`unitId`),
KEY `idx_tour_line_lot` (`lotId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养线路';
-- 疗休养事项表。
CREATE TABLE IF NOT EXISTS `tour_matter` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`matterName` varchar(100) DEFAULT NULL COMMENT '事项名称',
`settingId` varchar(32) DEFAULT NULL COMMENT '疗休养配置ID',
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_matter_year_name` (`year`, `matterName`),
KEY `idx_tour_matter_year` (`year`),
KEY `idx_tour_matter_creator` (`creatorUserId`),
KEY `idx_tour_matter_setting` (`settingId`),
KEY `idx_tour_matter_union` (`unionId`),
KEY `idx_tour_matter_org_type` (`organizationType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项';
-- 疗休养事项批次表。
CREATE TABLE IF NOT EXISTS `tour_matter_batch` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`matterId` varchar(32) DEFAULT NULL COMMENT '事项ID',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`batchName` varchar(100) DEFAULT NULL COMMENT '批次名称',
`signupStartTime` varchar(20) DEFAULT NULL COMMENT '报名开始时间',
`signupEndTime` varchar(20) DEFAULT NULL COMMENT '报名结束时间',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始时间',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束时间',
`changeDeadline` varchar(20) DEFAULT NULL COMMENT '变更截止时间',
`contactName` varchar(30) DEFAULT NULL COMMENT '联系人',
`contactPhone` varchar(30) DEFAULT NULL COMMENT '联系方式',
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
`estimatedCost` decimal(10,2) DEFAULT NULL COMMENT '预计费用',
`enabled` tinyint(1) DEFAULT 1 COMMENT '状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_matter_batch_matter` (`matterId`),
KEY `idx_tour_matter_batch_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项批次';
-- 直系亲属线路报名信息表。
CREATE TABLE IF NOT EXISTS `tour_ledger_direct_relative` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`ledgerId` varchar(32) DEFAULT NULL COMMENT '台账ID',
`relativeName` varchar(100) DEFAULT NULL COMMENT '亲属姓名',
`unitName` varchar(100) DEFAULT NULL COMMENT '所在单位',
`relationshipCode` varchar(50) DEFAULT NULL COMMENT '亲属关系编码',
`relationshipName` varchar(50) DEFAULT NULL COMMENT '亲属关系',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`lineName` varchar(100) DEFAULT NULL COMMENT '线路名称',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始日期',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束日期',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_ledger_direct_relative_ledger` (`ledgerId`),
KEY `idx_tour_ledger_direct_relative_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养直系亲属线路报名信息';
@@ -0,0 +1,17 @@
-- 疗休养配置分工会人员分配表,人员数量合计受配置的出行人数指标约束。
CREATE TABLE IF NOT EXISTS `tour_setting_union_quota` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`settingId` varchar(32) DEFAULT NULL COMMENT '所属疗休养配置ID',
`unionId` varchar(32) DEFAULT NULL COMMENT '分工会ID',
`unionName` varchar(100) DEFAULT NULL COMMENT '分工会名称',
`peopleQuota` int DEFAULT 0 COMMENT '人员数量',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_setting_union_quota_setting_union` (`settingId`, `unionId`),
KEY `idx_tour_setting_union_quota_setting` (`settingId`),
KEY `idx_tour_setting_union_quota_union` (`unionId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='疗休养配置分工会人员分配';
@@ -170,6 +170,16 @@ module.exports = {
type: Number,
default: 300
},
// 富文本编辑器占位提示,透传给 wangEditor 初始化配置。
placeholder: {
type: String,
default: ""
},
// 编辑区顶部红色提示,只做展示,不写入编辑器正文内容。
topTip: {
type: String,
default: ""
},
menus: {
type: Array,
default: () => {
@@ -205,13 +215,18 @@ module.exports = {
data() {
return {
editor: null,
cursorPos: 0
cursorPos: 0,
topTipElement: null
}
},
mounted() {
this.initEditor()
},
beforeDestroy() {
this.removeTopTip()
},
watch: {
value: {
handler: function (newValue) {
@@ -229,6 +244,13 @@ module.exports = {
})
},
immediate: true
},
topTip: {
handler: function () {
this.$nextTick(() => {
this.renderTopTip()
})
}
}
},
@@ -266,7 +288,43 @@ module.exports = {
this.editor.config.pasteFilterStyle = false
this.editor.config.height = this.height
this.editor.config.menus = this.menus
// wangEditor 的 placeholder 必须在 create 前设置,父页面传入才会生效。
this.editor.config.placeholder = this.placeholder
this.editor.create()
this.renderTopTip()
},
renderTopTip() {
if (!this.editor || !this.$refs.editorRef) {
return
}
const textContainer = this.$refs.editorRef.querySelector(".w-e-text-container")
if (!textContainer) {
return
}
if (!this.topTip) {
this.removeTopTip()
return
}
if (!this.topTipElement) {
this.topTipElement = document.createElement("div")
this.topTipElement.setAttribute("contenteditable", "false")
this.topTipElement.style.color = "#f56c6c"
this.topTipElement.style.fontSize = "12px"
this.topTipElement.style.lineHeight = "20px"
this.topTipElement.style.padding = "6px 10px 0"
this.topTipElement.style.userSelect = "none"
this.topTipElement.style.pointerEvents = "none"
}
// 提示节点放在可编辑正文区域外层,保证用户无法删除且保存内容不携带该提示。
this.topTipElement.innerText = this.topTip
if (textContainer.firstChild !== this.topTipElement) {
textContainer.insertBefore(this.topTipElement, textContainer.firstChild)
}
},
removeTopTip() {
if (this.topTipElement && this.topTipElement.parentNode) {
this.topTipElement.parentNode.removeChild(this.topTipElement)
}
},
uploadFiles(resultFiles) {
return resultFiles.map(async (file) => {
@@ -133,6 +133,12 @@ module.exports = {
default: 1024 * 1024 * 10,
required: false
},
// 是否限制上传文件大小,默认保留原有大小校验逻辑。
limit_upload_size: {
type: Boolean,
default: true,
required: false
},
// 上传按钮文字
upload_text: {
type: String,
@@ -216,7 +222,7 @@ module.exports = {
} else {
tips = tips + '不限格式;'
}
if (fileSize) {
if (this.limit_upload_size && fileSize) {
tips = tips + `单个文件大小不能超过<span style="color: red">${fileSize / 1024 / 1024}</span>M`
}
return tips
@@ -313,7 +319,8 @@ module.exports = {
// 这是兜底逻辑,保准只让这个image类型上传图片
beforeUpload(file) {
if (file.size > this.upload_size) {
// 需要兼容部分业务不限制附件大小,关闭后仅跳过大小校验,不影响数量和格式控制。
if (this.limit_upload_size && file.size > this.upload_size) {
this.$message.error("文件过大,请上传小于" + (this.upload_size / 1024 / 1024).toFixed(0) + "M的文件!")
return false
}
@@ -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()
}
})

Some files were not shown because too many files have changed in this diff Show More