注册协会申请完成后导出申请表
注册协会的上传申请表字段不必填
This commit is contained in:
@@ -70,4 +70,12 @@ public class ClubMyApplyController {
|
||||
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出协会申请表")
|
||||
@SaCheckPermission("club.register.myApply")
|
||||
public void exportApply(@Valid String id, javax.servlet.http.HttpServletResponse response) {
|
||||
sysClubService.exportApply(id, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,6 @@ public class SysClub extends BaseModel {
|
||||
@Column
|
||||
@Comment("申请成立报告")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
@NotEmpty(message = "申请成立报告不能为空")
|
||||
private List<JSONObject> establishReport;
|
||||
|
||||
@Column
|
||||
|
||||
@@ -46,9 +46,10 @@ public interface SysClubService extends BaseService<SysClub> {
|
||||
void validateManagePerson(List<NutMap> managePerson);
|
||||
|
||||
/**
|
||||
* 校验协会正式提交时申请成立报告和章程草案是否已上传。
|
||||
* 校验协会正式提交时章程草案是否已上传,申请成立报告为选填。
|
||||
*
|
||||
* @param club 协会申请信息
|
||||
* @param club 协会申请信息,rulesFile 应包含已上传的章程草案附件
|
||||
* @throws com.budwk.app.base.exception.BaseException 申请信息为空或未上传章程草案;校验通过时无返回值
|
||||
*/
|
||||
void validateRequiredFiles(SysClub club);
|
||||
|
||||
@@ -70,6 +71,14 @@ public interface SysClubService extends BaseService<SysClub> {
|
||||
*/
|
||||
void downloadRulesTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* 按协会申请表模板导出已提交的协会申请。
|
||||
*
|
||||
* @param clubId 申请协会 ID
|
||||
* @param response HTTP 响应,用于输出渲染后的 Word 文件
|
||||
*/
|
||||
void exportApply(String clubId, HttpServletResponse response);
|
||||
|
||||
Pagination<ClubRegisterPageVo> minePageData(@Valid ClubUserPageForm pageForm);
|
||||
|
||||
Pagination<ClubRegisterPageVo> schoolLeaderAuditPageData(@Valid ClubUserPageForm pageForm);
|
||||
|
||||
@@ -9,7 +9,9 @@ import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
|
||||
import com.budwk.app.bpm.enums.BpmProcessInstanceStatusEnum;
|
||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||
import com.budwk.app.bpm.models.BpmProcessInstance;
|
||||
@@ -33,6 +35,9 @@ import com.budwk.app.zhgh.club.service.SysClubUserService;
|
||||
import com.budwk.app.zhgh.club.vo.ClubCommonPageVo;
|
||||
import com.budwk.app.zhgh.club.vo.ClubRegisterPageVo;
|
||||
import com.budwk.app.zhgh.club.vo.ClubRegisterVo;
|
||||
import com.deepoove.poi.XWPFTemplate;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.deepoove.poi.config.Configure;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
@@ -43,7 +48,9 @@ import org.nutz.lang.util.NutMap;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -69,6 +76,8 @@ public class SysClubServiceImpl extends BaseServiceImpl<SysClub> implements SysC
|
||||
private BpmService bpmService;
|
||||
@Inject
|
||||
private SysFileService sysFileService;
|
||||
@Inject
|
||||
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
|
||||
|
||||
@Override
|
||||
public Pagination<ClubCommonPageVo> getAllClubWithPage(PageForm pageForm, Cnd cnd) {
|
||||
@@ -126,6 +135,114 @@ public class SysClubServiceImpl extends BaseServiceImpl<SysClub> implements SysC
|
||||
downloadClubTemplate("club_rules", "协会章程草案模板", request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportApply(String clubId, HttpServletResponse response) {
|
||||
Sql clubSql = Sqls.create("""
|
||||
SELECT c.clubName, c.createTime, c.introduce, c.purpose,
|
||||
u.username AS applicantName, u.mobile AS applicantMobile,
|
||||
u.unitName AS applicantUnitName
|
||||
FROM sys_club c
|
||||
LEFT JOIN vw_user u ON u.id = c.userId
|
||||
WHERE c.id = @clubId
|
||||
""");
|
||||
clubSql.setParam("clubId", clubId);
|
||||
clubSql.setCallback(Sqls.callback.map());
|
||||
dao().execute(clubSql);
|
||||
NutMap club = (NutMap) clubSql.getResult();
|
||||
if (ObjectUtil.isEmpty(club)) {
|
||||
throw new BaseException("协会申请不存在");
|
||||
}
|
||||
|
||||
Sql memberSql = Sqls.create("""
|
||||
SELECT u.username, u.unitName, u.mobile,
|
||||
CASE
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_PRESIDENT\"') THEN '会长'
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_SECRETARY\"') THEN '秘书长'
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_VICE_PRESIDENT\"') THEN '副会长'
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_VICE_SECRETARY\"') THEN '副秘书长'
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_OPERATOR\"') THEN '经办人'
|
||||
ELSE '理事'
|
||||
END AS roleName
|
||||
FROM club_user cu
|
||||
LEFT JOIN vw_user u ON u.id = cu.userId
|
||||
WHERE cu.clubId = @clubId
|
||||
ORDER BY CASE
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_PRESIDENT\"') THEN 1
|
||||
WHEN JSON_CONTAINS(cu.roleCode, '\"CLUB_SECRETARY\"') THEN 2
|
||||
ELSE 3
|
||||
END
|
||||
""");
|
||||
memberSql.setParam("clubId", clubId);
|
||||
List<NutMap> members = listMap(memberSql);
|
||||
StringBuilder managementInfo = new StringBuilder();
|
||||
for (NutMap member : members) {
|
||||
if (managementInfo.length() > 0) {
|
||||
managementInfo.append("\n");
|
||||
}
|
||||
managementInfo.append(member.getString("roleName", "理事"))
|
||||
.append(":").append(member.getString("username", ""))
|
||||
.append(",所属单位:").append(member.getString("unitName", ""))
|
||||
.append(",联系电话:").append(member.getString("mobile", ""));
|
||||
}
|
||||
|
||||
Sql auditSql = Sqls.create("""
|
||||
SELECT t.variable, t.finishTime
|
||||
FROM wf_process_task t
|
||||
INNER JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||
WHERE ins.businessNo = @clubId
|
||||
AND t.taskState = 20
|
||||
AND t.taskName <> 'startTask'
|
||||
ORDER BY t.finishTime DESC
|
||||
LIMIT 1
|
||||
""");
|
||||
auditSql.setParam("clubId", clubId);
|
||||
auditSql.setCallback(Sqls.callback.map());
|
||||
dao().execute(auditSql);
|
||||
NutMap audit = (NutMap) auditSql.getResult();
|
||||
String schoolUnionOpinion = "";
|
||||
String schoolUnionAuditTime = "";
|
||||
if (ObjectUtil.isNotEmpty(audit)) {
|
||||
String variable = audit.getString("variable");
|
||||
if (JSONUtil.isTypeJSON(variable)) {
|
||||
cn.hutool.json.JSONObject data = JSONUtil.parseObj(variable);
|
||||
schoolUnionOpinion = data.getStr("tf_opinion", data.getStr("tf_approvalComment", data.getStr("approvalOpinion", "")));
|
||||
}
|
||||
if (audit.get("finishTime") != null) {
|
||||
schoolUnionAuditTime = DateUtil.format((java.util.Date) audit.get("finishTime"), "yyyy年MM月dd日");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> docData = new HashMap<>();
|
||||
docData.put("clubName", club.getString("clubName", ""));
|
||||
docData.put("applyTime", formatDate(club.getString("createTime")));
|
||||
docData.put("applicantName", club.getString("applicantName", ""));
|
||||
docData.put("applicantMobile", club.getString("applicantMobile", ""));
|
||||
docData.put("applicantUnitName", club.getString("applicantUnitName", ""));
|
||||
docData.put("introduce", toPlainText(club.getString("introduce", "")));
|
||||
docData.put("managementInfo", managementInfo.toString());
|
||||
docData.put("schoolUnionOpinion", schoolUnionOpinion);
|
||||
docData.put("schoolUnionAuditTime", schoolUnionAuditTime);
|
||||
|
||||
try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
|
||||
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("clubRegisterApply"), Configure.builder().build())
|
||||
.render(docData).writeAndClose(output);
|
||||
CommonDownloadUtil.download("教职工社团申请表(" + club.getString("clubName", "") + ").docx", output.toByteArray(), response);
|
||||
} catch (IOException e) {
|
||||
throw new BaseException("协会申请表导出失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String formatDate(String value) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return "";
|
||||
}
|
||||
return DateUtil.format(DateUtil.parse(value), "yyyy年MM月dd日");
|
||||
}
|
||||
|
||||
private String toPlainText(String value) {
|
||||
return StrUtil.blankToDefault(value, "").replaceAll("<[^>]*>", "").replace(" ", " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* 按固定模板代码下载协会模板,模板代码仅由服务内部指定,避免下载其他业务模板。
|
||||
*/
|
||||
@@ -275,11 +392,8 @@ public class SysClubServiceImpl extends BaseServiceImpl<SysClub> implements SysC
|
||||
|
||||
@Override
|
||||
public void validateRequiredFiles(SysClub club) {
|
||||
// 文件上传组件提交空数组时,不能仅依赖 Bean Validation 的 @NotEmpty,需要在正式提交前显式校验。
|
||||
if (club == null || ObjectUtil.isEmpty(club.getEstablishReport())) {
|
||||
throw new BaseException("请上传申请成立报告");
|
||||
}
|
||||
if (ObjectUtil.isEmpty(club.getRulesFile())) {
|
||||
// 申请成立报告为选填;章程草案仍需显式检查空附件列表,并保留申请信息为空时的保护。
|
||||
if (club == null || ObjectUtil.isEmpty(club.getRulesFile())) {
|
||||
throw new BaseException("请上传章程草案");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +180,7 @@ const CLUB_FORM_TEMPLATE = {
|
||||
clubType: [{ required: true, message: "请选择协会类型", trigger: ["blur", "change"] }],
|
||||
concatPerson: [{ required: true, message: "请选择协会联系人", trigger: ["blur", "change"] }],
|
||||
foundTime: [{ required: true, message: "请选择成立时间", trigger: ["blur", "change"] }],
|
||||
establishReport: [{ required: true, message: "请上传申请成立报告", trigger: ["blur", "change"] }],
|
||||
rulesFile: [{ required: true, message: "请上传章程草案", trigger: ["blur", "change"] }]
|
||||
// establishReport: [{ required: true, message: "请上传申请成立报告", trigger: ["blur", "change"] }]
|
||||
//rulesFile: [{ required: true, message: "请上传章程草案", trigger: ["blur", "change"] }],
|
||||
//manageFile: [{ required: true, message: "请上传经费来源及管理办法", trigger: ["blur", "change"] }],
|
||||
//yearPlanFile: [{ required: true, message: "请上传年度活动计划", trigger: ["blur", "change"] }]
|
||||
|
||||
@@ -62,17 +62,11 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
methods: {
|
||||
nextStep() {
|
||||
let valid = true
|
||||
this.$refs.clubFormRef.$refs.form.validateField(
|
||||
["clubName", "clubType", "foundTime", "establishReport", "rulesFile"],
|
||||
(errMsg) => {
|
||||
if (!errMsg) {
|
||||
valid = false
|
||||
}
|
||||
}
|
||||
)
|
||||
if (valid) return
|
||||
this.activeName = 1
|
||||
this.$refs.clubFormRef.$refs.form.validate().then(() => {
|
||||
this.activeName = 1
|
||||
}).catch(() => {
|
||||
this.$message.warning({ title: "警告", message: "存在必填项未填写!" })
|
||||
})
|
||||
},
|
||||
async onSave() {
|
||||
let valid = true
|
||||
@@ -100,13 +94,9 @@ layout("/layouts/platform.html"){
|
||||
this.$message.warning({ title: "警告", message: "存在必填项未填写!" })
|
||||
})
|
||||
},
|
||||
// 文件上传组件使用数组承载文件,提交前显式检查空数组,避免表单校验误判为已填写。
|
||||
// 申请成立报告为选填;章程草案仍需上传,提交前显式检查空数组,避免表单校验误判。
|
||||
validateRequiredFiles() {
|
||||
const formData = this.$refs.clubFormRef.formData
|
||||
if (!formData.establishReport || formData.establishReport.length === 0) {
|
||||
this.$message.warning({ title: "警告", message: "请上传申请成立报告" })
|
||||
return false
|
||||
}
|
||||
if (!formData.rulesFile || formData.rulesFile.length === 0) {
|
||||
this.$message.warning({ title: "警告", message: "请上传章程草案" })
|
||||
return false
|
||||
|
||||
@@ -56,6 +56,7 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column label="操作" width="300">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button v-if="row.instanceState === 20" @click="exportApply(row)" size="mini" type="primary">导出申请表</el-button>
|
||||
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="onRevoke(row)">撤回</el-button>
|
||||
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)" size="mini" type="danger">
|
||||
@@ -112,6 +113,9 @@ layout("/layouts/platform.html"){
|
||||
onEdit(row) {
|
||||
commonUtil.pjaxPush('/platform/club/register/clubRegisterApply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
||||
},
|
||||
exportApply(row) {
|
||||
this.$downLoad("/platform/club/register/clubMyApply/exportApply", { id: row.id })
|
||||
},
|
||||
async onDelete(id) {
|
||||
const confirm = await this.$confirm("此操作将永久删除, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
|
||||
Reference in New Issue
Block a user