This commit is contained in:
2025-07-31 15:35:08 +08:00
parent bcca78d121
commit ac02be1aec
139 changed files with 14203 additions and 539 deletions
@@ -64,6 +64,7 @@ public class Audit extends BaseModel {
@ColDefine(type = ColType.INT)
private Integer auditType;
public Date nowDate() {
return new Date();
}
@@ -1,21 +0,0 @@
package com.budwk.app.zhgh.activity.qsv.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
@ApiModel(value = "答题得分计算结果")
@Data
@Accessors(chain = true)
@Builder
public class QsvCheckAnswerResult {
@ApiModelProperty(value = "是否正确")
private boolean isCorrect;
@ApiModelProperty(value = "得分")
private float score;
}
@@ -0,0 +1,91 @@
package com.budwk.app.zhgh.asset.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.asset.model.AssetCategory;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @author zhf
* @date 2025/7/16 15:05
* @description 资产类别
*/
@IocBean
@At("/platform/asset/category")
@Ok("json:full")
@Slf4j
@Api(tags = "资产类别")
public class AssetCategoryController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/asset/category/index.html")
@SaCheckPermission("asset.category")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("asset.category")
public Result pageData(AssetPageForm pageForm) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("categoryName", pageForm.getSearchKeyword());
group.orLike("categoryCode", pageForm.getSearchKeyword());
cnd.and(group);
}
Sql sql = Sqls.create("""
SELECT * FROM `asset_category`
$condition
""");
cnd.asc("categoryCode");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("资产类型新增/编辑")
@SaCheckPermission("asset.category")
public Result doSubmit(AssetCategory assetCategory) {
baseService.insertOrUpdate(assetCategory);
return Result.success();
}
@At
@ApiOperation("资产类型新增")
@SaCheckPermission("asset.category")
public Result doDelete(String id) {
baseService.dao().delete(AssetCategory.class, id);
return Result.success();
}
@At
@ApiOperation("全部资产类型")
public Result queryCategory() {
List<AssetCategory> categoryList = baseService.dao().query(AssetCategory.class, Cnd.NEW().asc("categoryCode"));
return Result.success(categoryList);
}
}
@@ -0,0 +1,113 @@
package com.budwk.app.zhgh.asset.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetDepreciationRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/17 11:32
* @description 资产折旧
*/
@IocBean
@At("/platform/asset/depreciation")
@Ok("json:full")
@Slf4j
@Api(tags = "资产折旧管理")
public class AssetDepreciationRecordController {
@Inject
private AssetDepreciationRecordService assetDepreciationRecordService;
@At("")
@Ok("beetl:/platform/zhgh/asset/depreciation/index.html")
@SaCheckPermission("asset.depreciation")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("asset.depreciation")
public Result pageData(AssetPageForm pageForm) {
Sql sql = assetDepreciationRecordService.getSql(pageForm);
Pagination pagination = assetDepreciationRecordService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("资产折旧信息删除")
@SLog(type = "assetDepreciation", tag = "资产折旧", msg = "删除了一条资产折旧信息")
@SaCheckPermission("asset.depreciation")
public Result doDelete(String id) {
assetDepreciationRecordService.clear(Cnd.where("assetId", "=", id));
return Result.success();
}
@At
@ApiOperation("资产折旧")
@SLog(type = "assetDepreciation", tag = "资产折旧", msg = "一键折旧资产")
@SaCheckPermission("asset.depreciation")
public Result doDepreciation() {
assetDepreciationRecordService.doDepreciation();
return Result.success();
}
@At
@ApiOperation("按条件导出资产折旧信息")
@SaCheckPermission("asset.depreciation")
@SLog(type = "assetDepreciation", tag = "资产折旧", msg = "按条件导出资产折旧信息")
public void doExport(AssetPageForm pageForm, HttpServletResponse response) {
Sql sql = assetDepreciationRecordService.getSql(pageForm);
List<NutMap> list = assetDepreciationRecordService.listMap(sql);
try {
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("资产编号", "assetNumber", 20));
exportEntities.add(new ExcelExportEntity("资产名称", "assetName", 20));
exportEntities.add(new ExcelExportEntity("类别名称", "categoryName", 20));
exportEntities.add(new ExcelExportEntity("责任人", "assetUseUserName", 20));
ExcelExportEntity assetAllMoneyEntity = new ExcelExportEntity("原值(元)", "assetAllMoney", 20);
assetAllMoneyEntity.setType(10);
exportEntities.add(assetAllMoneyEntity);
ExcelExportEntity assetSurplusMoneyEntity = new ExcelExportEntity("净值(元)", "assetSurplusMoney", 20);
assetSurplusMoneyEntity.setType(10);
exportEntities.add(assetSurplusMoneyEntity);
ExcelExportEntity assetDepreciationMoneyEntity = new ExcelExportEntity("累计折旧(元)", "assetDepreciationMoney", 20);
assetDepreciationMoneyEntity.setType(10);
exportEntities.add(assetDepreciationMoneyEntity);
exportEntities.add(new ExcelExportEntity("预计使用月份", "assetUsageMonth", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
CommonDownloadUtil.download("资产折旧信息.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,218 @@
package com.budwk.app.zhgh.asset.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.model.AssetDepreciationRecord;
import com.budwk.app.zhgh.asset.model.AssetStocktaking;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetDepreciationRecordService;
import com.budwk.app.zhgh.asset.service.AssetService;
import com.budwk.app.zhgh.staffmanage.member.param.MemberInfoPageForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* @author zhf
* @date 2025/7/16 14:33
* @description 资产台账管理
*/
@IocBean
@At("/platform/asset/manage")
@Ok("json:full")
@Slf4j
@Api(tags = "资产台账管理")
public class AssetManageController {
@Inject
private AssetService assetService;
@Inject
private AssetDepreciationRecordService assetDepreciationRecordService;
@At("")
@Ok("beetl:/platform/zhgh/asset/manage/index.html")
@SaCheckPermission("asset.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("asset.manage")
public Result pageData(AssetPageForm pageForm) {
Sql sql = assetService.getSql(pageForm);
Pagination pagination = assetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("资产新增")
@SLog(type = "assetManage", tag = "资产管理", msg = "新增了一条资产信息")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("asset.manage")
public Result doAdd(Asset asset) {
int year = Calendar.getInstance().get(Calendar.YEAR);
if (StrUtil.isBlank(asset.getAssetNumber())) {
Sql sql = Sqls.create("""
SELECT count(1) FROM `asset` where LEFT(assetNumber,4) = @year and LENGTH(assetNumber) = 8
""").setParam("year", year);
int count = assetService.count(sql);
String bh = String.format("%04d", count + 1);
asset.setAssetNumber(year + bh);
}
asset.setApplyUserId(SecurityUtil.getUserId());
assetService.insert(asset);
//增加折旧表记录
AssetDepreciationRecord record = assetDepreciationRecordService.initAssetDepreciationRecord(asset.getAssetUnitPrice(), asset.getAssetQuantity(), asset.getAssetUsedDate(), asset.getAssetRetiredAssetsDate());
if (ObjectUtil.isNotEmpty(record)) {
record.setAssetId(asset.getId());
assetService.insert(record);
}
return Result.success();
}
@At
@ApiOperation("资产编辑")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "assetManage", tag = "资产管理", msg = "编辑了一条资产信息")
@SaCheckPermission("asset.manage")
public Result doEdit(Asset asset) {
assetService.update(asset);
//增加折旧表记录
Asset fetch = assetService.fetch(asset.getId());
//如果资产类型不等于原来的或者预计报废时间不等于原来的
if (!fetch.getAssetCategoryId().equals(asset.getAssetCategoryId()) || !fetch.getAssetRetiredAssetsDate().equals(asset.getAssetRetiredAssetsDate())) {
assetDepreciationRecordService.clear(Cnd.where("assetId", "=", asset.getId()));
AssetDepreciationRecord record = assetDepreciationRecordService.initAssetDepreciationRecord(asset.getAssetUnitPrice(), asset.getAssetQuantity(), asset.getAssetUsedDate(), asset.getAssetRetiredAssetsDate());
if (ObjectUtil.isNotEmpty(record)) {
record.setAssetId(asset.getId());
assetService.insert(record);
}
}
return Result.success();
}
@At
@ApiOperation("资产删除")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "assetManage", tag = "资产管理", msg = "删除了一条资产信息")
@SaCheckPermission("asset.manage")
public Result doDelete(String id) {
assetDepreciationRecordService.clear(Cnd.where("assetId", "=", id));
assetService.delete(id);
assetService.dao().clear(AssetStocktaking.class, Cnd.where("assetId", "=", id));
return Result.success();
}
@At
@ApiOperation("查询资产单条记录")
@SaCheckPermission("asset.manage")
public Result findOne(String id) {
return Result.success(assetService.fetch(id));
}
@At
@ApiOperation("查询资产单条记录并跟关联的信息")
@SaCheckPermission("asset.manage")
public Result fondOneAsset(String id) {
return Result.success(assetService.findOne(id));
}
@At
@ApiOperation("查询责任人")
@SaCheckPermission("asset.manage")
public Result searchAssetUseUser(String query) {
Cnd cnd = Cnd.NEW();
cnd.where().orLike("username", query);
cnd.where().orLike("loginname", query);
cnd.where().orLike("id", query);
Sql sql = Sqls.create("""
SELECT
id,
loginname,
username,
unionName,
unionId
FROM
`vw_user`
$condition
""");
sql.setCondition(cnd);
Pagination pagination = assetService.listPage(1, 10, sql);
return Result.success(pagination.getList());
}
@At
@ApiOperation("按条件导出资产台账")
@SaCheckPermission("asset.manage")
@SLog(type = "assetManage", tag = "资产台账", msg = "按条件导出资产台账")
public void doExport(AssetPageForm pageForm, HttpServletResponse response) {
Sql sql = assetService.getSql(pageForm);
List<NutMap> list = assetService.listMap(sql);
try {
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("资产编号", "assetNumber", 20));
exportEntities.add(new ExcelExportEntity("资产名称", "assetName", 20));
exportEntities.add(new ExcelExportEntity("类别名称", "categoryName", 20));
exportEntities.add(new ExcelExportEntity("资产规格型号", "assetSpecs", 20));
exportEntities.add(new ExcelExportEntity("供应商名称", "assetSupplierName", 20));
exportEntities.add(new ExcelExportEntity("采购方式", "assetFundingSubjectName", 20));
exportEntities.add(new ExcelExportEntity("用途", "assetPurposeName", 20));
ExcelExportEntity assetUnitPriceEntity = new ExcelExportEntity("单价(元)", "assetUnitPrice", 20);
assetUnitPriceEntity.setType(10);
exportEntities.add(assetUnitPriceEntity);
ExcelExportEntity assetQuantityEntity = new ExcelExportEntity("数量(台/件)", "assetQuantity", 20);
assetUnitPriceEntity.setType(10);
exportEntities.add(assetQuantityEntity);
exportEntities.add(new ExcelExportEntity("开始使用日期", "assetUsedDate", 30));
exportEntities.add(new ExcelExportEntity("预计报废时间", "assetRetiredAssetsDate", 30));
exportEntities.add(new ExcelExportEntity("责任人", "assetUseUserName", 30));
exportEntities.add(new ExcelExportEntity("使用/管理部门", "assetUseUnionName", 30));
exportEntities.add(new ExcelExportEntity("存放地点", "assetStorageLocation", 30));
exportEntities.add(new ExcelExportEntity("使用状况", "assetUsageStateName", 30));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
CommonDownloadUtil.download("资产台账.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,75 @@
package com.budwk.app.zhgh.asset.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.model.AssetStocktaking;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetStocktakingService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @author zhf
* @date 2025/7/17 16:06
* @description 资产盘点
*/
@IocBean
@At("/platform/asset/stocktaking")
@Ok("json:full")
@Slf4j
@Api(tags = "资产盘点管理")
public class AssetStocktakingController {
@Inject
private AssetStocktakingService assetStocktakingService;
@At("")
@Ok("beetl:/platform/zhgh/asset/stocktaking/index.html")
@SaCheckPermission("asset.stocktaking")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("asset.stocktaking")
public Result pageData(AssetPageForm pageForm) {
Sql sql = assetStocktakingService.getSql(pageForm);
Pagination pagination = assetStocktakingService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("资产盘点提交")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "AssetStocktaking", tag = "资产盘点", msg = "提交了一条资产盘点信息")
@SaCheckPermission("asset.stocktaking")
public Result doSubmit(AssetStocktaking assetStocktaking) {
assetStocktakingService.doSubmit(assetStocktaking);
return Result.success();
}
@At
@ApiOperation("删除资产盘点")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "AssetStocktaking", tag = "资产盘点", msg = "删除了一条资产盘点信息")
@SaCheckPermission("asset.stocktaking")
public Result doDelete(String id,String assetStocktakingPlanId) {
assetStocktakingService.doDelete(id,assetStocktakingPlanId);
return Result.success();
}
}
@@ -0,0 +1,88 @@
package com.budwk.app.zhgh.asset.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.annotation.SLog;
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 com.budwk.app.zhgh.asset.model.AssetStocktakingPlan;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @author zhf
* @date 2025/7/17 14:40
* @description 资产盘点计划
*/
@IocBean
@At("/platform/asset/stocktakingPlan")
@Ok("json:full")
@Slf4j
@Api(tags = "资产折旧管理")
public class AssetStocktakingPlanController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/asset/stocktakingPlan/index.html")
@SaCheckPermission("asset.stocktakingPlan")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("asset.stocktakingPlan")
public Result pageData(PageForm pageForm, Integer year) {
Sql sql = Sqls.create("""
select * from asset_stocktaking_plan $condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("year", "=", year);
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("提交资产盘点计划/新增/编辑")
@SLog(type = "asset", tag = "资产管理", msg = "提交资产盘点计划/新增/编辑")
@SaCheckPermission("asset.stocktakingPlan")
public Result doSubmit(AssetStocktakingPlan assetStocktakingPlan) {
baseService.insertOrUpdate(assetStocktakingPlan);
return Result.success();
}
@At
@ApiOperation("资产盘点计划删除")
@SLog(type = "asset", tag = "资产管理", msg = "删除了一条资产盘点计划")
@SaCheckPermission("asset.stocktakingPlan")
public Result doDelete(String id) {
baseService.dao().delete(AssetStocktakingPlan.class, id);
return Result.success();
}
@At
@ApiOperation("按年度查询资产盘点计划")
@SaCheckPermission("asset.stocktakingPlan")
public Result queryStocktakingPlan(Integer year) {
List<AssetStocktakingPlan> planList = baseService.dao().query(AssetStocktakingPlan.class, Cnd.NEW().andEX(AssetStocktakingPlan::getYear, "=", year));
return Result.success(planList);
}
}
@@ -0,0 +1,142 @@
package com.budwk.app.zhgh.asset.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* @author zhf
* @date 2025/7/15 11:26
* @description 资产
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("asset")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("资产信息表")
public class Asset extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("资产编号")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetNumber;
@Column
@Comment("资产名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetName;
@Column
@Comment("资产类别Id")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String assetCategoryId;
@Column
@Comment("资产规格型号")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetSpecs;
@Column
@Comment("供应商名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetSupplierName;
@Column
@Comment("采购方式")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetFundingSubjectName;
@Column
@Comment("用途")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String assetPurposeName;
@Column
@Comment("单价")
@ColDefine(customType = "decimal(6,2)")
private BigDecimal assetUnitPrice;
@Column
@Comment("数量")
@ColDefine(type = ColType.INT)
private Integer assetQuantity;
@Column
@Comment("资产类型(1.校工会2.分工会)")
@ColDefine(type = ColType.INT)
private Integer assetTypeCode;
@Column
@Comment("开始使用日期")
@ColDefine(type = ColType.DATE)
private Date assetUsedDate;
@Column
@Comment("报废时间")
@ColDefine(type = ColType.DATE)
private Date assetRetiredAssetsDate;
@Column
@Comment("发票/购买信息")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> assetInvoiceFiles;
@Column
@Comment("资产图片")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> assetFiles;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR,width = 200)
private String assetNotes;
@Column
@Comment("录入人Id")
@ColDefine(type = ColType.VARCHAR,width = 32)
private String applyUserId;
@Column
@Comment("使用状况")
@ColDefine(type = ColType.VARCHAR,width = 30)
private String assetUsageStateName;
@Column
@Comment("责任人")
@ColDefine(type = ColType.VARCHAR,width = 32)
private String assetUseUserId;
@Column
@Comment("使用/管理部门")
@ColDefine(type = ColType.VARCHAR,width = 32)
private String assetUseUnionId;
@Column
@Comment("使用/管理部门")
@ColDefine(type = ColType.VARCHAR,width = 30)
private String assetUseUnionName;
@Column
@Comment("存放地点")
@ColDefine(type = ColType.VARCHAR,width = 30)
private String assetStorageLocation;
}
@@ -0,0 +1,43 @@
package com.budwk.app.zhgh.asset.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* @author zhf
* @date 2025/7/16 14:17
* @description 资产类别
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("asset_category")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("资产类别表")
public class AssetCategory extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("内容")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String categoryName;
@Column
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String categoryCode;
@Column
@Comment("折旧年限(年)")
@ColDefine(type = ColType.INT)
private int depreciationYear;
}
@@ -0,0 +1,68 @@
package com.budwk.app.zhgh.asset.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author zhf
* @date 2025/7/16 14:19
* @description 资产折旧记录表
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("asset_depreciation_record")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("资产折旧记录表")
public class AssetDepreciationRecord extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("资产登记id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String assetId;
@Column
@Comment("剩余月")
@ColDefine(type = ColType.INT)
private Integer assetRemainingMonths;
@Column
@Comment("资产全部的价值")
@ColDefine(customType = "decimal(6,2)")
private BigDecimal assetAllMoney;
@Column
@Comment("剩余价值")
@ColDefine(customType = "decimal(6,2)")
private BigDecimal assetSurplusMoney;
@Column
@Comment("累计折旧多少钱")
@ColDefine(customType = "decimal(6,2)")
private BigDecimal assetDepreciationMoney;
@Column
@Comment("平均一个月多少钱")
@ColDefine(customType = "decimal(6,2)")
private BigDecimal assetAverageMonthMoney;
@Column
@Comment("折旧到期时间")
@ColDefine(type = ColType.DATE)
private Date assetRetiredAssetsDate;
}
@@ -0,0 +1,97 @@
package com.budwk.app.zhgh.asset.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.util.List;
/**
* @author zhf
* @date 2025/7/17 15:40
* @description 资产盘点
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("asset_stocktaking")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("资产盘点表")
public class AssetStocktaking extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("资产登记id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String assetId;
@Column
@Comment("盘点计划id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String assetStocktakingPlanId;
@Column
@Comment("旧责任人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String oldAssetUseUserId;
@Column
@Comment("旧责任人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String oldAssetUseUserName;
@Column
@Comment("旧责任人工号")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String oldAssetUseLoginName;
@Column
@Comment("旧使用/管理部门")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String oldAssetUseUnionId;
@Column
@Comment("旧使用/管理部门")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String oldAssetUseUnionName;
@Column
@Comment("旧存放地点")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String oldAssetStorageLocation;
@Column
@Comment("旧使用状况")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String oldAssetUsageStateName;
@Column
@Comment("旧资产图片")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> oldAssetFiles;
@Column
@Comment("旧备注")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String oldAssetNotes;
private String assetUsageStateName;
private String assetStorageLocation;
private String assetUseUserId;
private String assetNotes;
private List<JSONObject> assetFiles;
}
@@ -0,0 +1,48 @@
package com.budwk.app.zhgh.asset.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* @author zhf
* @date 2025/7/17 12:11
* @description 资产盘点
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("asset_stocktaking_plan")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("资产盘点计划表")
public class AssetStocktakingPlan extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("年度")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String year;
@Column
@Comment("开始时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String startDate;
@Column
@Comment("时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String endDate;
@Column
@Comment("说明")
@ColDefine(type = ColType.VARCHAR, width = 300)
private String note;
}
@@ -0,0 +1,30 @@
package com.budwk.app.zhgh.asset.param;
import com.budwk.app.base.param.PageForm;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author zhf
* @date 2025/7/16 14:43
* @description 资产查询pageForm
*/
@EqualsAndHashCode(callSuper = false)
@Data
public class AssetPageForm extends PageForm {
//资产类型(1.校工会2.分工会)
private Integer assetTypeCode;
//资产类别Id
private String assetCategoryId;
//使用状况
private String assetUsageStateName;
//使用/管理部门
private String assetUseUnionId;
//盘点时间段
private String assetStocktakingPlanId;
//是否盘点
private Boolean isStocktaking;
}
@@ -0,0 +1,33 @@
package com.budwk.app.zhgh.asset.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.asset.model.AssetDepreciationRecord;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import org.nutz.dao.sql.Sql;
import java.math.BigDecimal;
import java.util.Date;
public interface AssetDepreciationRecordService extends BaseService<AssetDepreciationRecord> {
/**
*计算折旧记录
* @param assetUnitPrice 单价
* @param assetQuantity 数量
* @param assetUsedDate 开始使用日期
* @param assetRetiredAssetsDate 预计折旧到期时间
* @return
*/
AssetDepreciationRecord initAssetDepreciationRecord(BigDecimal assetUnitPrice,Integer assetQuantity,Date assetUsedDate, Date assetRetiredAssetsDate);
Sql getSql(AssetPageForm pageForm);
void doDepreciation();
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.asset.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import org.nutz.dao.sql.Sql;
import org.nutz.lang.util.NutMap;
public interface AssetService extends BaseService<Asset> {
Sql getSql(AssetPageForm pageForm);
NutMap findOne(String id);
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.asset.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.asset.model.AssetStocktaking;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import org.nutz.dao.sql.Sql;
public interface AssetStocktakingService extends BaseService<AssetStocktaking> {
Sql getSql(AssetPageForm pageForm);
void doSubmit(AssetStocktaking assetStocktaking);
void doDelete(String id,String assetStocktakingPlanId);
}
@@ -0,0 +1,192 @@
package com.budwk.app.zhgh.asset.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.model.AssetDepreciationRecord;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetDepreciationRecordService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
/**
* @author zhf
* @date 2025/7/16 14:30
* @description
*/
@IocBean(args = {"refer:dao"})
public class AssetDepreciationRecordServiceImpl extends BaseServiceImpl<AssetDepreciationRecord> implements AssetDepreciationRecordService {
public AssetDepreciationRecordServiceImpl(Dao dao) {
super(dao);
}
@Override
public AssetDepreciationRecord initAssetDepreciationRecord(BigDecimal assetUnitPrice, Integer assetQuantity, Date assetUsedDate, Date assetRetiredAssetsDate) {
// 将 Date 转换为 LocalDate
LocalDate assetUsedDateLocalDate = assetUsedDate.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
LocalDate assetRetiredAssetsDateLocalDate = assetRetiredAssetsDate.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate();
// 计算资产使用时间到折旧到期时间多少个月
long wholeMonth = ChronoUnit.MONTHS.between(assetUsedDateLocalDate, assetRetiredAssetsDateLocalDate);
//计算资产使用时间到现在使用了几个月
long usedMonth = ChronoUnit.MONTHS.between(assetUsedDateLocalDate, LocalDate.now());
AssetDepreciationRecord record = new AssetDepreciationRecord();
//如果折旧到期时间小于现在时间直接设为0
if (assetRetiredAssetsDateLocalDate.isBefore(LocalDate.now())) {
//预计折旧到期时间
record.setAssetRetiredAssetsDate(assetRetiredAssetsDate);
//资产剩余的月
record.setAssetRemainingMonths(0);
//资产全部的金额
record.setAssetAllMoney(assetUnitPrice.multiply(new BigDecimal(assetQuantity)));
//资产平均每月价值
record.setAssetAverageMonthMoney(record.getAssetAllMoney().divide(new BigDecimal(wholeMonth), 2, RoundingMode.DOWN));
//剩余价值
record.setAssetSurplusMoney(BigDecimal.ZERO);
record.setAssetDepreciationMoney(assetUnitPrice.multiply(new BigDecimal(assetQuantity)));
return record;
} else if (wholeMonth - usedMonth >= 0) {
//预计折旧到期时间
record.setAssetRetiredAssetsDate(assetRetiredAssetsDate);
//资产剩余的月
record.setAssetRemainingMonths((int) (wholeMonth - usedMonth < 0 ? 0 : wholeMonth - usedMonth));
//资产全部的金额
record.setAssetAllMoney(assetUnitPrice.multiply(new BigDecimal(assetQuantity)));
//资产平均每月价值
record.setAssetAverageMonthMoney(record.getAssetAllMoney().divide(new BigDecimal(wholeMonth), 2, RoundingMode.DOWN));
//剩余价值
if (usedMonth == 0) {
//如果等于0代表一个月都没用到直接设为全部的金额
record.setAssetSurplusMoney(assetUnitPrice.multiply(new BigDecimal(assetQuantity)));
} else {
record.setAssetSurplusMoney(record.getAssetAverageMonthMoney().multiply(BigDecimal.valueOf(record.getAssetRemainingMonths())));
}
//累计折旧多少钱
record.setAssetDepreciationMoney(record.getAssetAverageMonthMoney().multiply(BigDecimal.valueOf(usedMonth)));
return record;
}
return null;
}
@Override
public Sql getSql(AssetPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
t2.*,
t1.assetAllMoney,
t1.assetSurplusMoney,
t1.assetDepreciationMoney,
IFNULL(t3.depreciationYear, 0) * 12 AS assetUsageMonth,
t3.categoryName,
t4.username AS assetUseUserName
FROM
asset_depreciation_record t1
LEFT JOIN `asset` t2 ON t2.id = t1.assetId
LEFT JOIN asset_category t3 ON t3.id = t2.assetCategoryId
LEFT JOIN sys_user t4 ON t4.id = t2.assetUseUserId
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("t2.assetNumber", pageForm.getSearchKeyword());
group.orLike("t2.assetName", pageForm.getSearchKeyword());
cnd.and(group);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("t2.assetUseUnionId", "=", SecurityUtil.getUnionId());
}
cnd.andEX("t2.assetUseUnionId", "=", pageForm.getAssetUseUnionId());
cnd.andEX("t2.assetCategoryId", "=", pageForm.getAssetCategoryId());
cnd.andEX("t2.assetTypeCode", "=", pageForm.getAssetTypeCode());
cnd.andEX("t2.assetUsageStateName", "=", pageForm.getAssetUsageStateName());
sql.setCondition(cnd);
return sql;
}
@Override
public void doDepreciation() {
//查询所有资产中剩余价值不等于0的
Sql sql = Sqls.create("""
SELECT
t2.*,
t1.assetUnitPrice,
t1.assetQuantity,
t1.assetUsedDate,
t1.assetUsageStateName
FROM
`asset` t1
LEFT JOIN asset_depreciation_record t2 ON t1.id = t2.assetId
WHERE
t2.assetSurplusMoney > 0
""");
List<NutMap> assetList = listMap(sql);
//找出可以折旧的资产id
List<String> assetIds = assetList.stream().map(v -> v.getString("assetId")).toList();
//根据上面的id找出折旧表里面的记录
List<AssetDepreciationRecord> depreciationRecordList = query(Cnd.where("assetId", "in", assetIds));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
depreciationRecordList.forEach(record -> {
//找出该资产的使用状况是不是正常的
NutMap map = assetList.stream().filter(v -> v.getString("assetId").equals(record.getAssetId())).findFirst().orElse(null);
LocalDate assetRetiredAssetsLocalDate = LocalDate.parse(map.getString("assetRetiredAssetsDate"), formatter);
if (map != null && !"正常".equals(map.getString("assetUsageStateName"))) {
//如果这个资产不是正常的就直接把剩余价值设为0,剩余月份也设为0
record.setAssetSurplusMoney(BigDecimal.ZERO);
record.setAssetRemainingMonths(0);
} else if (assetRetiredAssetsLocalDate.isBefore(LocalDate.now())) {
//如果这个资产折旧到期时间小于现在时间直接设为0
record.setAssetSurplusMoney(BigDecimal.ZERO);
record.setAssetRemainingMonths(0);
} else {
//转换时间为我上面方法所需要的类型
BigDecimal assetUnitPrice = new BigDecimal(map.getString("assetUnitPrice"));
int assetQuantity = map.getInt("assetQuantity");
LocalDateTime assetUsedLocalDateTime = LocalDateTime.parse(map.getString("assetUsedDate"), formatter);
Date assetUsedDate = Date.from(assetUsedLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime assetRetiredAssetsLocalDateTime = LocalDateTime.parse(map.getString("assetRetiredAssetsDate"), formatter);
Date assetRetiredAssetsDate = Date.from(assetRetiredAssetsLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
//算出剩余的月份和价值
AssetDepreciationRecord inited = initAssetDepreciationRecord(assetUnitPrice, assetQuantity, assetUsedDate, assetRetiredAssetsDate);
//如果返回空代表一个月也没使用不增加
if (ObjectUtil.isNotEmpty(inited)) {
record.setAssetRemainingMonths(inited.getAssetRemainingMonths());
record.setAssetSurplusMoney(inited.getAssetSurplusMoney());
record.setAssetDepreciationMoney(inited.getAssetDepreciationMoney());
}
}
});
update(depreciationRecordList);
}
}
@@ -0,0 +1,86 @@
package com.budwk.app.zhgh.asset.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.model.AssetStocktaking;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
/**
* @author zhf
* @date 2025/7/16 14:28
* @description
*/
@IocBean(args = {"refer:dao"})
public class AssetServiceImpl extends BaseServiceImpl<Asset> implements AssetService {
public AssetServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getSql(AssetPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
t1.*,
t3.categoryName,
t4.username AS assetUseUserName
FROM
`asset` t1
LEFT JOIN asset_depreciation_record t2 ON t1.id = t2.assetId
LEFT JOIN asset_category t3 ON t3.id = t1.assetCategoryId
LEFT JOIN sys_user t4 ON t4.id = t1.assetUseUserId
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("t1.assetNumber", pageForm.getSearchKeyword());
group.orLike("t1.assetName", pageForm.getSearchKeyword());
cnd.and(group);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("t1.assetUseUnionId", "=", SecurityUtil.getUnionId());
}
cnd.andEX("t1.assetUseUnionId", "=", pageForm.getAssetUseUnionId());
cnd.andEX("t1.assetCategoryId", "=", pageForm.getAssetCategoryId());
cnd.andEX("t1.assetTypeCode", "=", pageForm.getAssetTypeCode());
cnd.andEX("t1.assetUsageStateName", "=", pageForm.getAssetUsageStateName());
sql.setCondition(cnd);
return sql;
}
@Override
public NutMap findOne(String id) {
Sql sql = Sqls.create("""
SELECT
t1.*,
t3.categoryName AS assetCategoryName,
t3.depreciationYear AS assetDepreciationYear,
t4.username AS assetUseUserName
FROM
`asset` t1
LEFT JOIN asset_depreciation_record t2 ON t1.id = t2.assetId
LEFT JOIN asset_category t3 ON t3.id = t1.assetCategoryId
LEFT JOIN sys_user t4 ON t4.id = t1.assetUseUserId
WHERE
t1.id = @id
""").setParam("id",id);
NutMap nutMap = (NutMap) dao().execute(sql.setCallback(Sqls.callback.map())).getResult();
nutMap.setv("assetStocktakingList", dao().query(AssetStocktaking.class,
Cnd.where("assetId", "=", id)));
return nutMap;
}
}
@@ -0,0 +1,120 @@
package com.budwk.app.zhgh.asset.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.asset.model.Asset;
import com.budwk.app.zhgh.asset.model.AssetStocktaking;
import com.budwk.app.zhgh.asset.param.AssetPageForm;
import com.budwk.app.zhgh.asset.service.AssetStocktakingService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.IocBean;
/**
* @author zhf
* @date 2025/7/17 16:08
* @description
*/
@IocBean(args = {"refer:dao"})
public class AssetStocktakingServiceImpl extends BaseServiceImpl<AssetStocktaking> implements AssetStocktakingService {
public AssetStocktakingServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getSql(AssetPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
t1.*,
t3.categoryName,
t4.username AS assetUseUserName,
COUNT(t5.assetId) AS isStocktaking
FROM
`asset` t1
LEFT JOIN asset_depreciation_record t2 ON t1.id = t2.assetId
LEFT JOIN asset_category t3 ON t3.id = t1.assetCategoryId
LEFT JOIN sys_user t4 ON t4.id = t1.assetUseUserId
LEFT JOIN asset_stocktaking t5 ON t5.assetId = t1.id
AND t5.assetStocktakingPlanId =@assetStocktakingPlanId
$condition
$stocktakingCnd
""").setParam("assetStocktakingPlanId", pageForm.getAssetStocktakingPlanId());
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("t1.assetNumber", pageForm.getSearchKeyword());
group.orLike("t1.assetName", pageForm.getSearchKeyword());
cnd.and(group);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("t1.assetUseUnionId", "=", SecurityUtil.getUnionId());
}
if (pageForm.getIsStocktaking() != null) {
sql.setVar("stocktakingCnd", "HAVING COUNT(t5.assetId) " + (pageForm.getIsStocktaking() ? ">" : "=") + "0");
}
cnd.andEX("t1.assetUseUnionId", "=", pageForm.getAssetUseUnionId());
cnd.andEX("t1.assetCategoryId", "=", pageForm.getAssetCategoryId());
cnd.andEX("t1.assetTypeCode", "=", pageForm.getAssetTypeCode());
cnd.andEX("t1.assetUsageStateName", "=", pageForm.getAssetUsageStateName());
sql.setCondition(cnd);
return sql;
}
@Override
public void doSubmit(AssetStocktaking assetStocktaking) {
Asset asset = dao().fetch(Asset.class, assetStocktaking.getAssetId());
//插入盘点表记录上一次的数据
//查询旧的责任人是谁
View_user oldUser = dao().fetch(View_user.class, Cnd.where("id", "=", asset.getAssetUseUserId()));
assetStocktaking.setOldAssetFiles(asset.getAssetFiles());
assetStocktaking.setOldAssetNotes(asset.getAssetNotes());
assetStocktaking.setOldAssetStorageLocation(asset.getAssetStorageLocation());
assetStocktaking.setOldAssetUseUserId(asset.getAssetUseUserId());
assetStocktaking.setOldAssetUseUserName(oldUser.getUsername());
assetStocktaking.setOldAssetUseLoginName(oldUser.getLoginname());
assetStocktaking.setOldAssetUseUnionId(asset.getAssetUseUnionId());
assetStocktaking.setOldAssetUseUnionName(asset.getAssetUseUnionName());
assetStocktaking.setOldAssetUsageStateName(asset.getAssetUsageStateName());
insert(assetStocktaking);
//跟新资产信息表,资产信息表始终是最新的数据
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", assetStocktaking.getAssetUseUserId()));
asset.setAssetFiles(assetStocktaking.getAssetFiles());
asset.setAssetNotes(assetStocktaking.getAssetNotes());
asset.setAssetStorageLocation(assetStocktaking.getAssetStorageLocation());
asset.setAssetUseUserId(assetStocktaking.getAssetUseUserId());
asset.setAssetUseUnionId(user.getUnionId());
asset.setAssetUseUnionName(user.getUnionName());
asset.setAssetUsageStateName(assetStocktaking.getAssetUsageStateName());
dao().update(asset);
}
@Override
public void doDelete(String id, String assetStocktakingPlanId) {
//找出盘点的信息,修改到资产信息表
AssetStocktaking assetStocktaking = fetch(Cnd.where("assetId", "=", id)
.and("assetStocktakingPlanId", "=", assetStocktakingPlanId));
Asset asset = dao().fetch(Asset.class, assetStocktaking.getAssetId());
asset.setAssetFiles(assetStocktaking.getOldAssetFiles());
asset.setAssetNotes(assetStocktaking.getOldAssetNotes());
asset.setAssetStorageLocation(assetStocktaking.getOldAssetStorageLocation());
asset.setAssetUseUserId(assetStocktaking.getOldAssetUseUserId());
asset.setAssetUseUnionId(assetStocktaking.getOldAssetUseUnionId());
asset.setAssetUseUnionName(assetStocktaking.getOldAssetUseUnionName());
asset.setAssetUsageStateName(assetStocktaking.getOldAssetUsageStateName());
dao().update(asset);
//删除盘点信息
clear(Cnd.where("assetId", "=", id)
.and("assetStocktakingPlanId", "=", assetStocktakingPlanId));
}
}
@@ -1,15 +1,14 @@
package com.budwk.app.zhgh.activity.qsv.controller;
package com.budwk.app.zhgh.dayofficework.qsv.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
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 com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvOption;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.service.QsvActivityService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvOption;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvActivityService;
import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
@@ -28,6 +27,7 @@ import java.util.List;
@IocBean
@At("/platform/qsv/activity")
@Ok("json:full")
@ApiOperation("问卷调查管理")
public class QsvActivityController {
@Inject
@@ -36,16 +36,17 @@ public class QsvActivityController {
private QsvActivityService qsvActivityService;
@At("")
@Ok("beetl:/platform/zhgh/activity/qsv/activity/index.html")
@Ok("beetl:/platform/zhgh/dayofficework/qsv/activity/index.html")
@SaCheckPermission("qsv.activity")
public void index() {
}
// 分页查询
@At
@SaCheckPermission("qsv.activity")
@ApiOperation("分页查询")
public Result pageData(@Valid PageForm pageForm, Integer year,String title) {
public Result pageData(@Valid PageForm pageForm, Integer year, String title) {
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(startTime)", "=", year);
cnd.and(Cnd.likeEX("title",title));
@@ -54,9 +55,11 @@ public class QsvActivityController {
}
// 保存问卷基础信息
@At
@SaCheckPermission("qsv.activity")
@ApiOperation("保存问卷基础信息")
@SLog(type = "qsv.activity", tag = "保存问卷基础信息", msg = "保存问卷基础信息")
public Result save(QsvActivity qsvActivity) {
if (qsvActivity.getCategory().equals("QUIZ")) {
if (qsvActivity.getMode().equals("SCHEDULED")) {
@@ -76,20 +79,25 @@ public class QsvActivityController {
return Result.success(activity);
}
// 删除问卷
@At
@SaCheckPermission("qsv.activity")
@ApiOperation("删除问卷")
@SLog(type = "qsv.activity", tag = "删除问卷", msg = "删除问卷")
public Result delete(@Valid String id) {
dao.delete(QsvActivity.class, id);
return Result.success();
}
// 保存问卷题目
@At
@SaCheckPermission("qsv.activity")
@ApiOperation("保存问卷题目")
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("保存问卷题目")
@SLog(type = "qsv.activity", tag = "保存问卷题目", msg = "保存问卷题目")
public Result saveSubjects(@Param("activityId") @Valid String activityId, @Param("subjects") QsvSubject[] qsvSubjects) {
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId));
List<String> subjectIds = subjects.stream().map(QsvSubject::getId).toList();
//新题目
@@ -111,7 +119,7 @@ public class QsvActivityController {
List<QsvOption> newOptions = qsvSubject.getOptions();
List<String> optionIds = newOptions.stream().map(QsvOption::getId).toList();
List<QsvOption> oldOptions = dao.query(QsvOption.class, Cnd.where(QsvOption::getSubjectId, "=", qsvSubject.getId()));
List<QsvOption> oldOptions = dao.query(QsvOption.class, Cnd.where("subjectId", "=", qsvSubject.getId()));
List<String> oldOptionIds = oldOptions.stream().map(QsvOption::getId).toList();
@@ -127,7 +135,7 @@ public class QsvActivityController {
List<String> correctOptionIds = newOptions.stream().filter(QsvOption::getIsCorrect).map(QsvOption::getId).toList();
qsvSubject.setCorrectAnswer(correctOptionIds);
} else {
dao.clear(QsvOption.class, Cnd.where(QsvOption::getSubjectId, "=", qsvSubject.getId()));
dao.clear(QsvOption.class, Cnd.where("subjectId", "=", qsvSubject.getId()));
}
dao.update(qsvSubject);
}
@@ -135,12 +143,14 @@ public class QsvActivityController {
return Result.success();
}
// 查询问卷题目
@At
@SaCheckPermission("qsv.activity")
@ApiOperation("查询问卷题目")
@SLog(type = "qsv.activity", tag = "查询问卷题目", msg = "查询问卷题目")
public Result listSubjects(@Valid String activityId) {
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId).asc(QsvSubject::getSortNum));
dao.fetchLinks(subjects, "options",Cnd.NEW().asc(QsvOption::getSortNum));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
dao.fetchLinks(subjects, "options",Cnd.NEW().asc("sortNum"));
return Result.success(subjects);
}
@@ -1,21 +1,16 @@
package com.budwk.app.zhgh.activity.qsv.controller;
package com.budwk.app.zhgh.dayofficework.qsv.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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 com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.param.QsvQuizRankPageForm;
import com.budwk.app.zhgh.activity.qsv.service.QsvQuizRankService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvQuizRankPageForm;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvQuizRankService;
import io.swagger.annotations.ApiOperation;
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 org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@@ -26,6 +21,7 @@ import java.util.List;
@IocBean
@At("/platform/qsv/quizRank")
@Ok("json:full")
@ApiOperation("答题得分统计")
public class QsvQuizRankController {
@Inject
@@ -34,25 +30,27 @@ public class QsvQuizRankController {
private QsvQuizRankService qsvQuizRankService;
@At("")
@Ok("beetl:/platform/zhgh/activity/qsv/quiz/rank.html")
@Ok("beetl:/platform/zhgh/dayofficework/qsv/quiz/rank.html")
@SaCheckPermission("qsv.quiz.rank")
public void index() {
}
// 根据年度查询问卷
@At
@SaCheckPermission("qsv.quiz.rank")
@ApiOperation("根据年度查询问卷")
public Result listQuiz(Integer year) {
Cnd cnd = Cnd.where(QsvActivity::getCategory, "=", "QUIZ");
Cnd cnd = Cnd.where("category", "=", "QUIZ");
cnd.andEX("YEAR(startTime)", "=", year);
cnd.desc(QsvActivity::getCreatedAt);
cnd.desc("category");
List<QsvActivity> list = dao.query(QsvActivity.class, cnd);
return Result.success(list);
}
@At
@SaCheckPermission("qsv.quiz.rank")
@ApiOperation("分页查询")
public Result pageData(@Valid QsvQuizRankPageForm pageForm) {
Pagination pagination = qsvQuizRankService.pageData(pageForm);
return Result.success(pagination);
@@ -61,7 +59,8 @@ public class QsvQuizRankController {
@At
@Ok("void")
@SaCheckPermission("qsv.quiz.rank")
public void exportXlsx(@Valid QsvQuizRankPageForm pageForm, HttpServletResponse response) {
@ApiOperation("导出数据")
public void exportXlsx(QsvQuizRankPageForm pageForm, HttpServletResponse response) {
qsvQuizRankService.exportXlsx(pageForm, response);
}
@@ -1,24 +1,18 @@
package com.budwk.app.zhgh.activity.qsv.controller;
package com.budwk.app.zhgh.dayofficework.qsv.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.annotation.SLog;
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.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvQuizRankPageForm;
import com.budwk.app.zhgh.activity.qsv.service.QsvActivityService;
import com.budwk.app.zhgh.activity.qsv.service.QsvQuizRankService;
import com.budwk.app.zhgh.activity.qsv.service.QsvSurveyService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvActivityService;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvSurveyService;
import io.swagger.annotations.ApiOperation;
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;
@@ -27,13 +21,12 @@ import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@IocBean
@At("/platform/qsv/survey")
@Ok("json:full")
@ApiOperation("调查统计")
public class QsvSurveyController {
@Inject
@@ -44,7 +37,7 @@ public class QsvSurveyController {
private QsvSurveyService qsvSurveyService;
@At("")
@Ok("beetl:/platform/zhgh/activity/qsv/survey/index.html")
@Ok("beetl:/platform/zhgh/dayofficework/qsv/survey/index.html")
@SaCheckPermission("qsv.survey")
public void index() {
@@ -53,50 +46,67 @@ public class QsvSurveyController {
@At
@SaCheckPermission("qsv.survey")
@ApiOperation("分页查询")
public Result pageData(@Valid PageForm pageForm, Integer year) {
Cnd cnd = Cnd.where(QsvActivity::getCategory, "=", "SURVEY");
Cnd cnd = Cnd.where("category", "=", "SURVEY");
cnd.andEX("YEAR(startTime)", "=", year);
cnd.desc(QsvActivity::getCreatedAt);
cnd.desc("category");
Pagination pagination = qsvActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@SaCheckPermission("qsv.survey")
@ApiOperation("报告")
@ApiOperation("生成报告")
public Result report(@Valid String activityId) {
List<NutMap> report = qsvSurveyService.report(activityId);
return Result.success(report);
}
@At
@Ok("void")
@SaCheckPermission("qsv.survey")
@ApiOperation("导出报告")
public void exportReportXlsx(String activityId, HttpServletResponse response) {
qsvSurveyService.exportReportXlsx(activityId, response);
}
@At
@SaCheckPermission("qsv.survey")
@ApiOperation("选项选择详情")
public Result selectOptionUsers(@Valid String activityId, @Valid String subjectId, @Valid String optionId) {
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId));
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId));
List<QsvUserAnswerRecord> selectOptionUsers = answerRecords.stream().filter(ext -> ObjectUtil.isNotNull(ext.getExtJson().get(subjectId, JSONObject.class)) && ext.getExtJson().get(subjectId, JSONObject.class).getJSONArray("optionIds").contains(optionId)).toList();
return Result.success(selectOptionUsers);
}
@At
@SaCheckPermission("qsv.survey")
@ApiOperation("用户答题")
public Result userAnswer(@Valid String activityId) {
NutMap map = qsvSurveyService.userAnswer(activityId);
@SLog(type = "qsv.survey", tag = "用户答题", msg = "用户答了一题")
public Result userAnswer(PageForm pageForm, @Valid String activityId) {
NutMap map = qsvSurveyService.userAnswer(pageForm, activityId);
return Result.success(map);
}
@At
@SaCheckPermission("qsv.survey")
@ApiOperation("删除用户答题记录")
@SLog(type = "qsv.survey", tag = "删除用户答题记录", msg = "删除用户答题记录")
public Result deleteUserAnswer(@Valid String id) {
dao.delete(QsvUserAnswerRecord.class, id);
return Result.success();
}
@At
@Ok("void")
@SaCheckPermission("qsv.survey")
@ApiOperation("导出用户答题记录xlsx")
@ApiOperation("导出用户答题记录")
public void exportUserAnswerXlsx(@Valid String activityId, HttpServletResponse response) {
qsvSurveyService.exportUserAnswerXlsx(activityId, response);
}
@@ -0,0 +1,17 @@
package com.budwk.app.zhgh.dayofficework.qsv.dto;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;
//答题得分计算结果
@Data
@Accessors(chain = true)
@Builder
public class QsvCheckAnswerResult {
private boolean isCorrect;
private float score;
}
@@ -1,13 +1,9 @@
package com.budwk.app.zhgh.activity.qsv.h5controller;
package com.budwk.app.zhgh.dayofficework.qsv.h5controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.service.QsvActivityService;
import io.swagger.annotations.ApiOperation;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvActivityService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
@@ -27,19 +23,17 @@ public class H5QsvController {
private QsvActivityService qsvActivityService;
@At("")
@Ok("beetl:/platform/zhghh5/activity/qsv/index.html")
@SaCheckPermission("h5.qsv")
@Ok("beetl:/mobile/qsv/index.html")
public void index() {
}
// 分页查询
@At
@SaCheckPermission("h5.qsv")
@ApiOperation("分页查询")
public Result pageData(@Valid PageForm pageForm, @Valid String category) {
Cnd cnd = Cnd.NEW();
cnd.andEX(QsvActivity::getCategory, "=", category);
cnd.desc(QsvActivity::getStartTime);
cnd.andEX("category", "=", category);
cnd.desc("startTime");
Pagination pagination = qsvActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@@ -1,20 +1,19 @@
package com.budwk.app.zhgh.activity.qsv.h5controller;
package com.budwk.app.zhgh.dayofficework.qsv.h5controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvOption;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.activity.qsv.service.QsvQuizService;
import com.budwk.app.zhgh.activity.qsv.service.QsvUserAnswerRecordService;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.dayofficework.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvQuizService;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvUserAnswerRecordService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
@@ -45,24 +44,28 @@ public class H5QsvQuizController {
private QsvQuizService qsvQuizService;
@At("")
@Ok("beetl:/platform/zhghh5/activity/qsv/quiz/index.html")
@SaCheckLogin
@Ok("beetl:/mobile/qsv/quiz/index.html")
public void index() {
}
@At
@Ok("beetl:/platform/zhghh5/activity/qsv/quiz/result.html")
@SaCheckLogin
@Ok("beetl:/mobile/qsv/quiz/result.html")
public void result() {
}
// 题目列表
@At
@SaCheckLogin
@ApiOperation("题目列表")
public Result subjects(@Valid String activityId) {
QsvActivity activity = dao.fetch(QsvActivity.class, activityId);
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getGroupId())
.and("userId", "=", SecurityUtil.getUserId()));
if (count != 1) {
return Result.error("您无需参加此次答题,感谢您的关注!");
}
String mode = activity.getMode();
//能否重复答题
Boolean repeatable = activity.getRepeatable();
@@ -72,52 +75,54 @@ public class H5QsvQuizController {
Integer maxAttempts = activity.getMaxAttempts();
//题目显示模式
String displayMode = activity.getDisplayMode();
// 重复答题显示提示
Boolean repeatTips = false;
//最终返回的题目数据
List<QsvSubject> resultSubjects = new ArrayList<>();
String answerRecordId = null;
//查询用户的答题记录
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId()));
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()));
if (activity.getEndTime().after(new Date())) {
if (activity.getEndTime().before(new Date())) {
//已结束 查询最新一次的答题记录
Optional<QsvUserAnswerRecord> lastRecordOptional = answerRecords.stream().max(Comparator.comparing(QsvUserAnswerRecord::getAnswerTime));
if (lastRecordOptional.isPresent()) {
List<String> subjectIds = lastRecordOptional.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
answerRecordId = lastRecordOptional.get().getId();
}else{
//没生成过 那就看全部的题目
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId));
QsvUserAnswerRecord answerRecord = qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).collect(Collectors.toList()));
answerRecordId = answerRecord.getId();
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
}
} else {
if (mode.equals("REGULAR")) {
if ("REGULAR".equals(mode)) {
if (ObjectUtil.isEmpty(answerRecords)) {
//首次进来生成答题记录
if (displayMode.equals("ALL")) {
resultSubjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
if ("ALL".equals(displayMode)) {
resultSubjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
answerRecordId = qsvUserAnswerRecordService.insertRecord(activityId, resultSubjects.stream().map(QsvSubject::getId).collect(Collectors.toList())).getId();
} else if (displayMode.equals("RANDOM")) {
} else if ("RANDOM".equals(displayMode)) {
//单次随机抽取题目数量
Integer randomCount = activity.getRandomCount();
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId));
if (subjects.size() < randomCount) {
throw new BaseException("题目数不够,无法生成题目");
throw new RuntimeException("题目数不够,无法生成题目");
}
//从subjects里随机抽取randomCount个题目
@@ -127,60 +132,70 @@ public class H5QsvQuizController {
answerRecordId = answerRecord.getId();
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
}
} else {
if (displayMode.equals("ALL")) {
if ("ALL".equals(displayMode)) {
//判断能否重复答题 如果可重复要根据次数判断是否再次生成记录 不能重复直接返回最新的一次记录
if (repeatable) {
//已回答次数
if (answerRecords.size() < maxAttempts) {
//生成答题记录
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
answerRecordId = qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).collect(Collectors.toList())).getId();
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, answerRecordId);
QsvUserAnswerRecord fetch = dao.fetch(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()).and("isFinish", "=", false)
.desc("randomNumber"));
List<String> subjectIds = new ArrayList<>();
if (fetch == null) {
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
answerRecordId = qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).collect(Collectors.toList())).getId();
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, answerRecordId);
subjectIds = answerRecord.getSubjectIds();
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
} else {
subjectIds = fetch.getSubjectIds();
answerRecordId = fetch.getId();
}
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
repeatTips = true;
} else {
//已达到最大次数 返回最新一次记录
Optional<QsvUserAnswerRecord> maxAnswerRecordOptional = answerRecords.stream().max(Comparator.comparingLong(QsvUserAnswerRecord::getRandomNumber));
if (maxAnswerRecordOptional.isPresent()) {
List<String> subjectIds = maxAnswerRecordOptional.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
answerRecordId = maxAnswerRecordOptional.get().getId();
} else {
throw new BaseException("业务异常");
throw new RuntimeException("业务异常");
}
}
} else {
Optional<QsvUserAnswerRecord> maxAnswerRecordOptional = answerRecords.stream().max(Comparator.comparingLong(QsvUserAnswerRecord::getRandomNumber));
if (maxAnswerRecordOptional.isPresent()) {
List<String> subjectIds = maxAnswerRecordOptional.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
answerRecordId = maxAnswerRecordOptional.get().getId();
} else {
throw new BaseException("业务异常");
throw new RuntimeException("业务异常");
}
}
} else if (displayMode.equals("RANDOM")) {
} else if ("RANDOM".equals(displayMode)) {
//判断是否有未答完的记录
Optional<QsvUserAnswerRecord> notFinishRecordOptional = answerRecords.stream().filter(r -> !r.getIsFinish()).findFirst();
if (notFinishRecordOptional.isPresent()) {
List<String> subjectIds = notFinishRecordOptional.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
@@ -202,11 +217,11 @@ public class H5QsvQuizController {
if (answerRecords.size() < totalRandom) {
//进行下一次抽取
List<String> subjectIds = answerRecords.stream().map(QsvUserAnswerRecord::getSubjectIds).flatMap(Collection::stream).toList();
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId)
.and(QsvSubject::getId, "not in", subjectIds));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId)
.and("id", "not in", subjectIds).asc("sortNum"));
if (subjects.size() < randomCount) {
throw new BaseException("题目数不够,无法生成题目");
throw new RuntimeException("题目数不够,无法生成题目");
}
//从subjects里随机抽取randomCount个题目
@@ -218,13 +233,13 @@ public class H5QsvQuizController {
Optional<QsvUserAnswerRecord> maxAnswerRecordOptional = answerRecords.stream().max(Comparator.comparingLong(QsvUserAnswerRecord::getRandomNumber));
if (maxAnswerRecordOptional.isPresent()) {
List<String> subjectIds = maxAnswerRecordOptional.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
answerRecordId = maxAnswerRecordOptional.get().getId();
} else {
throw new BaseException("业务异常");
throw new RuntimeException("业务异常");
}
}
// }else{
@@ -233,13 +248,13 @@ public class H5QsvQuizController {
}
}
}
} else if (mode.equals("SCHEDULED")) {
} else if ("SCHEDULED".equals(mode)) {
//定时定题
//查询今天的题目
List<QsvUserAnswerRecord> todayRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId())
.and(QsvUserAnswerRecord::getAttemptDate, "=", DateUtil.today())
List<QsvUserAnswerRecord> todayRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId())
.and("attemptDate", "=", DateUtil.today())
);
if (ObjectUtil.isNotEmpty(todayRecords)) {
@@ -248,13 +263,13 @@ public class H5QsvQuizController {
//如果今天已生成的题目已答完并且还可以重复答
if (todayAllFinish && todayRecords.size() < maxAttempts) {
//生成今天的记录
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId)
.and(QsvSubject::getDisplayDate, "=", DateUtil.today()));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId)
.and("displayDate", "=", DateUtil.today()).asc("sortNum"));
QsvUserAnswerRecord answerRecord = qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).collect(Collectors.toList()));
answerRecordId = answerRecord.getId();
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
@@ -265,23 +280,23 @@ public class H5QsvQuizController {
answerRecordId = maxTodayRecord.get().getId();
List<String> subjectIds = maxTodayRecord.get().getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
} else {
throw new BaseException("业务异常");
throw new RuntimeException("业务异常");
}
}
} else {
//生成今天的记录
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId)
.and(QsvSubject::getDisplayDate, "=", DateUtil.today()));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId)
.and("displayDate", "=", DateUtil.today()).asc("sortNum"));
QsvUserAnswerRecord answerRecord = qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).collect(Collectors.toList()));
answerRecordId = answerRecord.getId();
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
resultSubjects = dao.query(QsvSubject.class, cnd);
@@ -289,25 +304,26 @@ public class H5QsvQuizController {
}
}
dao.fetchLinks(resultSubjects, "options", Cnd.NEW().asc(QsvOption::getSortNum));
dao.fetchLinks(resultSubjects, "options", Cnd.NEW().asc("sortNum"));
resultSubjects.forEach(v -> v.setUserSelectOptionIds(new ArrayList<>()));
NutMap result = NutMap.NEW().addv("subjects", resultSubjects).addv("answerRecordId", answerRecordId).addv("activity", activity);
NutMap result = NutMap.NEW().addv("subjects", resultSubjects).addv("answerRecordId", answerRecordId)
.addv("activity", activity).addv("repeatTips", repeatTips);
return Result.success(result);
}
// 答题记录
@At
@SaCheckLogin
@ApiOperation("答题记录")
public Result answerRecord(@Valid String answerRecordId) {
QsvUserAnswerRecord record = dao.fetch(QsvUserAnswerRecord.class, answerRecordId);
return Result.success(record);
}
// 提交答题
@At
@SaCheckLogin
@ApiOperation("提交答题")
@SLog(type = "qsv.quiz", tag = "提交答题", msg = "问卷调查提交答题")
public Result submitAnswer(@Valid @Param("answer") QsvAnswerParam qsvAnswerParam) {
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, qsvAnswerParam.getAnswerRecordId());
JSONObject extJson = answerRecord.getExtJson();
@@ -345,25 +361,24 @@ public class H5QsvQuizController {
}
@At
@SaCheckLogin
public Result historyScore(@Valid String activityId) {
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId).and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId()).desc(QsvUserAnswerRecord::getCreatedAt));
List<QsvUserAnswerRecord> answerRecords = dao.query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()).desc("createdAt"));
return Result.success(answerRecords);
}
@At
@SaCheckLogin
@ApiOperation("答题记录(结果页展示)")
public Result answerResult(@Valid String answerRecordId) {
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, answerRecordId);
List<String> subjectIds = answerRecord.getSubjectIds();
Cnd cnd = Cnd.where(QsvSubject::getId, "in", subjectIds);
Cnd cnd = Cnd.where("id", "in", subjectIds);
String dynamic = subjectIds.stream().map(id -> "'" + id + "'").collect(Collectors.joining(","));
cnd.and(new Static("1=1 ORDER BY FIELD (id," + dynamic + ")"));
List<QsvSubject> subjects = dao.query(QsvSubject.class, cnd);
dao.fetchLinks(subjects, "options", Cnd.NEW().asc(QsvOption::getSortNum));
dao.fetchLinks(subjects, "options", Cnd.NEW().asc("sortNum"));
subjects.forEach(v -> v.setUserSelectOptionIds(new ArrayList<>()));
@@ -1,16 +1,15 @@
package com.budwk.app.zhgh.activity.qsv.h5controller;
package com.budwk.app.zhgh.dayofficework.qsv.h5controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.result.Result;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.activity.qsv.service.QsvUserAnswerRecordService;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvUserAnswerRecordService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
@@ -36,32 +35,37 @@ public class H5QsvSurveyController {
private QsvUserAnswerRecordService qsvUserAnswerRecordService;
@At("")
@Ok("beetl:/platform/zhghh5/activity/qsv/survey/index.html")
@SaCheckLogin
@Ok("beetl:/mobile/qsv/survey/index.html")
public void index() {
}
@At
@SaCheckLogin
public Result subjects(@Valid String activityId) {
public Result subjects(String activityId) {
QsvActivity activity = dao.fetch(QsvActivity.class, activityId);
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getGroupId())
.and("userId", "=", SecurityUtil.getUserId()));
if (count != 1) {
return Result.error("您无需参加此次投票,感谢您的关注!");
}
String answerRecordId = null;
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId).and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId())
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId()));
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()));
if (answerRecord == null) {
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
qsvUserAnswerRecordService.insertRecord(activityId, subjects.stream().map(QsvSubject::getId).toList());
}
QsvUserAnswerRecord answerRecord2 = dao.fetch(QsvUserAnswerRecord.class,
Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId()));
Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()));
answerRecordId = answerRecord2.getId();
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where(QsvSubject::getId, "in", answerRecord2.getSubjectIds()));
dao.fetchLinks(subjects, "options");
List<QsvSubject> subjects = dao.query(QsvSubject.class, Cnd.where("id", "in", answerRecord2.getSubjectIds()).asc("sortNum"));
dao.fetchLinks(subjects, "options", Cnd.NEW().asc("sortNum"));
for (QsvSubject subject : subjects) {
if (subject.getUserSelectOptionIds() == null) {
@@ -74,14 +78,12 @@ public class H5QsvSurveyController {
}
@At
@SaCheckLogin
public Result answerRecord(@Valid String answerRecordId) {
QsvUserAnswerRecord record = dao.fetch(QsvUserAnswerRecord.class, answerRecordId);
return Result.success(record);
}
@At
@SaCheckLogin
public Result submitAnswer(@Valid @Param("answer") QsvAnswerParam qsvAnswerParam) {
QsvUserAnswerRecord answerRecord = dao.fetch(QsvUserAnswerRecord.class, qsvAnswerParam.getAnswerRecordId());
JSONObject extJson = answerRecord.getExtJson();
@@ -1,8 +1,6 @@
package com.budwk.app.zhgh.activity.qsv.models;
package com.budwk.app.zhgh.dayofficework.qsv.models;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.services.SysHomeConvert;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
@@ -11,12 +9,12 @@ import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Data
@Table("qsv_activity")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("问卷调查投票活动表")
public class QsvActivity extends BaseModel implements Serializable, SysHomeConvert {
public class QsvActivity extends BaseModel implements Serializable {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@@ -109,18 +107,4 @@ public class QsvActivity extends BaseModel implements Serializable, SysHomeConve
@Comment("封面图片")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String cover;
@Override
public Sys_home_activity covertToSysHomeActivity() {
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(this.getId());
sysHomeActivity.setName(this.getTitle());
sysHomeActivity.setCover(this.getCover());
sysHomeActivity.setH5Url("/platform/h5/qsv");
sysHomeActivity.setStartDate(this.getStartTime());
sysHomeActivity.setEndDate(this.getEndTime());
sysHomeActivity.setAllowUserGroupId(this.getGroupId());
sysHomeActivity.setEnable(true);
return sysHomeActivity;
}
}
@@ -1,4 +1,4 @@
package com.budwk.app.zhgh.activity.qsv.models;
package com.budwk.app.zhgh.dayofficework.qsv.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
@@ -6,12 +6,14 @@ import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@Data
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("qsv_option")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("问卷调查投票选项表")
public class QsvOption extends BaseModel {
public class QsvOption extends BaseModel implements Serializable {
@Name
@Comment("ID")
@@ -39,6 +41,16 @@ public class QsvOption extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 255)
private String imgUrl;
@Column
@Comment("链接地址")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String link;
@Column
@Comment("详情")
@ColDefine(customType = "longtext")
private String description;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
@@ -1,4 +1,4 @@
package com.budwk.app.zhgh.activity.qsv.models;
package com.budwk.app.zhgh.dayofficework.qsv.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@@ -14,7 +15,7 @@ import java.util.List;
@Table("qsv_subject")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("问卷调查投票题目表")
public class QsvSubject extends BaseModel {
public class QsvSubject extends BaseModel implements Serializable {
@Name
@Comment("ID")
@@ -52,6 +53,11 @@ public class QsvSubject extends BaseModel {
@ColDefine(type = ColType.DATE)
private Date displayDate;
@Column
@Comment("多选,最多选几个")
@ColDefine(type = ColType.INT, width = 1)
private Integer maxMulti;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT, width = 1)
@@ -1,4 +1,4 @@
package com.budwk.app.zhgh.activity.qsv.models;
package com.budwk.app.zhgh.dayofficework.qsv.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
@@ -7,6 +7,7 @@ import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@@ -15,7 +16,7 @@ import java.util.List;
@Table("qsv_user_answer_record")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("问卷调查投票记录表")
public class QsvUserAnswerRecord extends BaseModel {
public class QsvUserAnswerRecord extends BaseModel implements Serializable {
@Name
@Comment("ID")
@@ -1,25 +1,19 @@
package com.budwk.app.zhgh.activity.qsv.param;
package com.budwk.app.zhgh.dayofficework.qsv.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
@ApiModel(value = "答题参数")
//答题参数
public class QsvAnswerParam {
@ApiModelProperty("答题活动")
private String activityId;
@ApiModelProperty("答题记录")
private String answerRecordId;
@ApiModelProperty("答题题目")
private List<Subject> subjects;
@ApiModelProperty("答题用时")
private Integer answerTime;
@Data
@@ -1,8 +1,6 @@
package com.budwk.app.zhgh.activity.qsv.param;
package com.budwk.app.zhgh.dayofficework.qsv.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -10,19 +8,15 @@ import java.util.Date;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("问卷排名得分分页查询参数")
//问卷排名得分分页查询参数
public class QsvQuizRankPageForm extends PageForm {
@ApiModelProperty("活动ID")
private String activityId;
@ApiModelProperty("分工会ID")
private String unionId;
@ApiModelProperty("单位ID")
private String unitId;
@ApiModelProperty("答题日期")
private Date attemptDate;
}
@@ -1,7 +1,8 @@
package com.budwk.app.zhgh.activity.qsv.service;
package com.budwk.app.zhgh.dayofficework.qsv.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
public interface QsvActivityService extends BaseService<QsvActivity> {
}
@@ -1,13 +1,13 @@
package com.budwk.app.zhgh.activity.qsv.service;
package com.budwk.app.zhgh.dayofficework.qsv.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvQuizRankPageForm;
import org.nutz.lang.util.NutMap;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvQuizRankPageForm;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
public interface QsvQuizRankService extends BaseService<QsvUserAnswerRecord> {
@@ -1,8 +1,10 @@
package com.budwk.app.zhgh.activity.qsv.service;
package com.budwk.app.zhgh.dayofficework.qsv.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import java.util.List;
@@ -1,18 +1,21 @@
package com.budwk.app.zhgh.activity.qsv.service;
package com.budwk.app.zhgh.dayofficework.qsv.service;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import org.nutz.lang.util.NutMap;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
public interface QsvSurveyService extends BaseService<QsvUserAnswerRecord> {
List<NutMap> report(String activityId);
void exportReportXlsx(String activityId, HttpServletResponse response);
void exportUserAnswerXlsx(String activityId, HttpServletResponse response);
NutMap userAnswer(String activityId);
// NutMap userAnswer(String activityId);
NutMap userAnswer(PageForm pageForm, String activityId);
}
@@ -1,9 +1,10 @@
package com.budwk.app.zhgh.activity.qsv.service;
package com.budwk.app.zhgh.dayofficework.qsv.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvAnswerParam;
import java.util.List;
@@ -1,8 +1,8 @@
package com.budwk.app.zhgh.activity.qsv.service.impl;
package com.budwk.app.zhgh.dayofficework.qsv.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.service.QsvActivityService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvActivityService;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -1,18 +1,17 @@
package com.budwk.app.zhgh.activity.qsv.service.impl;
package com.budwk.app.zhgh.dayofficework.qsv.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvQuizRankPageForm;
import com.budwk.app.zhgh.activity.qsv.service.QsvQuizRankService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvQuizRankPageForm;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvQuizRankService;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
@@ -24,7 +23,6 @@ import org.nutz.lang.util.NutMap;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@IocBean(args = {"refer:dao"})
@@ -60,7 +58,7 @@ public class QsvQuizRankServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord>
QsvActivity activity = dao().fetch(QsvActivity.class, activityId);
if (activity == null) {
throw new BaseException("活动不存在: " + activityId);
throw new RuntimeException("活动不存在: " + activityId);
}
String mode = activity.getMode();
@@ -95,9 +93,9 @@ public class QsvQuizRankServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord>
t1.userId,
t1.userName,
t1.loginName,
u.sex,
t1.unitName,
t1.unionName,
t1.sex,
u.mobile,
t1.totalScore,
t1.attemptDate,
@@ -1,11 +1,11 @@
package com.budwk.app.zhgh.activity.qsv.service.impl;
package com.budwk.app.zhgh.dayofficework.qsv.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.activity.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.service.QsvQuizService;
import com.budwk.app.zhgh.dayofficework.qsv.dto.QsvCheckAnswerResult;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvQuizService;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -1,22 +1,25 @@
package com.budwk.app.zhgh.activity.qsv.service.impl;
package com.budwk.app.zhgh.dayofficework.qsv.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
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.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvOption;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.service.QsvSurveyService;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvOption;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvSurveyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
@@ -47,7 +50,8 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
try {
// 查询用户答题记录
List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId));
List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("isFinish", "=", true));
// 将答题记录的扩展JSON转换为JSONObject列表
List<JSONObject> answerExtList = answerRecords.stream().map(QsvUserAnswerRecord::getExtJson).toList();
@@ -57,7 +61,7 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
List<String> subjectIds = subjects.stream().map(v -> v.getString("id")).toList();
// 查询题目选项列表
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc(QsvOption::getSortNum));
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
// 按题目ID分组选项
Map<String, List<QsvOption>> optionsGroup = options.stream().collect(Collectors.groupingBy(QsvOption::getSubjectId));
@@ -79,6 +83,10 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
}
// 处理单选类型题目 处理多选类型题目
else if ("radio".equals(subjectType) || "checkbox".equals(subjectType)) {
long selectTotal = answerExtList.stream()
.filter(ext -> ext.containsKey(subject.getString("id")))
.count();
subjectOptions.forEach(subjectOption -> {
long selectCount = answerExtList.stream()
.filter(ext ->
@@ -89,15 +97,22 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
&& jsonObject.getJSONArray("optionIds").contains(subjectOption.getString("id"));
})
.count();
long round = Math.round((double) selectCount / selectTotal * 100);
subjectOption.put("selectPercent", round + "%");
subjectOption.put("selectCount", selectCount);
});
long selectTotal = answerExtList.stream()
.filter(ext -> ext.containsKey(subject.getString("id")))
.count();
subjectOptions.sort((o1, o2) -> {
int count1 = o1.getInt("selectCount");
int count2 = o2.getInt("selectCount");
if (count1 == count2) {
return Integer.compare(o1.getInt("sortNum"), o2.getInt("sortNum"));
}
return Integer.compare(count2, count1);
});
subject.put("selectTotal", selectTotal);
}
// 添加选项到题目中
subject.addv("options", subjectOptions);
}
@@ -105,10 +120,36 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
return subjects;
} catch (Exception e) {
log.error("报告生成失败", e);
throw new BaseException("报告生成失败", e);
throw new RuntimeException("报告生成失败", e);
}
}
@Override
public void exportReportXlsx(String activityId, HttpServletResponse response) {
List<NutMap> report = report(activityId);
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("选项名称", "text", 20));
exportEntities.add(new ExcelExportEntity("选择人数", "selectCount", 20));
exportEntities.add(new ExcelExportEntity("选择比例", "selectPercent", 20));
Map<String, List<NutMap>> listMap = report.stream().collect(Collectors.groupingBy(v -> v.getString("id")));
Workbook workbook = new XSSFWorkbook();
listMap.forEach((k, v) -> {
NutMap nutMap = v.get(0);
ExcelExportService service = new ExcelExportService();
ExportParams exportParams = new ExportParams();
exportParams.setTitle(nutMap.getString("title"));
exportParams.setSheetName(nutMap.getString("title"));
exportParams.setType(ExcelType.XSSF);
service.createSheetForMap(workbook, exportParams, exportEntities, nutMap.getList("options", NutMap.class));
});
CommonDownloadUtil.download("调研分析.xlsx", workbook, response);
}
@Override
public void exportUserAnswerXlsx(String activityId, HttpServletResponse response) {
// 检查活动ID是否为空
@@ -124,19 +165,20 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
}
// 查询用户答题记录
List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId));
List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("isFinish", "=", true));
// 将答题记录的扩展JSON转换为JSONObject列表
List<JSONObject> answerExtList = answerRecords.stream().map(QsvUserAnswerRecord::getExtJson).toList();
// 查询活动题目列表
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where("activityId", "=", activityId));
// 将题目列表转换为Map
Map<String, QsvSubject> subjectMap = subjects.stream().collect(Collectors.toMap(QsvSubject::getId, v -> v));
// 获取题目ID列表
List<String> subjectIds = subjects.stream().map(QsvSubject::getId).toList();
// 查询题目选项列表
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc(QsvOption::getSortNum));
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
// 将选项列表转换为Map
Map<String, QsvOption> optionMap = options.stream().collect(Collectors.toMap(QsvOption::getId, v -> v));
@@ -154,39 +196,74 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
}
} catch (Exception e) {
log.error("导出Excel失败", e);
throw new BaseException("导出Excel失败", e);
throw new RuntimeException("导出Excel失败", e);
}
}
@Override
public NutMap userAnswer(String activityId) {
public NutMap userAnswer(PageForm pageForm, String activityId) {
// 检查活动ID是否为空
if (activityId == null || activityId.isEmpty()) {
throw new IllegalArgumentException("活动ID不能为空");
}
try {
Cnd cnd = Cnd.NEW();
cnd.and("activityId", "=", activityId);
cnd.and("isFinish", "=", true);
// Cnd.where("activityId", "=", activityId)
// .and("isFinish", "=", true)
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
List<NutMap> answerRecords = pagination.getList();
// 查询用户答题记录
List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId));
// List<QsvUserAnswerRecord> answerRecords = dao().query(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
// .and("isFinish", "=", true));
// 将答题记录的扩展JSON转换为JSONObject列表
List<JSONObject> answerExtList = answerRecords.stream().map(QsvUserAnswerRecord::getExtJson).toList();
// List<JSONObject> answerExtList = answerRecords.stream().map(QsvUserAnswerRecord::getExtJson).toList();
// 查询活动题目列表
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where(QsvSubject::getActivityId, "=", activityId));
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where("activityId", "=", activityId));
// 将题目列表转换为Map
Map<String, QsvSubject> subjectMap = subjects.stream().collect(Collectors.toMap(QsvSubject::getId, v -> v));
// 获取题目ID列表
List<String> subjectIds = subjects.stream().map(QsvSubject::getId).toList();
// 查询题目选项列表
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc(QsvOption::getSortNum));
List<QsvOption> options = dao().query(QsvOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
// 将选项列表转换为Map
Map<String, QsvOption> optionMap = options.stream().collect(Collectors.toMap(QsvOption::getId, v -> v));
// 构建Excel导出实体
List<ExcelExportEntity> excelExportEntities = buildExcelExportEntities(subjects);
// 构建答题记录列表
List<NutMap> list = buildAnswerRecords(answerRecords, subjectMap, options);
List<NutMap> list = answerRecords.stream().map(record -> {
NutMap map = NutMap.NEW()
.addv("id", record.getString("id"))
.addv("loginName", record.getString("loginName"))
.addv("userName", record.getString("userName"))
.addv("unitName", record.getString("unitName"))
.addv("unionName", record.getString("unionName"));
JSONObject extJson = record.getAs("extJson", JSONObject.class);
extJson.forEach((k, v) -> {
JSONObject jsonVal = (JSONObject) v;
String type = subjectMap.get(k).getType();
if (type.equals("text")) {
map.addv(k, jsonVal.getStr("text"));
} else if (type.equals("radio") || type.equals("checkbox")) {
JSONArray optionIds = jsonVal.getJSONArray("optionIds");
String selectOptionTexts = options.stream().filter(option -> optionIds.contains(option.getId()))
.map(QsvOption::getText).collect(Collectors.joining(";"));
map.addv(k, selectOptionTexts);
}
});
return map;
}).toList();
pagination.setList(list);
// List<NutMap> list = buildAnswerRecords(answerRecords, subjectMap, options);
// 构建表格列信息
List<NutMap> tableColumns = excelExportEntities.stream()
@@ -195,9 +272,9 @@ public class QsvSurveyServiceImpl extends BaseServiceImpl<QsvUserAnswerRecord> i
return NutMap.NEW()
.addv("tableColumns", tableColumns)
.addv("tableData", list);
.addv("tableData", pagination);
} catch (Exception e) {
throw new BaseException("获取用户答题记录失败", e);
throw new RuntimeException("获取用户答题记录失败", e);
}
}
@@ -1,24 +1,22 @@
package com.budwk.app.zhgh.activity.qsv.service.impl;
package com.budwk.app.zhgh.dayofficework.qsv.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.qsv.models.QsvActivity;
import com.budwk.app.zhgh.activity.qsv.models.QsvSubject;
import com.budwk.app.zhgh.activity.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.activity.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.activity.qsv.service.QsvUserAnswerRecordService;
import io.swagger.annotations.ApiOperation;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvActivity;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvSubject;
import com.budwk.app.zhgh.dayofficework.qsv.models.QsvUserAnswerRecord;
import com.budwk.app.zhgh.dayofficework.qsv.param.QsvAnswerParam;
import com.budwk.app.zhgh.dayofficework.qsv.service.QsvUserAnswerRecordService;
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.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.*;
@@ -37,7 +35,7 @@ public class QsvUserAnswerRecordServiceImpl extends BaseServiceImpl<QsvUserAnswe
Boolean shuffleSubject = activity.getShuffleSubject();
//打乱题目顺序
if (category.equals("QUIZ") && shuffleSubject) {
if ("QUIZ".equals(category) && shuffleSubject) {
Collections.shuffle(subjectIds);
}
@@ -56,26 +54,26 @@ public class QsvUserAnswerRecordServiceImpl extends BaseServiceImpl<QsvUserAnswe
}
record.setExtJson(extJson);
View_user user = dao().fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
record.setLoginName(user.getLoginname());
record.setUserName(user.getUsername());
record.setUnitId(SecurityUtil.getUnitId());
record.setUnitId(user.getUnitId());
record.setUnitName(user.getUnitName());
record.setUnionId(user.getUnionId());
record.setUnionName(user.getUnionName());
//问卷模式
if (category.equals("QUIZ")) {
if (mode.equals("REGULAR")) {
if ("QUIZ".equals(category)) {
if ("REGULAR".equals(mode)) {
//常规模式 抽取随机题目
int count = dao().count(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId()));
int count = dao().count(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId()));
record.setRandomNumber(count + 1);
} else if (mode.equals("SCHEDULED")) {
} else if ("SCHEDULED".equals(mode)) {
//定时定题模式
int count = dao().count(QsvUserAnswerRecord.class, Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", SecurityUtil.getUserId())
.and(QsvUserAnswerRecord::getAttemptDate, "=", DateUtil.today()));
int count = dao().count(QsvUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
.and("userId", "=", SecurityUtil.getUserId())
.and("attemptDate", "=", DateUtil.today()));
record.setRandomNumber(count + 1);
record.setAttemptDate(new Date());
}
@@ -90,7 +88,7 @@ public class QsvUserAnswerRecordServiceImpl extends BaseServiceImpl<QsvUserAnswe
@Override
public float calcScore(QsvAnswerParam qsvAnswerParam) {
List<String> subjectIds = qsvAnswerParam.getSubjects().stream().map(QsvAnswerParam.Subject::getId).toList();
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where(QsvSubject::getId, "in", subjectIds));
List<QsvSubject> subjects = dao().query(QsvSubject.class, Cnd.where("id", "in", subjectIds));
float score = 0;
@@ -113,12 +111,12 @@ public class QsvUserAnswerRecordServiceImpl extends BaseServiceImpl<QsvUserAnswe
}
@Override
@ApiOperation(TransAop.READ_COMMITTED)
@Aop(TransAop.READ_COMMITTED)
public void calcByScoreMode(String activityId, String userId) {
// 获取活动信息
QsvActivity activity = dao().fetch(QsvActivity.class, activityId);
if (activity == null) {
throw new BaseException("活动找不到" + activityId);
throw new RuntimeException("活动找不到" + activityId);
}
String mode = activity.getMode();
@@ -182,18 +180,18 @@ public class QsvUserAnswerRecordServiceImpl extends BaseServiceImpl<QsvUserAnswe
String orderByField = isHighest ? "totalScore" : "updatedAt";
// 更新所有记录的标志位为0
Cnd cnd = Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId)
.and(QsvUserAnswerRecord::getUserId, "=", userId);
Cnd cnd = Cnd.where("activityId", "=", activityId)
.and("userId", "=", userId);
if (isScheduled) {
cnd.and(QsvUserAnswerRecord::getAttemptDate, "=", DateUtil.today());
cnd.and("attemptDate", "=", DateUtil.today());
}
dao().update(QsvUserAnswerRecord.class, Chain.make(flagField, 0), cnd);
// 找出符合条件的最大记录
Cnd cnd2 = Cnd.where(QsvUserAnswerRecord::getActivityId, "=", activityId).and(QsvUserAnswerRecord::getUserId, "=", userId);
Cnd cnd2 = Cnd.where("activityId", "=", activityId).and("userId", "=", userId);
if (isScheduled) {
cnd2.and(QsvUserAnswerRecord::getAttemptDate, "=", DateUtil.today());
cnd2.and("attemptDate", "=", DateUtil.today());
}
cnd2.desc(orderByField);
QsvUserAnswerRecord record = dao().fetch(QsvUserAnswerRecord.class, cnd2);
@@ -0,0 +1,23 @@
package com.budwk.app.zhgh.enrollmentRegistration.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.entity.annotation.Table;
import org.nutz.dao.entity.annotation.TableMeta;
import java.io.Serializable;
/**
* @author zhf
* @date 2025/7/15 08:48
* @description 入学登记
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("enrollment_registration")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("入学登记表")
public class EnrollmentRegistration extends BaseModel implements Serializable {
}
@@ -0,0 +1,125 @@
package com.budwk.app.zhgh.healthCheckup.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.base.service.BaseService;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupCampus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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.random.R;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @ClassName HealthCheckupCampusController
* @Description TODO 体检院区
* @Author zzr
* @Date 2023/7/20 09:50
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "体检院区")
@At("/platform/healthCheckup/campus")
public class HealthCheckupCampusController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/healthCheckup/campus/index.html")
@SaCheckPermission("healthCheckup.campus")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("healthCheckup.campus")
public Result pageData(PageForm pageForm, @Param(value = "campusName") String campusName) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("select * from health_checkup_campus $condition");
cnd.and(Cnd.likeEX("campusName", campusName));
cnd.asc("campusCode");
sql.setCondition(cnd);
return Result.success(baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At
@ApiOperation("添加院区")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "添加院区")
@SaCheckPermission("healthCheckup.campus")
public Result doAdd(HealthCheckupCampus campus) {
try {
int count = baseService.dao().count(HealthCheckupCampus.class, Cnd.where(HealthCheckupCampus::getCampusCode, "=", campus.getCampusCode()));
if (count > 0) {
return Result.error("编码重复");
}
baseService.dao().insert(campus);
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
@At
@ApiOperation("编辑院区")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "编辑院区")
@SaCheckPermission("healthCheckup.campus")
public Result doEdit(HealthCheckupCampus campus) {
try {
int count = baseService.dao().count(HealthCheckupCampus.class,
Cnd.where(HealthCheckupCampus::getCampusCode, "=", campus.getCampusCode())
.and(HealthCheckupCampus::getId, "!=", campus.getId()));
if (count > 0) {
return Result.error("编码重复");
}
baseService.dao().update(campus);
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
@At
@ApiOperation("编辑院区")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "删除院区")
@SaCheckPermission("healthCheckup.campus")
public Result doDelete(String id) {
try {
baseService.dao().clear(HealthCheckupCampus.class, Cnd.where(HealthCheckupCampus::getId, "=", id));
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
@At
@ApiOperation("查询所有院区")
@SaCheckPermission("healthCheckup.campus")
public Result queryCampus() {
try {
List<HealthCheckupCampus> campusList = baseService.dao().query(HealthCheckupCampus.class, Cnd.NEW().asc("campusCode"));
return Result.success(campusList);
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
}
@@ -0,0 +1,295 @@
package com.budwk.app.zhgh.healthCheckup.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.model.ExcelImportRes;
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.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.EasyExcelUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.healthCheckup.model.*;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupProjectService;
import com.budwk.app.zhgh.healthCheckup.template.HealthCheckupImportTemp;
import com.budwk.app.zhgh.integral.controller.IntegralManageController;
import com.budwk.app.zhgh.welfare.mode.WelfareUserImportExcel;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
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.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName HealthCheckupListController
* @Description TODO
* @Author zhf
* @Date 2023/7/18 8:43
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "体检名单")
@At("/platform/healthCheckup/list/mange")
public class HealthCheckupListController {
@Inject
private Dao dao;
@Inject
private HealthCheckupProjectService healthCheckupProjectService;
@At("")
@Ok("beetl:/platform/zhgh/healthCheckup/listMange/index.html")
@SaCheckPermission("healthCheckup.list.mange")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("healthCheckup.list.mange")
public Result pageData(PageForm pageForm,
String projectId,
String unionId,
String unitId) {
List<HealthCheckupUnionConfirm> confirms = dao.query(HealthCheckupUnionConfirm.class, Cnd.where("projectId", "=", projectId));
HealthCheckupProject project = healthCheckupProjectService.findOne(projectId);
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
hcu.userId AS id,
hcu.loginName,
hcu.userName,
hcu.sex,
hcu.unionId,
hcu.unionName,
hcu.unitName,
hcus.selectTime,
hcus.campus,
hcus.subjectId,
ca.campusName
FROM
health_checkup_user hcu
LEFT JOIN health_checkup_user_selection hcus ON hcu.userId = hcus.selectUserId
AND hcus.projectId=@projectId
LEFT JOIN health_checkup_campus ca on ca.id=hcus.campus
$condition
""").setParam("projectId", projectId);
sql.setCondition(cnd);
cnd.andEX("hcu.projectId", "=", projectId);
cnd.andEX("hcu.unionId", "=", unionId);
cnd.andEX("hcu.unitId", "=", unitId);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("hcu.unionId", "=", SecurityUtil.getUnionId());
}
if (StrUtil.isNotBlank(pageForm.getSearchName()) && StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword()));
}
cnd.groupBy("hcu.userId");
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), "ascending".equalsIgnoreCase(pageForm.getPageOrderBy()) ? "ASC" : "DESC");
} else {
cnd.desc("hcus.selectTime").asc("hcu.unitId");
}
Pagination pagination = healthCheckupProjectService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
List<NutMap> paginationList = pagination.getList();
paginationList.forEach(v -> {
if (StrUtil.isNotBlank(v.getString("subjectId"))) {
List<HealthCheckupProjectSubject> subjects = project.getHealthCheckupProjectSubjects();
HealthCheckupProjectSubject subject = subjects.stream().filter(s -> s.getId().equals(v.getString("subjectId"))).findFirst().orElse(null);
v.setv("optionName", subject.getOptionName());
}
if (StrUtil.isNotBlank(v.getString("unionId"))) {
HealthCheckupUnionConfirm confirm = confirms.stream().filter(o -> o.getUnionId().equals(v.getString("unionId"))).findFirst().orElse(null);
v.setv("isAudit", confirm != null ? confirm.getIsAudit() : "");
v.setv("auditTime", confirm != null ? confirm.getAuditTime() : "");
}
});
return Result.success(pagination);
}
@At
@ApiOperation("体检名单确认")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "healthCheckup", tag = "体检管理", msg = "体检名单确认")
@SaCheckPermission("healthCheckup.list.mange")
public Result doAuditUser(String projectId,
String unionId,
Boolean flag) {
if (flag) {
dao.update(HealthCheckupUnionConfirm.class, Chain.make("isAudit", true)
.add("auditTime", DateUtil.date())
.add("auditUser", SecurityUtil.getUserId()),
Cnd.where("projectId", "=", projectId).and("unionId", "=", unionId));
} else {
dao.update(HealthCheckupUnionConfirm.class, Chain.make("isAudit", null)
.add("auditTime", null)
.add("auditUser", null),
Cnd.where("projectId", "=", projectId).and("unionId", "=", unionId));
}
return Result.success();
}
@At
@ApiOperation("体检名单管理员编辑选择记录")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "管理员编辑了一条选择记录")
@SaCheckPermission("healthCheckup.list.mange")
public Result doEditHealthCheckupData(String subjectId, String campus, String projectId, String userId) {
//查询用户有没有选择过套餐
HealthCheckupUserSelection userSelection = healthCheckupProjectService.dao().fetch(HealthCheckupUserSelection.class,
Cnd.where("projectId", "=", projectId).and("selectUserId", "=", userId));
//如果选择过套餐就修改选择的套餐id
if (Lang.isNotEmpty(userSelection)) {
userSelection.setSubjectId(subjectId);
userSelection.setCampus(campus);
healthCheckupProjectService.update(userSelection);
} else {
//如果没有选择过套餐添加一条记录
HealthCheckupUserSelection checkupUserSelection = new HealthCheckupUserSelection();
checkupUserSelection.setSelectUserId(userId);
checkupUserSelection.setProjectId(projectId);
checkupUserSelection.setSubjectId(subjectId);
checkupUserSelection.setCampus(campus);
checkupUserSelection.setSelectTime(new Date());
healthCheckupProjectService.insert(checkupUserSelection);
}
return Result.success();
}
@At
@ApiOperation("体检名单导入名单")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "管理员导入了体检名单")
@SaCheckPermission("healthCheckup.list.mange")
@Aop(TransAop.READ_COMMITTED)
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result healthImport(TempFile file, String healthProjectId) {
// 读取数据
List<T> ts = EasyExcelUtil.syncReadModel(file.getFile(), HealthCheckupImportTemp.class, 0, 1);
List<HealthCheckupImportTemp> healthCheckupImportTemps = JSONUtil.parseArray(JSONUtil.toJsonStr(ts)).toList(HealthCheckupImportTemp.class);
List<String> loginNames = healthCheckupImportTemps.stream().filter(v -> Strings.isNotBlank(v.getLoginName())).map(v -> v.getLoginName()).collect(Collectors.toList());
//全部的体检名单
List<HealthCheckupUser> healthCheckupUserList = dao.query(HealthCheckupUser.class, Cnd.where(HealthCheckupUser::getProjectId, "=", healthProjectId));
List<View_user> userList = dao.query(View_user.class, Cnd.where(View_user::getLoginname, "in", loginNames));
HealthCheckupProject checkupProject = dao.fetch(HealthCheckupProject.class, healthProjectId);
ActivityUserScope userScope = dao.fetch(ActivityUserScope.class, Cnd.where("groupId", "=", checkupProject.getActivityGroupId()));
List<ActivityUserScope> userScopeList = new ArrayList<>();
for (int i = 0; i < healthCheckupImportTemps.size(); i++) {
HealthCheckupImportTemp excel = healthCheckupImportTemps.get(i);
if (StrUtil.isBlank(excel.getLoginName())) {
excel.setErrInfo("工号为空", i + 1);
continue;
}
// 不能在excel里重复
if (healthCheckupImportTemps.stream().filter(s -> s.getLoginName().equals(excel.getLoginName())).count() > 1) {
excel.setErrInfo("重复数据", i + 1);
}
View_user user = userList.stream().filter(s -> s.getLoginname().equals(excel.getLoginName())).findFirst().orElse(null);
if (user == null) {
excel.setErrInfo("无此用户", i + 1);
continue;
}
if (healthCheckupUserList.stream().anyMatch(s -> s.getUserId().equals(user.getId()))) {
excel.setErrInfo("该用户已加入体检名单", i + 1);
continue;
}
ActivityUserScope s = new ActivityUserScope();
s.setGroupId(userScope.getGroupId());
s.setGroupName(userScope.getGroupName());
s.setUserId(user.getId());
s.setCreator(SecurityUtil.getUserId());
userScopeList.add(s);
}
;
dao.insert(userScopeList);
// 创建结果集
ExcelImportRes<HealthCheckupImportTemp> excelImportRes = new ExcelImportRes<>();
excelImportRes.setTotalRecords(healthCheckupImportTemps.size());
// 添加错误记录
excelImportRes.setErrorDetails(healthCheckupImportTemps.stream().filter(s -> StrUtil.isNotBlank(s.getErrMsg())).collect(Collectors.toList()));
excelImportRes.setFailedCount(excelImportRes.getErrorDetails().size());
return Result.success(excelImportRes);
}
@At
@Ok("void")
@ApiOperation("下载体检参加人员导入模版")
@SaCheckPermission("healthCheckup.list.mange")
public void downloadTem(HttpServletResponse response) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
EasyExcel.write(byteArrayOutputStream, HealthCheckupImportTemp.class)
.sheet("参加人员导入模版")
.doWrite(ArrayList::new);
CommonDownloadUtil.download("参加人员导入模版.xlsx", byteArrayOutputStream.toByteArray(), response);
} catch (Exception e) {
log.error("下载参加人员导入模版失败", e);
}
}
}
@@ -0,0 +1,210 @@
package com.budwk.app.zhgh.healthCheckup.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
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.sys.models.Sys_union;
import com.budwk.app.zhgh.healthCheckup.model.*;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupProjectService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
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.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName HealthCheckupProjectMangeController
* @Description TODO
* @Author zhf
* @Date 2023/7/17 10:58
*/
@IocBean
@Ok("json:full")
@Api(tags = "体检项目")
@At("/platform/healthCheckup/project/mange")
public class HealthCheckupProjectMangeController {
@Inject
private HealthCheckupProjectService healthCheckupProjectService;
@At("")
@Ok("beetl:/platform/zhgh/healthCheckup/projectMange/index.html")
@SaCheckPermission("healthCheckup.projectMange")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("healthCheckup.projectMange")
public Result pageData(PageForm pageForm,
Integer year,
String name) {
Sql sql = Sqls.create("""
SELECT
hcp.id,
hcp.`year`,
hcp.`name`,
hcp.choiceTimeStart,
hcp.choiceTimeEnd,
hcp.activityGroupId,
hcp.cover,
hcp.activityGroupName,
hcp.healthCheckupType,
IF((select count(userId) from health_checkup_user hcu where hcu.projectId = hcp.id) > 0,true,false) AS isHasUserList,
IF(NOW() > hcp.choiceTimeStart AND NOW() < hcp.choiceTimeEnd, true, false) AS isWithinChoiceTime,
IF(NOW() < hcp.choiceTimeStart, true, false) AS canCreated
FROM
health_checkup_project hcp
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("hcp.`year`", "=", year);
cnd.andEX("hcp.`name`", "=", name);
cnd.desc("hcp.choiceTimeStart");
sql.setCondition(cnd);
return Result.success(healthCheckupProjectService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At
@ApiOperation("体检名单确认")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("healthCheckup.projectMange")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "提交体检项目")
public Result doAdd(HealthCheckupProject healthCheckupProject, @Param(value = "deleteRowIds") String[] deleteRowIds) {
String projectId;
//如果是保存
if (StrUtil.isBlank(healthCheckupProject.getId())) {
healthCheckupProject.setYear(DateUtil.thisYear());
HealthCheckupProject checkupProject = healthCheckupProjectService.insertWith(healthCheckupProject, "healthCheckupProjectSubjects");
projectId = checkupProject.getId();
} else {
projectId = healthCheckupProject.getId();
healthCheckupProjectService.dao().clear(HealthCheckupProjectSubject.class, Cnd.where("id", "in", deleteRowIds));
healthCheckupProject.getHealthCheckupProjectSubjects().forEach(v -> {
v.setProjectId(healthCheckupProject.getId());
});
healthCheckupProjectService.dao().insertOrUpdate(healthCheckupProject.getHealthCheckupProjectSubjects());
healthCheckupProjectService.update(healthCheckupProject);
}
healthCheckupProjectService.dao().clear(HealthCheckupUnionConfirm.class, Cnd.where("projectId", "=", projectId));
List<Sys_union> unionList = healthCheckupProjectService.dao().query(Sys_union.class, Cnd.NEW());
List<HealthCheckupUnionConfirm> confirmList = new ArrayList<>();
unionList.forEach(item -> {
HealthCheckupUnionConfirm c = new HealthCheckupUnionConfirm();
c.setProjectId(projectId);
c.setUnionId(item.getId());
c.setIsAudit(false);
confirmList.add(c);
});
healthCheckupProjectService.dao().insert(confirmList);
return Result.success();
}
@At
@ApiOperation("查询体检项目内容")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "查询体检项目内容")
public Result findOne(String id) {
return Result.success(healthCheckupProjectService.findOne(id));
}
@At
@ApiOperation("删除体检项目")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("healthCheckup.projectMange")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "删除了一条体检项目")
public Result doDelete(String id) {
healthCheckupProjectService.delete(id);
healthCheckupProjectService.dao().clear(HealthCheckupProjectSubject.class, Cnd.where("projectId", "=", id));
return Result.success();
}
@At
@ApiOperation("按年份获取体检项目")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "查询了所有的体检项目")
public Result getHealthCheckupProject(Integer year) {
List<HealthCheckupProject> projectList = healthCheckupProjectService.query(Cnd.NEW().andEX("year", "=", year).desc("choiceTimeStart"));
return Result.success(projectList);
}
/**
* 创建体检名单
*
* @param healthCheckupProject
* @return
*/
@At
@ApiOperation("创建体检名单")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("healthCheckup.projectMange")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "创建体检名单")
public Result createUserList(HealthCheckupProject healthCheckupProject) {
healthCheckupProjectService.addHealthCheckupUser(healthCheckupProject);
return Result.success();
}
/**
* 更新名单
*
* @param healthCheckupProject
* @return
*/
@At
@ApiOperation("更新体检名单")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("healthCheckup.projectMange")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "更新体检名单")
public Result renewUserList(HealthCheckupProject healthCheckupProject) {
healthCheckupProjectService.renewHealthCheckupUser(healthCheckupProject);
return Result.success();
}
/**
* 重置名单
*
* @param healthCheckupProject
* @return
*/
@At
@ApiOperation("重置体检名单")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("healthCheckup.projectMange")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "重置体检名单")
public Result resetUserList(HealthCheckupProject healthCheckupProject) {
//重置名单,清空已选择的用户记录
Sql sql = Sqls.create("select id,selectUserId from health_checkup_user_selection where projectId = @projectId").setParam("projectId", healthCheckupProject.getId());
List<NutMap> list = (List<NutMap>) Daos.query(healthCheckupProjectService.dao(), sql.toString(), Sqls.callback.maps());
List<String> userSelectionIds = list.stream().map(v -> v.getString("id")).collect(Collectors.toList());
List<String> userIds = list.stream().map(v -> v.getString("selectUserId")).collect(Collectors.toList());
healthCheckupProjectService.dao().clear(HealthCheckupUserSelection.class, Cnd.where("selectUserId", "in", userIds));
healthCheckupProjectService.dao().clear(HealthCheckupUserCompanion.class, Cnd.where("userSelectionId", "in", userSelectionIds));
healthCheckupProjectService.dao().clear(HealthCheckupUser.class, Cnd.where("projectId", "=", healthCheckupProject.getId()));
healthCheckupProjectService.addHealthCheckupUser(healthCheckupProject);
return Result.success();
}
}
@@ -0,0 +1,278 @@
package com.budwk.app.zhgh.healthCheckup.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
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.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.ManyAddOrRenewUtil;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProject;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProjectSubject;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupUserSelection;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupSingleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
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.Strings;
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 javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName HealthCheckupSingleController
* @Description TODO
* @Author zhf
* @Date 2023/7/18 13:53
*/
@IocBean
@Ok("json:full")
@Api(tags = "体检数据统计")
@At("/platform/healthCheckup/statistics/single")
public class HealthCheckupSingleController {
@Inject
private HealthCheckupSingleService healthCheckupSingleService;
@Inject
private ManyAddOrRenewUtil manyAddOrRenewUtil;
@At("")
@Ok("beetl:/platform/zhgh/healthCheckup/statisticsSingle/index.html")
@SaCheckPermission("healthCheckup.statisticsSingle")
public void index() {
}
@At
@ApiOperation("首页查询")
@SaCheckPermission("healthCheckup.statisticsSingle")
public Result pageData(String projectId,
String unionId) {
NutMap nutMap = healthCheckupSingleService.pageData(projectId, unionId);
return Result.success(nutMap);
}
/**
* 每个分工会领取人员/未领取人员
*
* @param page
* @param isSelected 是否领取
* @param projectId
* @param unionId
* @return
*/
@At
@ApiOperation("每个分工会领取人员/未领取人员")
@SaCheckPermission("healthCheckup.statisticsSingle")
public Result receivePageData(PageForm page, String isSelected,
String projectId,
String unionId) {
List<NutMap> labelList = healthCheckupSingleService.receivePageDataColumns(projectId);
Pagination list = healthCheckupSingleService.receivePageData(page.getPageNumber(), page.getPageSize(), page.getSearchName(), page.getSearchKeyword(), projectId, unionId, isSelected);
return Result.success(NutMap.NEW().addv("list", list).addv("label", labelList));
}
/**
* 导出已选/未选人员名单
*
* @param projectId
* @param unionId
* @param year
* @param flag
* @param response
*/
@At
@Ok("void")
@ApiOperation("导出已选/未选人员名单")
@SaCheckPermission("healthCheckup.statisticsSingle")
public void exportReceiveDetail(String projectId,
String unionId,
Integer year,
boolean flag, HttpServletResponse response) {
List<ExcelExportEntity> entityList = new ArrayList<>() {{
add(new ExcelExportEntity("职工号", "loginName", 20));
add(new ExcelExportEntity("姓名", "userName", 20));
add(new ExcelExportEntity("性别", "sex", 20));
add(new ExcelExportEntity("出生年月", "birthday", 20));
add(new ExcelExportEntity("年龄", "age", 20));
add(new ExcelExportEntity("婚姻状况", "marriage", 20));
add(new ExcelExportEntity("证件号", "idCard", 20));
add(new ExcelExportEntity("部门", "unitName", 20));
add(new ExcelExportEntity("部门编码", "unitCode", 20));
add(new ExcelExportEntity("自选项目", "subjectName", 20));
add(new ExcelExportEntity("自选院区", "campusName", 50));
}};
List<NutMap> list;
if (flag) {
//已选人员
list = healthCheckupSingleService.receivePageData(projectId, unionId, "0");
} else {
//未选人员
list = healthCheckupSingleService.receivePageData(projectId, unionId, "1");
}
//获取当前年
Calendar calendar = Calendar.getInstance();
int thisYear = calendar.get(Calendar.YEAR);
list.forEach(v -> {
int substring = 0;
if (Strings.isNotBlank(v.getString("birthday"))) {
substring = Integer.parseInt(v.getString("birthday").substring(0, 4));
} else if (Strings.isNotBlank(v.getString("idCard")) && v.getString("idCard").length() >= 10) {
substring = Integer.parseInt(v.getString("idCard").substring(6, 10));
}
v.put("age", thisYear - substring);
});
List<NutMap> list2 = list.stream().filter(v -> Strings.isNotBlank(v.getString("unionName"))).collect(Collectors.toList());
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
exportParams.setSheetName(year + "年教职工体检项目及地点统计表");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list2);
CommonDownloadUtil.download((flag ? year + "年教职工体检项目及地点统计表" : "未选名单") + ".xlsx", workbook, response);
}
@At
@Ok("void")
@ApiOperation("导出教职工家属体检登记表")
@SaCheckPermission("healthCheckup.statisticsSingle")
public void exportUserCompanion(String projectId,
String unionId,
Integer year, HttpServletResponse response) {
Sql sql = Sqls.create("""
SELECT
u.username,
u.unitname unitName,
u.mobile,
hcuc.userName familyName,
hcuc.sex,
hcuc.marry isMarried,
hcuc.idCard,
hcc.campusName,
(
SELECT
GROUP_CONCAT( hcps.optionName )
FROM
health_checkup_user_selection hcus
LEFT JOIN `health_checkup_project_subject` hcps ON hcps.id = hcus.subjectId
WHERE
hcus.projectId = @projectId
AND hcus.selectUserId = u.id
) optionName
FROM
`health_checkup_user_companion` hcuc
LEFT JOIN `health_checkup_user_selection` hcus ON hcus.id = hcuc.userSelectionId
LEFT JOIN `health_checkup_campus` hcc ON hcc.id = hcus.campus
LEFT JOIN `vw_user` u ON u.id = hcus.selectUserId
LEFT JOIN `health_checkup_project` hcp ON hcp.id = hcus.projectId
$condition
""").setParam("projectId", projectId);
Cnd cnd = Cnd.NEW();
cnd.andEX("hcus.projectId", "=", projectId);
cnd.andEX("u.unionid", "=", unionId);
cnd.andEX("hcp.year", "=", year);
cnd.asc("u.unioncode");
sql.setCondition(cnd);
//家属信息表
List<NutMap> companionList = healthCheckupSingleService.listMap(sql);
for (int i = 0; i < companionList.size(); i++) {
companionList.get(i).put("index", i + 1);
}
List<ExcelExportEntity> entityList = new ArrayList<>() {{
add(new ExcelExportEntity("序号", "index", 20));
add(new ExcelExportEntity("教职工姓名", "username", 20));
add(new ExcelExportEntity("学院(部门)", "unitName", 20));
add(new ExcelExportEntity("手机", "mobile", 20));
add(new ExcelExportEntity("体检人姓名", "familyName", 20));
add(new ExcelExportEntity("性别", "sex", 20));
add(new ExcelExportEntity("婚否", "isMarried", 20));
add(new ExcelExportEntity("体检人身份证号", "idCard", 50));
add(new ExcelExportEntity("自选项目", "optionName", 50));
add(new ExcelExportEntity("自选院区", "campusName", 50));
}};
try {
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
exportParams.setTitle(year + "教职工家属体检登记表");
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, companionList);
CommonDownloadUtil.download(year + "教职工家属体检登记表.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
@At
@ApiOperation("管理员一键代选")
@Ok("json:full")
@SaCheckPermission("healthCheckup.statisticsSingle")
@SLog(type = "healthCheckup", tag = "体检管理", msg = "管理员一键代选")
public Result doSelectByAdmin(String projectId, String optionId, String campus) {
Dao dao = healthCheckupSingleService.dao();
HealthCheckupProject project = dao.fetch(HealthCheckupProject.class, projectId);
HealthCheckupProjectSubject subject = dao.fetch(HealthCheckupProjectSubject.class, optionId);
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
u.id,
u.loginname loginName,
u.username userName,
u.sex,
u.birthday,
u.unitname unitName,
u.unionname unionName,
u.idcard idCard,
u.mobile
FROM
`activity_user_scope` aus
LEFT JOIN `vw_user` u ON u.id = aus.userId
$projectCnd $condition
""");
cnd.and("aus.groupId", "=", project.getActivityGroupId());
sql.setVar("projectCnd", "AND u.id NOT IN ( SELECT selectUserId FROM `health_checkup_user_selection` WHERE projectId = '" + projectId + "' AND selectUserId IS NOT NULL )");
cnd.groupBy("u.loginname");
sql.setCondition(cnd);
List<NutMap> mapList = healthCheckupSingleService.listMap(sql);
List<String> userIds = mapList.stream().map(v -> v.getString("id")).collect(Collectors.toList());
//题目id
List<HealthCheckupUserSelection> selections = userIds.stream().map(v -> {
HealthCheckupUserSelection selection = new HealthCheckupUserSelection();
selection.setProjectId(projectId);
selection.setSelectUserId(v);
selection.setCampus(campus);
selection.setSubjectId(optionId);
return selection;
}).collect(Collectors.toList());
manyAddOrRenewUtil.asyncExecuteFastInsert(selections,null);
return Result.success();
}
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* @ClassName HealthCheckupCampus
* @Description TODO 体检院区
* @Author zzr
* @Date 2023/7/20 09:50
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_campus")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检院区表")
public class HealthCheckupCampus extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("院区编码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String campusCode;
@Column
@Comment("院区名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String campusName;
}
@@ -0,0 +1,78 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @ClassName HealthCheckupProject
* @Description TODO
* @Author zhf
* @Date 2023/7/17 10:40
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_project")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检项目表")
public class HealthCheckupProject extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("年度")
@ColDefine(type = ColType.INT, width = 4)
private Integer year;
@Column
@Comment("项目名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column
@Comment("体检对象类型")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String healthCheckupType;
@Column
@Comment("选择开始时间")
@ColDefine(type = ColType.DATETIME)
private Date choiceTimeStart;
@Column
@Comment("选择结束时间")
@ColDefine(type = ColType.DATETIME)
private Date choiceTimeEnd;
@Column
@Comment("发送对象")
@ColDefine(type = ColType.INT, width = 32)
private Integer activityGroupId;
@Column
@Comment("发送对象名称")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String activityGroupName;
@Column
@Comment("封面")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String cover;
@Many(field = "projectId")
private List<HealthCheckupProjectSubject> healthCheckupProjectSubjects;
}
@@ -0,0 +1,54 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* @ClassName HealthCheckupProjectSubject
* @Description 体检套餐
* @Author zhf
* @Date 2023/7/17 10:51
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_project_subject")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检套餐表")
public class HealthCheckupProjectSubject extends BaseModel implements Serializable {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("所属项目")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String projectId;
@Column
@Comment("选项名称")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String optionName;
@Column
@Comment("选项排序")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String optionSort;
@Column
@Comment("图片地址")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String imgUrl;
@Column
@Comment("说明描述")
@ColDefine(type = ColType.TEXT)
private String description;
}
@@ -0,0 +1,52 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_union_confirm")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("分工会体检确认表")
public class HealthCheckupUnionConfirm extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("所属项目")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String projectId;
@Column
@Comment("工会id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("是否确认")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isAudit;
@Column
@Comment("确认时间")
@ColDefine(type = ColType.DATETIME)
private Date auditTime;
@Column
@Comment("操作人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String auditUser;
}
@@ -0,0 +1,76 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* @version 1.0
* @Author zzr
* @nameHealthCheckupUser
* @Date 2024/7/24 15:42
* @注释 体检用户
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_user")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检名单表")
public class HealthCheckupUser extends BaseModel implements Serializable {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("所属项目")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String projectId;
@Column
@Comment("用户id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("用户姓名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String userName;
@Column
@Comment("性别")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String sex;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String loginName;
@Column
@Comment("所属工会")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionName;
@Column
@Comment("工会Id")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String unionId;
@Column
@Comment("所属单位")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unitName;
@Column
@Comment("单位Id")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String unitId;
}
@@ -0,0 +1,66 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* @ClassName HealthCheckupUserCompanion
* @Description TODO 体检家属表
* @Author zzr
* @Date 2023/7/20 10:40
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_user_companion")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检家属表")
public class HealthCheckupUserCompanion extends BaseModel implements Serializable {
@Name
@Comment("id")
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("体检选择表Id")
private String userSelectionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("姓名")
private String userName;
@Column
@ColDefine(type = ColType.CHAR, width = 1)
@Comment("性别")
private String sex;
@Column
@ColDefine(type = ColType.INT)
@Comment("年龄")
private Integer age;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("婚否")
private String marry;
@Column
@ColDefine(type = ColType.VARCHAR, width = 18)
@Comment("身份证号")
private String idCard;
@Column
@ColDefine(type = ColType.VARCHAR, width = 18)
@Comment("手机号")
private String mobile;
}
@@ -0,0 +1,59 @@
package com.budwk.app.zhgh.healthCheckup.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @ClassName HealthCheckupUserSelection
* @Description TODO
* @Author zhf
* @Date 2023/7/18 9:20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("health_checkup_user_selection")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("体检教职工选择表")
public class HealthCheckupUserSelection extends BaseModel implements Serializable {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("所属项目")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String projectId;
@Column
@Comment("所属选项")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String subjectId;
@Column
@Comment("选择用户")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String selectUserId;
@Column
@Comment("选择院区")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String campus;
@Column
@Comment("选择时间")
@ColDefine(type = ColType.DATETIME)
private Date selectTime;
@Many(field = "userSelectionId")
private List<HealthCheckupUserCompanion> companionList;
}
@@ -0,0 +1,24 @@
package com.budwk.app.zhgh.healthCheckup.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProject;
import org.nutz.lang.util.NutMap;
public interface HealthCheckupProjectService extends BaseService<HealthCheckupProject> {
HealthCheckupProject findOne(String id);
/**
* 添加体检用户
* @param healthCheckupProject
*/
void addHealthCheckupUser(HealthCheckupProject healthCheckupProject);
/**
* 更新体检用户
* @param healthCheckupProject
*/
void renewHealthCheckupUser(HealthCheckupProject healthCheckupProject);
}
@@ -0,0 +1,46 @@
package com.budwk.app.zhgh.healthCheckup.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProject;
import org.nutz.lang.util.NutMap;
import java.util.List;
public interface HealthCheckupSingleService extends BaseService<HealthCheckupProject> {
/**
* 分页查询
*
* @param projectId 福利id
* @return
*/
NutMap pageData(String projectId,String unionId);
/**
* 导出发放详细表
*
* @param projectId
* @return
*/
List<NutMap> receivePageDataColumns(String projectId);
/**
* 领取详情分页
*
* @param projectId 体检id
* @return
*/
Pagination receivePageData(Integer pageNumber, Integer pageSize, String searchName, String searchKeyword, String projectId, String unionId, String isSelected);
/**
* 领取详情不分页
*
* @param projectId 体检id
* @return
*/
List<NutMap> receivePageData(String projectId, String unionId,String isSelected);
}
@@ -0,0 +1,125 @@
package com.budwk.app.zhgh.healthCheckup.service.impl;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.ManyAddOrRenewUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.views.View_user;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProject;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupUser;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupUserCompanion;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupUserSelection;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupProjectService;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.annotation.Comment;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.Mirror;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @ClassName HealthCheckupProjectServiceImpl
* @Description TODO
* @Author zhf
* @Date 2023/7/17 14:48
*/
@IocBean(args = {"refer:dao"})
public class HealthCheckupProjectServiceImpl extends BaseServiceImpl<HealthCheckupProject> implements HealthCheckupProjectService {
@Inject
private ManyAddOrRenewUtil manyAddOrRenewUtil;
public HealthCheckupProjectServiceImpl(Dao dao) {
super(dao);
}
@Override
public HealthCheckupProject findOne(String id) {
HealthCheckupProject project = fetchLinks(fetch(id), "healthCheckupProjectSubjects", Cnd.NEW().asc("optionSort"));
return project;
}
@Override
public void addHealthCheckupUser(HealthCheckupProject healthCheckupProject) {
List<HealthCheckupUser> needAddUsers = getHealthCheckupUserListByProject(healthCheckupProject);
manyAddOrRenewUtil.asyncExecuteFastInsert(needAddUsers, null);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void renewHealthCheckupUser(HealthCheckupProject healthCheckupProject) {
//全部组别人员
List<HealthCheckupUser> allGroupUsers = getHealthCheckupUserListByProject(healthCheckupProject);
//已选取人员,选择表的人员
List<HealthCheckupUser> userList = dao().query(HealthCheckupUser.class, Cnd.where("projectId", "=", healthCheckupProject.getId()));
// 找出在 userList 中但不在allGroupUsers中的userId,这部分人要删除体检信息
List<String> needDeleteUserIds = userList.stream()
.map(HealthCheckupUser::getUserId)
.filter(selectUserId -> allGroupUsers.stream()
.noneMatch(user -> user.getUserId().equals(selectUserId)))
.collect(Collectors.toList());
//获取生成名单中没有的用户,这部分要添加
Sql sql = Sqls.create("select userId from health_checkup_user where projectId = @projectId").setParam("projectId", healthCheckupProject.getId());
List<NutMap> sourceSelectionUserMaps = (List<NutMap>) Daos.query(dao(), sql.toString(), Sqls.callback.maps());
Set<String> sourceSelectionUserIds = sourceSelectionUserMaps.stream().map(v -> v.getString("userId")).collect(Collectors.toSet());
//找出原来名单中没有的人,没有的就可以新增
List<HealthCheckupUser> canInsertSelectionUsers = allGroupUsers.stream().filter(v -> !sourceSelectionUserIds.contains(v.getId())).collect(Collectors.toList());
//过滤出原有名单中没有的,可以新增
List<HealthCheckupUser> needInsertSelectionUsers = canInsertSelectionUsers.parallelStream()
.filter(v -> !sourceSelectionUserIds.contains(v.getUserId()))
.collect(Collectors.toList());
List<String> userSelectionIds = userList.stream().filter(needDeleteUserIds::contains).map(HealthCheckupUser::getId).collect(Collectors.toList());
dao().clear(HealthCheckupUser.class, Cnd.where("userId", "in", needDeleteUserIds));
dao().clear(HealthCheckupUserSelection.class, Cnd.where("selectUserId", "in", needDeleteUserIds));
dao().clear(HealthCheckupUserCompanion.class, Cnd.where("userSelectionId", "in", userSelectionIds));
manyAddOrRenewUtil.asyncExecuteFastInsert(needInsertSelectionUsers, null);
}
public List<HealthCheckupUser> getHealthCheckupUserListByProject(HealthCheckupProject healthCheckupProject) {
String projectId = healthCheckupProject.getId();
List<ActivityUserScope> groupUsers = dao().query(ActivityUserScope.class, Cnd.where("groupId", "=", healthCheckupProject.getActivityGroupId()));
List<String> userIds = groupUsers.stream().map(ActivityUserScope::getUserId).collect(Collectors.toList());
List<View_user> userMapList = dao().query(View_user.class, Cnd.where("id", "in", userIds));
return userMapList.stream().map(v -> {
HealthCheckupUser user = new HealthCheckupUser();
user.setId(R.UU32());
user.setProjectId(projectId);
user.setUserId(v.getId());
user.setLoginName(v.getLoginname());
user.setUserName(v.getUsername());
user.setSex(v.getSex());
user.setUnitId(v.getUnitId());
user.setUnitName(v.getUnitName());
user.setUnionId(v.getUnionId());
user.setUnionName(v.getUnionName());
return user;
}).collect(Collectors.toList());
}
}
@@ -0,0 +1,273 @@
package com.budwk.app.zhgh.healthCheckup.service.impl;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProject;
import com.budwk.app.zhgh.healthCheckup.model.HealthCheckupProjectSubject;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupProjectService;
import com.budwk.app.zhgh.healthCheckup.service.HealthCheckupSingleService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@IocBean(args = {"refer:dao"})
public class HealthCheckupSingleServiceImpl extends BaseServiceImpl<HealthCheckupProject> implements HealthCheckupSingleService {
public HealthCheckupSingleServiceImpl(Dao dao) {
super(dao);
}
@Inject
private HealthCheckupProjectService healthCheckupProjectService;
@Override
public NutMap pageData(String projectId, String unionId) {
HealthCheckupProject project = healthCheckupProjectService.findOne(projectId);
Sql sql = Sqls.create("""
SELECT
su.id,
su.name unionName,
(SELECT count( 1 ) FROM `health_checkup_user` hcu WHERE hcu.projectId=@projectId and hcu.unionId = su.id ) sumCount
FROM
sys_union su
$condition
""").setParam("projectId", projectId);
Cnd cnd = Cnd.NEW();
cnd.andEX("su.id", "=", unionId);
cnd.asc("su.unionCode");
sql.setCondition(cnd);
//分工会参加体检人数汇总
List<NutMap> healthCheckupList = listMap(sql);
//该体检项目下的套餐
List<HealthCheckupProjectSubject> subjectList = project.getHealthCheckupProjectSubjects();
//体检人员详情
List<NutMap> userSelectList = this.getUserSelectionByProjectId(projectId);
for (NutMap healthCheckup : healthCheckupList) {
List<NutMap> thisUnionSelectList = userSelectList.stream().filter(x ->
x.getString("unionId").equals(healthCheckup.getString("id")) &&
x.getString("projectId").equals(projectId)).collect(Collectors.toList());
subjectList.forEach(o -> {
//每一项选择的人数
Cnd optionCountCnd = Cnd.NEW();
Sql optionCountSql = Sqls.create("""
SELECT
COUNT(*)
FROM
`health_checkup_user_selection` hs
LEFT JOIN health_checkup_user hcu ON hcu.userId = hs.selectUserId
AND hcu.projectId = @projectId
$condition
""").setParam("projectId", projectId);
optionCountCnd.andEX("hcu.unionId", "=", healthCheckup.getString("id"));
optionCountCnd.andEX("hs.projectId", "=", projectId);
optionCountCnd.andEX("hs.subjectId", "=", o.getId());
optionCountSql.setCondition(optionCountCnd);
int count = count(optionCountSql);
healthCheckup.put(o.getOptionName(), count);
});
//已选人数
healthCheckup.put("totalCount", thisUnionSelectList.stream().map(v -> v.getString("selectUserId")).distinct().count());
//未选人数
healthCheckup.put("unselectedTeacherSum", healthCheckup.getInt("sumCount") - healthCheckup.getInt("totalCount"));
}
//表格列数据
List<NutMap> labelList = new ArrayList<>();
labelList.add(NutMap.NEW().addv("label", "本次体检人数").addv("prop", "sumCount"));
subjectList.forEach(v -> {
labelList.add(NutMap.NEW().addv("label", v.getOptionName()).addv("prop", v.getOptionName()));
});
labelList.add(NutMap.NEW().addv("label", "参加人数").addv("prop", "totalCount"));
labelList.add(NutMap.NEW().addv("label", "未选人数").addv("prop", "unselectedTeacherSum"));
return NutMap.NEW().addv("tableList", healthCheckupList).addv("tableColumn", labelList);
}
/**
* 体检参加人员
*
* @param projectId
* @return
*/
public List<NutMap> getUserSelectionByProjectId(String projectId) {
Cnd cnd = Cnd.NEW();
cnd.and("hcu.unionId", "is not", null);
cnd.andEX("hu.projectId", "=", projectId);
cnd.asc("hu.selectUserId");
Sql sql = Sqls.create("""
SELECT
hu.subjectId,
hu.selectTime,
hu.projectId,
hu.selectUserId,
hcu.unionId
FROM
`health_checkup_user_selection` hu
LEFT JOIN `health_checkup_user` hcu ON hcu.userId = hu.selectUserId and hcu.projectId=@projectId
$condition
""").setParam("projectId", projectId);
sql.setCondition(cnd);
return listMap(sql);
}
@Override
public List<NutMap> receivePageDataColumns(String projectId) {
List<NutMap> labelList = new ArrayList<>();
labelList.add(NutMap.NEW().addv("label", "工号").addv("prop", "loginName"));
labelList.add(NutMap.NEW().addv("label", "姓名").addv("prop", "userName"));
labelList.add(NutMap.NEW().addv("label", "联系电话").addv("prop", "mobile"));
labelList.add(NutMap.NEW().addv("label", "身份证").addv("prop", "idCard").addv("width", 20));
labelList.add(NutMap.NEW().addv("label", "人员类型").addv("prop", "personType"));
labelList.add(NutMap.NEW().addv("label", "工会").addv("prop", "unionName"));
labelList.add(NutMap.NEW().addv("label", "单位").addv("prop", "unitName"));
return labelList;
}
@Override
public Pagination receivePageData(Integer pageNumber, Integer pageSize, String searchName,
String searchKeyword, String projectId, String unionId, String isSelected) {
Sql sql = null;
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(isSelected)) {
//查看已选择体检
if ("0".equals(isSelected)) {
sql = Sqls.create("""
SELECT
u.loginname AS loginName,
u.username AS userName,
u.sex,
u.birthday,
u.personType,
u.unitname AS unitName,
u.unionname AS unionName,
u.idcard AS idCard,
u.mobile
FROM
`health_checkup_user_selection` hcus
LEFT JOIN `vw_user` u ON u.id = hcus.selectUserId
LEFT JOIN `health_checkup_project_subject` hcps ON hcps.id = hcus.subjectId
$condition
""").setParam("projectId", projectId);
cnd.and("hcus.projectId", "=", projectId);
cnd.andEX("u.unionId", "=", unionId);
cnd.desc("hcus.subjectId");
} else if ("1".equals(isSelected)) {//查看未选择体检
sql = Sqls.create("""
SELECT
u.id,
hcu.loginName,
hcu.userName,
hcu.sex,
u.birthday,
u.personType,
hcu.unitName,
hcu.unionName,
u.idcard idCard,
u.mobile
FROM
`health_checkup_user` hcu
LEFT JOIN `vw_user` u ON u.id = hcu.userId
$condition
""");
cnd.and(new Static("u.id NOT IN ( SELECT selectUserId FROM `health_checkup_user_selection` WHERE projectId = '" + projectId + "' AND selectUserId IS NOT NULL )"));
cnd.andEX("hcu.unionId", "=", unionId);
cnd.andEX("hcu.projectId", "=", projectId);
}
}
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
cnd.and(searchName, "like", "%" + searchKeyword + "%");
}
cnd.asc("u.unionCode");
cnd.groupBy("u.loginname");
sql.setCondition(cnd);
return listPageMap(pageNumber, pageSize, sql);
}
@Override
public List<NutMap> receivePageData(String projectId, String unionId, String isSelected) {
Sql sql = null;
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(isSelected)) {
//查看已选择体检
if ("0".equals(isSelected)) {
sql = Sqls.create("""
SELECT
u.loginname AS loginName,
u.username AS userName,
u.sex,
u.birthday,
u.personType,
u.unitName,
u.unitCode,
u.marriage,
u.unionName,
u.idCard,
u.mobile,
hcps.optionName subjectName,
hcc.campusName,
(
SELECT
GROUP_CONCAT( hcps.optionName )
FROM
health_checkup_user_selection hcus
LEFT JOIN `health_checkup_project_subject` hcps ON hcps.id = hcus.subjectId
WHERE
hcus.projectId = @projectId
AND hcus.selectUserId = u.id
) optionName
FROM
`health_checkup_user_selection` hcus
LEFT JOIN `vw_user` u ON u.id = hcus.selectUserId
LEFT JOIN `health_checkup_user` hcu ON hcu.userId = hcus.selectUserId and hcu.projectId=@projectId
LEFT JOIN `health_checkup_project_subject` hcps ON hcps.id = hcus.subjectId
LEFT JOIN `health_checkup_campus` hcc ON hcc.id = hcus.campus
$condition
""").setParam("projectId", projectId);
cnd.and("hcus.projectId", "=", projectId);
cnd.desc("hcus.subjectId");
} else if ("1".equals(isSelected)) {//查看未选择体检
sql = Sqls.create("""
SELECT
u.id,
hcu.loginName,
hcu.userName,
hcu.sex,
u.birthday,
u.marriage,
u.personType,
hcu.unitName,
hcu.unionName,
u.idcard idCard,
u.mobile
FROM
`health_checkup_user` hcu
LEFT JOIN `vw_user` u ON u.id = hcu.userId
$condition
""");
sql.setVar("projectCnd", projectId);
cnd.and(new Static("u.id NOT IN ( SELECT selectUserId FROM `health_checkup_user_selection` WHERE projectId = '" + projectId + "' AND selectUserId IS NOT NULL )"));
}
}
cnd.andEX("hcu.projectId", "=", projectId);
cnd.andEX("hcu.unionId", "=", unionId);
cnd.asc("u.unionCode");
cnd.groupBy("u.loginname");
sql.setCondition(cnd);
return listMap(sql);
}
}
@@ -0,0 +1,25 @@
package com.budwk.app.zhgh.healthCheckup.template;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.budwk.app.base.model.ExcelImportError;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
@ContentRowHeight(20) // 内容行高
@HeadRowHeight(20) // 表头行高
@ColumnWidth(25)
public class HealthCheckupImportTemp extends ExcelImportError {
@ExcelProperty("工号" )
private String loginName;
@ExcelProperty("姓名")
private String userName;
}
@@ -0,0 +1,114 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.integral.controller.IntegralManageController;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.activityBudget.template.ActivityBudgetTemp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/21 11:30
* @description 预算申报
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算申报")
@At("/platform/activity/budget/apply")
public class ActivityBudgetApplyController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/apply/index.html")
@SaCheckPermission("activity.budget.apply")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/apply/form.html")
@SaCheckPermission("activity.budget.apply")
public void form() {
}
@At
@ApiOperation("提交年度预算申报")
@SaCheckPermission("activity.budget.apply")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApply", tag = "年度预算申报-预算申报", msg = "提交年度预算申报")
public Result doSubmit(@Param("activityBudget") ActivityBudget activityBudget, Boolean flag) {
return activityBudgetService.doSubmit(activityBudget, flag);
}
@At
@ApiOperation("查询校工会申报的年度预算")
@SaCheckPermission("activity.budget.apply")
public Result getSchoolBudget() {
Sql sql = Sqls.create("""
SELECT
ab.*
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ins.state = 20
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_ONE'
""").setParam("year", DateUtil.thisYear());
List<NutMap> budgetList = activityBudgetService.listMap(sql);
return Result.success(budgetList);
}
@At
@Ok("void")
@ApiOperation("下载导入的模版")
@SaCheckPermission("activity.budget.apply")
public void downloadImport(HttpServletResponse response) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();) {
EasyExcel.write(byteArrayOutputStream, ActivityBudgetTemp.class)
.sheet("预算申报模版")
.doWrite(ArrayList::new);
CommonDownloadUtil.download("预算申报模版.xlsx", byteArrayOutputStream.toByteArray(), response);
} catch (Exception e) {
log.error("下载福利名单导入模版失败", e);
}
}
}
@@ -0,0 +1,167 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
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.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
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 javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
* @author zhf
* @date 2025/7/24 11:46
* @description 我的申报
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "我的预算申报")
@At("/platform/activity/budget/applyList")
public class ActivityBudgetApplyListController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/applyList/index.html")
@SaCheckPermission("activity.budget.applyList")
public void index() {
}
@At("/view")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/view/index.html")
@SaCheckPermission("activity.budget.applyList")
public void view() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.applyList")
public Result pageData(PageForm pageForm, Integer year, String activityMatter) {
Sql sqlByApplyList = activityBudgetService.getSqlByApplyList(pageForm, year, activityMatter, Cnd.NEW());
Pagination pagination = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sqlByApplyList);
return Result.success(pagination);
}
@At
@ApiOperation("批量删除申报数据")
@SaCheckPermission("activity.budget.applyList")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "删除了${ids.length}条数据,${ids}")
public Result batchDelete(@Param("ids[]") @Valid String[] ids) {
if (ObjectUtil.isNotEmpty(ids)) {
activityBudgetService.clear(Cnd.where("id", "in", ids));
activityBudgetService.dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "in", ids));
List<ProcessInstance> instanceList = activityBudgetService.dao().query(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", ids));
if (ObjectUtil.isNotEmpty(instanceList)) {
List<Long> instanceIds = instanceList.stream().map(ProcessInstance::getId).toList();
activityBudgetService.dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "in", instanceIds));
activityBudgetService.dao().clear(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "in", ids));
}
}
return Result.success();
}
@At
@ApiOperation("删除一条申报数据")
@SaCheckPermission("activity.budget.applyList")
@Aop(TransAop.READ_COMMITTED)
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "删除了一条条数据,${id}")
public Result doDelete(String id) {
activityBudgetService.dao().delete(ActivityBudget.class, id);
activityBudgetService.dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", id));
ProcessInstance instance = activityBudgetService.dao().fetch(ProcessInstance.class, Cnd.where(ProcessInstance::getBusinessNo, "=", id));
if (ObjectUtil.isNotEmpty(instance)) {
activityBudgetService.dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
activityBudgetService.dao().delete(ProcessInstance.class, instance.getId());
}
return Result.success();
}
@At
@ApiOperation("提交申报数据")
@SaCheckPermission("activity.budget.applyList")
@SLog(type = "activityBudgetApplyList", tag = "年度预算申报-我的申报", msg = "提交了${ids.length}条数据,${ids}")
public Result batchSubmit(@Valid @Param("ids[]") String[] ids) {
List<ActivityBudget> budgetList = activityBudgetService.query(Cnd.where("id", "in", ids));
List<ActivityBudget> budgets = budgetList.stream().filter(a ->
ObjectUtil.isEmpty(a.getDeclareTotalBudgetMoney())
|| ObjectUtil.isEmpty(a.getHelpUnitName())
|| ObjectUtil.isEmpty(a.getOutlayManageSource())).toList();
List<String> names = budgets.stream().map(ActivityBudget::getActivityMatter).toList();
if (ObjectUtil.isNotEmpty(names)) {
return Result.error("请完善活动预算信息【:" + StrUtil.join(",", names) + "");
}
budgetList.forEach(b -> {
b.setTotalBudgetMoney(b.getDeclareTotalBudgetMoney());
b.setAuditState(1);
});
activityBudgetService.update(budgetList);
return Result.success();
}
@At
@ApiOperation("查询单个预算详细信息")
@SaCheckPermission("activity.budget.applyList")
public Result findOne(String id) {
return Result.success(activityBudgetService.findOne(id));
}
@At
@ApiOperation("查询申报的金额")
@SaCheckPermission("activity.budget.applyList")
public Result getApplyMoney(Integer year, String activityMatter) {
Cnd cnd = Cnd.NEW();
cnd.andEX("info.isSchoolBudget", "=", 0);
cnd.andEX("ins.state", "=", 20);
Sql sql = activityBudgetService.getSqlByApplyList(null, year, activityMatter, cnd);
sql.setCondition(cnd);
List<NutMap> list = activityBudgetService.listMap(sql);
double declareTotalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("declareTotalBudgetMoney")).sum();
double totalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("totalBudgetMoney")).sum();
return Result.success(Map.of("declareTotalBudgetMoney", declareTotalBudgetMoney, "totalBudgetMoney", totalBudgetMoney));
}
@At
@Ok("void")
@SaCheckPermission("activity.budget.applyList")
public void doExport(@Valid Integer year, String activityMatter, HttpServletResponse response) {
activityBudgetService.doExport(year, activityMatter, response);
}
}
@@ -0,0 +1,129 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
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.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetApplyStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
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.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author zhf
* @date 2025/7/24 17:28
* @description
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算汇总")
@At("/platform/activity/budget/applyStatistics")
public class ActivityBudgetApplyStatisticsController {
@Inject
private ActivityBudgetApplyStatisticsService activityBudgetService;
@Inject
private SysDictService sysDictService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/applyStatistics/index.html")
@SaCheckPermission("activity.budget.applyStatistics")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.applyStatistics")
public Result pageData(PageForm pageForm, Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, activityMatter);
Pagination pagination = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("查询预算有多少钱")
@SaCheckPermission("activity.budget.applyStatistics")
public Result getApplyMoney(Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, activityMatter);
List<NutMap> list = activityBudgetService.listMap(sql);
list = list.stream().filter(v -> !v.getBoolean("isSchoolBudget")).toList();
double declareTotalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("declareTotalBudgetMoney")).sum();
double totalBudgetMoney = list.stream().mapToDouble(map -> map.getDouble("totalBudgetMoney")).sum();
return Result.success(Map.of("declareTotalBudgetMoney", declareTotalBudgetMoney, "totalBudgetMoney", totalBudgetMoney));
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("activity.budget.applyStatistics")
public void doExport(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource, HttpServletResponse response) {
Sql sql = activityBudgetService.getsql(year, unionId, clubId, outlayManageSource, null);
List<NutMap> mapList = activityBudgetService.listMap(sql);
List<Sys_dict> dictList = sysDictService.getSubListByCode("ACTIVITY_BUDGET_TYPE");
mapList.forEach(map -> {
Sys_dict dict = dictList.stream().filter(d -> d.getCode().equals(map.getString("outlayManageSource"))).findFirst().orElse(null);
map.put("outlayManageSource", dict.getName());
});
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
entities.add(new ExcelExportEntity("申报人姓名", "userName", 20));
entities.add(new ExcelExportEntity("申报人工号", "loginName", 20));
entities.add(new ExcelExportEntity("联系方式", "mobile", 20));
entities.add(new ExcelExportEntity("申报类型", "outlayManageSource", 20));
entities.add(new ExcelExportEntity("申报单位", "helpUnitName", 20));
entities.add(new ExcelExportEntity("事项", "activityMatter", 20));
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("申报预算金额", "declareTotalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExcelExportEntity draftCodeEntity2 = new ExcelExportEntity("审核预算金额", "totalBudgetMoney", 20);
draftCodeEntity2.setType(10);
entities.add(draftCodeEntity2);
entities.add(new ExcelExportEntity("申报时间", "applyDate", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
@At
@ApiOperation("删除申报记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("activity.budget.applyStatistics")
@SLog(type = "activity.budget.applyStatistics", tag = "删除申报记录", msg = "删除申报记录:${args[0]}")
public Result doDelete(String id) {
activityBudgetService.doDelete(id);
return Result.success();
}
}
@@ -0,0 +1,97 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetQueryStatisticsService;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
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 javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/24 16:35
* @description
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "预算汇总")
@At("/platform/activity/budget/queryStatistics")
public class ActivityBudgetQueryStatisticsController {
@Inject
private ActivityBudgetQueryStatisticsService statisticsService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/queryStatistics/index.html")
@SaCheckPermission("activity.budget.queryStatistics")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.queryStatistics")
public Result pageData(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource) {
return Result.success(statisticsService.getDataByBudgetTypeCode(year, clubId, unionId, outlayManageSource));
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("activity.budget.queryStatistics")
public void doExport(@Valid Integer year, String clubId, String unionId, @Valid String outlayManageSource, HttpServletResponse response) {
List<NutMap> mapList = statisticsService.getDataByBudgetTypeCode(year, clubId, unionId, outlayManageSource);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")){
mapList.forEach(m->{
if (StrUtil.isEmpty(m.getString("unionName"))){
m.put("unionName",m.getString("unitName"));
m.put("unionCode",m.getString("unionId"));
}
});
}
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
if (List.of("ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
entities.add(new ExcelExportEntity("事项", "activityMatter", 50));
}else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
entities.add(new ExcelExportEntity("编码", "unionCode", 20));
entities.add(new ExcelExportEntity("分工会", "unionName", 20));
}else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
entities.add(new ExcelExportEntity("编码", "clubCode", 20));
entities.add(new ExcelExportEntity("协会名称", "clubName", 20));
}
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("预算金额", "totalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
}
@@ -0,0 +1,116 @@
package com.budwk.app.zhgh.outlay.activityBudget.conteoller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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 org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.List;
/**
* @author zhf
* @date 2025/7/29 10:59
* @description 校工会审核
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "校工会审核年度预算申报")
@At("/platform/activity/budget/schoolAudit")
public class ActivityBudgetSchoolAuditController {
@Inject
private ActivityBudgetService activityBudgetService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/schoolAudit/index.html")
@SaCheckPermission("activity.budget.schoolAudit")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/activityBudget/schoolAudit/form.html")
@SaCheckPermission("activity.budget.schoolAudit")
public void form() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("activity.budget.schoolAudit")
public Result pageData(PageForm pageForm,
Integer year,
String unionId,
String clubId,
Boolean approval,
String outlayManageSource,
String activityMatter) {
Sql sql = Sqls.create("""
SELECT
info.*,
YEAR(info.applyDate) year,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariale
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN activity_budget info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "b6f29037-972d-4b97-8677-c3b3672ef0dc");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
cnd.andEX("info.unionId", "=", unionId);
cnd.andEX("info.outlayManageSource", "=", outlayManageSource);
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.WITHDRAW.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
cnd.desc("t.createdAt");
cnd.andEX("YEAR(info.applyDate)", "=", year);
cnd.and(Cnd.likeEX("info.activityMatter", activityMatter));
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.applyDate");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination<NutMap> pageVO = activityBudgetService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -0,0 +1,130 @@
package com.budwk.app.zhgh.outlay.activityBudget.interceptor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.json.Json;
import java.util.List;
/**
* @author zhf
* @date 2025/7/28 17:01
* @description 活动预算申报提交后置拦截器
*/
public class OutlayActBudgetApplyPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
ActivityBudget activityBudget = Json.fromJson(ActivityBudget.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
if (StrUtil.isEmpty(activityBudget.getId())) {
activityBudget.setUserId(SecurityUtil.getUserId());
activityBudget.setLoginName(SecurityUtil.getUserLoginname());
activityBudget.setUserName(SecurityUtil.getUserUsername());
//查询分工会这个项目有没有申报过
// if (List.of("ACTIVITY_BUDGET_TYPE_TWO").contains(activityBudget.getBudgetTypeCode())) {
// int activityMatterCount = dao.count(ActivityBudget.class, Cnd.where("activityMatter", "=",
// activityBudget.getActivityMatter()).and("unionId", "=", SecurityUtil.getUnionId()));
// if (activityMatterCount > 0) {
// return Result.error(activityBudget.getActivityMatter() + "已填写申请!");
// }
// }
}
//删除预算详情表
if (StrUtil.isNotBlank(activityBudget.getId())) {
dao.clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
}
if (List.of("superadmin").contains(SecurityUtil.getUserLoginname())) {
//如果是超级管理员就可以直接提交不用审核
activityBudget.setTotalBudgetMoney(activityBudget.getDeclareTotalBudgetMoney());
ActivityBudget budget = null;
if (StrUtil.isNotBlank(activityBudget.getId())) {
budget = dao.fetch(ActivityBudget.class, activityBudget.getId());
}
//如果申报的是校工会预算
if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool outlayManageSchool = dao.fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(outlayManageSchool)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
//如果传过来有预算Id,代表是修改的,那么就减去原来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
//直接修改为现在传过来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(outlayManageSchool);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//如果申报的是分工会预算
OutlayManageUnion outlayManageUnion = dao.fetch(OutlayManageUnion.class,
Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", activityBudget.getUnionId()));
if (ObjectUtil.isNotEmpty(outlayManageUnion)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(outlayManageUnion);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_THREE")) {
//如果不等于校工会预算才往表里面加预算
//代表协会可能用的是校工会的预算
// if (!activityBudget.getIsSchoolBudget()) {
// jf_club jfClub = dao.fetch(jf_club.class, Cnd.where("year", "=", DateUtil.getYear())
// .and("club_id", "=", activityBudget.getClubId()));
// if (ObjectUtil.isNotEmpty(jfClub)) {
// if (StrUtil.isNotBlank(activityBudget.getId())) {
// jfClub.setTotalQuota(jfClub.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
// }
// jfClub.setTotalQuota(jfClub.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
// dao.updateIgnoreNull(jfClub);
// }
// }
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_FOUR")) {
// 更新其他经费表
// JfOther jfOther = dao.fetch(JfOther.class, Cnd.where("year", "=", DateUtil.getYear()));
// if (ObjectUtil.isNotEmpty(jfOther)) {
// if (StrUtil.isNotBlank(activityBudget.getId())) {
// jfOther.setTotalQuota(jfOther.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
// }
// jfOther.setTotalQuota(jfOther.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
// dao.updateIgnoreNull(jfOther);
// }
}
}
dao.insertOrUpdate(activityBudget);
// for (ActivityBudgetDetails details : activityBudget.getBudgetDetails()) {
// details.setBudgetId(activityBudget.getId());
// }
// //添加预算详情表
// dao.insert(activityBudget.getBudgetDetails());
execution.getArgs().set(FlowConst.FORM_DATA,Json.toJson(activityBudget));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", activityBudget.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,35 @@
package com.budwk.app.zhgh.outlay.activityBudget.interceptor;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
/**
* @author zhf
* @date 2025/7/28 17:01
* @description 活动预算申报提交后置拦截器
*/
public class OutlayActBudgetSchoolPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
NutMap activityBudget = Json.fromJson(NutMap.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
dao.update(ActivityBudget.class, Chain.make("totalBudgetMoney", execution.getArgs().getStr("tf_totalBudgetMoney")),
Cnd.where("id", "=", activityBudget.getString("id")));
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(activityBudget));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", activityBudget.getString("id")), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,140 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @ClassName ActivityBudget
* @Description TODO
* @Author zhf
* @Date 2024/12/3 10:09
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算")
public class ActivityBudget extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("用户姓名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String userName;
@Column
@Comment("用户工号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String loginName;
@Column
@Comment("联系方式")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String mobile;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String activityDate;
@Column
@Comment("活动事项")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String activityMatter;
@Column
@Comment("活动内容")
@ColDefine(type = ColType.TEXT)
private String activityContent;
@Column
@Comment("预算金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalBudgetMoney;
@Column
@Comment("申报金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal declareTotalBudgetMoney;
@Column
@Comment("预算类型")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String outlayManageSource;
@Column
@Comment("创建人工会")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("创建人所属社团")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String clubId;
@Column
@Comment("举办单位")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String helpUnitName;
@Column
@Comment("申报时间")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String applyDate;
@Column
@Comment("校工会审核")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String schoolAuditId;
@Column
@Comment("签字")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String applySign;
@Column
@Comment("审核状态")
@Default("0")
@ColDefine(type = ColType.INT)
private Integer auditState;
@Column
@Comment("是否属于校工会预算")
@Default("0")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isSchoolBudget;
@Column
@Comment("是否可以重复报销")
@Default("1")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isRepeatReimburse;
@Column
@Comment("校工会预算")
@ColDefine(type = ColType.VARCHAR,width = 32)
private String schoolBudgetId;
@Many(field = "budgetId")
private List<ActivityBudgetDetails> budgetDetails;
private Audit schoolAudit;
private List<Audit> allocationEditAuditList;
}
@@ -0,0 +1,58 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @ClassName ActivityBudgetDetails
* @Description TODO
* @Author zhf
* @Date 2024/12/3 10:15
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget_details")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算记录详情")
public class ActivityBudgetDetails extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("申报id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetId;
@Column
@Comment("类别")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String detailName;
@Column
@Comment("预算金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal budgetMoney;
@Column
@Comment("金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal money;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
private Integer detailsOrder;
}
@@ -0,0 +1,56 @@
package com.budwk.app.zhgh.outlay.activityBudget.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* @ClassName ActivityBudgetType
* @Description TODO
* @Author zhf
* @Date 2024/12/3 14:55
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("activity_budget_type")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("活动预算类型")
public class ActivityBudgetType extends BaseModel implements Serializable {
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("类型")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetTypeName;
@Column
@Comment("金额")
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
private Double budgetTypeMoney;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String note;
@Column
@Comment("年度")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("排序")
@ColDefine(type = ColType.INT)
private Integer location;
}
@@ -0,0 +1,12 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
import com.budwk.app.base.service.BaseService;
import org.nutz.dao.sql.Sql;
public interface ActivityBudgetApplyStatisticsService extends BaseService {
Sql getsql(Integer year, String unionId,String clubId, String outlayManageSource,String activityMatter);
void doDelete(String id);
}
@@ -0,0 +1,11 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
import com.budwk.app.base.service.BaseService;
import org.nutz.lang.util.NutMap;
import java.util.List;
public interface ActivityBudgetQueryStatisticsService extends BaseService {
List<NutMap> getDataByBudgetTypeCode(Integer year, String clubId, String unionId, String outlayManageSource);
}
@@ -0,0 +1,28 @@
package com.budwk.app.zhgh.outlay.activityBudget.service;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Sql;
import javax.servlet.http.HttpServletResponse;
public interface ActivityBudgetService extends BaseService<ActivityBudget> {
Sql getSqlByApplyList(PageForm pageForm, Integer year, String activityMatter, Cnd cnd);
/**
* 提交年度预算申报
* @param activityBudget
* @param flag
*/
Result doSubmit(ActivityBudget activityBudget, Boolean flag);
ActivityBudget findOne(String id);
void doExport(Integer year, String activityMatter, HttpServletResponse response);
}
@@ -0,0 +1,100 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.entity.ProcessTaskActor;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetApplyStatisticsService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
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.IocBean;
import java.util.List;
/**
* @ClassName ActivityBudgetApplyStatisticsServiceImpl
* @Description TODO
* @Author zhf
* @Date 2025/3/5 下午8:21
*/
@IocBean(args = {"refer:dao"})
public class ActivityBudgetApplyStatisticsServiceImpl extends BaseServiceImpl implements ActivityBudgetApplyStatisticsService {
public ActivityBudgetApplyStatisticsServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getsql(Integer year, String unionId, String clubId, String outlayManageSource, String activityMatter) {
Sql sql = Sqls.create("""
SELECT
YEAR(ab.applyDate) year,
ab.*,
ins.id AS instanceId,
ins.businessNo
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(activityMatter)) {
cnd.andEX("ab.activityMatter", "like", "%" + activityMatter + "%");
}
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.andEX("ab.unionId", "=", unionId);
/* if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
cnd.andEX("ab.isSchoolBudget", "=", 0);
}*/
cnd.andEX("ab.clubId", "=", clubId);
cnd.andEX("ab.outlayManageSource", "=", outlayManageSource);
cnd.andEX("ins.state", "=", 20);
cnd.desc("ab.applyDate");
sql.setCondition(cnd);
return sql;
}
@Override
public void doDelete(String id) {
ActivityBudget budget = dao().fetch(ActivityBudget.class, id);
if (budget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool school = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(school)) {
school.setTotalQuota(school.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
updateIgnoreNull(school);
}
} else if (budget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
// 更新分工会活动经费表
OutlayManageUnion union = dao().fetch(OutlayManageUnion.class, Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", budget.getUnionId()));
if (ObjectUtil.isNotEmpty(union)) {
union.setTotalQuota(union.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
updateIgnoreNull(union);
}
}
//查出流程实例
ProcessInstance instance = dao().fetch(ProcessInstance.class, Cnd.where("businessNo", "=", id));
if (ObjectUtil.isNotEmpty(instance)) {
//查询流程任务
List<ProcessTask> taskList = dao().query(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
List<Long> taskIds = taskList.stream().map(ProcessTask::getId).toList();
//删除流程任务下面所有的人员
dao().clear(ProcessTask.class, Cnd.where(ProcessTaskActor::getProcessTaskId, "in", taskIds));
//删除流程任务
dao().clear(ProcessTask.class, Cnd.where(ProcessTask::getProcessInstanceId, "=", instance.getId()));
//删除流程实例
dao().delete(ProcessInstance.class, instance.getId());
//删除预算
dao().delete(ActivityBudget.class, id);
}
}
}
@@ -0,0 +1,90 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetQueryStatisticsService;
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.IocBean;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.List;
@IocBean(args = {"refer:dao"})
public class ActivityBudgetQueryStatisticsServiceImpl extends BaseServiceImpl implements ActivityBudgetQueryStatisticsService {
public ActivityBudgetQueryStatisticsServiceImpl(Dao dao) {
super(dao);
}
@Override
public List<NutMap> getDataByBudgetTypeCode(Integer year, String clubId, String unionId, String outlayManageSource) {
if (List.of("ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
Sql sql = Sqls.create("""
SELECT
@year `year`,
ab.activityMatter,
ab.totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.andEX("ab.outlayManageSource", "=", outlayManageSource);
cnd.andEX("wpi.state", "=", 20);
sql.setCondition(cnd);
return listMap(sql);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//分工会
Sql sql = Sqls.create("""
SELECT
@year `year`,
un.unionCode,
un.name AS unionName,
ab.unionId,
COALESCE ( SUM( ab.totalBudgetMoney ), 0 ) AS totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN sys_union un ON ab.unionId = un.id
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("ab.unionId", "=", unionId);
cnd.andEX("ab.isSchoolBudget", "=", 0);
cnd.andEX("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_TWO");
cnd.andEX("wpi.state", "=", 20);
cnd.andEX("YEAR(ab.applyDate)", "=", year);
cnd.groupBy("ab.unionId");
cnd.asc("un.unionCode");
sql.setCondition(cnd);
return listMap(sql);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
/* Sql sql = Sqls.create("""
SELECT
@year `year`,
sc.`code` AS clubCode,
sc.`name` AS clubName,
COALESCE ( SUM( ab.totalBudgetMoney ), 0 ) AS totalBudgetMoney
FROM
sys_club sc
LEFT JOIN activity_budget ab ON ab.clubId = sc.id
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_THREE'
AND ab.auditState = 4
AND YEAR(ab.applyDate)=@year
$condition
""").setParam("year", year);
Cnd cnd = Cnd.NEW();
cnd.andEX("sc.id", "=", clubId);
cnd.groupBy("sc.id");
cnd.asc("sc.`code`");
sql.setCondition(cnd);
return listMap(sql);*/
}
return new ArrayList<>();
}
}
@@ -0,0 +1,249 @@
package com.budwk.app.zhgh.outlay.activityBudget.service.impl;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudgetDetails;
import com.budwk.app.zhgh.outlay.activityBudget.service.ActivityBudgetService;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/21 11:32
* @description
*/
@IocBean(args = {"refer:dao"})
public class ActivityBudgetServiceImpl extends BaseServiceImpl<ActivityBudget> implements ActivityBudgetService {
public ActivityBudgetServiceImpl(Dao dao) {
super(dao);
}
@Inject
private SysDictService sysDictService;
@Override
public Sql getSqlByApplyList(PageForm pageForm, Integer year, String activityMatter,Cnd cnd) {
Sql sql = Sqls.create("""
SELECT
info.*,
YEAR(info.applyDate) year,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariale,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariale
FROM
activity_budget info
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
LEFT JOIN wf_process_task t ON t.processInstanceId = ins.id
AND t.taskState = 10
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
$condition
""");
if (StrUtil.isNotBlank(activityMatter)) {
cnd.andEX("info.activityMatter", "like", "%" + activityMatter + "%");
}
SqlExpressionGroup group = new SqlExpressionGroup();
if (AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name(), RoleConstant.BRANCH_UNION_ADMIN.name())) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
group1.or("info.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_TWO");
group1.and("info.unionId", "=", SecurityUtil.getUnionId());
group.or(group1);
}
/*if (ShiroUtil.hasAnyRoles("club01,club05")) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
SqlExpressionGroup group2 = new SqlExpressionGroup();
group2.or("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_THREE");
group2.or("ab.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_FOUR");
List<String> clubIds = this.getClubsByRole().stream().map(v -> v.getString("id")).toList();
group1.and("ab.clubId", "in", clubIds);
group1.and(group2);
group.or(group1);
}*/
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
SqlExpressionGroup group1 = new SqlExpressionGroup();
group1.and("info.outlayManageSource", "=", "ACTIVITY_BUDGET_TYPE_ONE");
group1.or("info.loginName", "=", SecurityUtil.getUserLoginname());
group.or(group1);
}
cnd.and(group);
cnd.andEX("YEAR(info.applyDate)", "=", year);
cnd.desc("info.applyDate");
sql.setCondition(cnd);
return sql;
}
@Override
public Result doSubmit(ActivityBudget activityBudget, Boolean flag) {
if (flag) {
activityBudget.setAuditState(1);
}
if (StrUtil.isEmpty(activityBudget.getId())) {
activityBudget.setUserId(SecurityUtil.getUserId());
activityBudget.setLoginName(SecurityUtil.getUserLoginname());
activityBudget.setUserName(SecurityUtil.getUserUsername());
//查询分工会这个项目有没有申报过
if (List.of("ACTIVITY_BUDGET_TYPE_TWO").contains(activityBudget.getOutlayManageSource())) {
int activityMatterCount = count(Cnd.where("activityMatter", "=",
activityBudget.getActivityMatter()).and("unionId", "=", SecurityUtil.getUnionId()));
if (flag && activityMatterCount > 0) {
return Result.error(activityBudget.getActivityMatter() + "已填写申请!");
}
}
}
//删除预算详情表
if (StrUtil.isNotBlank(activityBudget.getId()) ) {
dao().clear(ActivityBudgetDetails.class, Cnd.where("budgetId", "=", activityBudget.getId()));
}
if (List.of("superadmin").contains(SecurityUtil.getUserLoginname())) {
//如果是超级管理员就可以直接提交不用审核
if (flag) {
activityBudget.setAuditState(4);
activityBudget.setTotalBudgetMoney(activityBudget.getDeclareTotalBudgetMoney());
ActivityBudget budget = null;
if (StrUtil.isNotBlank(activityBudget.getId())) {
budget = fetch(activityBudget.getId());
}
//如果申报的是校工会预算
if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool outlayManageSchool = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
if (ObjectUtil.isNotEmpty(outlayManageSchool)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
//如果传过来有预算Id,代表是修改的,那么就减去原来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
//直接修改为现在传过来的金额
outlayManageSchool.setTotalQuota(outlayManageSchool.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
updateIgnoreNull(outlayManageSchool);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//如果申报的是分工会预算
OutlayManageUnion outlayManageUnion = dao().fetch(OutlayManageUnion.class,
Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", activityBudget.getUnionId()));
if (ObjectUtil.isNotEmpty(outlayManageUnion)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
outlayManageUnion.setTotalQuota(outlayManageUnion.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
updateIgnoreNull(outlayManageUnion);
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_THREE")) {
//如果不等于校工会预算才往表里面加预算
//代表协会可能用的是校工会的预算
if (!activityBudget.getIsSchoolBudget()) {
/* jf_club jfClub = dao.fetch(jf_club.class, Cnd.where("year", "=", DateUtil.getYear())
.and("club_id", "=", activityBudget.getClubId()));
if (ObjectUtil.isNotEmpty(jfClub)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
jfClub.setTotalQuota(jfClub.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
jfClub.setTotalQuota(jfClub.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(jfClub);
}*/
}
} else if (activityBudget.getOutlayManageSource().equals("ACTIVITY_BUDGET_TYPE_FOUR")) {
// 更新其他经费表
/*JfOther jfOther = dao.fetch(JfOther.class, Cnd.where("year", "=", DateUtil.getYear()));
if (ObjectUtil.isNotEmpty(jfOther)) {
if (StrUtil.isNotBlank(activityBudget.getId())) {
jfOther.setTotalQuota(jfOther.getTotalQuota().subtract(budget.getTotalBudgetMoney()));
}
jfOther.setTotalQuota(jfOther.getTotalQuota().add(activityBudget.getTotalBudgetMoney()));
dao.updateIgnoreNull(jfOther);
}*/
}
}
}
insertOrUpdate(activityBudget);
for (ActivityBudgetDetails details : activityBudget.getBudgetDetails()) {
details.setBudgetId(activityBudget.getId());
}
//添加预算详情表
insert(activityBudget.getBudgetDetails());
return Result.success();
}
@Override
public ActivityBudget findOne(String id) {
ActivityBudget activityBudget = fetchLinks(fetch(id), "budgetDetails", Cnd.NEW().asc("detailsOrder"));
activityBudget.setSchoolAudit(dao().fetch(Audit.class, Cnd.where("id", "=", activityBudget.getSchoolAuditId())));
// activityBudget.setAllocationEditAuditList(dao().query(Audit.class, Cnd.where("parentId", "=", activityBudget.getId())));
return activityBudget;
}
@Override
public void doExport(Integer year, String activityMatter, HttpServletResponse response) {
Sql sql = getSqlByApplyList(null, year, activityMatter,Cnd.NEW());
List<NutMap> mapList = listMap(sql);
List<Sys_dict> dictList = sysDictService.getSubListByCode("ACTIVITY_BUDGET_TYPE");
mapList.forEach(map -> {
Sys_dict dict = dictList.stream().filter(d -> d.getCode().equals(map.getString("outlayManageSource"))).findFirst().orElse(null);
map.put("outlayManageSource", dict.getName());
});
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 20));
entities.add(new ExcelExportEntity("申报人姓名", "userName", 20));
entities.add(new ExcelExportEntity("申报人工号", "loginName", 20));
entities.add(new ExcelExportEntity("联系方式", "mobile", 20));
entities.add(new ExcelExportEntity("申报类型", "outlayManageSource", 20));
entities.add(new ExcelExportEntity("申报单位", "helpUnitName", 20));
entities.add(new ExcelExportEntity("事项", "activityMatter", 20));
ExcelExportEntity draftCodeEntity = new ExcelExportEntity("申报预算金额", "declareTotalBudgetMoney", 20);
draftCodeEntity.setType(10);
entities.add(draftCodeEntity);
ExcelExportEntity draftCodeEntity2 = new ExcelExportEntity("审核预算金额", "totalBudgetMoney", 20);
draftCodeEntity2.setType(10);
entities.add(draftCodeEntity2);
entities.add(new ExcelExportEntity("申报时间", "applyDate", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, mapList);
CommonDownloadUtil.download("预算申报汇总表.xlsx", workbook, response);
}
}
@@ -0,0 +1,55 @@
package com.budwk.app.zhgh.outlay.activityBudget.template;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import com.budwk.app.base.model.ExcelImportError;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @ClassName ActivityBudgetTemp
* @Description TODO
* @Author zhf
* @Date 2025/3/12 上午11:13
*/
@Data
@EqualsAndHashCode
@ContentRowHeight(20) // 内容行高
@HeadRowHeight(20) // 表头行高
@ColumnWidth(25)
public class ActivityBudgetTemp extends ExcelImportError {
@ExcelProperty("活动时间")
private String activityDate;
@ExcelProperty("活动项目名称")
private String activityMatter;
@ExcelProperty("活动内容概述")
private String activityContent;
@ExcelProperty("联系方式")
private String mobile;
@ExcelProperty("预算类型(请在下拉菜单中选择)")
private String outlayManageSource;
@ExcelProperty("审核预算")
private String totalBudgetMoney;
@ExcelProperty("预算金额")
private String declareTotalBudgetMoney;
@ExcelProperty("审核意见")
private String auditOpinion;
@ExcelProperty("申报单位(仅社团申报时可在下拉菜单中选择,其他类型不用填写)")
private String helpUnitName;
}
@@ -0,0 +1,79 @@
package com.budwk.app.zhgh.outlay.outlayManage.model;
import com.budwk.app.base.model.BaseModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 17:36
* @description 经费使用详情
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_use_detail")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("经费使用详情")
public class OutlayUseDetail extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("预算Id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String outlayManageId;
@Column
@Comment("项目")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String projectName;
@Column
@Comment("调整金额")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal adjustMoney;
@Column
@Comment("调整事由")
@ColDefine(type = ColType.TEXT)
private String adjustReason;
@Column
@Comment("调整人")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustUserId;
@Column
@Comment("调整人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustUserName;
@Column
@Comment("调整人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String adjustLoginName;
@Column
@Comment("活动人数")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String activityNumber;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR)
private String activityTime;
}
@@ -0,0 +1,125 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.aspose.slides.internal.og.bas;
import com.budwk.app.base.annotation.SLog;
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 com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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 org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 14:37
* @description 校工会经费预算管理
*/
@IocBean
@At("/platform/outlay/outlayManage/schoolManage")
@Ok("json:full")
@Slf4j
@Api(tags = "校工会经费预算管理")
public class OutlayManageSchoolController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/school/manage/index.html")
@SaCheckPermission("outlay.outlayManage.school.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.school.manage")
public Result pageData(PageForm pageForm, Integer year) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT * FROM `outlay_manage_school` $condition
""");
cnd.andEX("year", "=", year);
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("修改预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "修改了预算分配的金额:${args[0]},id:${args[1]}")
public Result doSubmit(String totalQuota, String id) {
OutlayManageSchool outlayManageSchool = baseService.dao().fetch(OutlayManageSchool.class, id);
outlayManageSchool.setTotalQuota(new BigDecimal(totalQuota));
baseService.updateIgnoreNull(outlayManageSchool);
return Result.success();
}
@At
@ApiOperation("查看是否分配")
@SaCheckPermission("outlay.outlayManage.school.manage")
public Result getIsAllocationOutlay(Integer year) {
int count = baseService.dao().count(OutlayManageSchool.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("重置预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "重置了预算分配的金额:${args[0]}")
public Result resetOutlay(Integer year) {
int count = baseService.dao().clear(OutlayManageSchool.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("下发预算")
@SaCheckPermission("outlay.outlayManage.school.manage")
@SLog(tag = "校工会预算分配", msg = "下发预算的金额:${args[0]}")
public Result issuedOutlay() {
Sql sql = Sqls.create("""
SELECT
totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_ONE'
AND wpi.state = 20
""").setParam("year",DateUtil.thisYear());
List<NutMap> budgetList = baseService.listMap(sql);
BigDecimal totalBudgetMoney = budgetList.stream()
.map(v->new BigDecimal(v.getString("totalBudgetMoney"))) // 提取 money 属性
.reduce(BigDecimal.ZERO, BigDecimal::add);
OutlayManageSchool outlayManageSchool = new OutlayManageSchool();
outlayManageSchool.setYear(DateUtil.thisYear());
outlayManageSchool.setTotalQuota(totalBudgetMoney);
baseService.insert(outlayManageSchool);
return Result.success();
}
}
@@ -0,0 +1,128 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
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 com.budwk.app.base.utils.PageUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 15:59
* @description 校工会预算使用明细
*/
@IocBean
@At("/platform/outlay/outlayManage/schoolUseDetail")
@Ok("json:full")
@Slf4j
@Api(tags = "校工会预算使用明细")
public class OutlayManageSchoolUseDetailController {
@Inject
private BaseService baseService;
@Inject
private OutlayUseDetailService outlayUseDetailService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/school/useDetail/index.html")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result pageData(PageForm pageForm, String outlayManageId,String projectName) {
Sql sql = Sqls.create("""
select * from outlay_use_detail $condition
""");
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(projectName)) {
cnd.and("projectName", "LIKE", "%" + projectName + "%");
}
cnd.and("outlayManageId", "=", outlayManageId);
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("查询校工会所有的预算")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result getOutlayManageList() {
List<OutlayManageSchool> schoolList = baseService.dao().query(OutlayManageSchool.class, Cnd.NEW().desc("year"));
return Result.success(schoolList);
}
@At
@ApiOperation("查询报销了有多少钱")
@SaCheckPermission("outlay.outlayManage.school.useDetail")
public Result getApplyMoney(String outlayManageId,String projectName) {
OutlayManageSchool school = baseService.dao().fetch(OutlayManageSchool.class, Cnd.where("id", "=", outlayManageId));
if (StrUtil.isEmpty(outlayManageId)){
return Result.success(Map.of("totalMoney", 0, "totalQuota", school.getTotalQuota(), "usedQuota", school.getUsedQuota()));
}
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotEmpty(projectName)){
cnd.and("projectName", "LIKE", "%" + projectName + "%");
}
cnd.and("outlayManageId", "=", outlayManageId);
List<OutlayUseDetail> newList = baseService.dao().query(OutlayUseDetail.class, cnd);
BigDecimal totalMoney = newList.stream()
.map(OutlayUseDetail::getAdjustMoney)
.filter(Objects::nonNull) // 避免 null 值导致计算错误
.reduce(BigDecimal.ZERO, BigDecimal::add);
return Result.success(Map.of("totalMoney", totalMoney, "totalQuota", school.getTotalQuota(), "usedQuota", school.getUsedQuota()));
}
@At
@ApiOperation("删除校工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.school.useDetail")
@SLog(tag = "校工会预算使用详情", msg = "删除了校工会预算使用详情:${args[0]}")
public Result doDeleteDetail(String id) {
outlayUseDetailService.doDeleteDetail(id,"school");
return Result.success();
}
@At
@ApiOperation("编辑校工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.school.useDetail")
@SLog(tag = "校工会预算使用详情", msg = "编辑了校工会预算使用详情:${args[0]}")
public Result doEditDetail(OutlayUseDetail outlayUseDetail) {
outlayUseDetailService.doEditDetail(outlayUseDetail,"school");
return Result.success();
}
}
@@ -0,0 +1,46 @@
package com.budwk.app.zhgh.outlay.outlayManage.school.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 14:31
* @description 校工会经费管理
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_manage_school")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("校工会经费管理")
public class OutlayManageSchool extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("年份")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("总额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalQuota;
@Column
@Comment("已使用额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal usedQuota;
}
@@ -0,0 +1,16 @@
package com.budwk.app.zhgh.outlay.outlayManage.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
public interface OutlayUseDetailService extends BaseService<OutlayUseDetail> {
/**
* 删除预算详情表数据
* @param id 详情的id
* @param outlayType 预算类型/school/union/club等
*/
void doDeleteDetail(String id,String outlayType);
void doEditDetail(OutlayUseDetail outlayUseDetail,String outlayType);
}
@@ -0,0 +1,71 @@
package com.budwk.app.zhgh.outlay.outlayManage.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import org.nutz.dao.Dao;
import org.nutz.ioc.loader.annotation.IocBean;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/25 11:30
* @description
*/
@IocBean(args = {"refer:dao"})
public class OutlayUseDetailServiceImpl extends BaseServiceImpl<OutlayUseDetail> implements OutlayUseDetailService {
public OutlayUseDetailServiceImpl(Dao dao) {
super(dao);
}
@Override
public void doDeleteDetail(String id, String outlayType) {
//更新预算表的金额
updateOutlayManage(id, null,outlayType,false);
//更新完删除
delete(id);
}
@Override
public void doEditDetail(OutlayUseDetail outlayUseDetail,String outlayType) {
updateOutlayManage(outlayUseDetail.getId(), outlayUseDetail,outlayType,true);
update(outlayUseDetail);
}
/**
* 更新预算表
*
* @param id
* @param outlayType
*/
private void updateOutlayManage(String id, OutlayUseDetail outlayUseDetail,String outlayType,Boolean isEdit) {
//找到是哪一条的预算详情
OutlayUseDetail detail = fetch(id);
//拿到预算详情的调整金额
if (outlayType.equals("school")) {
//找到预算分配的记录
OutlayManageSchool manageSchool = dao().fetch(OutlayManageSchool.class, detail.getOutlayManageId());
manageSchool.setUsedQuota(manageSchool.getUsedQuota().subtract(detail.getAdjustMoney()));
if (isEdit){
//如果是修改,就先减去原来的值在加上现在新的值
manageSchool.setUsedQuota(manageSchool.getUsedQuota().add(outlayUseDetail.getAdjustMoney()));
}
update(manageSchool);
} else if (outlayType.equals("union")) {
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class, detail.getOutlayManageId());
manageUnion.setUsedQuota(manageUnion.getUsedQuota().subtract(detail.getAdjustMoney()));
if (isEdit){
//如果是修改,就先减去原来的值在加上现在新的值
manageUnion.setUsedQuota(manageUnion.getUsedQuota().add(outlayUseDetail.getAdjustMoney()));
}
update(manageUnion);
}
}
}
@@ -0,0 +1,143 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
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 com.budwk.app.sys.models.Sys_union;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd;
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 org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/21 17:17
* @description 分工会经费预算管理
*/
@IocBean
@At("/platform/outlay/outlayManage/unionManage")
@Ok("json:full")
@Slf4j
@Api(tags = "分工会经费预算管理")
public class OutlayManageUnionController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/union/manage/index.html")
@SaCheckPermission("outlay.outlayManage.union.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.union.manage")
public Result pageData(PageForm pageForm, Integer year) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT * FROM `outlay_manage_union` $condition
""");
cnd.andEX("year", "=", year);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("unionId", "=", SecurityUtil.getUnionId());
}
cnd.asc("unionCode");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("修改预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "修改了预算分配的金额:${args[0]},id:${args[1]}")
public Result doSubmit(String totalQuota, String id) {
OutlayManageUnion outlayManageUnion = baseService.dao().fetch(OutlayManageUnion.class, id);
outlayManageUnion.setTotalQuota(new BigDecimal(totalQuota));
baseService.updateIgnoreNull(outlayManageUnion);
return Result.success();
}
@At
@ApiOperation("查看是否分配")
@SaCheckPermission("outlay.outlayManage.union.manage")
public Result getIsAllocationOutlay(Integer year) {
int count = baseService.dao().count(OutlayManageUnion.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("重置预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "重置了预算分配的金额:${args[0]}")
public Result resetOutlay(Integer year) {
int count = baseService.dao().clear(OutlayManageUnion.class, Cnd.where("year", "=", year));
return Result.success(count);
}
@At
@ApiOperation("下发预算")
@SaCheckPermission("outlay.outlayManage.union.manage")
@SLog(tag = "分工会预算分配", msg = "根据申报的金额修改本年的预算预算")
public Result issuedOutlay() {
Sql sql = Sqls.create("""
SELECT
unionId,
totalBudgetMoney
FROM
activity_budget ab
LEFT JOIN wf_process_instance wpi ON wpi.businessNo = ab.id
WHERE
YEAR(ab.applyDate) = @year
AND ab.outlayManageSource = 'ACTIVITY_BUDGET_TYPE_TWO'
AND wpi.state = 20
""").setParam("year", DateUtil.thisYear());
List<NutMap> budgetList = baseService.listMap(sql);
List<Sys_union> unionList = baseService.dao().query(Sys_union.class, Cnd.NEW());
List<OutlayManageUnion> insertUnionList = new ArrayList<>();
unionList.forEach(v -> {
BigDecimal totalBudgetMoney = budgetList.stream()
.filter(budget -> budget.getString("unionId").equals(v.getId()))
.map(budget -> new BigDecimal(budget.getString("totalBudgetMoney"))) // 提取 money 属性
.reduce(BigDecimal.ZERO, BigDecimal::add);
OutlayManageUnion outlayManageUnion = new OutlayManageUnion();
outlayManageUnion.setYear(DateUtil.thisYear());
outlayManageUnion.setUnionName(v.getName());
outlayManageUnion.setUnionCode(v.getUnionCode());
outlayManageUnion.setUnionId(v.getId());
outlayManageUnion.setTotalQuota(totalBudgetMoney);
insertUnionList.add(outlayManageUnion);
});
baseService.insert(insertUnionList);
return Result.success();
}
}
@@ -0,0 +1,117 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
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 com.budwk.app.base.utils.PageUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.outlayManage.model.OutlayUseDetail;
import com.budwk.app.zhgh.outlay.outlayManage.service.OutlayUseDetailService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @author zhf
* @date 2025/7/21 17:19
* @description 分工会预算使用明细
*/
@IocBean
@At("/platform/outlay/outlayManage/unionUseDetail")
@Ok("json:full")
@Slf4j
@Api(tags = "分工会预算使用明细")
public class OutlayManageUnionUseDetailController {
@Inject
private BaseService baseService;
@Inject
private OutlayUseDetailService outlayUseDetailService;
@At("")
@Ok("beetl:/platform/zhgh/outlay/outlayManage/union/useDetail/index.html")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public Result pageData(PageForm pageForm,
Integer year,
String unionId) {
Sql sql = Sqls.create("""
select * from outlay_manage_union $condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("totalQuota", "IS NOT", null);
cnd.and("year", "=", year);
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.andEX("unionId", "=", unionId);
} else {
cnd.and("unionId", "=", SecurityUtil.getUnionId());
}
if (Strings.isNotBlank(pageForm.getPageOrderBy()) && Strings.isNotBlank(pageForm.getPageOrderName())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.asc("unionCode");
}
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("某个分工会预算使用详情")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public Result detailInfo(PageForm pageForm, String outlayManageId) {
Sql sql = Sqls.create("""
select * from outlay_use_detail where outlayManageId=@outlayManageId
""").setParam("outlayManageId", outlayManageId);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("删除分工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.union.useDetail")
@SLog(tag = "分工会预算使用详情", msg = "删除了分工会预算使用详情:${args[0]}")
public Result doDeleteDetail(String id) {
outlayUseDetailService.doDeleteDetail(id,"union");
return Result.success();
}
@At
@ApiOperation("编辑分工会预算详情")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("outlay.outlayManage.union.useDetail")
@SLog(tag = "分工会预算使用详情", msg = "编辑了分工会预算使用详情:${args[0]}")
public Result doEditDetail(OutlayUseDetail outlayUseDetail) {
outlayUseDetailService.doEditDetail(outlayUseDetail,"union");
return Result.success();
}
}
@@ -0,0 +1,62 @@
package com.budwk.app.zhgh.outlay.outlayManage.union.model;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @author zhf
* @date 2025/7/21 17:22
* @description 分工会经费管理
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_manage_union")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("分工会经费管理")
public class OutlayManageUnion extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("年份")
@ColDefine(type = ColType.INT)
private Integer year;
@Column
@Comment("总额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal totalQuota;
@Column
@Comment("已使用额度")
@Default("0")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal usedQuota;
@Column
@Comment("院级工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("院级工会名称")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionName;
@Column
@Comment("院级工会code")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionCode;
}
@@ -0,0 +1,80 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.zhgh.outlay.outlayReimburse.service.OutlayReimburseApplyListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @author zhf
* @date 2025/7/30 15:22
* @description 我的报销
*/
@IocBean
@At("/platform/outlay/reimburse/apply")
@Ok("json:full")
@Api("我的报销")
public class OutlayReimburseApplyListController {
@Inject
private OutlayReimburseApplyListService outlayReimburseApplyListService;
@At("/index")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/apply/index.html")
@SaCheckPermission("outlay.reimburse.apply")
public void index() {
}
@At("/form")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/apply/form.html")
@SaCheckPermission("outlay.reimburse.apply")
public void form() {
}
@At("/view")
@Ok("beetl:/platform/zhgh/outlay/outlayReimburse/view/index.html")
@SaCheckPermission("outlay.reimburse.apply")
public void view() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.reimburse.apply")
public Result pageData(PageForm pageForm) {
return Result.success();
}
@At
@ApiOperation("获取预算金额或活动")
@SaCheckPermission("outlay.reimburse.apply")
public Result getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id) {
return Result.success(outlayReimburseApplyListService.getBudgetMoneyOrActivity(outlayManageSource, clubId, unionId, id));
}
@At
@ApiOperation("查询这个预算已经报销了的金额")
@SaCheckPermission("outlay.reimburse.apply")
public Result getBxMoneyByBudgetId(String budgetId) {
return Result.success(outlayReimburseApplyListService.getBxMoneyByActivityId(budgetId));
}
@At
@ApiOperation("判断这个报销的记录预算是否充足")
@SaCheckPermission("outlay.reimburse.apply")
public Result bxAddValidate(String budgetId, String money, String outlayManageSource,String clubId) {
return outlayReimburseApplyListService.bxAddValidate(budgetId,money, outlayManageSource,clubId);
}
}
@@ -0,0 +1,34 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.interceptor;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
import com.budwk.app.flow.engine.core.ServiceContext;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
/**
* @author zhf
* @date 2025/7/30 15:58
* @description
*/
public class OutlayReimburseApplyPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
OutlayReimburse outlayReimburse = Json.fromJson(OutlayReimburse.class, formDataStr);
Dao dao = ServiceContext.find(Dao.class);
dao.insertOrUpdate(outlayReimburse);
execution.getArgs().set("outlayManageSource", outlayReimburse.getOutlayManageSource());
execution.getArgs().set(FlowConst.FORM_DATA, Json.toJson(outlayReimburse));
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
dao.update(ProcessInstance.class, Chain.make("businessNo", outlayReimburse.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
}
}
@@ -0,0 +1,16 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.interceptor;
import com.budwk.app.flow.engine.FlowInterceptor;
import com.budwk.app.flow.engine.core.Execution;
/**
* @author zhf
* @date 2025/7/30 16:02
* @description
*/
public class OutlayReimburseSchoolZxAuditPostInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
}
}
@@ -0,0 +1,124 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.model;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
/**
* @author zhf
* @date 2025/7/30 14:53
* @description 经费报销
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("outlay_reimburse")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("经费报销")
public class OutlayReimburse extends BaseModel implements Serializable {
@Column
@Name
@Comment("id")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("经办人id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("经办人姓名")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userName;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String loginName;
@Column
@Comment("经办人电话")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String mobile;
@Column
@Comment("单位")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String unitName;
@Column
@Comment("单位id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@Column
@Comment("工会")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String unionName;
@Column
@Comment("工会id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("社团id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String clubId;
@Column
@Comment("报销经费来源")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String outlayManageSource;
@Column
@Comment("活动时间")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String activityTime;
@Column
@Comment("支付内容")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String paymentContent;
@Column
@Comment("金额")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal money;
@Column
@Comment("活动事项")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String activityMatter;
@Column
@Comment("年度预算id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String budgetId;
@Column
@Comment("申请时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String applyTime;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Column
@Comment("经办人签字")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String userSign;
}
@@ -0,0 +1,40 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.service;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
public interface OutlayReimburseApplyListService extends BaseService<OutlayReimburse> {
/**
* 获取预算金额或活动
*
* @param outlayManageSource
* @param clubId
* @param unionId
* @param id
* @return
*/
NutMap getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id);
/**
* 查询这个预算已经报销了的金额
* @param budgetId
* @return
*/
BigDecimal getBxMoneyByActivityId(String budgetId);
/**
* 判断这个报销的记录预算是否充足
* @param budgetId
* @param money
* @param outlayManageSource
* @param clubId
* @return
*/
Result bxAddValidate(String budgetId, String money, String outlayManageSource,String clubId);
}
@@ -0,0 +1,260 @@
package com.budwk.app.zhgh.outlay.outlayReimburse.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.outlay.activityBudget.models.ActivityBudget;
import com.budwk.app.zhgh.outlay.outlayManage.school.model.OutlayManageSchool;
import com.budwk.app.zhgh.outlay.outlayManage.union.model.OutlayManageUnion;
import com.budwk.app.zhgh.outlay.outlayReimburse.model.OutlayReimburse;
import com.budwk.app.zhgh.outlay.outlayReimburse.service.OutlayReimburseApplyListService;
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.IocBean;
import org.nutz.lang.util.NutMap;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author zhf
* @date 2025/7/30 17:38
* @description
*/
@IocBean(args = {"refer:dao"})
public class OutlayReimburseApplyListServiceImpl extends BaseServiceImpl<OutlayReimburse> implements OutlayReimburseApplyListService {
public OutlayReimburseApplyListServiceImpl(Dao dao) {
super(dao);
}
@Override
public NutMap getBudgetMoneyOrActivity(String outlayManageSource, String clubId, String unionId, String id) {
String sqlStr = """
SELECT
ab.id,
ab.schoolBudgetId,
ab.totalBudgetMoney,
ab.isRepeatReimburse,
ab.activityMatter
FROM
activity_budget ab
LEFT JOIN wf_process_instance ins ON ins.businessNo = ab.id
$condition
""";
//找出可以重复报销的预算,并且是今年的预算
Sql sql = Sqls.create(sqlStr);
Cnd cnd = Cnd.NEW();
cnd.and("YEAR(ab.applyDate)", "=", DateUtil.thisYear());
cnd.and("isRepeatReimburse", "=", true);
cnd.and("ins.state", "=", 20);
sql.setCondition(cnd);
List<NutMap> budgetList = listMap(sql);
List<String> budgetIds = budgetList.stream().map(budget -> budget.getString("id")).toList();
//找出已经报销了的年度预算id,排除可以重复报销的预算
List<OutlayReimburse> outlayReimburseList = dao().query(OutlayReimburse.class,
Cnd.NEW().andEX(OutlayReimburse::getId, "!=", id)
.and(OutlayReimburse::getBudgetId, "not in", budgetIds)
.and(OutlayReimburse::getBudgetId, "is not", null));
List<String> outlayReimburseIds = outlayReimburseList.stream().map(OutlayReimburse::getBudgetId).toList();
//找出可以报销的预算
Sql sql1 = Sqls.create(sqlStr);
Cnd cnd1 = Cnd.NEW();
cnd1.and("YEAR(ab.applyDate)", "=", DateUtil.thisYear());
cnd1.and("ab.isRepeatReimburse", "=", true);
cnd1.and("ab.outlayManageSource", "=", outlayManageSource);
cnd1.and("ins.state", "=", 20);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
cnd1.and("unionId", "=", StrUtil.isNotBlank(unionId) ? unionId : SecurityUtil.getUnionId());
} else if (List.of("ACTIVITY_BUDGET_TYPE_THREE").contains(outlayManageSource)) {
cnd1.and("clubId", "=", clubId);
}
cnd1.andEX("ab.id", "not in", outlayReimburseIds);
sql1.setCondition(cnd1);
List<NutMap> canBudgetList = listMap(sql1);
//查询每个活动预算下面,有没有关联的子活动预算
canBudgetList.forEach(budget -> {
//找出来这一条活动预算有没有子预算,如果有子预算那么这一条预算肯定是校工会的预算
List<NutMap> twoLevelBudgetList = budgetList.stream().filter(b -> StrUtil.isNotBlank(b.getString("schoolBudgetId"))
&& b.getString("schoolBudgetId").equals(budget.getString("id"))).toList();
if (!twoLevelBudgetList.isEmpty()) {
//找出所有子预算的和
BigDecimal totalBudgetMoney = twoLevelBudgetList.stream().map(twoLevelBudget -> new BigDecimal(twoLevelBudget.getString("totalBudgetMoney"))).reduce(BigDecimal.ZERO, BigDecimal::add);
budget.put("twoLevelTotalBudgetMoney", totalBudgetMoney);
budget.put("twoLevelBudgetList", twoLevelBudgetList);
} else {
budget.put("twoLevelTotalBudgetMoney", 0);
budget.put("twoLevelBudgetList", List.of());
}
});
NutMap map = new NutMap();
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_ONE")) {
OutlayManageSchool school = dao().fetch(OutlayManageSchool.class, Cnd.where("year", "=", DateUtil.thisYear()));
map.put("budgetMoney", school.getTotalQuota().subtract(school.getUsedQuota()));
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
OutlayManageUnion union = dao().fetch(OutlayManageUnion.class, Cnd.where("year", "=", DateUtil.thisYear())
.and("unionId", "=", StrUtil.isNotBlank(unionId) ? unionId : SecurityUtil.getUnionId()));
map.put("budgetMoney", ObjectUtil.isNotEmpty(union) ? union.getTotalQuota().subtract(union.getUsedQuota()) : 0);
} else if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_THREE")) {
}
map.put("activityList", canBudgetList);
return map;
}
@Override
public BigDecimal getBxMoneyByActivityId(String budgetId) {
Sql sql = Sqls.create("""
SELECT
rei.money
FROM
`outlay_reimburse` rei
LEFT JOIN wf_process_instance ins ON ins.businessNo = rei.id
WHERE
rei.budgetId = @budgetId
AND ins.state = 20
""").setParam("budgetId", budgetId);
List<NutMap> reiList = listMap(sql);
BigDecimal totalMoney = reiList.stream()
.map(rei -> new BigDecimal(rei.getString("money")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return totalMoney;
}
@Override
public Result bxAddValidate(String budgetId, String money, String outlayManageSource, String clubId) {
BigDecimal moneyBig = new BigDecimal(money);
if (StrUtil.isAllEmpty(budgetId, outlayManageSource)) {
return Result.error("参数错误");
}
if (List.of("ACTIVITY_BUDGET_TYPE_TWO", "ACTIVITY_BUDGET_TYPE_ONE").contains(outlayManageSource)) {
ActivityBudget budget = dao().fetch(ActivityBudget.class, budgetId);
if (outlayManageSource.equals("ACTIVITY_BUDGET_TYPE_TWO")) {
//判断是否可以重复报
if (budget.getIsRepeatReimburse()) {
//1.查询已经报销了的总金额
BigDecimal bXMoney = getBxMoneyByActivityId(budgetId);
if (budget.getIsSchoolBudget()) {
//如果是分工会进来并且报销的活动是校会预算
// 1. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = bXMoney.add(moneyBig);
// 2. 判断是否超出预算
if (totalReimbursement.compareTo(budget.getTotalBudgetMoney()) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
} else {
//如果是自己的项目就能超20%
//1.算出现在还能报销多少钱
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
// 2. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = bXMoney.add(moneyBig);
// 3. 判断是否超出预算的 20%
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//分工会进来报销自己的预算
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱
//判断是否超出预算的 20%
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
if (moneyBig.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//如果是校工会进来
//如果报销的项目是可以重复报销的
if (budget.getIsRepeatReimburse()) {
//这个预算已经报销了多少钱
BigDecimal totalMoney = getBxMoneyByActivityId(budgetId);
//查出这个活动有没有跟其他预算关联,如果跟其他预算关联了,代表当前这条预算是分工会也能报校工会也能报,
// schoolBudgetId字段不为空就代表这条预算是使用的校工会的金额
List<ActivityBudget> budgetList = dao().query(ActivityBudget.class,
Cnd.where("schoolBudgetId", "=", budgetId));
if (ObjectUtil.isNotEmpty(budgetList) && !budgetList.isEmpty()) {
//如果报销的项目是分工会也能报校工会也能报,就要减去所有已分配分工会的钱在算能报销多少钱。
//1.减去分工会可以报的那一部分预算,比如校工会这个预算有1000,分工会可以报100.那么校工会只能报900
//找出分配给分工会的预算是多少钱
BigDecimal unionTotalMoney = budgetList.stream()
.map(ActivityBudget::getTotalBudgetMoney)
.filter(Objects::nonNull) // 避免 null 值导致计算错误
.reduce(BigDecimal.ZERO, BigDecimal::add);
//找出能报销多少钱,校工会预算1000-分工会可以报的预算unionTotalMoney=校工会目前可以使用的预算
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().subtract(unionTotalMoney);
//已报销加上现在的钱
BigDecimal totalReimbursement = totalMoney.add(moneyBig);
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
} else {
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱,判断是否超出预算的 20%
//1.算出现在还能报销多少钱
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
//2. 计算本次加上之前的报销总金额
BigDecimal totalReimbursement = totalMoney.add(moneyBig);
// 3. 判断是否超出预算的 20%
if (totalReimbursement.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
} else {
//正常判断这个活动是否超出预算
//算出现在还能报销多少钱,判断是否超出预算的 20%
BigDecimal twentyPercent = budget.getTotalBudgetMoney().multiply(new BigDecimal("20")).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_UP);
BigDecimal totalBudgetMoney = budget.getTotalBudgetMoney().add(twentyPercent);
if (moneyBig.compareTo(totalBudgetMoney) > 0) {
return Result.error("该活动预算金额不足!");
} else {
return Result.success();
}
}
}
}
return null;
}
}
@@ -0,0 +1,236 @@
package com.budwk.app.zhgh.thirtyTeach.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
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.alibaba.excel.EasyExcel;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.EasyExcelUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.integral.controller.IntegralManageController;
import com.budwk.app.zhgh.thirtyTeach.param.ThirtyTeachPageForm;
import com.budwk.app.zhgh.thirtyTeach.service.ThirtyTeachService;
import com.budwk.app.zhgh.thirtyTeach.template.ThirtyTeachTemp;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.AdaptBy;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author zhf
* @date 2025/7/25 18:27
* @description 教职工管理
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "三十龄教工-教职工管理")
@At("/platform/thirtyTeach/manage")
public class ThirtyTeachController {
@Inject
private ThirtyTeachService thirtyTeachService;
@Inject
private SysUserService sysUserService;
@At("")
@Ok("beetl:/platform/zhgh/thirtyTeach/manage/index.html")
@SaCheckPermission("thirtyTeach.manage")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("thirtyTeach.manage")
public Result pageData(ThirtyTeachPageForm pageForm) {
Sql sql = thirtyTeachService.getSql(pageForm);
Pagination pagination = thirtyTeachService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("一键设置三十龄教工")
@SaCheckPermission("thirtyTeach.manage")
@SLog(type = "30龄教工-教职工管理", tag = "设置三十龄教工",msg = "设置三十龄教工设置教龄${args[0]}")
public Result setThirtyTeach(Integer setNum, boolean isFlag){
if (isFlag) {
sysUserService.update(Chain.make("isThirtyTeach", 0), Cnd.NEW());
}
Cnd cnd = Cnd.NEW();
cnd.and("arrivalAtSchoolDate", "is not", null);
cnd.and("arrivalAtSchoolDate", "!=", "");
cnd.and("TIMESTAMPDIFF(YEAR, CONCAT(arrivalAtSchoolDate, '-01'), CURDATE())", ">", setNum);
sysUserService.update(Chain.make("isThirtyTeach", 1), cnd);
return Result.success();
}
@At
@ApiOperation("批量删除三十龄教工")
@SaCheckPermission("thirtyTeach.manage")
@SLog(type = "30龄教工-教职工管理", tag = "批量删除三十龄教工",msg = "批量删除三十龄教工${args[0]}")
public Result doBatchDelete(@Param("userIds") String[] userIds) {
List<String> userIdList = Arrays.asList(userIds);
if (Lang.isNotEmpty(userIdList)) {
sysUserService.update(Chain.make("isThirtyTeach", 0), Cnd.where("id", "in", userIdList));
}
return Result.success();
}
@At
@SaCheckPermission("thirtyTeach.manage")
@Ok("void")
@ApiOperation("导出30教龄教职工名单")
public void doExport(ThirtyTeachPageForm pageForm, HttpServletResponse response){
Sql sql = thirtyTeachService.getSql(pageForm);
List<NutMap> list = thirtyTeachService.listMap(sql);
List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
no.setFormat("isAddIndex");
entityList.add(no);
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
entityList.add(new ExcelExportEntity("姓名", "username", 20));
entityList.add(new ExcelExportEntity("性别", "sex", 20));
entityList.add(new ExcelExportEntity("教龄(年)", "teachNum", 20));
entityList.add(new ExcelExportEntity("电话", "mobile", 20));
entityList.add(new ExcelExportEntity("工会", "unionName", 20));
entityList.add(new ExcelExportEntity("单位", "unitName", 20));
entityList.add(new ExcelExportEntity("在职状态", "userState", 20));
entityList.add(new ExcelExportEntity("人员类型", "personType", 20));
entityList.add(new ExcelExportEntity("荣誉证办理年月", "thirtyCertificateProcessingTime", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, list);
CommonDownloadUtil.download("30教龄教职工名单.xlsx", workbook, response);
}
@At
@Ok("void")
@ApiOperation("下载导入30教龄教职工模版")
@SaCheckPermission("thirtyTeach.manage")
public void downloadImportTemp(HttpServletResponse response) {
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
EasyExcel.write(byteArrayOutputStream, ThirtyTeachTemp.class)
.sheet("30教龄教职工模版")
.doWrite(ArrayList::new);
CommonDownloadUtil.download("30教龄教职工模版.xlsx", byteArrayOutputStream.toByteArray(), response);
} catch (Exception e) {
log.error("下载导入模版失败", e);
}
}
@At
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("thirtyTeach.manage")
@ApiOperation("导入30教龄教职工名单")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result doImport(TempFile file, Boolean isFlag) {
try {
List<T> ts = EasyExcelUtil.syncReadModel(file.getFile(), ThirtyTeachTemp.class, 0, 1);
List<ThirtyTeachTemp> teachTempList = JSONUtil.parseArray(JSONUtil.toJsonStr(ts)).toList(ThirtyTeachTemp.class);
List<Sys_user> users = sysUserService.query();
List<ThirtyTeachTemp> errorInfos = new ArrayList<>();
List<Sys_user> insertUserList = new ArrayList<>();
for (ThirtyTeachTemp temp : teachTempList) {
if (StrUtil.isBlank(temp.getUserName())) {
temp.setResult("获取不到该用户的姓名!");
errorInfos.add(temp);
break;
} else if (StrUtil.isBlank(temp.getLoginName())) {
temp.setResult("获取不到该用户的出生日期!");
errorInfos.add(temp);
break;
}else if (StrUtil.isBlank(temp.getThirtyCertificateProcessingTime())) {
temp.setResult("获取不到该用户的荣誉证办理时间!");
errorInfos.add(temp);
break;
}
List<Sys_user> matchUsers = users.stream().filter(u -> u.getLoginname().equals(temp.getLoginName())).map(u -> {
Sys_user user = new Sys_user();
user.setId(u.getId());
user.setLoginname(temp.getLoginName());
user.setIsThirtyTeach(true);
user.setThirtyCertificateProcessingTime(temp.getThirtyCertificateProcessingTime());
return user;
}).collect(Collectors.toList());
insertUserList.addAll(matchUsers);
}
int i = 0;
if (Lang.isNotEmpty(insertUserList)) {
if (isFlag) {
sysUserService.update(Chain.make("isThirtyTeach", 0), Cnd.NEW());
}
i = sysUserService.updateIgnoreNull(insertUserList);
}
if (Lang.isNotEmpty(errorInfos)) {
NutMap nutMap = new NutMap();
nutMap.setv("totalCount", teachTempList.size());
nutMap.setv("successCount", i);
nutMap.setv("errorCount", errorInfos.size());
nutMap.setv("errorList", errorInfos.stream().map(v -> {
return NutMap.NEW().addv("工号", v.getLoginName()).addv("姓名", v.getUserName()).addv("错误原因", v.getResult());
}).collect(Collectors.toList()));
return Result.success(nutMap);
}
return Result.success();
}catch (Exception e){
log.error("导入30教龄教职工名单失败", e);
e.printStackTrace();
return Result.error();
}
}
}
@@ -0,0 +1,131 @@
package com.budwk.app.zhgh.thirtyTeach.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.thirtyTeach.param.ThirtyTeachPageForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhf
* @date 2025/7/25 18:28
* @description 教职工汇总
*/
@IocBean
@Ok("json:full")
@Slf4j
@Api(tags = "三十龄教工-教职工汇总")
@At("/platform/thirtyTeach/summary")
public class ThirtyTeachSummaryController {
@Inject
private SysUserService sysUserService;
@At("")
@Ok("beetl:/platform/zhgh/thirtyTeach/summary/index.html")
@SaCheckPermission("thirtyTeach.summary")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("thirtyTeach.summary")
public Result pageData(String unionId,String unitId){
Sql sql = Sqls.create("""
SELECT
su.*,
COUNT( u.id ) AS userNum
FROM
sys_union su
LEFT JOIN `vw_user` u ON u.unionid = su.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("u.isThirtyTeach", "=", 1);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
}
cnd.andEX("u.unionId", "=", unionId);
cnd.andEX("u.unitId", "=", unitId);
cnd.groupBy("su.unionCode");
cnd.asc("su.unionCode");
sql.setCondition(cnd);
return Result.success(sysUserService.listMap(sql));
}
@At
@SaCheckPermission("thirtyTeach.summary")
@Ok("void")
@ApiOperation("导出工会汇总名单")
public void doExportSummary(String unionId,String unitId, HttpServletResponse response){
Sql sql = Sqls.create("""
SELECT
su.*,
COUNT( u.id ) AS userNum
FROM
sys_union su
LEFT JOIN `vw_user` u ON u.unionid = su.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("u.isThirtyTeach", "=", 1);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
}
cnd.andEX("u.unionId", "=", unionId);
cnd.andEX("u.unitId", "=", unitId);
cnd.groupBy("su.unionCode");
cnd.asc("su.unionCode");
sql.setCondition(cnd);
List<NutMap> thirtyTeachList = sysUserService.listMap(sql);
List<ExcelExportEntity> entityList = new ArrayList<>();
ExcelExportEntity no = new ExcelExportEntity("序号", "no", 10);
no.setFormat("isAddIndex");
entityList.add(no);
entityList.add(new ExcelExportEntity("分工会", "name", 20));
ExcelExportEntity entity = new ExcelExportEntity("在职人数", "userNum", 20);
entity.setType(10);
entityList.add(entity);
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, thirtyTeachList);
CommonDownloadUtil.download("30教龄教职工在职人员汇总表.xlsx", workbook, response);
}
}
@@ -0,0 +1,23 @@
package com.budwk.app.zhgh.thirtyTeach.param;
import com.budwk.app.base.param.PageForm;
import lombok.Data;
/**
* @author zhf
* @date 2025/7/28 10:09
* @description 30龄教工
*/
@Data
public class ThirtyTeachPageForm extends PageForm {
private String unionId;
private String unitId;
//进校时长
private String teachNum;
//办证年月
private String thirtyCertificateProcessingTime;
private String userState;
private String personType;
}
@@ -0,0 +1,15 @@
package com.budwk.app.zhgh.thirtyTeach.service;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.thirtyTeach.param.ThirtyTeachPageForm;
import org.nutz.dao.sql.Sql;
/**
* @author zhf
* @date 2025/7/28 11:52
* @description
*/
public interface ThirtyTeachService extends BaseService {
Sql getSql(ThirtyTeachPageForm pageForm);
}
@@ -0,0 +1,77 @@
package com.budwk.app.zhgh.thirtyTeach.service.impl;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.thirtyTeach.param.ThirtyTeachPageForm;
import com.budwk.app.zhgh.thirtyTeach.service.ThirtyTeachService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.IocBean;
/**
* @author zhf
* @date 2025/7/28 11:53
* @description
*/
@IocBean(args = {"refer:dao"})
public class ThirtyTeachServiceImpl extends BaseServiceImpl implements ThirtyTeachService {
public ThirtyTeachServiceImpl(Dao dao) {
super(dao);
}
@Override
public Sql getSql(ThirtyTeachPageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
id,
loginname,
username,
sex,
member,
personType,
userState,
unionName,
unitName,
mobile,
birthday,
thirtyCertificateProcessingTime,
TIMESTAMPDIFF(YEAR, CONCAT(arrivalAtSchoolDate, '-01'), CURDATE()) AS teachNum
FROM
`vw_user`
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("isThirtyTeach", "=", 1);
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("loginname", pageForm.getSearchKeyword());
seg.orLike("username", pageForm.getSearchKeyword());
cnd.and(seg);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("unionId", "=", SecurityUtil.getUnionId());
}
cnd.andEX("TIMESTAMPDIFF(YEAR, CONCAT(arrivalAtSchoolDate, '-01'), CURDATE())", "=", pageForm.getTeachNum());
cnd.andEX("unionId", "=", pageForm.getUnionId());
cnd.andEX("unitId", "=", pageForm.getUnitId());
cnd.andEX("personType", "=", pageForm.getPersonType());
cnd.andEX("userState", "=", pageForm.getUserState());
cnd.and(Cnd.likeEX("thirtyCertificateProcessingTime",pageForm.getThirtyCertificateProcessingTime()));
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("unionCode").asc("unitCode");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
return sql;
}
}
@@ -0,0 +1,31 @@
package com.budwk.app.zhgh.thirtyTeach.template;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode
@ContentRowHeight(20) // 内容行高
@HeadRowHeight(20) // 表头行高
@ColumnWidth(25)
public class ThirtyTeachTemp {
@ExcelProperty("工号")
private String loginName;
@ExcelProperty("姓名")
private String userName;
@ExcelProperty("《30年教龄荣誉证》办理年月")
private String thirtyCertificateProcessingTime;
@ExcelIgnore
private String result;
}