注册协会申请完成后导出申请表
注册协会的上传申请表字段不必填
This commit is contained in:
@@ -70,4 +70,12 @@ public class ClubMyApplyController {
|
|||||||
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
||||||
return Result.success();
|
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
|
@Column
|
||||||
@Comment("申请成立报告")
|
@Comment("申请成立报告")
|
||||||
@ColDefine(type = ColType.MYSQL_JSON)
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
@NotEmpty(message = "申请成立报告不能为空")
|
|
||||||
private List<JSONObject> establishReport;
|
private List<JSONObject> establishReport;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
|
|||||||
@@ -46,9 +46,10 @@ public interface SysClubService extends BaseService<SysClub> {
|
|||||||
void validateManagePerson(List<NutMap> managePerson);
|
void validateManagePerson(List<NutMap> managePerson);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验协会正式提交时申请成立报告和章程草案是否已上传。
|
* 校验协会正式提交时章程草案是否已上传,申请成立报告为选填。
|
||||||
*
|
*
|
||||||
* @param club 协会申请信息
|
* @param club 协会申请信息,rulesFile 应包含已上传的章程草案附件
|
||||||
|
* @throws com.budwk.app.base.exception.BaseException 申请信息为空或未上传章程草案;校验通过时无返回值
|
||||||
*/
|
*/
|
||||||
void validateRequiredFiles(SysClub club);
|
void validateRequiredFiles(SysClub club);
|
||||||
|
|
||||||
@@ -70,6 +71,14 @@ public interface SysClubService extends BaseService<SysClub> {
|
|||||||
*/
|
*/
|
||||||
void downloadRulesTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException;
|
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> minePageData(@Valid ClubUserPageForm pageForm);
|
||||||
|
|
||||||
Pagination<ClubRegisterPageVo> schoolLeaderAuditPageData(@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.page.Pagination;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
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.PageUtil;
|
||||||
|
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
|
||||||
import com.budwk.app.bpm.enums.BpmProcessInstanceStatusEnum;
|
import com.budwk.app.bpm.enums.BpmProcessInstanceStatusEnum;
|
||||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||||
import com.budwk.app.bpm.models.BpmProcessInstance;
|
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.ClubCommonPageVo;
|
||||||
import com.budwk.app.zhgh.club.vo.ClubRegisterPageVo;
|
import com.budwk.app.zhgh.club.vo.ClubRegisterPageVo;
|
||||||
import com.budwk.app.zhgh.club.vo.ClubRegisterVo;
|
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.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.Sqls;
|
import org.nutz.dao.Sqls;
|
||||||
@@ -43,7 +48,9 @@ import org.nutz.lang.util.NutMap;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -69,6 +76,8 @@ public class SysClubServiceImpl extends BaseServiceImpl<SysClub> implements SysC
|
|||||||
private BpmService bpmService;
|
private BpmService bpmService;
|
||||||
@Inject
|
@Inject
|
||||||
private SysFileService sysFileService;
|
private SysFileService sysFileService;
|
||||||
|
@Inject
|
||||||
|
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pagination<ClubCommonPageVo> getAllClubWithPage(PageForm pageForm, Cnd cnd) {
|
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);
|
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
|
@Override
|
||||||
public void validateRequiredFiles(SysClub club) {
|
public void validateRequiredFiles(SysClub club) {
|
||||||
// 文件上传组件提交空数组时,不能仅依赖 Bean Validation 的 @NotEmpty,需要在正式提交前显式校验。
|
// 申请成立报告为选填;章程草案仍需显式检查空附件列表,并保留申请信息为空时的保护。
|
||||||
if (club == null || ObjectUtil.isEmpty(club.getEstablishReport())) {
|
if (club == null || ObjectUtil.isEmpty(club.getRulesFile())) {
|
||||||
throw new BaseException("请上传申请成立报告");
|
|
||||||
}
|
|
||||||
if (ObjectUtil.isEmpty(club.getRulesFile())) {
|
|
||||||
throw new BaseException("请上传章程草案");
|
throw new BaseException("请上传章程草案");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,9 +180,7 @@ const CLUB_FORM_TEMPLATE = {
|
|||||||
clubType: [{ required: true, message: "请选择协会类型", trigger: ["blur", "change"] }],
|
clubType: [{ required: true, message: "请选择协会类型", trigger: ["blur", "change"] }],
|
||||||
concatPerson: [{ required: true, message: "请选择协会联系人", trigger: ["blur", "change"] }],
|
concatPerson: [{ required: true, message: "请选择协会联系人", trigger: ["blur", "change"] }],
|
||||||
foundTime: [{ 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"] }]
|
rulesFile: [{ required: true, message: "请上传章程草案", trigger: ["blur", "change"] }]
|
||||||
// establishReport: [{ required: true, message: "请上传申请成立报告", trigger: ["blur", "change"] }]
|
|
||||||
//rulesFile: [{ required: true, message: "请上传章程草案", trigger: ["blur", "change"] }],
|
//rulesFile: [{ required: true, message: "请上传章程草案", trigger: ["blur", "change"] }],
|
||||||
//manageFile: [{ required: true, message: "请上传经费来源及管理办法", trigger: ["blur", "change"] }],
|
//manageFile: [{ required: true, message: "请上传经费来源及管理办法", trigger: ["blur", "change"] }],
|
||||||
//yearPlanFile: [{ required: true, message: "请上传年度活动计划", trigger: ["blur", "change"] }]
|
//yearPlanFile: [{ required: true, message: "请上传年度活动计划", trigger: ["blur", "change"] }]
|
||||||
|
|||||||
@@ -62,17 +62,11 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
nextStep() {
|
nextStep() {
|
||||||
let valid = true
|
this.$refs.clubFormRef.$refs.form.validate().then(() => {
|
||||||
this.$refs.clubFormRef.$refs.form.validateField(
|
|
||||||
["clubName", "clubType", "foundTime", "establishReport", "rulesFile"],
|
|
||||||
(errMsg) => {
|
|
||||||
if (!errMsg) {
|
|
||||||
valid = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if (valid) return
|
|
||||||
this.activeName = 1
|
this.activeName = 1
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.warning({ title: "警告", message: "存在必填项未填写!" })
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async onSave() {
|
async onSave() {
|
||||||
let valid = true
|
let valid = true
|
||||||
@@ -100,13 +94,9 @@ layout("/layouts/platform.html"){
|
|||||||
this.$message.warning({ title: "警告", message: "存在必填项未填写!" })
|
this.$message.warning({ title: "警告", message: "存在必填项未填写!" })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// 文件上传组件使用数组承载文件,提交前显式检查空数组,避免表单校验误判为已填写。
|
// 申请成立报告为选填;章程草案仍需上传,提交前显式检查空数组,避免表单校验误判。
|
||||||
validateRequiredFiles() {
|
validateRequiredFiles() {
|
||||||
const formData = this.$refs.clubFormRef.formData
|
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) {
|
if (!formData.rulesFile || formData.rulesFile.length === 0) {
|
||||||
this.$message.warning({ title: "警告", message: "请上传章程草案" })
|
this.$message.warning({ title: "警告", message: "请上传章程草案" })
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-table-column label="操作" width="300">
|
<el-table-column label="操作" width="300">
|
||||||
<template v-slot="{row}">
|
<template v-slot="{row}">
|
||||||
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
|
<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.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.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">
|
<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) {
|
onEdit(row) {
|
||||||
commonUtil.pjaxPush('/platform/club/register/clubRegisterApply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
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) {
|
async onDelete(id) {
|
||||||
const confirm = await this.$confirm("此操作将永久删除, 是否继续?", "提示", {
|
const confirm = await this.$confirm("此操作将永久删除, 是否继续?", "提示", {
|
||||||
confirmButtonText: "确定",
|
confirmButtonText: "确定",
|
||||||
|
|||||||
Reference in New Issue
Block a user