新增web端职代会管理(职代会届次取值teacher_congress_session表数据);

This commit is contained in:
2026-07-29 14:57:41 +08:00
parent 704bc278fa
commit 8bff6f8ce9
34 changed files with 3841 additions and 0 deletions
@@ -0,0 +1,170 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/materials/manage")
@Ok("json:full")
public class CongressMaterialsManageController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/materials/manage/index.html")
@SaCheckPermission("congress.materials.manage")
public void index() {
}
@At("/sessions")
@SaCheckPermission("congress.materials.manage")
public Result sessions() {
return Result.success(congressManageService.sessionOptions());
}
@At("/types")
@SaCheckPermission("congress.materials.manage")
public Result types() {
return Result.success(congressManageService.typeOptions());
}
@At("/pageData")
@SaCheckPermission("congress.materials.manage")
public Result materialsPageData(PageForm pageForm,
@Param("sessionId") String sessionId,
@Param("typeId") String typeId,
@Param("name") String name) {
StringBuilder text = new StringBuilder("""
SELECT
m.id,
m.name,
m.session_id AS sessionId,
m.time_id AS timeId,
m.type_id AS typeId,
m.sort_no AS sortNo,
m.file_name AS fileName,
m.file_url AS fileUrl,
m.file_type AS fileType,
m.file_size AS fileSize,
m.create_time AS createTime,
mt.name AS typeName,
tcs.fullName AS sessionName
FROM congress_materials m
LEFT JOIN congress_materials_type mt ON mt.id = m.type_id
LEFT JOIN teacher_congress_session tcs ON tcs.id = m.session_id
WHERE COALESCE(m.deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
congressManageService.appendEquals(text, params, "m.session_id", "sessionId", sessionId);
congressManageService.appendEquals(text, params, "m.type_id", "typeId", typeId);
if (StrUtil.isNotBlank(name)) {
text.append(" AND m.name LIKE @name");
params.addv("name", "%" + name.trim() + "%");
}
text.append(" ORDER BY m.sort_no, m.create_time DESC, m.id DESC");
return congressManageService.page(pageForm, text.toString(), params);
}
@At("/get")
@SaCheckPermission("congress.materials.manage")
public Result materialsGet(@Param("id") String id) {
return Result.success(congressManageService.fetchMap("""
SELECT
id,
name,
session_id AS sessionId,
time_id AS timeId,
type_id AS typeId,
sort_no AS sortNo,
file_name AS fileName,
file_url AS fileUrl,
file_type AS fileType,
file_size AS fileSize
FROM congress_materials
WHERE id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)));
}
@At("/save")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.materials.manage")
@SLog(tag = "职代会-会议资料", msg = "保存会议资料")
public Result materialsSave(@Param("id") String id,
@Param("name") String name,
@Param("sessionId") String sessionId,
@Param("typeId") String typeId,
@Param("sortNo") Integer sortNo,
@Param("fileName") String fileName,
@Param("fileUrl") String fileUrl,
@Param("fileType") String fileType,
@Param("fileSize") String fileSize) {
if (StrUtil.hasBlank(name, sessionId, typeId, fileUrl)) {
return Result.error("届次、资料名称、资料类型和文件不能为空");
}
Date now = new Date();
Chain chain = Chain.make("name", name.trim())
.add("session_id", sessionId)
.add("time_id", null)
.add("type_id", typeId)
.add("sort_no", sortNo == null ? 0 : sortNo)
.add("file_name", StrUtil.blankToDefault(fileName, name.trim()))
.add("file_url", fileUrl)
.add("file_type", StrUtil.blankToDefault(fileType, null))
.add("file_size", StrUtil.blankToDefault(fileSize, null))
.add("update_time", now);
if (StrUtil.isBlank(id)) {
String newId = R.UU32();
chain.add("id", newId)
.add("create_time", now)
.add("deleted", 0);
dao.insert("congress_materials", chain);
return Result.success(newId);
}
dao.update("congress_materials", chain,
Cnd.where("id", "=", id).and("deleted", "=", 0));
return Result.success(id);
}
@At("/delete")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.materials.manage")
@SLog(tag = "职代会-会议资料", msg = "删除会议资料")
public Result materialsDelete(@Param("id") String id) {
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_voting_issue
WHERE materials_id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)) > 0) {
return Result.error("该资料已关联投票议题,不能删除");
}
congressManageService.softDelete("congress_materials", id);
return Result.success();
}
}
@@ -0,0 +1,132 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/materials/type")
@Ok("json:full")
public class CongressMaterialsTypeController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/materials/type/index.html")
@SaCheckPermission("congress.materials.type")
public void index() {
}
@At("/pageData")
@SaCheckPermission("congress.materials.type")
public Result typePageData(PageForm pageForm,
@Param("name") String name,
@Param("isVote") String isVote) {
StringBuilder text = new StringBuilder("""
SELECT id, name, is_vote AS isVote, sort_no AS sortNo, create_time AS createTime
FROM congress_materials_type
WHERE COALESCE(deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
if (StrUtil.isNotBlank(name)) {
text.append(" AND name LIKE @name");
params.addv("name", "%" + name.trim() + "%");
}
if (StrUtil.isNotBlank(isVote)) {
text.append(" AND is_vote = @isVote");
params.addv("isVote", "1".equals(isVote) || "true".equalsIgnoreCase(isVote) ? 1 : 0);
}
text.append(" ORDER BY sort_no, create_time, id");
return congressManageService.page(pageForm, text.toString(), params);
}
@At("/get")
@SaCheckPermission("congress.materials.type")
public Result typeGet(@Param("id") String id) {
return Result.success(congressManageService.fetchMap("""
SELECT id, name, is_vote AS isVote, sort_no AS sortNo
FROM congress_materials_type
WHERE id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)));
}
@At("/save")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.materials.type")
@SLog(tag = "职代会-资料类型", msg = "保存资料类型")
public Result typeSave(@Param("id") String id,
@Param("name") String name,
@Param("isVote") boolean isVote,
@Param("sortNo") Integer sortNo) {
if (StrUtil.isBlank(name)) {
return Result.error("资料类型不能为空");
}
int repeat = congressManageService.count("""
SELECT COUNT(1)
FROM congress_materials_type
WHERE name = @name
AND COALESCE(deleted, 0) = 0
AND (@id IS NULL OR id <> @id)
""", NutMap.NEW().addv("name", name.trim()).addv("id", StrUtil.blankToDefault(id, null)));
if (repeat > 0) {
return Result.error("资料类型已存在");
}
Date now = new Date();
Chain chain = Chain.make("name", name.trim())
.add("is_vote", isVote ? 1 : 0)
.add("sort_no", sortNo == null ? 0 : sortNo)
.add("update_time", now);
if (StrUtil.isBlank(id)) {
chain.add("id", R.UU32())
.add("create_time", now)
.add("deleted", 0);
dao.insert("congress_materials_type", chain);
} else {
dao.update("congress_materials_type", chain,
Cnd.where("id", "=", id).and("deleted", "=", 0));
}
return Result.success();
}
@At("/delete")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.materials.type")
@SLog(tag = "职代会-资料类型", msg = "删除资料类型")
public Result typeDelete(@Param("id") String id) {
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_materials
WHERE type_id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)) > 0) {
return Result.error("该类型下已有资料,不能删除");
}
congressManageService.softDelete("congress_materials_type", id);
return Result.success();
}
}
@@ -0,0 +1,92 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/record")
@Ok("json:full")
public class CongressRecordController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/record/index.html")
@SaCheckPermission("congress.signIn.record")
public void index() {
}
@At("/sessions")
@SaCheckPermission("congress.signIn.record")
public Result sessions() {
return Result.success(congressManageService.sessionOptions());
}
@At("/meetings")
@SaCheckPermission("congress.signIn.record")
public Result meetings(@Param("sessionId") String sessionId) {
return Result.success(congressManageService.meetingOptions(sessionId));
}
@At("/pageData")
@SaCheckPermission("congress.signIn.record")
public Result recordPageData(PageForm pageForm,
@Param("sessionId") String sessionId,
@Param("meetingId") String meetingId,
@Param("keyword") String keyword) {
StringBuilder text = new StringBuilder("""
SELECT
si.id,
si.emplid,
si.name,
si.create_time AS signInTime,
si.meeting_id AS meetingId,
si.time_id AS timeId,
m.meeting_name AS meetingName,
m.sign_in_start_time AS signInStartTime,
m.sign_in_end_time AS signInEndTime,
tcs.fullName AS sessionName,
COALESCE(r.delegation_name, d.name) AS delegationName
FROM congress_sign_in si
LEFT JOIN congress_sign_in_meeting m ON m.id = si.meeting_id
LEFT JOIN teacher_congress_session tcs ON tcs.id = si.session_id AND tcs.delFlag = 0
LEFT JOIN congress_rep r ON r.id = si.rep_id
LEFT JOIN congress_delegation d ON d.id = si.delegation_id
WHERE COALESCE(si.deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
congressManageService.appendEquals(text, params, "si.session_id", "sessionId", sessionId);
congressManageService.appendEquals(text, params, "si.meeting_id", "meetingId", meetingId);
if (StrUtil.isNotBlank(keyword)) {
text.append(" AND (si.emplid LIKE @keyword OR si.name LIKE @keyword)");
params.addv("keyword", "%" + keyword.trim() + "%");
}
text.append(" ORDER BY si.create_time DESC, si.id DESC");
return congressManageService.page(pageForm, text.toString(), params);
}
}
@@ -0,0 +1,155 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/signIn")
@Ok("json:full")
public class CongressSignInController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/signIn/index.html")
@SaCheckPermission("congress.signIn.manage")
public void index() {
}
@At("/sessions")
@SaCheckPermission("congress.signIn.manage")
public Result sessions() {
return Result.success(congressManageService.sessionOptions());
}
@At("/pageData")
@SaCheckPermission("congress.signIn.manage")
public Result signInPageData(PageForm pageForm, @Param("sessionId") String sessionId) {
StringBuilder text = new StringBuilder("""
SELECT
m.id,
m.meeting_name AS meetingName,
m.sign_in_start_time AS signInStartTime,
m.sign_in_end_time AS signInEndTime,
m.session_id AS sessionId,
m.time_id AS timeId,
m.remark,
tcs.fullName AS sessionName,
(
SELECT COUNT(1)
FROM congress_sign_in si
WHERE si.meeting_id = m.id
AND COALESCE(si.deleted, 0) = 0
) AS signInCount
FROM congress_sign_in_meeting m
LEFT JOIN teacher_congress_session tcs ON tcs.id = m.session_id AND tcs.delFlag = 0
WHERE COALESCE(m.deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
congressManageService.appendEquals(text, params, "m.session_id", "sessionId", sessionId);
text.append(" ORDER BY m.sign_in_start_time DESC, m.create_time DESC, m.id DESC");
return congressManageService.page(pageForm, text.toString(), params);
}
@At("/get")
@SaCheckPermission("congress.signIn.manage")
public Result signInGet(@Param("id") String id) {
return Result.success(congressManageService.fetchMap("""
SELECT
id,
meeting_name AS meetingName,
sign_in_start_time AS signInStartTime,
sign_in_end_time AS signInEndTime,
session_id AS sessionId,
time_id AS timeId,
remark
FROM congress_sign_in_meeting
WHERE id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)));
}
@At("/save")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.signIn.manage")
@SLog(tag = "职代会-会议签到", msg = "保存会议签到配置")
public Result signInSave(@Param("id") String id,
@Param("meetingName") String meetingName,
@Param("sessionId") String sessionId,
@Param("signInStartTime") String signInStartTime,
@Param("signInEndTime") String signInEndTime,
@Param("remark") String remark) {
if (StrUtil.hasBlank(meetingName, sessionId, signInStartTime, signInEndTime)) {
return Result.error("届次、会议名称和签到时间不能为空");
}
Date startTime = congressManageService.parseDate(signInStartTime);
Date endTime = congressManageService.parseDate(signInEndTime);
if (startTime == null || endTime == null) {
return Result.error("签到时间格式不正确");
}
if (!endTime.after(startTime)) {
return Result.error("签到结束时间必须晚于开始时间");
}
Date now = new Date();
Chain chain = Chain.make("meeting_name", meetingName.trim())
.add("session_id", sessionId)
.add("time_id", null)
.add("sign_in_start_time", startTime)
.add("sign_in_end_time", endTime)
.add("remark", StrUtil.blankToDefault(remark, null))
.add("update_time", now);
if (StrUtil.isBlank(id)) {
chain.add("id", R.UU32())
.add("sign_in_count", 0)
.add("create_time", now)
.add("deleted", 0);
dao.insert("congress_sign_in_meeting", chain);
} else {
dao.update("congress_sign_in_meeting", chain,
Cnd.where("id", "=", id).and("deleted", "=", 0));
}
return Result.success();
}
@At("/delete")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.signIn.manage")
@SLog(tag = "职代会-会议签到", msg = "删除会议签到配置")
public Result signInDelete(@Param("id") String id) {
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_sign_in
WHERE meeting_id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)) > 0) {
return Result.error("该会议已有签到记录,不能删除");
}
congressManageService.softDelete("congress_sign_in_meeting", id);
return Result.success();
}
}
@@ -0,0 +1,217 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/materials/issue")
@Ok("json:full")
public class CongressVotingIssueController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/materials/issue/index.html")
@SaCheckPermission("congress.vote.issue")
public void index() {
}
@At("/sessions")
@SaCheckPermission("congress.vote.issue")
public Result sessions() {
return Result.success(congressManageService.sessionOptions());
}
@At("/types")
@SaCheckPermission("congress.vote.issue")
public Result types() {
return Result.success(congressManageService.typeOptions());
}
@At("/materials")
@SaCheckPermission("congress.vote.issue")
public Result materials(@Param("sessionId") String sessionId, @Param("typeId") String typeId) {
return Result.success(congressManageService.materialOptions(sessionId, typeId));
}
@At("/pageData")
@SaCheckPermission("congress.vote.issue")
public Result issuePageData(PageForm pageForm,
@Param("sessionId") String sessionId,
@Param("name") String name) {
StringBuilder text = new StringBuilder("""
SELECT
i.id,
i.name,
i.description,
i.session_id AS sessionId,
i.time_id AS timeId,
i.type_id AS typeId,
i.materials_id AS materialsId,
i.voting_start_time AS votingStartTime,
i.voting_end_time AS votingEndTime,
mt.name AS typeName,
m.name AS materialsName,
m.file_name AS fileName,
m.file_url AS fileUrl,
tcs.fullName AS sessionName,
(
SELECT COUNT(1)
FROM congress_voting_record r
WHERE r.issue_id = i.id
AND COALESCE(r.deleted, 0) = 0
) AS voteCount
FROM congress_voting_issue i
LEFT JOIN congress_materials_type mt ON mt.id = i.type_id
LEFT JOIN congress_materials m ON m.id = i.materials_id
LEFT JOIN teacher_congress_session tcs ON tcs.id = i.session_id AND tcs.delFlag = 0
WHERE COALESCE(i.deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
congressManageService.appendEquals(text, params, "i.session_id", "sessionId", sessionId);
if (StrUtil.isNotBlank(name)) {
text.append(" AND i.name LIKE @name");
params.addv("name", "%" + name.trim() + "%");
}
text.append(" ORDER BY i.create_time DESC, i.id DESC");
return congressManageService.page(pageForm, text.toString(), params);
}
@At("/get")
@SaCheckPermission("congress.vote.issue")
public Result issueGet(@Param("id") String id) {
return Result.success(congressManageService.fetchMap("""
SELECT
id,
name,
description,
content,
session_id AS sessionId,
time_id AS timeId,
type_id AS typeId,
materials_id AS materialsId,
voting_type AS votingType,
voting_start_time AS votingStartTime,
voting_end_time AS votingEndTime,
voting_content AS votingContent,
voting_content_item_header AS votingContentItemHeader,
voting_content_option_header AS votingContentOptionHeader
FROM congress_voting_issue
WHERE id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)));
}
@At("/save")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.vote.issue")
@SLog(tag = "职代会-投票管理", msg = "保存投票议题")
public Result issueSave(@Param("id") String id,
@Param("name") String name,
@Param("description") String description,
@Param("sessionId") String sessionId,
@Param("typeId") String typeId,
@Param("materialsId") String materialsId,
@Param("votingStartTime") String votingStartTime,
@Param("votingEndTime") String votingEndTime,
@Param("votingContent") String votingContent,
@Param("votingContentItemHeader") String votingContentItemHeader,
@Param("votingContentOptionHeader") String votingContentOptionHeader) {
if (StrUtil.hasBlank(name, sessionId, typeId, materialsId,
votingStartTime, votingEndTime, votingContent)) {
return Result.error("届次、会议名称、投票类型、资料、投票时间和投票内容不能为空");
}
Date startTime = congressManageService.parseDate(votingStartTime);
Date endTime = congressManageService.parseDate(votingEndTime);
if (startTime == null || endTime == null || !endTime.after(startTime)) {
return Result.error("投票结束时间必须晚于开始时间");
}
if (!JSONUtil.isTypeJSONArray(votingContent) || JSONUtil.parseArray(votingContent).isEmpty()) {
return Result.error("请至少配置一个投票事项");
}
NutMap session = congressManageService.fetchMap("""
SELECT id, fullName AS `sessionName`
FROM teacher_congress_session
WHERE id = @id
AND delFlag = 0
""", NutMap.NEW().addv("id", sessionId));
if (session == null) {
return Result.error("所选届次不存在");
}
Date now = new Date();
Chain chain = Chain.make("name", name.trim())
.add("description", StrUtil.blankToDefault(description, null))
.add("session_id", sessionId)
.add("session_name", session.getString("sessionName"))
.add("time_id", null)
.add("time_name", null)
.add("type_id", typeId)
.add("materials_id", materialsId)
.add("voting_type", 1)
.add("voting_start_time", startTime)
.add("voting_end_time", endTime)
.add("voting_content", votingContent)
.add("voting_content_item_header", StrUtil.blankToDefault(votingContentItemHeader, "表决事项"))
.add("voting_content_option_header", StrUtil.blankToDefault(votingContentOptionHeader, "表决内容"))
.add("update_time", now);
if (StrUtil.isBlank(id)) {
chain.add("id", R.UU32())
.add("create_time", now)
.add("deleted", 0);
dao.insert("congress_voting_issue", chain);
} else {
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_voting_record
WHERE issue_id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)) > 0) {
return Result.error("该议题已有投票记录,不能修改");
}
dao.update("congress_voting_issue", chain,
Cnd.where("id", "=", id).and("deleted", "=", 0));
}
return Result.success();
}
@At("/delete")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("congress.vote.issue")
@SLog(tag = "职代会-投票管理", msg = "删除投票议题")
public Result issueDelete(@Param("id") String id) {
if (congressManageService.count("""
SELECT COUNT(1)
FROM congress_voting_record
WHERE issue_id = @id
AND COALESCE(deleted, 0) = 0
""", NutMap.NEW().addv("id", id)) > 0) {
return Result.error("该议题已有投票记录,不能删除");
}
congressManageService.softDelete("congress_voting_issue", id);
return Result.success();
}
}
@@ -0,0 +1,134 @@
package com.budwk.app.zhgh.democratic.congress.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.democratic.congress.service.CongressManageService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.Date;
@IocBean
@At("/platform/congress/materials/statistical")
@Ok("json:full")
public class CongressVotingStatisticalController {
@Inject
private Dao dao;
@Inject
private CongressManageService congressManageService;
@At("/index")
@Ok("beetl:/platform/zhgh/democratic/congress/materials/statistical/index.html")
@SaCheckPermission("congress.vote.statistical")
public void index() {
}
@At("/sessions")
@SaCheckPermission("congress.vote.statistical")
public Result sessions() {
return Result.success(congressManageService.sessionOptions());
}
@At("/pageData")
@SaCheckPermission("congress.vote.statistical")
public Result statisticalPageData(PageForm pageForm,
@Param("sessionId") String sessionId,
@Param("name") String name) {
StringBuilder text = new StringBuilder("""
SELECT
i.id,
i.name,
i.description,
i.session_id AS sessionId,
i.time_id AS timeId,
i.type_id AS typeId,
i.materials_id AS materialsId,
i.voting_start_time AS votingStartTime,
i.voting_end_time AS votingEndTime,
mt.name AS typeName,
m.name AS materialsName,
m.file_name AS fileName,
m.file_url AS fileUrl,
tcs.fullName AS sessionName,
(
SELECT COUNT(1)
FROM congress_voting_record r
WHERE r.issue_id = i.id
AND COALESCE(r.deleted, 0) = 0
) AS voteCount
FROM congress_voting_issue i
LEFT JOIN congress_materials_type mt ON mt.id = i.type_id
LEFT JOIN congress_materials m ON m.id = i.materials_id
LEFT JOIN teacher_congress_session tcs ON tcs.id = i.session_id AND tcs.delFlag = 0
WHERE COALESCE(i.deleted, 0) = 0
""");
NutMap params = NutMap.NEW();
congressManageService.appendEquals(text, params, "i.session_id", "sessionId", sessionId);
if (StrUtil.isNotBlank(name)) {
text.append(" AND i.name LIKE @name");
params.addv("name", "%" + name.trim() + "%");
}
text.append(" ORDER BY i.create_time DESC, i.id DESC");
return congressManageService.page(pageForm, text.toString(), params);
}
@At("/records")
@SaCheckPermission("congress.vote.statistical")
public Result voteRecords(@Param("issueId") String issueId) {
Sql sql = Sqls.create("""
SELECT
r.id,
r.emplid,
r.name,
r.vote_result AS voteResult,
r.create_time AS createTime,
COALESCE(rep.union_id, du.union_id) AS unionId,
du.union_name AS unionName,
COALESCE(rep.delegation_name, d.name) AS delegationName
FROM congress_voting_record r
LEFT JOIN congress_rep rep ON rep.id = r.rep_id
LEFT JOIN congress_delegation d ON d.id = r.delegation_id
LEFT JOIN (
SELECT delegation_id, time_id, union_id, union_name
FROM (
SELECT
delegation_id,
time_id,
union_id,
union_name,
ROW_NUMBER() OVER (
PARTITION BY delegation_id, time_id
ORDER BY create_time DESC, id DESC
) AS row_num
FROM congress_delegation_union
WHERE COALESCE(deleted, 0) = 0
) latest_union
WHERE row_num = 1
) du ON du.delegation_id = r.delegation_id AND du.time_id = r.time_id
WHERE r.issue_id = @issueId
AND COALESCE(r.deleted, 0) = 0
ORDER BY r.create_time DESC, r.id DESC
""");
sql.setParam("issueId", issueId);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
return Result.success(sql.getList(NutMap.class));
}
}
@@ -0,0 +1,48 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.ColDefine;
import org.nutz.dao.entity.annotation.ColType;
import org.nutz.dao.entity.annotation.Column;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Default;
import java.io.Serializable;
import java.util.Date;
/**
* 职代会历史表公共审计字段。
*
* <p>这些表使用下划线字段和 DATETIME 时间,不能继承使用驼峰字段、时间戳的通用 BaseModel。</p>
*/
@Data
public abstract class CongressBaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column("create_by")
@Comment("创建人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String createBy;
@Column("create_time")
@Comment("创建时间")
@ColDefine(type = ColType.DATETIME)
private Date createTime;
@Column("update_by")
@Comment("修改人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String updateBy;
@Column("update_time")
@Comment("修改时间")
@ColDefine(type = ColType.DATETIME)
private Date updateTime;
@Column("deleted")
@Comment("删除标记")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean deleted;
}
@@ -0,0 +1,74 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_committee_elect_quota")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会委员预选分配")
@TableIndexes({
@Index(name = "idx_congress_committee_elect_quota_session", fields = {"sessionId"}, unique = false)
})
public class CongressCommitteeElectQuota extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("zbztjmes")
@Comment("筹备组推荐名额数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer zbztjmes;
@Column("wyhyxrs")
@Comment("委员会预选人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer wyhyxrs;
@Column("dbttjzs")
@Comment("代表团推荐总数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer dbttjzs;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("first_preselected_begin_time")
@Comment("第一次预选开始时间")
@ColDefine(type = ColType.DATETIME)
private Date firstPreselectedBeginTime;
@Column("first_preselected_end_time")
@Comment("第一次预选结束时间")
@ColDefine(type = ColType.DATETIME)
private Date firstPreselectedEndTime;
@Column("second_preselected_begin_time")
@Comment("第二次预选开始时间")
@ColDefine(type = ColType.DATETIME)
private Date secondPreselectedBeginTime;
@Column("second_preselected_end_time")
@Comment("第二次预选结束时间")
@ColDefine(type = ColType.DATETIME)
private Date secondPreselectedEndTime;
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_committee_elect_rep")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会委员推选")
@TableIndexes({
@Index(name = "idx_congress_committee_elect_rep_session", fields = {"sessionId"}, unique = false),
@Index(name = "idx_congress_committee_elect_rep_delegation", fields = {"delegationId"}, unique = false)
})
public class CongressCommitteeElectRep extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("rep_id")
@Comment("代表ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String repId;
@Column("type")
@Comment("推选类型")
@ColDefine(type = ColType.INT)
private Integer type;
@Column("times")
@Comment("第几次")
@ColDefine(type = ColType.INT)
private Integer times;
@Column("user_id")
@Comment("团长用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
}
@@ -0,0 +1,80 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_delegation")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表团")
@TableIndexes({
@Index(name = "idx_congress_delegation_time", fields = {"timeId"}, unique = false)
})
public class CongressDelegation extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("name")
@Comment("代表团名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("time_name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String timeName;
@Column("code")
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String code;
@Column("official_number")
@Comment("正式代表人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer officialNumber;
@Column("attendance_number")
@Comment("列席代表人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer attendanceNumber;
@Column("invite_number")
@Comment("特邀代表人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer inviteNumber;
@Column("committee_allot_number")
@Comment("委员分配人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer committeeAllotNumber;
}
@@ -0,0 +1,76 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_delegation_head")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表团团长")
@TableIndexes({
@Index(name = "idx_congress_delegation_head_delegation", fields = {"delegationId"}, unique = false)
})
public class CongressDelegationHead extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("user_id")
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column("emplid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String emplid;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("unit")
@Comment("单位")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unit;
@Column("mobile")
@Comment("电话")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String mobile;
@Column("sex")
@Comment("性别")
@ColDefine(type = ColType.INT)
private Integer sex;
@Column("identity")
@Comment("身份")
@ColDefine(type = ColType.INT)
private Integer identity;
}
@@ -0,0 +1,66 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_delegation_rep")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表团代表")
@TableIndexes({
@Index(name = "idx_congress_delegation_rep_delegation", fields = {"delegationId"}, unique = false)
})
public class CongressDelegationRep extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("user_id")
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column("empid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String empid;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("unit")
@Comment("单位")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unit;
@Column("mobile")
@Comment("电话")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String mobile;
@Column("sex")
@Comment("性别")
@ColDefine(type = ColType.INT)
private Integer sex;
@Column("identity")
@Comment("身份")
@ColDefine(type = ColType.INT)
private Integer identity;
}
@@ -0,0 +1,47 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_delegation_union")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表团工会")
@TableIndexes({
@Index(name = "idx_congress_delegation_union_delegation", fields = {"delegationId"}, unique = false),
@Index(name = "idx_congress_delegation_union_time", fields = {"timeId"}, unique = false)
})
public class CongressDelegationUnion extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("union_id")
@Comment("工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column("union_name")
@Comment("工会名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unionName;
}
@@ -0,0 +1,72 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_materials")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会资料")
@TableIndexes({
@Index(name = "idx_congress_materials_time_type", fields = {"timeId", "typeId"}, unique = false)
})
public class CongressMaterials extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("type_id")
@Comment("资料类型ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String typeId;
@Column("sort_no")
@Comment("排序")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer sortNo;
@Column("name")
@Comment("资料名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("file_name")
@Comment("文件名")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String fileName;
@Column("file_url")
@Comment("文件地址")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String fileUrl;
@Column("file_type")
@Comment("文件类型")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String fileType;
@Column("file_size")
@Comment("文件大小")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String fileSize;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_materials_type")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会资料类型")
public class CongressMaterialsType extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("sort_no")
@Comment("排序")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer sortNo;
@Column("name")
@Comment("名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("is_vote")
@Comment("是否表决类")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isVote;
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_org")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会机构")
@TableIndexes({
@Index(name = "idx_congress_org_session", fields = {"sessionId"}, unique = false),
@Index(name = "idx_congress_org_parent", fields = {"parentId"}, unique = false)
})
public class CongressOrg extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("name")
@Comment("机构名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("code")
@Comment("机构代码")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String code;
@Column("type")
@Comment("机构类别")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String type;
@Column("remark")
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String remark;
@Column("parent_id")
@Comment("父节点")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String parentId;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
}
@@ -0,0 +1,87 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_org_member")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会机构成员")
@TableIndexes({
@Index(name = "idx_congress_org_member_org", fields = {"orgId"}, unique = false),
@Index(name = "idx_congress_org_member_session", fields = {"sessionId"}, unique = false)
})
public class CongressOrgMember extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("user_id")
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column("empid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String empid;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("unit")
@Comment("单位")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unit;
@Column("mobile")
@Comment("电话")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String mobile;
@Column("sex")
@Comment("性别")
@ColDefine(type = ColType.INT)
private Integer sex;
@Column("identity")
@Comment("身份")
@ColDefine(type = ColType.INT)
private Integer identity;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("org_id")
@Comment("机构ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String orgId;
@Column("role_id")
@Comment("角色ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String roleId;
@Column("role_name")
@Comment("角色名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String roleName;
}
@@ -0,0 +1,171 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_rep")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表")
@TableIndexes({
@Index(name = "idx_congress_rep_emplid", fields = {"emplid"}, unique = false),
@Index(name = "idx_congress_rep_time_emplid", fields = {"timeId", "emplid"}, unique = false),
@Index(name = "idx_congress_rep_session_id", fields = {"sessionId"}, unique = false)
})
public class CongressRep extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("time_name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String timeName;
@Column("user_id")
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("emplid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String emplid;
@Column("sex")
@Comment("性别")
@ColDefine(type = ColType.VARCHAR, width = 16)
private String sex;
@Column("birthdate")
@Comment("出生日期")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String birthdate;
@Column("politics_status")
@Comment("政治面貌")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String politicsStatus;
@Column("position")
@Comment("职务")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String position;
@Column("education")
@Comment("学历")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String education;
@Column("work_unit")
@Comment("工作单位")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String workUnit;
@Column("work_experience")
@Comment("工作经历")
@ColDefine(type = ColType.TEXT)
private String workExperience;
@Column("tags")
@Comment("标签")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String tags;
@Column("filling_status")
@Comment("填报状态")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String fillingStatus;
@Column("identity")
@Comment("身份")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String identity;
@Column("type")
@Comment("代表类型")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String type;
@Column("is_gdh")
@Comment("是否工代会代表")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isGdh;
@Column("is_zdh")
@Comment("是否职代会代表")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isZdh;
@Column("union_id")
@Comment("工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("delegation_name")
@Comment("代表团名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String delegationName;
@Column("supplement")
@Comment("补充说明")
@ColDefine(type = ColType.TEXT)
private String supplement;
@Column("status")
@Comment("状态")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer status;
@Column("precinct_union_id")
@Comment("选区工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String precinctUnionId;
@Column("precinct_union_name")
@Comment("选区工会名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String precinctUnionName;
@Column("nation")
@Comment("民族")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String nation;
}
@@ -0,0 +1,111 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_rep_supplement")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会代表增补")
@TableIndexes({
@Index(name = "idx_congress_rep_supplement_time", fields = {"timeId"}, unique = false)
})
public class CongressRepSupplement extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("precinct_union_id")
@Comment("选区")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String precinctUnionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("time_name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String timeName;
@Column("add_user_id")
@Comment("增加代表用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String addUserId;
@Column("add_user_union_id")
@Comment("增加代表工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String addUserUnionId;
@Column("add_user_name")
@Comment("增加代表姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String addUserName;
@Column("add_emplid")
@Comment("增加代表工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String addEmplid;
@Column("sub_user_id")
@Comment("替换代表用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String subUserId;
@Column("sub_user_name")
@Comment("替换代表姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String subUserName;
@Column("sub_emplid")
@Comment("替换代表工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String subEmplid;
@Column("reason")
@Comment("原因")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String reason;
@Column("add_precinct_union_id")
@Comment("增加选区工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String addPrecinctUnionId;
@Column("add_precinct_union_name")
@Comment("增加选区工会名")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String addPrecinctUnionName;
@Column("sub_precinct_union_id")
@Comment("替换选区工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String subPrecinctUnionId;
@Column("sub_precinct_union_name")
@Comment("替换选区工会名")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String subPrecinctUnionName;
@Column("type")
@Comment("类型")
@ColDefine(type = ColType.INT)
private Integer type;
}
@@ -0,0 +1,66 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_sessions")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会届次")
@TableIndexes({
@Index(name = "idx_congress_sessions_union_id", fields = {"unionId"}, unique = false)
})
public class CongressSessions extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("year")
@Comment("年份")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String year;
@Column("description")
@Comment("描述")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String description;
@Column("sc_session")
@Comment("省产届次")
@ColDefine(type = ColType.INT)
private Integer scSession;
@Column("uc_session")
@Comment("校产届次")
@ColDefine(type = ColType.INT)
private Integer ucSession;
@Column("union_id")
@Comment("工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column("type")
@Comment("会类型")
@ColDefine(type = ColType.INT)
private Integer type;
@Column("union_name")
@Comment("工会名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unionName;
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_sign_in")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会签到记录")
@TableIndexes({
@Index(name = "uk_congress_sign_in_rep_meeting", fields = {"repId", "meetingId", "deleted"}, unique = true),
@Index(name = "idx_congress_sign_in_meeting", fields = {"meetingId"}, unique = false)
})
public class CongressSignIn extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("meeting_id")
@Comment("签到会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String meetingId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("rep_id")
@Comment("代表ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String repId;
@Column("emplid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String emplid;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_sign_in_meeting")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会签到会议")
@TableIndexes({
@Index(name = "idx_congress_sign_in_meeting_time", fields = {"timeId"}, unique = false)
})
public class CongressSignInMeeting extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("meeting_name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String meetingName;
@Column("sign_in_start_time")
@Comment("签到开始时间")
@ColDefine(type = ColType.DATETIME)
private Date signInStartTime;
@Column("sign_in_end_time")
@Comment("签到结束时间")
@ColDefine(type = ColType.DATETIME)
private Date signInEndTime;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("remark")
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String remark;
@Column("sign_in_count")
@Comment("签到人数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer signInCount;
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_times")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会会议")
@TableIndexes({
@Index(name = "idx_congress_times_session_id", fields = {"sessionId"}, unique = false)
})
public class CongressTimes extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("year")
@Comment("年份")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String year;
@Column("name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("sc_times")
@Comment("省产次数")
@ColDefine(type = ColType.INT)
private Integer scTimes;
@Column("uc_times")
@Comment("校产次数")
@ColDefine(type = ColType.INT)
private Integer ucTimes;
}
@@ -0,0 +1,69 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_union")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会工会名额")
@TableIndexes({
@Index(name = "idx_congress_union_session", fields = {"sessionId"}, unique = false),
@Index(name = "idx_congress_union_delegation", fields = {"delegationId"}, unique = false)
})
public class CongressUnion extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("union_id")
@Comment("工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column("union_name")
@Comment("工会名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unionName;
@Column("quota_config")
@Comment("名额配置")
@ColDefine(type = ColType.TEXT)
private String quotaConfig;
@Column("member_number")
@Comment("会员数")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer memberNumber;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("sort_no")
@Comment("排序")
@ColDefine(type = ColType.INT)
@Default("0")
private Integer sortNo;
}
@@ -0,0 +1,107 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_voting_issue")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会议题表决")
@TableIndexes({
@Index(name = "idx_congress_voting_issue_materials", fields = {"materialsId"}, unique = false),
@Index(name = "idx_congress_voting_issue_time", fields = {"timeId"}, unique = false)
})
public class CongressVotingIssue extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("session_name")
@Comment("届次名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String sessionName;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("time_name")
@Comment("会议名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String timeName;
@Column("name")
@Comment("议题名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String name;
@Column("description")
@Comment("描述")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String description;
@Column("content")
@Comment("内容")
@ColDefine(type = ColType.TEXT)
private String content;
@Column("voting_type")
@Comment("表决类型")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String votingType;
@Column("voting_start_time")
@Comment("表决开始时间")
@ColDefine(type = ColType.DATETIME)
private Date votingStartTime;
@Column("voting_end_time")
@Comment("表决结束时间")
@ColDefine(type = ColType.DATETIME)
private Date votingEndTime;
@Column("voting_content")
@Comment("表决内容")
@ColDefine(type = ColType.TEXT)
private String votingContent;
@Column("voting_content_item_header")
@Comment("表决项表头")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String votingContentItemHeader;
@Column("voting_content_option_header")
@Comment("表决选项表头")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String votingContentOptionHeader;
@Column("materials_id")
@Comment("资料ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String materialsId;
@Column("type_id")
@Comment("资料类型ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String typeId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
}
@@ -0,0 +1,72 @@
package com.budwk.app.zhgh.democratic.congress.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("congress_voting_record")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("职代会表决记录")
@TableIndexes({
@Index(name = "uk_congress_voting_record_rep_issue", fields = {"repId", "issueId", "deleted"}, unique = true),
@Index(name = "idx_congress_voting_record_issue", fields = {"issueId"}, unique = false)
})
public class CongressVotingRecord extends CongressBaseModel {
@Name
@Comment("主键")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column("issue_id")
@Comment("议题ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String issueId;
@Column("rep_id")
@Comment("代表ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String repId;
@Column("emplid")
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 64)
private String emplid;
@Column("name")
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column("session_id")
@Comment("届次ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String sessionId;
@Column("time_id")
@Comment("会议ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String timeId;
@Column("delegation_id")
@Comment("代表团ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String delegationId;
@Column("vote_result")
@Comment("表决结果")
@ColDefine(type = ColType.TEXT)
private String voteResult;
@Column("user_id")
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
}
@@ -0,0 +1,151 @@
package com.budwk.app.zhgh.democratic.congress.service;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
/**
* 职代会管理公共服务类。
*
* <p>本服务不注册页面路由,只集中维护六个菜单控制器共用的查询和基础操作。</p>
*/
@IocBean
public class CongressManageService {
@Inject
private Dao dao;
@Inject
private BaseService<?> baseService;
public List<NutMap> sessionOptions() {
return listMaps("""
SELECT id AS `id`, fullName AS `fullName`
FROM teacher_congress_session
WHERE delFlag = 0
ORDER BY startDate desc, createdAt desc
""");
}
public List<NutMap> typeOptions() {
return listMaps("""
SELECT id, name, sort_no AS sortNo, is_vote AS isVote
FROM congress_materials_type
WHERE COALESCE(deleted, 0) = 0
ORDER BY sort_no, create_time, id
""");
}
public List<NutMap> meetingOptions(String sessionId) {
Sql sql = Sqls.create("""
SELECT id, meeting_name AS meetingName
FROM congress_sign_in_meeting
WHERE COALESCE(deleted, 0) = 0
AND session_id = @sessionId
ORDER BY sign_in_start_time DESC, create_time DESC
""");
sql.setParam("sessionId", sessionId);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
return sql.getList(NutMap.class);
}
public List<NutMap> materialOptions(String sessionId, String typeId) {
StringBuilder sqlText = new StringBuilder("""
SELECT
m.id,
m.name,
m.type_id AS typeId,
m.file_name AS fileName,
m.file_url AS fileUrl
FROM congress_materials m
WHERE COALESCE(m.deleted, 0) = 0
AND m.session_id = @sessionId
""");
if (StrUtil.isNotBlank(typeId)) {
sqlText.append(" AND m.type_id = @typeId");
}
sqlText.append(" ORDER BY m.sort_no, m.create_time DESC");
Sql sql = Sqls.create(sqlText.toString());
sql.setParam("sessionId", sessionId);
sql.setParam("typeId", typeId);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
return sql.getList(NutMap.class);
}
public Result page(PageForm pageForm, String sqlText, NutMap params) {
Sql sql = Sqls.create(sqlText);
params.forEach(sql::setParam);
Pagination pagination = baseService.listPageMap(
pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
public List<NutMap> listMaps(String sqlText) {
Sql sql = Sqls.create(sqlText);
sql.setCallback(Sqls.callback.maps());
dao.execute(sql);
return sql.getList(NutMap.class);
}
public NutMap fetchMap(String sqlText, NutMap params) {
Sql sql = Sqls.create(sqlText);
params.forEach(sql::setParam);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
return sql.getObject(NutMap.class);
}
public int count(String sqlText, NutMap params) {
Sql sql = Sqls.create(sqlText);
params.forEach(sql::setParam);
sql.setCallback(Sqls.callback.integer());
dao.execute(sql);
return sql.getInt();
}
public void softDelete(String tableName, String id) {
dao.update(tableName,
Chain.make("deleted", 1).add("update_time", new Date()),
Cnd.where("id", "=", id).and("deleted", "=", 0));
}
public Date parseDate(String value) {
if (StrUtil.isBlank(value)) {
return null;
}
try {
return DateUtil.parse(value);
} catch (Exception e) {
return null;
}
}
public void appendEquals(StringBuilder sql, NutMap params,
String column, String paramName, Object value) {
if (value instanceof String && StrUtil.isBlank((String) value)) {
return;
}
if (value == null) {
return;
}
sql.append(" AND ").append(column).append(" = @").append(paramName);
params.addv(paramName, value);
}
}
@@ -0,0 +1,228 @@
-- 职代会电脑端菜单(MySQL 8)。
-- 不包含库名前缀,可重复执行。
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
'congress_pc_root', '',
LPAD(IFNULL(MAX(CAST(`path` AS UNSIGNED)), 0) + 1, 4, '0'),
'职代会管理', 'Congress', 'menu', '', '', 'ti-agenda',
1, 0, 'congress', NULL, 1, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'z', 0, 0
FROM sys_menu
WHERE (parentId IS NULL OR parentId = '') AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress') t
);
-- 一级分组:会议资料(排序 6)。
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
'congress_pc_materials', p.id, CONCAT(p.path, '0006'),
'会议资料', 'Congress Materials', 'menu', '', '', 'ti-file',
1, 0, 'congress.materials', NULL, 6, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'h', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.materials') t
);
-- 一级分组:会议签到(排序 7)。
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
'congress_pc_signin', p.id, CONCAT(p.path, '0007'),
'会议签到', 'Congress Sign In', 'menu', '', '', 'ti-calendar',
1, 0, 'congress.signIn', NULL, 7, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'h', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.signIn') t
);
-- 一级分组:会议投票(排序 8)。
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
'congress_pc_vote', p.id, CONCAT(p.path, '0008'),
'会议投票', 'Congress Vote', 'menu', '', '', 'ti-bar-chart',
1, 0, 'congress.vote', NULL, 8, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'h', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.vote') 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
'congress_pc_signin_manage', p.id, CONCAT(p.path, '0001'),
'会议管理', 'Meeting Manage', 'menu', '/platform/congress/signIn/index', 'data-pjax', 'ti-layout-grid2',
1, 0, 'congress.signIn.manage', NULL, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'h', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.signIn'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.signIn.manage') 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
'congress_pc_signin_record', p.id, CONCAT(p.path, '0002'),
'签到记录', 'Sign In Record', 'menu', '/platform/congress/record/index', 'data-pjax', 'ti-layout-grid2',
1, 0, 'congress.signIn.record', NULL, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'q', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.signIn'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.signIn.record') 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
'congress_pc_vote_issue', p.id, CONCAT(p.path, '0001'),
'投票管理', 'Vote Manage', 'menu', '/platform/congress/materials/issue/index', 'data-pjax', 'ti-menu-alt',
1, 0, 'congress.vote.issue', NULL, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 't', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.vote'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.vote.issue') 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
'congress_pc_vote_statistics', p.id, CONCAT(p.path, '0002'),
'投票统计', 'Vote Statistics', 'menu', '/platform/congress/materials/statistical/index', 'data-pjax', 'ti-menu-alt',
1, 0, 'congress.vote.statistical', NULL, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 't', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.vote'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.vote.statistical') 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
'congress_pc_materials_manage', p.id, CONCAT(p.path, '0002'),
'资料管理', 'Materials Manage', 'menu', '/platform/congress/materials/manage/index', 'data-pjax', 'ti-file',
1, 0, 'congress.materials.manage', NULL, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'z', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.materials'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.materials.manage') 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
'congress_pc_materials_type', p.id, CONCAT(p.path, '0001'),
'资料类型', 'Materials Type', 'menu', '/platform/congress/materials/type/index', 'data-pjax', 'ti-share-alt',
1, 0, 'congress.materials.type', NULL, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000,
'', UNIX_TIMESTAMP(NOW()) * 1000,
0, 'PC', NULL, NULL, 'z', 0, 0
FROM sys_menu p
WHERE p.permission = 'congress.materials'
AND NOT EXISTS (
SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'congress.materials.type') t
);
-- 兼容已执行过旧版脚本的数据:根菜单和分组菜单只负责展开,不请求后台地址。
UPDATE sys_menu
SET href = '',
target = '',
updatedBy = '',
updatedAt = UNIX_TIMESTAMP(NOW()) * 1000
WHERE id IN (
'congress_pc_root',
'congress_pc_materials',
'congress_pc_signin',
'congress_pc_vote'
);
-- 系统管理员默认拥有模块菜单,其他角色在角色管理中按需授权。
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission IN (
'congress',
'congress.signIn',
'congress.signIn.manage',
'congress.signIn.record',
'congress.vote',
'congress.vote.issue',
'congress.vote.statistical',
'congress.materials',
'congress.materials.manage',
'congress.materials.type'
)
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,295 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="届次">
<el-select v-model="pageForm.sessionId" clearable filterable placeholder="请选择届次">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="会议名称">
<el-input v-model.trim="pageForm.name" clearable placeholder="请输入会议名称"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="投票管理">
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="name" label="会议名称" min-width="200" show-overflow-tooltip></el-table-column>
<el-table-column label="届次" min-width="220">
<template slot-scope="{row}">{{row.sessionName}}</template>
</el-table-column>
<el-table-column prop="typeName" label="投票类型" min-width="130"></el-table-column>
<el-table-column prop="materialsName" label="投票资料" min-width="180" show-overflow-tooltip>
<template slot-scope="{row}">
<el-link v-if="row.fileUrl" type="primary" :href="row.fileUrl" target="_blank">
{{row.materialsName}}
</el-link>
<span v-else>{{row.materialsName || "-"}}</span>
</template>
</el-table-column>
<el-table-column label="投票时间" min-width="300">
<template slot-scope="{row}">
{{formatDate(row.votingStartTime)}} 至 {{formatDate(row.votingEndTime)}}
</template>
</el-table-column>
<el-table-column prop="voteCount" label="已投人数" width="90" align="center"></el-table-column>
<el-table-column label="操作" width="160" fixed="right" align="center">
<template slot-scope="{row}">
<el-button type="text" :disabled="row.voteCount > 0" @click="openEdit(row.id)">编辑</el-button>
<el-divider direction="vertical"></el-divider>
<el-button type="text" class="text-danger" :disabled="row.voteCount > 0"
@click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="formData.id ? '编辑投票' : '新增投票'" :visible.sync="dialogFormVisible"
width="850px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="届次" prop="sessionId">
<el-select v-model="formData.sessionId" filterable style="width:100%" @change="sessionChanged">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投票类型" prop="typeId">
<el-select v-model="formData.typeId" filterable style="width:100%" @change="typeChanged">
<el-option v-for="item in voteTypeOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="会议名称" prop="name">
<el-input v-model.trim="formData.name" maxlength="255" show-word-limit></el-input>
</el-form-item>
<el-form-item label="资料" prop="materialsId">
<el-select v-model="formData.materialsId" filterable style="width:100%"
:disabled="!formData.sessionId || !formData.typeId">
<el-option v-for="item in materialOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="投票开始" prop="votingStartTime">
<el-date-picker v-model="formData.votingStartTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="投票结束" prop="votingEndTime">
<el-date-picker v-model="formData.votingEndTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-form-item label="事项表头">
<el-input v-model.trim="formData.votingContentItemHeader" placeholder="表决事项"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="选项表头">
<el-input v-model.trim="formData.votingContentOptionHeader" placeholder="表决内容"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="投票内容" required>
<el-table :data="voteItems" border size="small">
<el-table-column label="表决事项" min-width="230">
<template slot-scope="{row}">
<el-input v-model.trim="row.itemName" maxlength="255" placeholder="请输入表决事项"></el-input>
</template>
</el-table-column>
<el-table-column label="表决选项(逗号分隔)" min-width="330">
<template slot-scope="{row}">
<el-input v-model.trim="row.optionsText" placeholder="赞成,不赞成,弃权"></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="80" align="center">
<template slot-scope="scope">
<el-button type="text" class="text-danger" @click="removeVoteItem(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-button class="mt10" size="small" icon="el-icon-plus" @click="addVoteItem">添加表决事项</el-button>
</el-form-item>
<el-form-item label="投票说明">
<el-input v-model.trim="formData.description" type="textarea" :rows="3"
maxlength="1000" show-word-limit></el-input>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="doSave">确定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
const validateEnd = (rule, value, callback) => {
if (!value) return callback(new Error("请选择投票结束时间"))
if (this.formData.votingStartTime && value <= this.formData.votingStartTime) {
return callback(new Error("投票结束时间必须晚于开始时间"))
}
callback()
}
return {
pageDataUrl: "/platform/congress/materials/issue/pageData",
sessionOptions: [],
typeOptions: [],
materialOptions: [],
voteItems: [],
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, sessionId: "", name: ""},
formData: {},
formRules: {
sessionId: [{required: true, message: "请选择届次", trigger: "change"}],
typeId: [{required: true, message: "请选择投票类型", trigger: "change"}],
name: [{required: true, message: "请输入会议名称", trigger: "blur"}],
materialsId: [{required: true, message: "请选择资料", trigger: "change"}],
votingStartTime: [{required: true, message: "请选择投票开始时间", trigger: "change"}],
votingEndTime: [{required: true, validator: validateEnd, trigger: "change"}]
}
}
},
computed: {
voteTypeOptions() {
return this.typeOptions.filter(v => !!v.isVote)
}
},
methods: {
formatDate(value) {
return value ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : "-"
},
async loadOptions() {
const [sessionsRes, typesRes] = await Promise.all([
this.$axios.post("/platform/congress/materials/issue/sessions"),
this.$axios.post("/platform/congress/materials/issue/types")
])
if (sessionsRes.code === 0) this.sessionOptions = sessionsRes.data || []
if (typesRes.code === 0) this.typeOptions = typesRes.data || []
},
async loadMaterials() {
this.materialOptions = []
if (!this.formData.sessionId || !this.formData.typeId) return
const res = await this.$axios.post("/platform/congress/materials/issue/materials", {
sessionId: this.formData.sessionId,
typeId: this.formData.typeId
})
if (res.code === 0) this.materialOptions = res.data || []
},
async sessionChanged() {
this.formData.materialsId = ""
await this.loadMaterials()
},
async typeChanged() {
this.formData.materialsId = ""
await this.loadMaterials()
},
addVoteItem() {
this.voteItems.push({itemName: "", optionsText: "赞成,不赞成,弃权"})
},
removeVoteItem(index) {
this.voteItems.splice(index, 1)
},
openAdd() {
this.formData = {
name: "", sessionId: "", typeId: "", materialsId: "",
votingStartTime: "", votingEndTime: "", description: "",
votingContentItemHeader: "表决事项", votingContentOptionHeader: "表决内容"
}
this.voteItems = [{itemName: "", optionsText: "赞成,不赞成,弃权"}]
this.materialOptions = []
this.dialogFormVisible = true
this.$nextTick(() => this.$refs.formRef && this.$refs.formRef.clearValidate())
},
async openEdit(id) {
const res = await this.$axios.post("/platform/congress/materials/issue/get", {id})
if (res.code !== 0) return
const data = res.data || {}
data.votingStartTime = this.formatDate(data.votingStartTime)
data.votingEndTime = this.formatDate(data.votingEndTime)
this.formData = data
try {
this.voteItems = JSON.parse(data.votingContent || "[]").map(item => ({
itemName: item.itemName || item.item || "",
optionsText: (item.options || []).join(",")
}))
} catch (e) {
this.voteItems = []
}
await this.loadMaterials()
this.dialogFormVisible = true
},
buildVotingContent() {
const items = this.voteItems.map(item => ({
itemName: (item.itemName || "").trim(),
options: (item.optionsText || "").split(/[,]/)
.map(v => v.trim()).filter(Boolean)
}))
if (!items.length || items.some(item => !item.itemName || !item.options.length)) {
this.$message.warning("请完整填写每个表决事项及表决选项")
return null
}
return JSON.stringify(items)
},
doSave() {
this.$refs.formRef.validate(async valid => {
if (!valid) return
const votingContent = this.buildVotingContent()
if (!votingContent) return
this.submitLoading = true
try {
const data = Object.assign({}, this.formData, {votingContent})
const res = await this.$axios.post("/platform/congress/materials/issue/save", data)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.pageData()
} else {
this.$message.error(res.msg)
}
} finally {
this.submitLoading = false
}
})
},
doDelete(id) {
this.$confirm("确认删除该投票议题吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/issue/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
},
async created() {
await this.loadOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,231 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="届次">
<el-select v-model="pageForm.sessionId" clearable filterable placeholder="请选择届次">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="资料类型">
<el-select v-model="pageForm.typeId" clearable filterable placeholder="请选择资料类型">
<el-option v-for="item in typeOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="资料名称">
<el-input v-model.trim="pageForm.name" clearable placeholder="请输入资料名称"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="资料管理">
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="name" label="资料名称" min-width="200" show-overflow-tooltip></el-table-column>
<el-table-column prop="typeName" label="资料类型" min-width="140"></el-table-column>
<el-table-column label="届次" min-width="220">
<template slot-scope="{row}">{{row.sessionName}}</template>
</el-table-column>
<el-table-column prop="sortNo" label="排序号" width="90" align="center"></el-table-column>
<el-table-column prop="fileName" label="文件" min-width="180" show-overflow-tooltip>
<template slot-scope="{row}">
<el-link v-if="row.fileUrl" type="primary" :href="row.fileUrl" target="_blank">
{{row.fileName || row.name}}
</el-link>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" width="160" fixed="right" align="center">
<template slot-scope="{row}">
<el-button type="text" @click="openEdit(row.id)">编辑</el-button>
<el-divider direction="vertical"></el-divider>
<el-button type="text" class="text-danger" @click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="formData.id ? '编辑资料' : '新增资料'" :visible.sync="dialogFormVisible"
width="700px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="届次" prop="sessionId">
<el-select v-model="formData.sessionId" filterable style="width:100%">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="资料类型" prop="typeId">
<el-select v-model="formData.typeId" filterable style="width:100%">
<el-option v-for="item in typeOptions" :key="item.id"
:label="item.name" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="资料名称" prop="name">
<el-input v-model.trim="formData.name" maxlength="255" show-word-limit
placeholder="不需要填写,默认是上传文件名称"></el-input>
</el-form-item>
<el-form-item label="排序号" prop="sortNo">
<el-input-number v-model="formData.sortNo" :min="0" :max="9999" style="width:100%"></el-input-number>
</el-form-item>
<el-form-item label="上传文件" prop="files">
<file-upload :value.sync="formData.files" :upload_number="1"
upload_result_type="url" upload_result_category="array"
complete_result accept=".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx"></file-upload>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="doSave">确定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/congress/materials/manage/pageData",
sessionOptions: [],
typeOptions: [],
pageForm: {
pageNumber: 1, pageSize: 10, totalCount: 0,
sessionId: "", typeId: "", name: ""
},
formData: {},
formRules: {
sessionId: [{required: true, message: "请选择届次", trigger: "change"}],
typeId: [{required: true, message: "请选择资料类型", trigger: "change"}],
name: [{required: true, message: "请输入资料名称", trigger: "blur"}],
files: [{required: true, message: "请上传文件", trigger: "change"}]
}
}
},
methods: {
async loadOptions() {
const [sessionsRes, typesRes] = await Promise.all([
this.$axios.post("/platform/congress/materials/manage/sessions"),
this.$axios.post("/platform/congress/materials/manage/types")
])
if (sessionsRes.code === 0) this.sessionOptions = sessionsRes.data || []
if (typesRes.code === 0) this.typeOptions = typesRes.data || []
},
openAdd() {
this.formData = {
name: "", sessionId: "", typeId: "",
sortNo: 0, fileName: "", fileUrl: "", fileType: "", fileSize: "", files: []
}
this.dialogFormVisible = true
this.$nextTick(() => this.$refs.formRef && this.$refs.formRef.clearValidate())
},
async openEdit(id) {
const res = await this.$axios.post("/platform/congress/materials/manage/get", {id})
if (res.code === 0) {
const data = res.data || {}
this.formData = Object.assign({}, data, {
files: this.buildUploadFiles(data)
})
this.dialogFormVisible = true
}
},
buildUploadFiles(data) {
if (!data || !data.fileUrl) return []
return [{
name: data.fileName || this.fileNameFromUrl(data.fileUrl) || data.name || "附件",
url: data.fileUrl,
status: "success",
response: {
code: 0,
data: data.fileUrl
}
}]
},
fileNameFromUrl(url) {
if (!url) return ""
const path = String(url).split("?")[0]
const name = path.substring(path.lastIndexOf("/") + 1)
try {
return decodeURIComponent(name)
} catch (e) {
return name
}
},
fileNameWithoutExt(name) {
return name ? String(name).replace(/\.[^/.]+$/, "") : ""
},
getUploadFileUrl(file) {
return file && file.response && file.response.data ? file.response.data : file && (file.url || file.data) || ""
},
syncUploadFiles(files) {
const file = Array.isArray(files) && files.length > 0 ? files[files.length - 1] : null
if (!file) {
this.$set(this.formData, "fileName", "")
this.$set(this.formData, "fileUrl", "")
this.$set(this.formData, "fileType", "")
this.$set(this.formData, "fileSize", "")
return
}
const fileName = file.name || this.fileNameFromUrl(this.getUploadFileUrl(file))
this.$set(this.formData, "fileName", fileName)
this.$set(this.formData, "fileUrl", this.getUploadFileUrl(file))
this.$set(this.formData, "fileType", file.raw && file.raw.type ? file.raw.type : file.type || "")
this.$set(this.formData, "fileSize", file.raw && file.raw.size ? file.raw.size : file.size || "")
if (!this.formData.name && fileName) {
this.$set(this.formData, "name", this.fileNameWithoutExt(fileName))
}
},
doSave() {
this.syncUploadFiles(this.formData.files)
this.$refs.formRef.validate(async valid => {
if (!valid) return
this.submitLoading = true
try {
const res = await this.$axios.post("/platform/congress/materials/manage/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.pageData()
} else {
this.$message.error(res.msg)
}
} finally {
this.submitLoading = false
}
})
},
doDelete(id) {
this.$confirm("确认删除该会议资料吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/manage/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
},
watch: {
"formData.files": {
handler(files) {
this.syncUploadFiles(files)
},
deep: true
}
},
async created() {
await this.loadOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,170 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="届次">
<el-select v-model="pageForm.sessionId" clearable filterable placeholder="请选择届次">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="会议名称">
<el-input v-model.trim="pageForm.name" clearable placeholder="请输入会议名称"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="投票统计"></table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="name" label="会议名称" min-width="200" show-overflow-tooltip></el-table-column>
<el-table-column prop="typeName" label="投票类型" min-width="130"></el-table-column>
<el-table-column prop="materialsName" label="资料" min-width="180" show-overflow-tooltip>
<template slot-scope="{row}">
<el-link v-if="row.fileUrl" type="primary" :href="row.fileUrl" target="_blank">
{{row.materialsName}}
</el-link>
<span v-else>{{row.materialsName || "-"}}</span>
</template>
</el-table-column>
<el-table-column prop="voteCount" label="投票人数" width="100" align="center"></el-table-column>
<el-table-column label="届次" min-width="220">
<template slot-scope="{row}">{{row.sessionName}}</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template slot-scope="{row}">
<el-button type="text" @click="openDetail(row)">查看统计</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-drawer title="投票明细" :visible.sync="detailVisible" size="72%" :with-header="true">
<div style="padding:0 24px 24px">
<el-descriptions v-if="currentIssue.id" :column="2" border>
<el-descriptions-item label="会议名称">{{currentIssue.name}}</el-descriptions-item>
<el-descriptions-item label="届次">{{currentIssue.sessionName}}</el-descriptions-item>
<el-descriptions-item label="投票类型">{{currentIssue.typeName}}</el-descriptions-item>
<el-descriptions-item label="投票人数">{{currentIssue.voteCount}}</el-descriptions-item>
</el-descriptions>
<el-tabs v-model="detailTab" class="mt10">
<el-tab-pane label="投票统计" name="summary">
<el-table :data="summaryData" border v-loading="detailLoading">
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="itemName" label="投票项目/人员" min-width="200"></el-table-column>
<el-table-column prop="option" label="投票选项" min-width="160"></el-table-column>
<el-table-column prop="count" label="票数" width="100" align="center"></el-table-column>
<el-table-column label="占比" width="120" align="center">
<template slot-scope="{row}">{{percent(row.count, row.itemTotal)}}</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="投票记录" name="records">
<el-table :data="recordData" border v-loading="detailLoading">
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="emplid" label="工号" min-width="110"></el-table-column>
<el-table-column prop="name" label="代表" min-width="100"></el-table-column>
<el-table-column prop="unionName" label="工会" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column prop="delegationName" label="代表团" min-width="150" show-overflow-tooltip></el-table-column>
<el-table-column label="投票结果" min-width="260" show-overflow-tooltip>
<template slot-scope="{row}">{{voteResultText(row.voteResult)}}</template>
</el-table-column>
<el-table-column label="投票时间" min-width="170">
<template slot-scope="{row}">{{formatDate(row.createTime)}}</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</div>
</el-drawer>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/congress/materials/statistical/pageData",
sessionOptions: [],
detailVisible: false,
detailLoading: false,
detailTab: "summary",
currentIssue: {},
recordData: [],
summaryData: [],
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, sessionId: "", name: ""}
}
},
methods: {
formatDate(value) {
return value ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : "-"
},
percent(count, total) {
return total ? (count * 100 / total).toFixed(2) + "%" : "0.00%"
},
parseVoteResult(value) {
if (!value) return []
try {
const data = typeof value === "string" ? JSON.parse(value) : value
return Array.isArray(data) ? data : []
} catch (e) {
return []
}
},
voteResultText(value) {
return this.parseVoteResult(value).map(item => {
return (item.item || item.itemName || "投票项") + "" +
(item.selected || item.option || item.value || "-")
}).join("")
},
buildSummary(records) {
const counter = {}
records.forEach(record => {
this.parseVoteResult(record.voteResult).forEach(item => {
const itemName = item.item || item.itemName || "投票项"
const option = item.selected || item.option || item.value || "-"
if (!counter[itemName]) counter[itemName] = {}
counter[itemName][option] = (counter[itemName][option] || 0) + 1
})
})
const rows = []
Object.keys(counter).forEach(itemName => {
const itemTotal = Object.values(counter[itemName]).reduce((sum, count) => sum + count, 0)
Object.keys(counter[itemName]).forEach(option => {
rows.push({itemName, option, count: counter[itemName][option], itemTotal})
})
})
return rows
},
async loadOptions() {
const res = await this.$axios.post("/platform/congress/materials/statistical/sessions")
if (res.code === 0) this.sessionOptions = res.data || []
},
async openDetail(row) {
this.currentIssue = row
this.detailVisible = true
this.detailLoading = true
this.detailTab = "summary"
try {
const res = await this.$axios.post("/platform/congress/materials/statistical/records", {issueId: row.id})
if (res.code === 0) {
this.recordData = res.data || []
this.summaryData = this.buildSummary(this.recordData)
}
} finally {
this.detailLoading = false
}
}
},
async created() {
await this.loadOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,130 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="资料类型">
<el-input v-model.trim="pageForm.name" clearable placeholder="请输入资料类型"></el-input>
</search-item>
<search-item label="是否投票">
<el-select v-model="pageForm.isVote" clearable placeholder="请选择">
<el-option label="是" value="1"></el-option>
<el-option label="否" value="0"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="资料类型">
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="name" label="资料类型" min-width="220"></el-table-column>
<el-table-column label="是否投票" width="120" align="center">
<template slot-scope="{row}">
<el-tag :type="row.isVote ? 'success' : 'info'" size="small">{{row.isVote ? "是" : "否"}}</el-tag>
</template>
</el-table-column>
<el-table-column prop="sortNo" label="排序号" width="120" align="center"></el-table-column>
<el-table-column label="操作" width="160" align="center">
<template slot-scope="{row}">
<el-button type="text" @click="openEdit(row.id)">编辑</el-button>
<el-divider direction="vertical"></el-divider>
<el-button type="text" class="text-danger" @click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="formData.id ? '编辑资料类型' : '新增资料类型'"
:visible.sync="dialogFormVisible" width="520px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="资料类型" prop="name">
<el-input v-model.trim="formData.name" maxlength="100" show-word-limit></el-input>
</el-form-item>
<el-form-item label="是否投票" prop="isVote">
<el-radio-group v-model="formData.isVote">
<el-radio :label="true"></el-radio>
<el-radio :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排序号" prop="sortNo">
<el-input-number v-model="formData.sortNo" :min="0" :max="9999" style="width:100%"></el-input-number>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="doSave">确定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/congress/materials/type/pageData",
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, name: "", isVote: ""},
formData: {},
formRules: {
name: [{required: true, message: "请输入资料类型", trigger: "blur"}],
sortNo: [{required: true, message: "请输入排序号", trigger: "change"}]
}
}
},
methods: {
openAdd() {
this.formData = {name: "", isVote: false, sortNo: 0}
this.dialogFormVisible = true
this.$nextTick(() => this.$refs.formRef && this.$refs.formRef.clearValidate())
},
async openEdit(id) {
const res = await this.$axios.post("/platform/congress/materials/type/get", {id})
if (res.code === 0) {
this.formData = res.data || {}
this.formData.isVote = !!this.formData.isVote
this.dialogFormVisible = true
}
},
doSave() {
this.$refs.formRef.validate(async valid => {
if (!valid) return
this.submitLoading = true
try {
const res = await this.$axios.post("/platform/congress/materials/type/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.pageData()
} else {
this.$message.error(res.msg)
}
} finally {
this.submitLoading = false
}
})
},
doDelete(id) {
this.$confirm("确认删除该资料类型吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/materials/type/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
},
created() {
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,84 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="届次">
<el-select v-model="pageForm.sessionId" clearable filterable placeholder="请选择届次" @change="loadMeetings">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="会议名称">
<el-select v-model="pageForm.meetingId" clearable filterable :disabled="!pageForm.sessionId">
<el-option v-for="item in meetingOptions" :key="item.id"
:label="item.meetingName" :value="item.id"></el-option>
</el-select>
</search-item>
<search-item label="关键字">
<el-input v-model.trim="pageForm.keyword" clearable placeholder="请输入工号或姓名"></el-input>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="签到记录"></table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="emplid" label="工号" min-width="120"></el-table-column>
<el-table-column prop="name" label="姓名" min-width="100"></el-table-column>
<el-table-column prop="meetingName" label="会议名称" min-width="200" show-overflow-tooltip></el-table-column>
<el-table-column label="届次" min-width="220">
<template slot-scope="{row}">{{row.sessionName}}</template>
</el-table-column>
<el-table-column prop="delegationName" label="代表团" min-width="160" show-overflow-tooltip></el-table-column>
<el-table-column label="签到状态" width="100" align="center">
<template><el-tag type="success" size="small">已签到</el-tag></template>
</el-table-column>
<el-table-column label="签到时间" min-width="170">
<template slot-scope="{row}">{{formatDate(row.signInTime)}}</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
return {
pageDataUrl: "/platform/congress/record/pageData",
sessionOptions: [],
meetingOptions: [],
pageForm: {
pageNumber: 1, pageSize: 10, totalCount: 0,
sessionId: "", meetingId: "", keyword: ""
}
}
},
methods: {
formatDate(value) {
return value ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : "-"
},
async loadOptions() {
const res = await this.$axios.post("/platform/congress/record/sessions")
if (res.code === 0) this.sessionOptions = res.data || []
},
async loadMeetings() {
this.pageForm.meetingId = ""
this.meetingOptions = []
if (!this.pageForm.sessionId) return
const res = await this.$axios.post("/platform/congress/record/meetings", {sessionId: this.pageForm.sessionId})
if (res.code === 0) this.meetingOptions = res.data || []
}
},
async created() {
await this.loadOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -0,0 +1,162 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="届次">
<el-select v-model="pageForm.sessionId" clearable filterable placeholder="请选择届次">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="会议管理">
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd">新增</el-button>
</table-tool>
<el-table :data="tableData" v-loading="tableLoading" class="vi-table">
<el-table-column type="index" :index="indexMethod" label="序号" width="70" align="center"></el-table-column>
<el-table-column prop="meetingName" label="会议名称" min-width="220" show-overflow-tooltip></el-table-column>
<el-table-column label="届次" min-width="220">
<template slot-scope="{row}">{{row.sessionName}}</template>
</el-table-column>
<el-table-column label="签到时间" min-width="300">
<template slot-scope="{row}">
{{formatDate(row.signInStartTime)}} 至 {{formatDate(row.signInEndTime)}}
</template>
</el-table-column>
<el-table-column prop="signInCount" label="签到人数" width="100" align="center"></el-table-column>
<el-table-column prop="remark" label="备注" min-width="160" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" width="160" fixed="right" align="center">
<template slot-scope="{row}">
<el-button type="text" @click="openEdit(row.id)">编辑</el-button>
<el-divider direction="vertical"></el-divider>
<el-button type="text" class="text-danger" @click="doDelete(row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog :title="formData.id ? '编辑会议' : '新增会议'" :visible.sync="dialogFormVisible"
width="620px" :close-on-click-modal="false">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="届次" prop="sessionId">
<el-select v-model="formData.sessionId" filterable style="width:100%">
<el-option v-for="item in sessionOptions" :key="item.id"
:label="item.fullName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="会议名称" prop="meetingName">
<el-input v-model.trim="formData.meetingName" maxlength="255" show-word-limit></el-input>
</el-form-item>
<el-form-item label="签到开始" prop="signInStartTime">
<el-date-picker v-model="formData.signInStartTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"></el-date-picker>
</el-form-item>
<el-form-item label="签到结束" prop="signInEndTime">
<el-date-picker v-model="formData.signInEndTime" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"></el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model.trim="formData.remark" type="textarea" :rows="3"
maxlength="1000" show-word-limit></el-input>
</el-form-item>
</el-form>
<span slot="footer">
<el-button @click="dialogFormVisible=false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="doSave">确定</el-button>
</span>
</el-dialog>
</div>
<script nonce="${cspNonce!}">
new Vue({
el: "#app",
mixins: [initTableMixins],
data() {
const validateEnd = (rule, value, callback) => {
if (!value) return callback(new Error("请选择签到结束时间"))
if (this.formData.signInStartTime && value <= this.formData.signInStartTime) {
return callback(new Error("签到结束时间必须晚于开始时间"))
}
callback()
}
return {
pageDataUrl: "/platform/congress/signIn/pageData",
sessionOptions: [],
pageForm: {pageNumber: 1, pageSize: 10, totalCount: 0, sessionId: ""},
formData: {},
formRules: {
sessionId: [{required: true, message: "请选择届次", trigger: "change"}],
meetingName: [{required: true, message: "请输入会议名称", trigger: "blur"}],
signInStartTime: [{required: true, message: "请选择签到开始时间", trigger: "change"}],
signInEndTime: [{required: true, validator: validateEnd, trigger: "change"}]
}
}
},
methods: {
formatDate(value) {
return value ? this.$moment(value).format("YYYY-MM-DD HH:mm:ss") : "-"
},
async loadOptions() {
const res = await this.$axios.post("/platform/congress/signIn/sessions")
if (res.code === 0) this.sessionOptions = res.data || []
},
openAdd() {
this.formData = {meetingName: "", sessionId: "", remark: ""}
this.dialogFormVisible = true
this.$nextTick(() => this.$refs.formRef && this.$refs.formRef.clearValidate())
},
async openEdit(id) {
const res = await this.$axios.post("/platform/congress/signIn/get", {id})
if (res.code === 0) {
const data = res.data || {}
data.signInStartTime = this.formatDate(data.signInStartTime)
data.signInEndTime = this.formatDate(data.signInEndTime)
this.formData = data
this.dialogFormVisible = true
}
},
doSave() {
this.$refs.formRef.validate(async valid => {
if (!valid) return
this.submitLoading = true
try {
const res = await this.$axios.post("/platform/congress/signIn/save", this.formData)
if (res.code === 0) {
this.dialogFormVisible = false
this.$message.success(res.msg)
this.pageData()
} else {
this.$message.error(res.msg)
}
} finally {
this.submitLoading = false
}
})
},
doDelete(id) {
this.$confirm("确认删除该会议签到配置吗?", "提示", {type: "warning"}).then(async () => {
const res = await this.$axios.post("/platform/congress/signIn/delete", {id})
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
} else {
this.$message.error(res.msg)
}
})
}
},
async created() {
await this.loadOptions()
this.pageData()
}
})
</script>
<!--#
}
#-->