first commit

This commit is contained in:
2026-08-26 14:25:17 +08:00
commit 06debfd1fc
10595 changed files with 1836924 additions and 0 deletions
@@ -0,0 +1,23 @@
package com.budwk.app.sys.annotation;
import java.lang.annotation.*;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DataCenterColumn {
/*
* 列名
*/
String name();
/*
* 列key
*/
String key();
// 字典码表名称
String dict() default "";
}
@@ -0,0 +1,105 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.services.SysApiService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
;
/**
* Created by wizzer on 2016/6/24.
*/
@IocBean
@At("/platform/sys/api")
public class SysApiController {
private static final Log log = Logs.get();
@Inject
private SysApiService sysApiService;
@At("")
@Ok("beetl:/platform/sys/api/index.html")
@SaCheckPermission("sys.manager.api")
public void index() {
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.api.add")
@SLog(tag = "新建密钥", msg = "应用名称:${name}")
public Object addDo(@Param("name") String name, HttpServletRequest req) {
try {
sysApiService.createAppkey(name, SecurityUtil.getUserId());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.api.delete")
@SLog(tag = "删除密钥", msg = "Appid:${appid}")
public Object delete(String appid, HttpServletRequest req) {
try {
sysApiService.deleteAppkey(appid);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.api.edit")
@SLog(tag = "启用密钥", msg = "Appid:${appid}")
public Object enable(String appid, HttpServletRequest req) {
try {
sysApiService.updateAppkey(appid, false);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.api.edit")
@SLog(tag = "禁用密钥", msg = "Appid:${appid}")
public Object disable(String appid, HttpServletRequest req) {
try {
sysApiService.updateAppkey(appid, true);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.api")
public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
}
return Result.success().addData(sysApiService.listPage(pageNumber, pageSize, cnd));
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,89 @@
package com.budwk.app.sys.controller;
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.utils.PageUtil;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.bpm.service.BpmService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.sys.vo.SysBranchUnionUserAuthorizationPageVO;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.article.param.ArticleInfoPageParam;
import com.budwk.app.zhgh.dayofficework.article.vo.ArticleInfoPageVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Cnd;
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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.validation.Valid;
@IocBean
@At("/platform/branchUnionUser/authorization")
@Ok("json:full")
@Api(tags = "分工会人员授权")
public class SysBranchUnionUserAuthorizationController {
@Inject
private SysUserService sysUserService;
@Inject
private BpmService bpmService;
@At
@SaCheckPermission("sys.branch.union.authorization")
@ApiOperation("分页查询")
public Result pageData(@Valid ArticleInfoPageParam pageForm, boolean approval) {
Sql sql = Sqls.create("""
SELECT
info.*,
inst.id processInstanceId,
inst.processInstanceNodeId,
inst.processInstanceNodeName,
inst.processInstanceTaskIds,
inst.processInstanceStatus,
task.id processInstanceTaskId,
task.taskStatus processInstanceTaskStatus,
COUNT(nt.id) OVER (PARTITION BY task.id) > 0 AS nextTaskIsComplete\s
FROM
bpm_process_task task
INNER JOIN bpm_process_node_define nd ON nd.id = task.processTaskNodeId
INNER JOIN bpm_process_instance inst ON inst.id = task.processInstanceId
INNER JOIN sys_branch_union_user_permission info ON info.id = inst.processInstanceBusinessId
LEFT JOIN bpm_process_task nt ON nt.prevTaskId = task.id AND nt.taskStatus = 'COMPLETE'
$condition
""");
Cnd cnd = Cnd.NEW();
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
cnd.and(new Static("JSON_CONTAINS( task.assignments, '\"%s\"' )".formatted(SecurityUtil.getUserLoginname())));
}
cnd.and("nd.nodeCode", "=", 20);
if (approval) {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.COMPLETE);
} else {
cnd.and("task.taskStatus", "=", BpmProcessTaskStatusEnum.ACTIVE);
}
cnd.andEX("YEAR(info.submitTime)", "=", pageForm.getYear());
cnd.and(Cnd.likeEX("info.title", pageForm.getTitle()));
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.createdAt");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
Pagination<SysBranchUnionUserAuthorizationPageVO> pageVO = sysUserService.listPageVO(pageForm, sql, SysBranchUnionUserAuthorizationPageVO.class);
return Result.success(pageVO);
}
}
@@ -0,0 +1,157 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_config;
import com.budwk.app.sys.services.SysConfigService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
;
/**
* Created by wizzer on 2016/6/28.
*/
@IocBean
@At("/platform/sys/conf")
public class SysConfController {
private static final Log log = Logs.get();
@Inject
private SysConfigService sysConfigService;
@Inject
private PubSubService pubSubService;
@Inject
private Dao dao;
@At("")
@Ok("beetl:/platform/sys/conf/index.html")
@SaCheckPermission("sys.manager.conf")
public void index() {
}
private void ensureAppImageConfig(String configKey, String note) {
if (sysConfigService.fetch(configKey) != null) {
return;
}
Sys_config conf = new Sys_config();
conf.setConfigKey(configKey);
conf.setConfigValue("");
conf.setNote(note);
conf.setCreatedBy(SecurityUtil.getUserId());
sysConfigService.insert(conf);
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.conf.add")
@SLog(tag = "添加参数", msg = "${conf.configKey}:${conf.configValue}")
public Object addDo(@Param("..") Sys_config conf) {
try {
conf.setCreatedBy(SecurityUtil.getUserId());
if (sysConfigService.insert(conf) != null) {
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
}
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.conf")
public Object edit(String id) {
try {
return Result.success().addData(sysConfigService.fetch(id));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.conf.edit")
@SLog(tag = "修改参数", msg = "${conf.configKey}:${conf.configValue}")
public Object editDo(@Param("..") Sys_config conf) {
try {
ensureConfigValueColumn(conf);
conf.setUpdatedBy(SecurityUtil.getUserId());
if (sysConfigService.updateIgnoreNull(conf) > 0) {
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
}
return Result.success();
} catch (Exception e) {
log.error("Update sys config failed: " + (conf == null ? "" : conf.getConfigKey()), e);
return Result.error("save failed: " + e.getMessage());
}
}
private void ensureConfigValueColumn(Sys_config conf) {
if (conf == null || (!"AppHomeImg".equals(conf.getConfigKey())
&& !"H5AppHomeImg".equals(conf.getConfigKey())
&& !"AppFeaturedActivityImg".equals(conf.getConfigKey())
&& !"AppFestivalBenefitImg".equals(conf.getConfigKey()))) {
return;
}
String configValue = Strings.sNull(conf.getConfigValue());
if (configValue.length() <= 100) {
return;
}
String dbType = Strings.sNull(dao.getJdbcExpert().getDatabaseType()).toLowerCase();
if (dbType.contains("mysql")) {
dao.execute(Sqls.create("ALTER TABLE `sys_config` MODIFY COLUMN `configValue` TEXT"));
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.conf.delete")
@SLog(tag = "删除参数", msg = "参数:${configKey}")
public Object delete(String configKey) {
try {
if (Strings.sBlank(configKey).startsWith("App")) {
return Result.error("系统参数不可删除");
}
if (sysConfigService.delete(configKey) > 0) {
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_config");
}
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.conf")
public Object data(@Param("pageNumber") int pageNumber,
@Param("pageSize") int pageSize,
@Param("pageOrderName") String pageOrderName,
@Param("pageOrderBy") String pageOrderBy,
@Param("configKey") String configKey) {
try {
ensureAppImageConfig("AppHomeImg", "PC首页轮播图");
ensureAppImageConfig("H5AppHomeImg", "移动端首页轮播图");
ensureAppImageConfig("AppFeaturedActivityImg", "精彩活动页顶部图片");
ensureAppImageConfig("AppFestivalBenefitImg", "节日福利页顶部图片");
return Result.success().addData(sysConfigService.pageData(
pageNumber, pageSize, pageOrderName, pageOrderBy, configKey));
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,451 @@
package com.budwk.app.sys.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
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.sys.enums.SysDataImportPlugin;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.entity.Record;
import org.nutz.dao.sql.Sql;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.random.R;
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.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@Slf4j
@IocBean
@Ok("json:full")
@At("/platform/sys/data/tool")
@Api("系统数据高级工具")
public class SysDataToolController {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Inject
private SysUserService sysUserService;
@Inject
private SysRoleService sysRoleService;
@Inject
private RedisService redisService;
@At("")
@Ok("beetl:/platform/sys/data/tool/index.html")
@SaCheckPermission("sys.data.advanced.tool")
public void index() {
}
@At
@ApiOperation("查询数据库中的表")
@SaCheckPermission("sys.data.advanced.tool")
public Result tableNames() {
Sql sql = Sqls.create("""
SELECT
table_name,
table_rows,
table_comment
FROM
information_schema.TABLES
WHERE
table_schema = (SELECT DATABASE())
ORDER BY
table_name
""");
return Result.success(sysUserService.listMap(sql));
}
@At
@ApiOperation("查询数据表字段")
@SaCheckPermission("sys.data.advanced.tool")
public Result columns(String tableName) {
if (StrUtil.isBlank(tableName)) {
return Result.error("请选择数据表");
}
return Result.success(getColumns(tableName));
}
@At
@ApiOperation("执行高级导入")
@SLog(tag = "数据管理-高级工具", msg = "执行高级导入")
@SaCheckPermission("sys.data.advanced.tool")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result importData(@Param("file") TempFile file,
String tableName,
String relation,
Integer method,
String field,
String plugins) throws IOException {
if (file == null) {
return Result.error("请上传 Excel 文件");
}
if (StrUtil.isBlank(tableName)) {
return Result.error("请选择数据表");
}
if (method == null) {
return Result.error("请选择导入方式");
}
if ((method == 1 || method == 3) && StrUtil.isBlank(field)) {
return Result.error("请选择关键字段");
}
if (StrUtil.isBlank(relation)) {
return Result.error("请配置字段对应关系");
}
List<Record> columns = getColumns(tableName);
if (columns.isEmpty()) {
return Result.error("未获取到数据表字段");
}
NutMap[] relations = parseRelations(relation);
List<NutMap> dataList = getDataForExcel(file, relations);
List<SysDataImportPlugin> pluginList = parsePlugins(plugins);
pluginList.sort(Comparator.comparingInt(SysDataImportPlugin::getLocation));
Record pkRecord = getPrimaryKey(columns).orElse(null);
Set<String> tableColumns = new HashSet<>();
columns.forEach(column -> tableColumns.add(column.getString("column_name")));
int total = 0;
int success = 0;
List<ImportError> errors = new ArrayList<>();
for (NutMap row : dataList) {
total++;
try {
if (StrUtil.isNotBlank(field)) {
row.setv(field, row.getString(field));
}
Chain chain = buildChain(row, tableColumns);
if (chain == null) {
continue;
}
Object pk;
if (method == 1) {
Record currentRecord = sysUserService.dao().fetch(tableName, Cnd.where(field, "=", row.get(field)));
if (currentRecord == null) {
pk = prepareBefore(tableName, pkRecord, field, pluginList, true, chain, row, tableColumns);
sysUserService.dao().insert(tableName, chain);
} else {
pk = prepareBefore(tableName, pkRecord, field, pluginList, false, chain, row, tableColumns);
sysUserService.dao().update(tableName, chain, Cnd.where(field, "=", row.get(field)));
}
} else if (method == 2) {
pk = prepareBefore(tableName, pkRecord, field, pluginList, true, chain, row, tableColumns);
sysUserService.dao().insert(tableName, chain);
} else if (method == 3) {
pk = prepareBefore(tableName, pkRecord, field, pluginList, false, chain, row, tableColumns);
sysUserService.dao().update(tableName, chain, Cnd.where(field, "=", row.get(field)));
} else {
throw new IllegalArgumentException("导入方式不正确");
}
applyAfterPlugins(tableName, tableColumns, chain, pk, pluginList);
success++;
} catch (Exception e) {
log.error("高级导入失败, table={}, row={}", tableName, row, e);
errors.add(new ImportError(Json.toJson(row), e.getMessage()));
}
}
String cacheKey = "";
if (!errors.isEmpty()) {
cacheKey = R.UU32();
redisService.setex(cacheKey, 60 * 60 * 5, Json.toJson(errors));
}
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success(NutMap.NEW().addv("total", total).addv("success", success).addv("cacheKey", cacheKey));
}
@At
@Ok("void")
@ApiOperation("导出错误记录")
@SaCheckPermission("sys.data.advanced.tool")
public void exportErrors(HttpServletResponse response, String cacheKey) {
if (StrUtil.isBlank(cacheKey)) {
CommonDownloadUtil.download("导入错误记录.xlsx",
ExcelExportUtil.exportExcel(new ExportParams(), ImportError.class, new ArrayList<>()),
response);
return;
}
String json = redisService.get(cacheKey);
List<ImportError> errors = StrUtil.isBlank(json) ? new ArrayList<>() : Json.fromJsonAsList(ImportError.class, json);
CommonDownloadUtil.download("导入错误记录.xlsx",
ExcelExportUtil.exportExcel(new ExportParams(), ImportError.class, errors),
response);
}
private void applyAfterPlugins(String tableName,
Set<String> tableColumns,
Chain chain,
Object pk,
List<SysDataImportPlugin> pluginList) {
if (pluginList.isEmpty()) {
return;
}
SysDataImportPlugin.PluginContext context = new SysDataImportPlugin.PluginContext(
tableName,
tableColumns,
chain,
pk,
sysUserService.dao(),
sysRoleService
);
pluginList.forEach(plugin -> plugin.after(context));
}
private Object prepareBefore(String tableName,
Record pkRecord,
String field,
List<SysDataImportPlugin> pluginList,
boolean save,
Chain chain,
NutMap row,
Set<String> tableColumns) {
Object pk = resolvePrimaryKeyValue(tableName, pkRecord, field, save, chain, row);
SysDataImportPlugin.PluginContext context = new SysDataImportPlugin.PluginContext(
tableName,
tableColumns,
chain,
pk,
sysUserService.dao(),
sysRoleService
);
pluginList.forEach(plugin -> plugin.before(context));
return pk;
}
private Object resolvePrimaryKeyValue(String tableName,
Record pkRecord,
String field,
boolean save,
Chain chain,
NutMap row) {
if (pkRecord == null) {
return null;
}
String pkColumnName = pkRecord.getString("column_name");
String pkColumnType = pkRecord.getString("column_type");
Object pk;
if (save) {
pk = row.get(pkColumnName);
if (pk == null) {
pk = generatePrimaryKey(pkColumnType);
chain.add(pkColumnName, pk);
}
} else {
Record record = sysUserService.dao().fetch(tableName, Cnd.where(field, "=", row.get(field)));
if (record == null) {
throw new IllegalArgumentException("未找到关键字段匹配的记录");
}
pk = record.get(pkColumnName);
}
if (pk == null) {
throw new IllegalArgumentException("主键生成失败");
}
return pk;
}
private Object generatePrimaryKey(String pkColumnType) {
if (StrUtil.isBlank(pkColumnType)) {
return R.UU32();
}
return switch (pkColumnType.toLowerCase()) {
case "int", "integer" -> R.random(1000, 9999);
case "varchar(16)" -> R.UU16();
case "varchar(64)" -> R.UU64();
default -> R.UU32();
};
}
private Chain buildChain(NutMap row, Set<String> tableColumns) {
NutMap filtered = NutMap.NEW();
row.forEach((key, value) -> {
if (key != null && tableColumns.contains(key)) {
filtered.addv(key, value);
}
});
return filtered.isEmpty() ? null : Chain.from(filtered);
}
private NutMap[] parseRelations(String relationJson) {
List<NutMap> relationList = Json.fromJsonAsList(NutMap.class, relationJson);
return relationList.toArray(new NutMap[0]);
}
private List<SysDataImportPlugin> parsePlugins(String pluginsJson) {
if (StrUtil.isBlank(pluginsJson)) {
return new ArrayList<>();
}
List<String> pluginNames = Json.fromJsonAsList(String.class, pluginsJson);
List<SysDataImportPlugin> plugins = new ArrayList<>();
for (String pluginName : pluginNames) {
if (StrUtil.isBlank(pluginName)) {
continue;
}
plugins.add(SysDataImportPlugin.valueOf(pluginName));
}
return plugins;
}
private Optional<Record> getPrimaryKey(List<Record> columns) {
return columns.stream().filter(column -> "PRI".equalsIgnoreCase(column.getString("column_key"))).findFirst();
}
private List<Record> getColumns(String tableName) {
Sql sql = Sqls.create("""
SELECT
column_name,
is_nullable,
column_type,
column_key,
column_comment
FROM
information_schema.COLUMNS
WHERE
table_name = @tableName
AND table_schema = (SELECT DATABASE())
ORDER BY
ordinal_position
""").setParam("tableName", tableName);
return sysUserService.list(sql);
}
private List<NutMap> getDataForExcel(TempFile file, NutMap[] relation) throws IOException {
List<NutMap> result = new ArrayList<>();
Map<Integer, String> headerColumnMap = new HashMap<>();
Sheet sheet = WorkbookFactory.create(file.getInputStream()).getSheetAt(0);
Row headerRow = sheet.getRow(0);
if (headerRow == null) {
return result;
}
int columnNum = headerRow.getPhysicalNumberOfCells();
for (int i = 0; i < columnNum; i++) {
Cell cell = headerRow.getCell(i);
if (cell == null) {
continue;
}
String header = cell.getStringCellValue();
for (NutMap item : relation) {
if (StrUtil.equals(item.getString("relation"), header)) {
headerColumnMap.put(i, item.getString("column_name"));
break;
}
}
}
int rowNum = sheet.getPhysicalNumberOfRows();
for (int i = 1; i < rowNum; i++) {
Row row = sheet.getRow(i);
if (row == null) {
continue;
}
NutMap data = NutMap.NEW();
for (int j = 0; j < columnNum; j++) {
String columnName = headerColumnMap.get(j);
if (columnName == null) {
continue;
}
data.setv(columnName, getCellValue(row.getCell(j)));
}
if (!data.isEmpty()) {
result.add(data);
}
}
return result;
}
private Object getCellValue(Cell cell) {
if (cell == null) {
return null;
}
CellType cellType = cell.getCellType();
if (cellType == CellType.NUMERIC) {
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
return DATE_TIME_FORMATTER.format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
}
double numericValue = cell.getNumericCellValue();
BigDecimal decimal = BigDecimal.valueOf(numericValue);
if (String.valueOf(numericValue).contains("E")) {
return decimal.toPlainString();
}
if (numericValue == Math.rint(numericValue)) {
return decimal.toBigInteger();
}
return numericValue;
}
if (cellType == CellType.STRING) {
return cell.getStringCellValue();
}
if (cellType == CellType.BOOLEAN) {
return cell.getBooleanCellValue();
}
if (cellType == CellType.ERROR) {
return cell.getErrorCellValue();
}
return null;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class ImportError {
@Excel(name = "行数据", width = 80)
private String row;
@Excel(name = "错误原因", width = 40)
private String errorMsg;
}
}
@@ -0,0 +1,19 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@IocBean
@At("/platform/sys/data/unit")
@Ok("json:full")
public class SysDataUnitController {
@At("")
@Ok("beetl:/platform/sys/data/unit/index.html")
@SaCheckPermission("sys.data.unit")
public void index() {
}
}
@@ -0,0 +1,103 @@
package com.budwk.app.sys.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.utils.PageUtil;
import com.budwk.app.sys.models.Sys_user_source;
import com.budwk.app.sys.param.SysDataUserPullPageForm;
import com.budwk.app.sys.services.SysDataUserPullService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
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 org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
@IocBean
@At("/platform/sys/data/user/pull")
@Ok("json:full")
@Api(value = "获取信息中心数据")
public class SysDataUserPullController {
@Inject
private SysDataUserPullService sysUserPullService;
@At("")
@Ok("beetl:/platform/sys/data/user/pull.html")
@SaCheckPermission("sys.data.user.pull")
public void index() {
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiOperation("分页数据")
@Ok("json:{locked:'password|idCard'}")
public Result pageData(@Valid SysDataUserPullPageForm pageForm) {
Sql sql = Sqls.create("select us.*,su.`name` AS unit_name from sys_user_source us left join sys_unit su ON su.id = us.unitId $condition");
Cnd cnd = Cnd.NEW();
cnd.andEX(Sys_user_source::getPullTime, "=", pageForm.getPullTime());
cnd.and(Cnd.likeEX(Sys_user_source::getUsername, pageForm.getUserName()));
cnd.and(Cnd.likeEX(Sys_user_source::getLoginname, pageForm.getLoginName()));
cnd.andEX(Sys_user_source::getUnitName, "=", pageForm.getUnitName());
cnd.andEX(Sys_user_source::getUserState, "=", pageForm.getUserState());
cnd.andEX(Sys_user_source::getPreparedBy, "=", pageForm.getPreparedBy());
cnd.andEX(Sys_user_source::getPersonType, "=", pageForm.getPersonType());
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.desc(Sys_user_source::getPullTime);
sql.setCondition(cnd);
Pagination pagination = sysUserPullService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiOperation("拉取用户数据")
public Result pullData() {
sysUserPullService.pull();
return Result.success();
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiOperation("删除用户数据")
public Result deleteData() {
sysUserPullService.clear();
return Result.success();
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiModelProperty("获取下拉框数据(单位、在职状态、教职工类别)")
public Result searchOptions() {
return Result.success(sysUserPullService.searchOptions());
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiModelProperty("获取数据源拉取时间列表")
public Result pullTimeOptions() {
return Result.success(sysUserPullService.pullTimeOptions());
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiOperation("根据拉取时间删除数据")
public Result deleteByPullTime(@Param(value = "pullTime") @Valid String[] pullTime) {
sysUserPullService.clear(Cnd.where(Sys_user_source::getPullTime, "in", pullTime));
return Result.success();
}
}
@@ -0,0 +1,139 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.EnumUtil;
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.PageUtil;
import com.budwk.app.sys.enums.SysDataUpdateMode;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_history;
import com.budwk.app.sys.param.SysDataUserUpdatePageForm;
import com.budwk.app.sys.param.SysDataUserUpdateParam;
import com.budwk.app.sys.services.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.Ioc;
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 javax.validation.Valid;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@IocBean
@At("/platform/sys/data/user/update")
@Ok("json:full")
@Api(value = "更新系统用户数据")
public class SysDataUserUpdateController {
@Inject("refer:$ioc")
private Ioc ioc;
@Inject
private SysUserService sysUserService;
@Inject
private SysDataUserPullService sysDataUserPullService;
@Inject
private SysDataUnitPullService sysDataUnitPullService;
@Inject
private SysDataDictPullService sysDataDictPullService;
@At("")
@Ok("beetl:/platform/sys/data/user/update.html")
@SaCheckPermission("sys.data.user.update")
public void index() {
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiOperation("分页数据")
@Ok("json:{locked:'password|idCard'}")
public Result pageData(@Valid SysDataUserUpdatePageForm pageForm) {
Sql sql = Sqls.create("""
SELECT
u.*,
his.changeTypes,
his.changeTime,
his.id AS userHistoryId
FROM
vw_user u
LEFT JOIN (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY loginname ORDER BY changeTime DESC) AS rn
FROM
sys_user_history
) his ON his.loginname = u.loginname AND his.rn = 1
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and(Cnd.likeEX("u.username", pageForm.getUserName()));
cnd.and(Cnd.likeEX("u.loginname", pageForm.getLoginName()));
cnd.andEX("u.unitId", "=", pageForm.getUnitId());
cnd.andEX("u.userState", "=", pageForm.getUserState());
cnd.andEX("u.;preparedBy", "=", pageForm.getPreparedBy());
cnd.andEX("u.personType", "=", pageForm.getPersonType());
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.desc("his.changeTime");
sql.setCondition(cnd);
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.data.user.pull")
@ApiModelProperty("获取数据源拉取时间列表")
public Result pullTimeOptions() {
return Result.success(sysDataUserPullService.pullTimeOptions());
}
@At
@SaCheckPermission("sys.data.user.pull")
@SLog(tag = "更新系统用户数据", msg = "更新数据")
@ApiOperation("更新数据")
public Result updateUserFormSource(@Valid @Param("param") SysDataUserUpdateParam updateParam) {
SysDataUpdateMode updateMode = EnumUtil.getBy(SysDataUpdateMode.class, (val) -> val.name().equals(updateParam.getUpdateMode()));
if (ObjectUtil.isNull(updateMode)) {
return Result.error("更新模式错误,请传入正确的更新模式。");
}
SysDataUserUpdateService sysDataUserUpdateService = (SysDataUserUpdateService) ioc.get(updateMode.getClazz());
return Result.success(sysDataUserUpdateService.update(updateParam));
}
@At
@SaCheckPermission("sys.data.user.pull")
@SLog(tag = "更新单位数据", msg = "更新单位数据")
@ApiOperation("更新单位数据")
public Result updateUnits(){
sysDataUnitPullService.updateUnits();
return Result.success();
}
@At
@SaCheckPermission("sys.data.user.pull")
@SLog(tag = "更新码表数据", msg = "更新码表数据")
@ApiOperation("更新码表数据")
public Result updateDataDict(){
sysDataDictPullService.pullDataDict();
return Result.success();
}
}
@@ -0,0 +1,254 @@
package com.budwk.app.sys.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.result.Result;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
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.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
;
/**
* Created by wizzer on 2016/6/24.
*/
@IocBean
@At("/platform/sys/dict")
public class SysDictController {
private static final Log log = Logs.get();
@Inject
private SysDictService sysDictService;
@At("")
@Ok("beetl:/platform/sys/dict/index.html")
@SaCheckPermission("sys.manager.dict")
public Object index() {
return sysDictService.query(Cnd.where("parentId", "=", "").or("parentId", "is", null).asc("location").asc("path"));
}
@At("/child")
@Ok("json")
@SaCheckLogin
public Object child(@Param("pid") String pid, HttpServletRequest req) {
List<Sys_dict> list = new ArrayList<>();
List<NutMap> treeList = new ArrayList<>();
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysDictService.query(cnd);
for (Sys_dict sysDict : list) {
if (sysDictService.count(Cnd.where("parentId", "=", sysDict.getId())) > 0) {
sysDict.setHasChildren(true);
}
NutMap map = Lang.obj2nutmap(sysDict);
map.addv("expanded", false);
map.addv("children", new ArrayList<>());
treeList.add(map);
}
return Result.success().addData(treeList);
}
@At("/tree")
@Ok("json")
@SaCheckLogin
public Object tree(@Param("pid") String pid, HttpServletRequest req) {
try {
List<NutMap> treeList = new ArrayList<>();
if (Strings.isBlank(pid)) {
NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择菜单").addv("leaf", true);
treeList.add(root);
}
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
List<Sys_dict> list = sysDictService.query(cnd);
for (Sys_dict sysDict : list) {
NutMap map = NutMap.NEW().addv("value", sysDict.getId()).addv("label", sysDict.getName());
if (sysDict.isHasChildren()) {
map.addv("children", new ArrayList<>());
map.addv("leaf", false);
} else {
map.addv("leaf", true);
}
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.dict.add")
@SLog(tag = "新建字典", msg = "字典名称:${args[0].name}")
public Object addDo(@Param("..") Sys_dict dict, @Param(value = "parentId", df = "") String parentId, HttpServletRequest req) {
try {
if ("root".equals(parentId)) {
parentId = "";
}
dict.setHasChildren(false);
dict.setCreatedBy(SecurityUtil.getUserId());
sysDictService.save(dict, parentId);
sysDictService.clearCache();
return Result.success("system.success");
} catch (Exception e) {
return Result.error("system.error");
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.dict")
public Object edit(String id, HttpServletRequest req) {
try {
return Result.success().addData(sysDictService.fetch(id));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.dict.edit")
@SLog(tag = "编辑字典", msg = "字典名称:${args[0].name}")
public Object editDo(@Param("..") Sys_dict dict, @Param("parentId") String parentId, HttpServletRequest req) {
try {
dict.setUpdatedBy(SecurityUtil.getUserId());
sysDictService.updateIgnoreNull(dict);
sysDictService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.dict.delete")
@SLog(tag = "删除字典", msg = "字典名称:${args[1].getAttribute('name')}")
public Object delete(String id, HttpServletRequest req) {
try {
Sys_dict dict = sysDictService.fetch(id);
req.setAttribute("name", dict.getName());
sysDictService.deleteAndChild(dict);
sysDictService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.dict.edit")
@SLog(tag = "启用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object enable(String menuId, HttpServletRequest req) {
try {
req.setAttribute("name", sysDictService.fetch(menuId).getName());
sysDictService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", menuId));
sysDictService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.dict.edit")
@SLog(tag = "禁用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object disable(String menuId, HttpServletRequest req) {
try {
req.setAttribute("name", sysDictService.fetch(menuId).getName());
sysDictService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", menuId));
sysDictService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/menuAll")
@Ok("json")
@SaCheckPermission("sys.manager.dict")
public Object menuAll(HttpServletRequest req) {
try {
List<Sys_dict> list = sysDictService.query(Cnd.NEW().asc("location").asc("path"));
NutMap menuMap = NutMap.NEW();
for (Sys_dict unit : list) {
List<Sys_dict> list1 = menuMap.getList(unit.getParentId(), Sys_dict.class);
if (list1 == null) {
list1 = new ArrayList<>();
}
list1.add(unit);
menuMap.put(unit.getParentId(), list1);
}
return Result.success().addData(getTree(menuMap, ""));
} catch (Exception e) {
return Result.error();
}
}
private List<NutMap> getTree(NutMap menuMap, String pid) {
List<NutMap> treeList = new ArrayList<>();
List<Sys_dict> subList = menuMap.getList(pid, Sys_dict.class);
for (Sys_dict menu : subList) {
NutMap map = Lang.obj2nutmap(menu);
map.put("label", menu.getName());
if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
map.put("children", getTree(menuMap, menu.getId()));
}
treeList.add(map);
}
return treeList;
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.dict.edit")
public Object sortDo(@Param("ids") String ids, HttpServletRequest req) {
try {
String[] menuIds = StringUtils.split(ids, ",");
int i = 0;
sysDictService.execute(Sqls.create("update sys_dict set location=0"));
for (String s : menuIds) {
if (!Strings.isBlank(s)) {
sysDictService.update(org.nutz.dao.Chain.make("location", i), Cnd.where("id", "=", s));
i++;
}
}
sysDictService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,262 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
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.result.Result;
import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.services.SysConfigService;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.google.common.net.HttpHeaders;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.Loader;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.io.RandomAccessRead;
import org.apache.pdfbox.io.RandomAccessReadBuffer;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.List;
@IocBean
@At("/platform/sys/file")
@Ok("json:full")
@Api(tags = "文件管理")
@Slf4j
public class SysFileController {
@Inject
private SysFileService sysFileService;
@Inject
private SysConfigService sysConfigService;
private SysFileMinIoUtil sysFileMinIoUtil;
@At("")
@Ok("beetl:/platform/sys/file/index.html")
@SaCheckPermission("sys.manager.file")
public void index() {
}
/**
* 动态上传文件返回url
**/
@At
@SLog(tag = "文件管理", msg = "动态上传文件返回url")
@POST
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@SaCheckLogin
public Result uploadDynamicReturnUrl(TempFile file) {
try {
if (file == null) {
return Result.error("文件内容为空");
}
String submittedFileName = file.getSubmittedFileName();
if (submittedFileName.contains("pdf")) {
try {
byte[] pdfBytes = Files.readAllBytes(file.getFile().toPath());
if (isPdfContainsJavaScript(pdfBytes)) {
//throw new BaseException("禁止上传包含 JavaScript 的 PDF 文件");
throw new BaseException("系统检测到此 PDF 文件具有一定危险性");
}
} catch (IOException e) {
log.warn("PDF 安全扫描失败,文件可能损坏", e);
// 可选择拒绝或放行(建议拒绝)
throw new BaseException("PDF 文件解析失败,请上传合法文件");
}
}
String id = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), file);
return Result.success().addData(id);
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
/**
* 获取文件分页列表
*/
@At
@SaCheckPermission("sys.manager.file")
public Result pageData(PageForm pageForm, String name) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(name)) {
cnd.where().andLike(Sys_file::getName, name);
}
cnd.desc(Sys_file::getCreatedAt);
Pagination pagination = sysFileService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
/**
* 获取文件列表
*/
@At
@SLog(tag = "文件管理", msg = "获取文件列表")
@SaCheckPermission("sys.manager.file")
public Result list(Sys_file file) {
return Result.success(sysFileService.list());
}
/**
* 下载文件
**/
@At
@Ok("void")
@SaCheckLogin
public void download(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
sysFileService.download(id, request, response);
}
@At
@Ok("void")
@SaCheckLogin
@ApiOperation("文件管理-转换PDF")
public void convertPDF(String id, HttpServletRequest request, HttpServletResponse response) throws IOException {
sysFileService.convertPDF(id, request, response);
}
@At
@SaCheckLogin
@ApiOperation("文件管理-转换HTML")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result convertHtml(TempFile file) {
return Result.success().addData(sysFileService.convertHtml(file));
}
@At
@ApiOperation("文件管理-删除文件")
@SLog(tag = "文件管理", msg = "删除文件")
@SaCheckPermission("sys.manager.file")
public Result delete(@Param("ids") String[] ids) {
sysFileService.delete(ids);
return Result.success();
}
@At
@SLog(tag = "文件管理", msg = "获取文件详情")
@SaCheckPermission("sys.manager.file")
@ApiOperation("文件管理-预览单文件文件完整数据")
public Result detail(String id) {
return Result.success(sysFileService.detail(id));
}
@At
@SaCheckLogin
@ApiOperation("文件管理-前端预览文件完整数据")
public Result previewFileData(@Param("ids") String[] ids) {
List<Sys_file> files = sysFileService.previewFileData(ids);
return Result.success(files);
}
@At
@SaCheckLogin
@ApiOperation("文件管理-视频播放")
@Ok("void")
public void videoPlay(String id, HttpServletRequest request, HttpServletResponse response) {
Sys_file sys_file = sysFileService.detail(id);
byte[] bytes = SysFileMinIoUtil.getFileBytes(sys_file.getBucket(), sys_file.getStoragePath());
// 设置响应头
String fileName = sys_file.getName();
String contentType = null;
switch (FileUtil.extName(fileName).toLowerCase()) {
case "mp4" -> contentType = "video/mp4";
case "avi" -> contentType = "video/x-msvideo";
case "mkv" -> contentType = "video/x-matroska";
case "mov" -> contentType = "video/quicktime";
case "wmv" -> contentType = "video/x-ms-wmv";
default -> contentType = "application/octet-stream";
}
response.setContentType(contentType);
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
String rangeHeader = request.getHeader(HttpHeaders.RANGE);
if (StrUtil.isNotBlank(rangeHeader) && rangeHeader.startsWith("bytes=")) {
// 处理Range请求
String[] ranges = rangeHeader.substring(6).split("-");
long start = StrUtil.isNotBlank(ranges[0]) ? Long.parseLong(ranges[0]) : 0;
long end = (ranges.length > 1 && StrUtil.isNotBlank(ranges[1])) ?
Long.parseLong(ranges[1]) : bytes.length - 1;
if (start >= bytes.length || end >= bytes.length) {
response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + bytes.length);
response.setStatus(416);
return;
}
int contentLength = (int) (end - start + 1);
response.setStatus(206);
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength));
response.setHeader(HttpHeaders.CONTENT_RANGE, StrUtil.format("bytes {}-{}/{}", start, end, bytes.length));
try (OutputStream out = response.getOutputStream()) {
out.write(bytes, (int) start, contentLength);
} catch (IOException e) {
log.error("视频播放失败", e);
}
} else {
// 非Range请求
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(bytes.length));
try (OutputStream out = response.getOutputStream()) {
out.write(bytes);
} catch (IOException e) {
log.error("视频播放失败", e);
}
}
}
public boolean isPdfContainsJavaScript(byte[] pdfBytes) throws IOException {
try (PDDocument document = Loader.loadPDF(new RandomAccessReadBuffer(pdfBytes))) {
COSDictionary catalog = document.getDocumentCatalog().getCOSObject();
// 1. 检查 /Names -> /JavaScript
if (catalog.containsKey(COSName.NAMES)) {
COSDictionary names = (COSDictionary) catalog.getDictionaryObject(COSName.NAMES);
if (names != null && names.containsKey(COSName.JAVA_SCRIPT)) {
return true;
}
}
// 2. 检查 /OpenAction(可能指向 JS action
if (catalog.containsKey(COSName.OPEN_ACTION)) {
var openAction = catalog.getDictionaryObject(COSName.OPEN_ACTION);
if (openAction instanceof COSDictionary) {
COSDictionary actionDict = (COSDictionary) openAction;
if (COSName.JAVA_SCRIPT.equals(actionDict.getDictionaryObject(COSName.S))) {
return true;
}
}
}
// 3. (可选)检查 AcroForm 中的 JS(更复杂,通常用于表单)
// 可根据安全需求决定是否实现
return false;
}
}
}
@@ -0,0 +1,126 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.service.ActivityBasicScopeService;
import io.swagger.annotations.Api;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
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 java.util.ArrayList;
import java.util.Date;
import java.util.List;
@IocBean
@At("/platform/h5")
@Api(tags = "移动端首页")
public class SysH5IndexController {
@Inject
private Dao dao;
@Inject
private ActivityBasicScopeService activityBasicScopeService;
@At
@Ok("beetl:/platform/zhghh5/sys/home/index.html")
@SaCheckLogin
public void home() {
}
@At
@Ok("beetl:/platform/zhghh5/sys/home/featuredActivity.html")
@SaCheckLogin
public void featuredActivity() {
}
@At
@Ok("beetl:/platform/zhghh5/sys/home/festivalBenefit.html")
@SaCheckLogin
public void festivalBenefit() {
}
@At
@Ok("beetl:/platform/zhghh5/index/mine/index.html")
@SaCheckLogin
public void mine() {
}
@At
@Ok("beetl:/platform/zhghh5/index/msg/index.html")
@SaCheckLogin
public void msg() {
}
@At
@Ok("beetl:/platform/zhghh5/index/work/index.html")
@SaCheckLogin
public void work() {
}
@At
@SaCheckLogin
@Ok("json")
public Result listHomeActivity() {
FieldFilter fieldFilter = FieldFilter.locked(Sys_home_activity.class, "classPath");
List<Sys_home_activity> list = Daos.ext(dao,fieldFilter) .query(Sys_home_activity.class, Cnd.where("enable", "=", 1).desc("top"));
String userId = SecurityUtil.getUserId();
List<Sys_home_activity> allowActivityList = new ArrayList<>();
// 今天的时间
Date today = DateUtil.date();
for (Sys_home_activity activity : list) {
// 该活动的时间范围
Date startDate = activity.getStartDate();
Date endDate = activity.getEndDate();
// 判断当前时间是否在活动范围内,不在就过滤掉
if (!DateUtil.isIn(today, startDate, endDate)) {
continue;
}
Integer allowUserGroupId = activity.getAllowUserGroupId();
String allowUserSql = activity.getAllowUserSql();
activity.setAllowUserSql(null);
if (allowUserGroupId == null && StrUtil.isBlank(allowUserSql)) {
allowActivityList.add(activity);
continue;
}
if (allowUserGroupId != null) {
if (activityBasicScopeService.isUserInGroup(allowUserGroupId, userId)) {
allowActivityList.add(activity);
continue;
}
}
if (StrUtil.isNotBlank(allowUserSql)){
Sql sql = Sqls.create(allowUserSql).setParam("userId", userId);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap nutMap = (NutMap) sql.getResult();
if (Lang.isNotEmpty(nutMap) && StrUtil.isNotBlank(nutMap.getString("userId"))) {
allowActivityList.add(activity);
}
}
}
return Result.success(allowActivityList);
}
}
@@ -0,0 +1,26 @@
package com.budwk.app.sys.controller;
import io.swagger.annotations.Api;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
/**
* @ClassName SysH5IndexMineController
* @Description TODO
* @Author zhf
* @Date 2024/10/15 9:31
*/
@IocBean
@At("/platform/h5/indexMine")
@Api(tags = "移动端首页我的")
public class SysH5IndexMineController {
@At("/userInfo")
@Ok("beetl:/platform/zhghh5/sys/userInfo/index.html")
public void userInfo() {
}
}
@@ -0,0 +1,88 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.Api;
import org.nutz.integration.jedis.RedisService;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
@IocBean
@At("/platform/sys/h5ScanCodeUploadFile")
@Ok("json:full")
@Api(tags = "h5扫码上传文件")
public class SysH5ScanCodeUploadFileController {
@Inject
private SysFileService sysFileService;
@Inject
private RedisService redisService;
@Inject
private PubSubService pubSubService;
@At("")
@Ok("beetl:/platform/sys/h5upload.html")
@SaCheckLogin
public void index() {
}
@At
@SLog(tag = "h5扫码上传文件", msg = "上传")
@POST
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@SaCheckLogin
public Result upload(@Param("file") TempFile file) {
try {
if (file == null) {
return Result.error("请选择要上传的文件");
}
String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), file);
return Result.success().addData(url);
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
@At
@SLog(tag = "文件管理", msg = "同步到PC")
@SaCheckLogin
public Result syncPc(@Param("files") JSONObject[] jsonObject, @Param("timestamp") String timestamp) {
try {
if(ObjectUtil.isEmpty(jsonObject)){
return Result.error("请选择要同步的文件");
}
ScanParams match = new ScanParams().match(RedisConstant.REDIS_KEY_WSROOM + SecurityUtil.getUserLoginname() + ":*");
ScanResult<String> scan = null;
do {
scan = redisService.scan(scan == null ? ScanParams.SCAN_POINTER_START : scan.getStringCursor(), match);
for (String key : scan.getResult()) {
NutMap data = NutMap.NEW().addv("action", "h5-scan-code-upload-file-" + timestamp).addv("files", jsonObject);
pubSubService.fire(key, Json.toJson(data));
}
} while (!scan.isCompleteIteration());
return Result.success().addData(null);
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
}
@@ -0,0 +1,106 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.param.SysHomeActivityPageForm;
import com.budwk.app.sys.services.SysHomeActivityService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
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 javax.validation.Valid;
@IocBean
@At("/platform/sys/homeActivity")
@Ok("json:full")
@Api(value = "首页活动")
public class SysHomeActivityController {
@Inject
private SysHomeActivityService sysHomeActivityService;
@At("")
@Ok("beetl:/platform/sys/homeActivity/index.html")
@SaCheckPermission("sys.homeActivity")
public void index() {
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("分页数据")
public Result pageData(@Valid SysHomeActivityPageForm pageForm) {
Cnd cnd = Cnd.NEW();
cnd.and(Cnd.likeEX(Sys_home_activity::getName,pageForm.getName()));
cnd.desc(Sys_home_activity::getSortNo);
Pagination pagination = sysHomeActivityService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("启用")
public Result enable(@Valid String id) {
sysHomeActivityService.update(Chain.make("enable", 1), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("关闭")
public Result disable(@Valid String id) {
sysHomeActivityService.update(Chain.make("enable", 0), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("置顶")
public Result topUp(@Valid String id){
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(id);
sysHomeActivity.setTop(true);
sysHomeActivityService.updateIgnoreNull(sysHomeActivity);
return Result.success();
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("取消置顶")
public Result cancelTopUp(@Valid String id){
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(id);
sysHomeActivity.setTop(false);
sysHomeActivityService.updateIgnoreNull(sysHomeActivity);
return Result.success();
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("推送大图")
public Result push(@Valid String id){
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(id);
sysHomeActivity.setPush(true);
sysHomeActivityService.updateIgnoreNull(sysHomeActivity);
return Result.success();
}
@At
@SaCheckPermission("sys.homeActivity")
@ApiOperation("取消推送大图")
public Result cancelPush(@Valid String id){
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(id);
sysHomeActivity.setPush(false);
sysHomeActivityService.updateIgnoreNull(sysHomeActivity);
return Result.success();
}
}
@@ -0,0 +1,326 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.models.Sys_home_template;
import com.budwk.app.sys.models.Sys_menu;
import com.budwk.app.sys.services.SysMenuService;
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.activity.basic.service.ActivityBasicScopeService;
import io.swagger.annotations.ApiOperation;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@IocBean
@At("/platform/home")
public class SysHomeController {
private static final Log log = Logs.get();
@Inject
private Dao dao;
@Inject
private SysMenuService sysMenuService;
@Inject
private SysUserService sysUserService;
@Inject
private RedisService redisService;
@Inject
private ActivityBasicScopeService activityBasicScopeService;
@At("")
@Ok("re")
@SaCheckLogin
public String home(HttpSession session, HttpServletRequest req) {
String userAgentStr = req.getHeader("User-Agent");
UserAgent userAgent = UserAgentUtil.parse(userAgentStr);
if (!userAgent.isMobile()) {
return "beetl:/layouts/v4/home/index.html";
} else {
return "beetl:/platform/zhghh5/sys/home/index.html";
}
}
@At("/platform/h5")
@Ok("re")
@SaCheckLogin
public String h5Home(HttpSession session, HttpServletRequest req) {
return "beetl:/platform/zhghh5/sys/home/index.html";
}
@At("/403")
@Ok("re")
public Object error403(HttpServletRequest req) {
if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
if (UserAgentUtil.parse(req.getHeader("User-Agent")).isMobile()) {
return ">>:/error/403.html";
}
return "beetl:/platform/sys/403.html";
} else {
return ">>:/error/404.html";
}
}
@At("/404")
@Ok("re")
public Object error404(HttpServletRequest req) {
if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
if (UserAgentUtil.parse(req.getHeader("User-Agent")).isMobile()) {
return ">>:/error/404.html";
}
return "beetl:/platform/sys/404.html";
} else {
return ">>:/error/404.html";
}
}
@At("/500")
@Ok("re")
public Object error500(HttpServletRequest req) {
if (Strings.sNull(req.getAttribute("original_request_uri")).startsWith("/platform")) {
if (UserAgentUtil.parse(req.getHeader("User-Agent")).isMobile()) {
return ">>:/error/500.html";
}
return "beetl:/platform/sys/500.html";
} else {
return ">>:/error/500.html";
}
}
@At("/unknownAccountError")
@Ok("re")
@ApiOperation("未知用户页面")
public Object unknownAccountError() {
return ">>:/error/unknownAccountError.html";
}
@At(value = {"/", "/index"}, top = true)
@Ok(">>:/platform/home")
public void index() {
}
@At(value = "/platform/h5", top = true)
@Ok("re")
@SaCheckLogin
public String h5Index() {
return "beetl:/platform/zhghh5/sys/home/index.html";
}
@At
@SaCheckLogin
@ApiOperation("电脑端推荐应用")
@Ok("json")
public Result listRecommendApp(@Param(value = "platform", df = "PC") String platform) {
List<Sys_menu> list = sysMenuService.query(Cnd.where(Sys_menu::getIsRecommendApp, "=", 1)
.and(Sys_menu::getDisabled, "=", 0)
.and(Sys_menu::getShowit, "=", 1)
.and(Sys_menu::getPlatform, "=", platform)
);
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
Set<String> allMenuIds = menus.stream().map(Sys_menu::getId).collect(Collectors.toSet());
Set<String> allParentMenuIds = menus.stream()
.map(Sys_menu::getParentId)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
List<Sys_menu> sysMenus = list.stream()
// 应用有已授权子菜单,或根菜单自身有链接且已授权时,才允许在首页展示入口。
.filter(menu -> allParentMenuIds.contains(menu.getId())
|| (StrUtil.isNotBlank(menu.getHref()) && allMenuIds.contains(menu.getId())))
.sorted(Comparator.comparing(Sys_menu::getLocation, Comparator.nullsLast(Integer::compareTo))
.thenComparing(Sys_menu::getId))
.toList();
return Result.success(sysMenus);
}
@At
@SaCheckLogin
@ApiOperation("电脑端推荐服务")
@Ok("json")
public Result listRecommendService(@Param(value = "platform", df = "PC") String platform) {
List<Sys_menu> list = sysMenuService.query(Cnd.where(Sys_menu::getIsRecommendService, "=", 1)
.and(Sys_menu::getDisabled, "=", 0)
.and(Sys_menu::getShowit, "=", 1)
.and(Sys_menu::getPlatform, "=", platform)
);
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
Set<String> allMenuIds = menus.stream().map(Sys_menu::getId).collect(Collectors.toSet());
List<Sys_menu> sysMenus = list.stream()
// 推荐项必须同时属于当前用户已授权菜单,避免首页展示无权限入口。
.filter(menu -> allMenuIds.contains(menu.getId()))
.sorted(Comparator.comparing(Sys_menu::getLocation, Comparator.nullsLast(Integer::compareTo))
.thenComparing(Sys_menu::getId))
.toList();
return Result.success(sysMenus);
}
@At
@SaCheckLogin
@ApiOperation("获取收藏应用")
@Ok("json")
public Result listFavorite(@Param(value = "platform", df = "PC") String platform) {
List<Sys_menu> list = sysMenuService.query(Cnd.where(Sys_menu::getId, "in", Sqls.create("select appId from sys_user_favorite_app where userId = @userId").setParam("userId", SecurityUtil.getUserId()))
.and(Sys_menu::getDisabled, "=", 0)
.and(Sys_menu::getShowit, "=", 1)
.and(Sys_menu::getPlatform, "=", platform)
);
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
List<String> allMenuIds = menus.stream().map(Sys_menu::getId).toList();
List<Sys_menu> sysMenus = list.stream().filter(m -> allMenuIds.contains(m.getId())).sorted(Comparator.comparingInt(Sys_menu::getLocation)).toList();
return Result.success(sysMenus);
}
@At
@SaCheckLogin
@ApiOperation("首页推送活动")
@Ok("json")
public Result listHomeActivity() {
FieldFilter fieldFilter = FieldFilter.locked(Sys_home_activity.class, "classPath");
List<Sys_home_activity> list = Daos.ext(dao, fieldFilter).query(Sys_home_activity.class, Cnd.where("enable", "=", 1).desc("top"));
String userId = SecurityUtil.getUserId();
List<Sys_home_activity> allowActivityList = new ArrayList<>();
// 今天的时间
Date today = DateUtil.date();
for (Sys_home_activity activity : list) {
// 该活动的时间范围
Date startDate = activity.getStartDate();
Date endDate = activity.getEndDate();
// 判断当前时间是否在活动范围内,不在就过滤掉
// if (!DateUtil.isIn(today, startDate, endDate)) {
// continue;
// }
// 只过滤结束的
if (DateUtil.compare(today, endDate) > 0) {
continue;
}
Integer allowUserGroupId = activity.getAllowUserGroupId();
String allowUserSql = activity.getAllowUserSql();
activity.setAllowUserSql(null);
if (allowUserGroupId == null && StrUtil.isBlank(allowUserSql)) {
allowActivityList.add(activity);
continue;
}
if (allowUserGroupId != null) {
if (activityBasicScopeService.isUserInGroup(allowUserGroupId, userId)) {
allowActivityList.add(activity);
continue;
}
}
if (StrUtil.isNotBlank(allowUserSql)) {
Sql sql = Sqls.create(allowUserSql).setParam("userId", userId);
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap nutMap = (NutMap) sql.getResult();
if (Lang.isNotEmpty(nutMap) && StrUtil.isNotBlank(nutMap.getString("userId"))) {
allowActivityList.add(activity);
}
}
}
return Result.success(allowActivityList);
//
//
//
//
// FieldFilter fieldFilter = FieldFilter.locked(Sys_home_activity.class, "allowUserSql|classPath");
// List<Sys_home_activity> list = Daos.ext(dao, fieldFilter).query(Sys_home_activity.class, Cnd.where("enable", "=", 1).desc("top"));
//
// List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
// Set<String> hrefs = menus.stream().map(Sys_menu::getHref).collect(Collectors.toSet());
//
// List<Sys_home_activity> hasPermisiionList = list.stream().filter(activity -> {
// String url = activity.getUrl();
// String h5Url = activity.getH5Url();
// return hrefs.contains(url) || hrefs.contains(h5Url);
// }).toList().stream().toList();
// return Result.success(hasPermisiionList);
}
@At
@SaCheckLogin
@ApiOperation("首页工作模板")
@Ok("json")
public Result listHomeTemplate() {
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
return Result.success(Collections.emptyList());
}
FieldFilter fieldFilter = FieldFilter.locked(Sys_home_template.class, "allowUserSql|classPath");
List<Sys_home_template> list = Daos.ext(dao, fieldFilter).query(Sys_home_template.class,
Cnd.where("enable", "=", 1).asc("sortNo"));
return Result.success(list);
}
@At
@SaCheckLogin
@ApiOperation("获取新闻")
@Ok("json")
// @CacheDefaults(cacheName = RedisConstant.PLATFORM_REDIS_WKCACHE_PREFIX + "web_news", isHash = true)
// @CacheResult(cacheKey = "news", ignoreNull = true, cacheLiveTime = 60 * 60 * 24)
public Result getNews() {
try {
String url = "https://xgh.cug.edu.cn/";
Document document = Jsoup.connect(url).get();
Elements homeElements = document.select(".gh,.jc,.fc,.jg");
List<Map<String, Object>> news = homeElements.stream().map(homeElement -> {
//获取板块名称
String name = homeElement.selectFirst(".title").text();
Elements liElements = homeElement.select("li");
List<NutMap> ele = liElements.stream().map(liElement -> {
NutMap row = NutMap.NEW();
String href = liElement.selectFirst("a").attr("href");
String time = liElement.selectFirst("span").text();
String title = liElement.selectFirst("a").attr("title");
row.put("href", href);
row.put("time", time);
row.put("text", title);
return row;
}).toList();
return Map.of("label", name, "value", ele);
}).collect(Collectors.toList());
redisService.setex("gonghui_news", 60 * 60 * 24, Json.toJson(news));
return Result.success(news);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -0,0 +1,110 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import com.budwk.app.sys.services.SysUserService;
import io.swagger.annotations.Api;
import org.nutz.dao.Dao;
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 org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
@IocBean
@At("/platform/v4")
@Api(value = "V4首页")
public class SysHomeV4Controller {
@Inject
private Dao dao;
@Inject
private SysUserService sysUserService;
@At("")
@Ok("beetl:/layouts/v4/platform.html")
@SaCheckLogin
public void index() {
}
// @At("/home")
// @Ok("beetl:/layouts/v4/home.html")
// @SaCheckLogin
// public void home() {
//
// }
@At("/home")
@Ok("beetl:/layouts/v4/home/index.html")
@SaCheckLogin
public void home2() {
}
/**
* 应用中心
*/
@At("/apps")
@Ok("beetl:/layouts/v4/apps.html")
@SaCheckLogin
public void apps() {
}
/**
* 服务中心
*/
@At("/serv")
@Ok("beetl:/layouts/v4/serv.html")
@SaCheckLogin
public void serv(){
}
/**
* 待办中心
*/
@At("/todo")
@Ok("beetl:/layouts/v4/todo.html")
@SaCheckLogin
public void todo(){
}
/**
* 消息中心
*/
@At("/msg")
@Ok("beetl:/layouts/v4/msg.html")
@SaCheckLogin
public void msg(){
}
/**
* 子系统
* @param appId 应用ID
* @param request 请求
*/
@At("/subApp")
@Ok("beetl:/layouts/platform.html")
@SaCheckLogin
public void subApp(@Param("appId") String appId, HttpServletRequest request) {
}
/**
* 个人中心
*/
@At("/personCenter")
@Ok("beetl:/layouts/v4/personCenter.html")
@SaCheckLogin
public void personCenter(){
}
}
@@ -0,0 +1,49 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.DateUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.services.SysLogService;
import org.apache.commons.lang3.StringUtils;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
;
/**
* Created by wizzer on 2016/6/29.
*/
@IocBean
@At("/platform/sys/log")
public class SysLogController {
private static final Log log = Logs.get();
@Inject
private SysLogService sysLogService;
@At("")
@Ok("beetl:/platform/sys/log/index.html")
@SaCheckPermission("sys.manager.log")
public void index(HttpServletRequest req) {
req.setAttribute("today", DateUtil.getDate());
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.log")
public Object data(@Param("searchDate") String searchDate, @Param("searchType") String searchType, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
String[] date = StringUtils.split(searchDate, ",");
return Result.success().addData(sysLogService.data(date, searchType, pageOrderName, PageUtil.getOrder(pageOrderBy), pageNumber, pageSize));
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,373 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.enums.LoginType;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.interceptor.sLog.SLogService;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.RsaUtils;
import com.budwk.app.sys.models.Sys_log;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.service.ValidateService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.validation.Assertion;
import org.nutz.dao.Cnd;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Filters;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@IocBean
@At("/platform/login")
@Ok("json:{locked:'password|createAt',ignoreNull:true}") // 忽略password和createAt属性,忽略空属性的json输出
@Api(tags = "登录")
public class SysLoginController {
private static final Log log = Logs.get();
private static final LoginRsaKeyRing LOGIN_RSA_KEY_RING = new LoginRsaKeyRing();
/**
* TODO: 临时屏蔽 localhost 平台登录验证码,恢复时改为 false。
*/
private static final boolean DISABLE_LOGIN_CAPTCHA = true;
@Inject
private SysUserService sysUserService;
@Inject
private RedisService redisService;
@Inject
private SLogService sLogService;
@Inject
private ValidateService validateService;
@Inject
protected PropertiesProxy conf;
@At("")
@Ok("re")
@ApiOperation("用户本地登录页面")
@Filters
public String login(HttpServletRequest req, HttpSession session) {
return "beetl:/platform/sys/login.html";
}
@At
@Ok("re")
@Filters
public String h5() {
return "beetl:/platform/sys/login.html";
}
@At("/noPermission")
@Ok("beetl:/platform/sys/noPermission.html")
@Filters
public void noPermission() {
}
@At("/doLogin")
@Ok("json")
@ApiOperation("用户本地账号密码登录")
public Object doLogin(@Param("username") String username,
@Param("password") String password,
@Param("platformKey") String captchaKey,
@Param("platformCaptcha") String captchaCode,
@Param("keyId") String keyId,
HttpServletRequest req,
HttpServletResponse response,
HttpSession session) {
if (StrUtil.isBlank(username)) {
return Result.error("用户名不能为空");
}
if (StrUtil.isBlank(password)) {
return Result.error("密码不能为空");
}
if (StrUtil.isBlank(keyId)) {
return Result.error("参数缺失");
}
String lockKey = RedisConstant.USER_LOGIN_LOCK_PREFIX + username;
int errCount = Convert.toInt(StrUtil.blankToDefault(redisService.get(lockKey), "0"));
log.info("用户名:" + username + "登录失败次数:" + errCount);
if (errCount > 5) {
redisService.setex(lockKey, 5 * 60, String.valueOf(errCount + 1));
return Result.error("登录失败次数过多,请5分钟后再试");
}
try {
// 验证码校验
if (!isLoginCaptchaDisabled(req)) {
try {
validateService.checkCode(captchaKey, captchaCode);
} catch (BaseException e) {
return Result.error(e.getMessage());
}
}
// 解密密码
LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.getPrivateKey(keyId);
if (rsaKey == null) {
throw new BaseException("Login key expired, please refresh the login page");
}
String decryptPwd = RsaUtils.decrypt(password, rsaKey.privateKey);
if (decryptPwd == null) {
throw new BaseException("用户登录失败");
}
decryptPwd = Base64Encoder.encode(decryptPwd);
// 用户名密码校验
Sys_user user = sysUserService.loginByPassword(username, decryptPwd);
if (user == null) {
throw new BaseException("用户登录失败");
}
// 成功登录
sysUserService.loginPlus(user, LoginType.PC_LOCAL, req);
return Result.success("login.success");
} catch (Exception e) {
log.error(e.getMessage(), e);
redisService.set(lockKey, Convert.toStr(errCount + 1));
String message = e.getMessage();
return Result.error(e.getMessage());
}
}
private boolean isLoginCaptchaDisabled(HttpServletRequest req) {
if (!DISABLE_LOGIN_CAPTCHA || req == null) {
return false;
}
String serverName = req.getServerName();
return "localhost".equalsIgnoreCase(serverName)
|| "127.0.0.1".equals(serverName)
|| "0:0:0:0:0:0:0:1".equals(serverName)
|| "::1".equals(serverName);
}
@At(value = "/platform/sso/login", top = true)
@Ok("re")
@ApiOperation("用户cas登录统一入口")
public String ssoLogin(HttpSession httpSession, HttpServletRequest request, HttpServletResponse response) {
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
if (null == assertion || assertion.getPrincipal() == null) {
return ">>:/platform/home";
}
String loginName = assertion.getPrincipal().getName();
sysUserService.checkThirdPlatformLoginName(loginName);
Sys_user sysUser = sysUserService.loginByLoginName(loginName);
return ">>:" + sysUserService.loginPlus(sysUser, LoginType.CAS, request);
}
@At(value = "/platform/wxwork/oauth2/callback", top = true)
@Ok("re")
@ApiOperation("企业微信登录回调")
public String wxworkOAuth2(@Param("code") String code, @Param("redirect") String redirect, HttpServletRequest request) {
if (StrUtil.isBlank(code)) {
return ">>:/platform/home";
}
String token = redisService.get(RedisConstant.REDIS_KEY_WX_WORK_TOKEN);
if (StrUtil.isBlank(token)) {
return ">>:/platform/home";
}
String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";
url = url.replace("ACCESS_TOKEN", token).replace("CODE", code);
String response = HttpUtil.get(url);
JSONObject jsonObject = JSONUtil.parseObj(response);
if (jsonObject.getInt("errcode") == 0) {
String loginName = jsonObject.getStr("userid");
sysUserService.checkThirdPlatformLoginName(loginName);
Sys_user sysUser = sysUserService.loginByLoginName(loginName);
return ">>:" + sysUserService.loginPlus(sysUser, LoginType.QI_YE_WECHAT, request);
} else {
return ">>:/platform/home/500";
}
}
@At(value = "/platform/wx/oauth2/callback", top = true)
@Ok("re")
@ApiOperation("微信登录回调")
public String wxOauth2(@Param("code") String code, HttpServletRequest request) {
if (StrUtil.isBlank(code)) {
return ">>:/platform/home";
}
try {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
url = url.replace("APPID", conf.get("wx.appID")).replace("SECRET", conf.get("wx.appSecret")).replace("CODE", code);
String response = HttpUtil.get(url);
JSONObject jsonObject = JSONUtil.parseObj(response);
String openid = jsonObject.getStr("openid");
Sys_user sysUser = sysUserService.fetch(Cnd.where(Sys_user::getWxOpenId, "=", openid));
if (sysUser == null) {
//没有绑定统一身份认证账号 跳过去绑定
String redirect = request.getParameter("redirect");
String callBackUrl = conf.get("cas.client-host-url") + conf.get("cas.client-call-back-url") + "?redirect=" + URLEncoder.encode(redirect, StandardCharsets.UTF_8) + "&wxOpenId=" + openid;
String authUrl = conf.get("cas.server-login-url") + "?service=" + URLEncoder.encode(callBackUrl, StandardCharsets.UTF_8);
return ">>:" + authUrl;
} else {
//直接登录
return ">>:" + sysUserService.loginPlus(sysUser, LoginType.WECHAT, request);
}
} catch (Exception e) {
e.printStackTrace();
return ">>:/platform/home/500";
}
}
@At
@Ok("re")
@ApiOperation("用户退出系统")
public void logout(HttpSession session, HttpServletRequest req, HttpServletResponse response) {
try {
if (StrUtil.isNotBlank(SecurityUtil.getUserId())) {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
StpUtil.logout();
if (user != null) {
Sys_log sysLog = new Sys_log();
sysLog.setType("info");
sysLog.setTag("用户登出");
sysLog.setSrc(this.getClass().getName() + "#logout");
sysLog.setMsg("成功退出系统!");
sysLog.setIp(Lang.getIP(req));
sysLog.setCreatedBy(user.getId());
sysLog.setUsername(user.getUsername());
sysLog.setLoginname(user.getLoginname());
sLogService.async(sysLog);
}
}
session.invalidate();
if (conf.getBoolean("cas.enable", false)) {
response.sendRedirect(conf.get("cas.server-url-prefix") + "/logout?service=" + URLEncoder.encode(Globals.AppDomain, StandardCharsets.UTF_8));
} else {
response.sendRedirect(Globals.AppDomain);
}
} catch (Exception e) {
log.debug("Logout error", e);
}
}
@At("/captcha")
@Ok("json")
@ApiOperation("获取验证码")
public Object next() {
return Result.success(validateService.getCaptcha());
}
@At("/publicKey")
@Ok("json")
@ApiOperation("获取公钥")
public Object publicKey() {
try {
LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.currentKey();
return Result.success(Map.of(
"publicKey", rsaKey.publicKey,
"keyId", rsaKey.keyId,
"expireAt", rsaKey.encryptExpireAt
));
} catch (Exception e) {
log.error("生成 RSA 密钥失败", e);
return Result.error("系统异常");
}
}
private static class LoginRsaKeyRing {
private static final long ACTIVE_MILLIS = 30 * 60 * 1000L;
private static final long DECRYPT_GRACE_MILLIS = 10 * 60 * 1000L;
private final ConcurrentHashMap<String, LoginRsaKey> keys = new ConcurrentHashMap<>();
private volatile LoginRsaKey current;
LoginRsaKey currentKey() throws Exception {
long now = System.currentTimeMillis();
LoginRsaKey key = current;
if (key != null && now < key.encryptExpireAt) {
return key;
}
synchronized (this) {
key = current;
now = System.currentTimeMillis();
if (key == null || now >= key.encryptExpireAt) {
key = generateKey(now);
current = key;
keys.put(key.keyId, key);
cleanup(now);
}
return key;
}
}
LoginRsaKey getPrivateKey(String keyId) {
if (StrUtil.isBlank(keyId)) {
return null;
}
long now = System.currentTimeMillis();
LoginRsaKey key = keys.get(keyId);
if (key == null) {
return null;
}
if (now >= key.decryptExpireAt) {
keys.remove(keyId);
return null;
}
return key;
}
private LoginRsaKey generateKey(long now) throws Exception {
KeyPair keyPair = RsaUtils.generateKeyPair();
String keyId = UUID.randomUUID().toString().replace("-", "");
return new LoginRsaKey(
keyId,
RsaUtils.getPublicKeyBase64(keyPair.getPublic()),
keyPair.getPrivate(),
now + ACTIVE_MILLIS,
now + ACTIVE_MILLIS + DECRYPT_GRACE_MILLIS
);
}
private void cleanup(long now) {
keys.entrySet().removeIf(entry -> now >= entry.getValue().decryptExpireAt);
}
}
private static class LoginRsaKey {
private final String keyId;
private final String publicKey;
private final PrivateKey privateKey;
private final long encryptExpireAt;
private final long decryptExpireAt;
private LoginRsaKey(String keyId, String publicKey, PrivateKey privateKey, long encryptExpireAt, long decryptExpireAt) {
this.keyId = keyId;
this.publicKey = publicKey;
this.privateKey = privateKey;
this.encryptExpireAt = encryptExpireAt;
this.decryptExpireAt = decryptExpireAt;
}
}
}
@@ -0,0 +1,458 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_menu;
import com.budwk.app.sys.models.Sys_module;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
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.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@IocBean
@At("/platform/sys/menu")
public class SysMenuController {
private static final Log log = Logs.get();
@Inject
private SysMenuService sysMenuService;
@Inject
private SysUserService sysUserService;
@Inject
private SysRoleService sysRoleService;
@At("")
@Ok("beetl:/platform/sys/menu/index.html")
@SaCheckPermission("sys.manager.menu")
public void index(HttpServletRequest req) {
}
@At("/child")
@Ok("json")
@SaCheckLogin
public Object child(@Param("pid") String pid, String menuName, String platform, String moduleId, HttpServletRequest req) {
List<Sys_menu> list;
List<NutMap> treeList = new ArrayList<>();
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and(Cnd.exps("parentId", "=", "").or("parentId", "is", null));
} else {
cnd.and("parentId", "=", pid);
}
if (StrUtil.isNotBlank(menuName)) {
cnd.and(Cnd.likeEX("`name`", menuName));
}
cnd.andEX(Sys_menu::getPlatform, "=", platform);
cnd.andEX(Sys_menu::getModuleId, "=", moduleId);
cnd.asc("location").asc("path");
list = sysMenuService.query(cnd);
for (Sys_menu menu : list) {
if (sysMenuService.count(Cnd.where("parentId", "=", menu.getId())) > 0) {
menu.setHasChildren(true);
}
NutMap map = Lang.obj2nutmap(menu);
map.put("expanded", false);
map.put("children", new ArrayList<>());
treeList.add(map);
}
return Result.success().addData(treeList);
}
@At("/tree")
@Ok("json")
@SaCheckLogin
public Object tree(@Param("pid") String pid, @Valid @Param("platform") String platform, HttpServletRequest req) {
try {
List<NutMap> treeList = new ArrayList<>();
if (Strings.isBlank(pid)) {
NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择菜单").addv("leaf", true);
treeList.add(root);
}
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and(Cnd.exps("parentId", "=", "").or("parentId", "is", null));
} else {
cnd.and("parentId", "=", pid);
}
cnd.and("type", "=", "menu");
cnd.asc("location").asc("path");
List<Sys_menu> list = sysMenuService.query(cnd);
for (Sys_menu menu : list) {
NutMap map = NutMap.NEW().addv("value", menu.getId()).addv("label", menu.getName());
if (menu.isHasChildren()) {
map.addv("children", new ArrayList<>());
map.addv("leaf", false);
} else {
map.addv("leaf", true);
}
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu")
public Result fullTree(@Valid String platform) {
List<Sys_menu> menus = sysMenuService.query(Cnd.where(Sys_menu::getPlatform, "=", platform)
.and(Sys_menu::getType, "=", "menu")
.and(Sys_menu::getPlatform, "=", platform)
.asc(Sys_menu::getLocation)
);
List<TreeNode<String>> nodeList = CollUtil.newArrayList();
for (int i = 0; i < menus.size(); i++) {
nodeList.add(new TreeNode<>(menus.get(i).getId(), menus.get(i).getParentId(), menus.get(i).getName(), i));
}
List<Tree<String>> treeList = TreeUtil.build(nodeList, "");
return Result.success(treeList);
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu.add")
@SLog(tag = "新建菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object addDo(@Param("menu") Sys_menu sysMenu, @Valid String platform, HttpServletRequest req) {
try {
int num = sysMenuService.count(Cnd.where("permission", "=", sysMenu.getPermission().trim()));
if (num > 0) {
return Result.error("sys.role.code");
}
if (ObjectUtil.isNotEmpty(sysMenu.getButtons())) {
for (Sys_menu button : sysMenu.getButtons()) {
int buttonNum = sysMenuService.count(Cnd.where("permission", "=", button.getPermission()));
if (buttonNum > 0) {
return Result.error("sys.role.code");
}
}
}
String parentId = sysMenu.getParentId();
if ("root".equals(sysMenu.getParentId())) {
parentId = "";
}
sysMenu.setType("menu");
sysMenu.setPlatform(platform);
sysMenu.setHasChildren(false);
sysMenu.setShowit(true);
sysMenu.setDisabled(false);
sysMenu.setCreatedBy(SecurityUtil.getUserId());
sysMenu.setInitialPinyinName(PinyinUtil.getFirstLetter(sysMenu.getName().charAt(0)));
sysMenuService.savePlus(sysMenu, Strings.sNull(parentId), sysMenu.getButtons());
// sysMenuService.save(sysMenu, Strings.sNull(parentId), buttons);
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
//编辑菜单,组装一下js表单数据
@At("/editMenu/?")
@Ok("json")
@SaCheckPermission("sys.manager.menu")
public Object editMenu(String id, HttpServletRequest req) {
try {
Sys_menu menu = sysMenuService.fetch(id);
NutMap map = Lang.obj2nutmap(menu);
map.put("moduleId", menu.getModuleId());
map.put("parentName", "");
map.put("children", "false");
if (Strings.isNotBlank(menu.getParentId())) {
map.put("parentName", sysMenuService.fetch(menu.getParentId()).getName());
//找出所有的父节点id
List<String> parentIds = new ArrayList<>();
while (Strings.isNotBlank(menu.getParentId())) {
menu = sysMenuService.fetch(menu.getParentId());
//始终加到第一个 element要求这样
parentIds.add(0, menu.getId());
}
map.put("parentIds", parentIds);
}
List<Sys_menu> list = sysMenuService.query(Cnd.where("parentId", "=", id).and("type", "=", "data").asc("location").asc("path"));
List<NutMap> buttons = new ArrayList<>();
if (list != null && list.size() > 0) {
map.put("children", "true");
for (Sys_menu m : list) {
buttons.add(NutMap.NEW().addv("key", m.getId()).addv("id", m.getId()).addv("name", m.getName()).addv("permission", m.getPermission()));
}
}
map.put("buttons", buttons);
return Result.success().addData(map);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
@SLog(tag = "修改菜单")
public Object editMenuDo(@Param("menu") Sys_menu sysMenu, @Valid String platform) {
try {
if (StrUtil.isNotBlank(sysMenu.getParentId()) && sysMenu.getId().equals(sysMenu.getParentId())) {
return Result.error("禁止套娃");
}
List<Sys_menu> buttons = sysMenu.getButtons();
//如果权限标识不是自己的,并且被其他记录占用
int num = sysMenuService.count(Cnd.where(Sys_menu::getPermission, "=", sysMenu.getPermission().trim()).and("id", "<>", sysMenu.getId()));
if (num > 0) {
return Result.error("sys.role.code");
}
for (Sys_menu button : buttons) {
num = sysMenuService.count(Cnd.where("permission", "=", button.getPermission()).and("id", "<>", StrUtil.blankToDefault(button.getId(), "")));
if (num > 0) {
return Result.error("sys.role.code");
}
}
sysMenu.setType("menu");
sysMenu.setPlatform(platform);
sysMenu.setHasChildren(false);
sysMenu.setShowit(true);
sysMenu.setDisabled(false);
sysMenu.setCreatedBy(SecurityUtil.getUserId());
sysMenu.setInitialPinyinName(PinyinUtil.getFirstLetter(sysMenu.getName().charAt(0)));
sysMenuService.editPlus(sysMenu, sysMenu.getParentId(), buttons);
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
@At("/editData/?")
@Ok("json")
@SaCheckPermission("sys.manager.menu")
public Object editData(String id, HttpServletRequest req) {
try {
return Result.success().addData(sysMenuService.fetch(id));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
@SLog(tag = "修改权限", msg = "权限名称:${args[0].name}")
public Object editDataDo(@Param("..") Sys_menu menu, HttpServletRequest req) {
try {
int num = sysMenuService.count(Cnd.where("permission", "=", menu.getPermission().trim()).and("id", "<>", menu.getId()));
if (num > 0) {
return Result.error("sys.role.code");
}
sysMenuService.updateIgnoreNull(menu);
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.menu.delete")
@SLog(tag = "删除菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object delete(String id, HttpServletRequest req) {
try {
Sys_menu menu = sysMenuService.fetch(id);
req.setAttribute("name", menu.getName());
if (menu.getPath().startsWith("0001")) {
return Result.error("system.not.allow");
}
sysMenuService.deleteAndChild(menu);
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
@SLog(tag = "启用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object enable(String menuId, HttpServletRequest req) {
try {
req.setAttribute("name", sysMenuService.fetch(menuId).getName());
sysMenuService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", menuId));
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
@SLog(tag = "禁用菜单", msg = "菜单名称:${args[1].getAttribute('name')}")
public Object disable(String menuId, HttpServletRequest req) {
try {
req.setAttribute("name", sysMenuService.fetch(menuId).getName());
sysMenuService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", menuId));
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/menuAll")
@Ok("json")
@SaCheckPermission("sys.manager.menu")
public Object menuAll(@Valid String platform, HttpServletRequest req) {
try {
List<Sys_menu> list = sysMenuService.query(
Cnd.where(Sys_menu::getType, "=", "menu")
.and(Sys_menu::getPlatform, "=", platform)
.asc(Sys_menu::getLocation).asc("path"));
NutMap menuMap = NutMap.NEW();
for (Sys_menu unit : list) {
List<Sys_menu> list1 = menuMap.getList(unit.getParentId(), Sys_menu.class);
if (list1 == null) {
list1 = new ArrayList<>();
}
list1.add(unit);
menuMap.put(unit.getParentId(), list1);
}
return Result.success().addData(getTree(menuMap, ""));
} catch (Exception e) {
return Result.error();
}
}
private List<NutMap> getTree(NutMap menuMap, String pid) {
List<NutMap> treeList = new ArrayList<>();
List<Sys_menu> subList = menuMap.getList(pid, Sys_menu.class);
for (Sys_menu menu : subList) {
NutMap map = Lang.obj2nutmap(menu);
map.put("label", menu.getName());
if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
map.put("children", getTree(menuMap, menu.getId()));
}
treeList.add(map);
}
return treeList;
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
public Object sortDo(@Param("ids") String ids, @Param("platform") String platform, HttpServletRequest req) {
try {
String[] menuIds = StringUtils.split(ids, ",");
int i = 0;
sysMenuService.execute(Sqls.create("update sys_menu set location=0 where platform = '%s'".formatted(platform)));
for (String s : menuIds) {
if (!Strings.isBlank(s)) {
sysMenuService.update(org.nutz.dao.Chain.make("location", i), Cnd.where("id", "=", s));
i++;
}
}
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu.edit")
public Object updateLocation(String id, Integer location) {
try {
if (StrUtil.isBlank(id) || location == null || location < 0) {
return Result.error("排序编码必须是非负整数");
}
sysMenuService.update(Chain.make("location", location), Cnd.where("id", "=", id));
sysMenuService.clearCache();
sysUserService.clearCache();
sysRoleService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu")
public Result listModule(String platform) {
List<Sys_module> list = sysMenuService.dao().query(Sys_module.class, Cnd.where(Sys_module::getPlatform, "=", platform).asc(Sys_module::getSortNum));
return Result.success(list);
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.menu")
@ApiOperation("更新首页推荐应用或服务")
public Result updateRecommendSetting(@Param("menuIds") String[] menuIds, String platform, String type) {
String column = "";
switch (type) {
case "app" -> column = "isRecommendApp";
case "service" -> column = "isRecommendService";
}
sysMenuService.update(Chain.make(column, 0), Cnd.where("id", "is not", null).and("platform", "=", platform));
if (ArrayUtil.isNotEmpty(menuIds)) {
sysMenuService.update(Chain.make(column, 1), Cnd.where("id", "in", menuIds).and("platform", "=", platform));
}
return Result.success();
}
}
@@ -0,0 +1,79 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
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.service.BaseService;
import com.budwk.app.sys.models.Sys_module;
import io.swagger.annotations.Api;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
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 javax.validation.Valid;
@Api(tags = "系统模块管理")
@IocBean
@At("/platform/sys/module")
@Ok("json:full")
public class SysModuleController {
@Inject
private Dao dao;
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/sys/module/index.html")
@SaCheckPermission("sys.manager.module")
public void index() {
}
@At
@SaCheckLogin
@SaCheckPermission("sys.manager.module")
public Object pageData(@Valid PageForm pageForm, @Valid String platform) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.where().andLike(Sys_module::getName, pageForm.getSearchKeyword());
}
cnd.and(Sys_module::getPlatform, "=", platform);
cnd.asc(Sys_module::getSortNum);
Pagination<Sys_module> pagination = baseService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), Sys_module.class, cnd);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.manager.module")
public Object insert(Sys_module module) {
Integer maxNum = (Integer) dao.func2(Sys_module.class, "max", "sortNum");
if (maxNum == null) {
maxNum = 0;
}
module.setSortNum(maxNum + 1);
dao.insert(module);
return Result.success();
}
@At
@SaCheckPermission("sys.manager.module")
public Object update(Sys_module module) {
dao.update(module);
return Result.success();
}
@At
@SaCheckPermission("sys.manager.module")
public Object delete(@Valid String id) {
dao.delete(Sys_module.class, id);
return Result.success();
}
}
@@ -0,0 +1,223 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
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.RepeatSubmit;
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.PageUtil;
import com.budwk.app.sys.models.Sys_msg;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.sys.services.SysMsgUserService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
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.Static;
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;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
@IocBean
@At("/platform/sys/msg")
@Api(tags = "系统消息")
@Slf4j
public class SysMsgController {
@Inject
private SysMsgService sysMsgService;
@Inject
private SysMsgUserService sysMsgUserService;
@Inject
private SysUserService sysUserService;
@At({"/", "/list/?"})
@Ok("beetl:/platform/sys/msg/index.html")
@SaCheckPermission("sys.manager.msg")
public void index(String type, HttpServletRequest req) {
req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.msg")
public Object data(@Param("searchType") String searchType, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Sql sql = Sqls.create("""
SELECT
msg.*,
u.username,
count( msgu.id ) all_num,
sum( CASE WHEN msgu.STATUS = 0 THEN 1 ELSE 0 END ) unread_num
FROM
sys_msg msg
LEFT JOIN sys_user u ON u.id = msg.createdBy
LEFT JOIN sys_msg_user msgu ON msgu.msgId = msg.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.groupBy("msg.id");
if (Strings.isNotBlank(searchType) && !"all".equals(searchType)) {
cnd.and("msg.type", "=", searchType);
}
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
}
cnd.and("msg.sendType", "!=", "hide");
cnd.desc("msg.sendAt");
sql.setCondition(cnd);
Pagination pagination = sysMsgService.listPageMap(pageNumber, pageSize, sql);
return Result.success().addData(pagination);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.msg")
public Object getRoleList() {
List<Sys_role> roles = sysUserService.dao().query(Sys_role.class, Cnd.NEW());
return Result.success(roles);
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.msg")
public Object user_view_data(PageForm pageForm,
@Param("type") String type,
@Param("unionId") String unionId,
@Param("unitId") String unitId,
@Param("id") String id) {
try {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
u.username,
u.loginname,
u.sex,
u.mobile,
u.email,
u.unitid,
u.unitname,
u.unionname,
m.STATUS,
m.readat
FROM
vw_user u, sys_msg_user m
$condition
""");
cnd.and(new Static("u.loginname = m.loginname"));
cnd.and("m.msgId", "=", id);
cnd.andEX("u.unionId", "=", unionId);
cnd.andEX("u.unitId", "=", unitId);
if (Strings.isNotBlank(type) && "unread".equals(type)) {
cnd.and("m.status", "=", 0);
}
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(pageForm.getSearchName(), "like", "%" + pageForm.getSearchKeyword() + "%");
}
if (Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
} else {
cnd.desc("unitId");
}
sql.setCondition(cnd);
return Result.success().addData(sysMsgService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
} catch (Exception e) {
return Result.error();
}
}
@At("/addDo")
@Ok("json")
@SaCheckPermission("sys.manager.msg.add")
@SLog(tag = "站内消息", msg = "${args[0].title}")
@ApiOperation("发送站内消息")
@RepeatSubmit
public Object addDo(@Param("msg") @Valid Sys_msg msg, @Param("users") String[] users) {
try {
if (ObjectUtil.isEmpty(users)) {
return Result.error("请选择用户");
}
if (users.length > 100) {
return Result.error("单条消息最多发送100人,请分批次发送。");
}
msg.setType("user");
if ("user".equalsIgnoreCase(msg.getType()) && ObjectUtil.isEmpty(users)) {
return Result.error("请选择用户");
}
msg.setSendType("show");
msg.setSendAt(DateUtil.current());
msg.setCreatedBy(SecurityUtil.getUserId());
sysMsgService.saveMsg(msg, users,true);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:{locked:'password|salt',ignoreNull:false}")
@SaCheckLogin
public Object user_data(@Valid PageForm pageForm, String unionId, String unitId, String roleId, String sex) {
try {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
select u.id,u.username,u.loginname,u.sex,u.mobile,u.unitname,u.unionname,u.userState,u.personType,u.preparedBy from vw_user u $condition
""");
cnd.andEX("u.unionId", "=", unionId);
cnd.andEX("u.unitId", "=", unitId);
cnd.andEX("u.sex", "=", sex);
if (StrUtil.isNotBlank(roleId)) {
cnd.and(new Static("u.id in (select userId from sys_user_role where roleId = '%s')".formatted(roleId)));
}
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(pageForm.getSearchName(), "like", "%" + pageForm.getSearchKeyword() + "%");
}
if (Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())) {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
return Result.success().addData(sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
} catch (Exception e) {
return Result.error();
}
}
@At({"/delete/?"})
@Ok("json")
@SaCheckPermission("sys.manager.msg.delete")
@SLog(tag = "站内消息", msg = "站内信标题:${req.getAttribute('title')}")
public Object delete(String id, HttpServletRequest req) {
try {
req.setAttribute("title", sysMsgService.fetch(id).getTitle());
sysMsgService.deleteMsg(id);
sysMsgUserService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,97 @@
package com.budwk.app.sys.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.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_msg;
import com.budwk.app.sys.param.SysMsgSummaryPageForm;
import com.budwk.app.sys.services.SysMsgUserSummaryService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.Api;
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.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
@IocBean
@Ok("json")
@At("/platform/sys/msg/summary")
@Api(tags = "消息统计")
public class SysMsgSummaryController {
@Inject
private Dao dao;
@Inject
private BaseService baseService;
@Inject
private SysMsgUserSummaryService sysMsgUserSummaryService;
@At("")
@Ok("beetl:/platform/sys/msg/summary/index.html")
@SaCheckPermission("sys.msg.summary")
public void index() {
}
@At
@SaCheckPermission("sys.msg.summary")
public Result pageData(@Valid PageForm pageForm, String msgId, String unionId, String unitId, Integer readStatus) {
if (StrUtil.isBlank(msgId)) {
return Result.success(new Pagination<>());
}
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
mu.*,
m.needBack
FROM
sys_msg_user mu
LEFT JOIN sys_msg m ON m.id = mu.msgId
$condition
""");
cnd.and("mu.msgId", "=", msgId);
// cnd.and("m.createdBy", "=", SecurityUtil.getUserId());
cnd.andEX("mu.unionId", "=", unionId);
cnd.andEX("mu.unitId", "=", unitId);
cnd.andEX("mu.status", "=", readStatus);
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(pageForm.getSearchName(), "like", "%" + pageForm.getSearchKeyword() + "%");
}
cnd.asc("mu.status").asc("mu.unionId");
sql.setCondition(cnd);
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.msg.summary")
public Result getMsg(String searchType) {
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(searchType) && !"all".equals(searchType)) {
cnd.and("type", "=", searchType);
}
cnd.and("sendType","!=","hide");
List<Sys_msg> sysMsgs = dao.query(Sys_msg.class, cnd);
return Result.success(sysMsgs);
}
@At
@Ok("void")
@SaCheckPermission("sys.msg.summary")
@ApiOperation("导出反馈附件压缩包")
public void exportMultipleAsZip(@Valid SysMsgSummaryPageForm pageForm, HttpServletResponse response) {
sysMsgUserSummaryService.exportMultipleAsZip(pageForm, response);
}
}
@@ -0,0 +1,274 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_msg_user;
import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.sys.services.SysMsgUserService;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Chain;
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.json.Json;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
@IocBean
@At("/platform/sys/msg/user")
public class SysMsgUserController {
private static final Log log = Logs.get();
@Inject
private SysMsgUserService sysMsgUserService;
@Inject
private SysMsgService sysMsgService;
@At("/all")
@Ok("beetl:/platform/sys/msg/user/indexAll.html")
@SaCheckPermission("sys.msg.all")
public void index(@Param("type") String type, HttpServletRequest req) {
req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
}
@At("/read")
@Ok("beetl:/platform/sys/msg/user/indexRead.html")
@SaCheckPermission("sys.msg.read")
@ApiOperation("已读消息页面")
public void read(@Param("type") String type, HttpServletRequest req) {
req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
}
@At("/unread")
@Ok("beetl:/platform/sys/msg/user/indexUnread.html")
@SaCheckPermission("sys.msg.unread")
@ApiOperation("未读消息页面")
public void unread(@Param("type") String type, HttpServletRequest req) {
req.setAttribute("type", Strings.isBlank(type) ? "all" : type);
}
@At("/data/?")
@Ok("json:full")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public Object data(String status, @Param("searchType") String type, PageForm pageForm) {
try {
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(status) && "read".equals(status)) {
cnd.and("a.status", "in", List.of(1, 2));
}
if (Strings.isNotBlank(status) && "unread".equals(status)) {
cnd.and("a.status", "=", 0);
}
cnd.and("a.loginname", "=", SecurityUtil.getUserLoginname());
cnd.and("a.delFlag", "=", false);
cnd.desc("a.createdAt");
if (Strings.isNotBlank(type) && !"all".equals(type)) {
cnd.and("b.type", "=", type);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name())) {
cnd.and("a.loginname", "=", SecurityUtil.getUserLoginname());
}
Sql sql = Sqls.create("SELECT b.needBack,b.type,b.title,b.note,b.url,b.sendAt,a.* FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgid $condition");
sql.setCondition(cnd);
Sql sqlCount = Sqls.create("SELECT count(*) FROM sys_msg b LEFT JOIN sys_msg_user a ON b.id=a.msgid $condition");
sqlCount.setCondition(cnd);
return Result.success().addData(sysMsgService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql, sqlCount));
} catch (Exception e) {
return Result.error();
}
}
@At({"/delete/?", "/delete"})
@Ok("json")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
@SLog(tag = "站内消息", msg = "${req.getAttribute('id')}")
public Object delete(String id, @Param("ids") String[] ids, HttpServletRequest req) {
try {
if (ids != null && ids.length > 0) {
sysMsgUserService.update(Chain.make("delFlag", true)
.add("updatedAt", System.currentTimeMillis())
.add("updatedBy", SecurityUtil.getUserId()), Cnd.where("id", "in", ids).and("loginname", "=", SecurityUtil.getUserLoginname()));
req.setAttribute("id", Arrays.toString(ids));
} else {
sysMsgUserService.update(Chain.make("delFlag", true)
.add("updatedAt", System.currentTimeMillis())
.add("updatedBy", SecurityUtil.getUserId()), Cnd.where("id", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
req.setAttribute("id", id);
}
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckLogin
@ApiOperation("未读消息数")
public Object unread_num() {
try {
int num = sysMsgUserService.getUnreadNum(SecurityUtil.getUserLoginname());
return Result.success().addData(num);
// NutMap nutMap = NutMap.NEW();
// nutMap.put("system", sysMsgUserService.count(Sqls.create("SELECT count(*) from sys_msg a,sys_msg_user b WHERE a.id=b.msgId AND a.type='system' AND a.delFlag=false AND b.status=0 AND b.delFlag=false AND b.loginname=@loginname").setParam("loginname", SecurityUtil.getUserLoginname())));
// nutMap.put("user", sysMsgUserService.count(Sqls.create("SELECT count(*) from sys_msg a,sys_msg_user b WHERE a.id=b.msgId AND a.type='user' AND a.delFlag=false AND b.status=0 AND b.delFlag=false AND b.loginname=@loginname").setParam("loginname", SecurityUtil.getUserLoginname())));
// return Result.success().addData(nutMap);
} catch (Exception e) {
return Result.error();
}
}
@At("/status/read")
@Ok("json")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
@SLog(tag = "站内消息", msg = "${req.getAttribute('id')}")
public Object read(@Param("ids") String[] ids, HttpServletRequest req) {
try {
sysMsgUserService.update(Chain.make("status", 1).add("readAt", Times.getTS())
.add("createdAt", System.currentTimeMillis())
.add("createdBy", SecurityUtil.getUserId()), Cnd.where("id", "in", ids).and("loginname", "=", SecurityUtil.getUserLoginname()));
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
req.setAttribute("id", Arrays.toString(ids));
return Result.success("system.success");
} catch (Exception e) {
return Result.error("system.error");
}
}
@At("/status/readAll")
@Ok("json")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
@SLog(tag = "站内消息", msg = "readAll")
public Object readAll(HttpServletRequest req) {
try {
sysMsgUserService.update(Chain.make("status", 1).add("readAt", Times.getTS())
.add("createdAt", System.currentTimeMillis()).add("createdBy", SecurityUtil.getUserId()), Cnd.where("loginname", "=", SecurityUtil.getUserLoginname()));
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/findOne")
@Ok("json")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public Result findOne(String id) {
if (StrUtil.isBlank(id)) {
return Result.error("参数为空");
}
Sys_msg_user msgUser = sysMsgUserService.fetch(Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
if (msgUser != null) {
if (msgUser.getStatus() != 2) {
sysMsgUserService.update(Chain.make("status", 1), Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
}
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
// sysMsgService.getMsg(SecurityUtil.getUserLoginname());
return Result.success(sysMsgService.fetch(id));
} else {
return Result.error("暂无消息可查看");
}
}
@At("/backDo")
@Ok("json")
@ApiOperation("反馈附件")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public Result backDo(@Valid String id, String backText, String files) {
List<JSONObject> fileList = StrUtil.isNotBlank(files) ? Json.fromJsonAsList(JSONObject.class, files) : List.of();
sysMsgUserService.update(
Chain.make("backFiles", fileList)
.add("backText", backText)
.add("status", 2), Cnd.where("id", "=", id));
return Result.success();
}
@At("/all/detail/?")
@Ok("beetl:/platform/sys/msg/user/detailAll.html")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public void allDetail(String id, HttpServletRequest req) {
if (!Strings.isBlank(id)) {
//判断用户是否是正常获取消息
int num = sysMsgUserService.count(Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
if (num > 0) {
req.setAttribute("obj", sysMsgService.fetch(id));
sysMsgUserService.update(Chain.make("status", 1), Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
} else {
req.setAttribute("obj", null);
}
} else {
req.setAttribute("obj", null);
}
}
@At("/read/detail/?")
@Ok("beetl:/platform/sys/msg/user/detailRead.html")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public void readDetail(String id, HttpServletRequest req) {
if (!Strings.isBlank(id)) {
//判断用户是否是正常获取消息
int num = sysMsgUserService.count(Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
if (num > 0) {
req.setAttribute("obj", sysMsgService.fetch(id));
sysMsgUserService.update(Chain.make("status", 1), Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
} else {
req.setAttribute("obj", null);
}
} else {
req.setAttribute("obj", null);
}
}
@At("/unread/detail/?")
@Ok("beetl:/platform/sys/msg/user/detailUnread.html")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
public void unreadDetail(String id, HttpServletRequest req) {
if (!Strings.isBlank(id)) {
//判断用户是否是正常获取消息
int num = sysMsgUserService.count(Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
if (num > 0) {
req.setAttribute("obj", sysMsgService.fetch(id));
sysMsgUserService.update(Chain.make("status", 1), Cnd.where("msgid", "=", id).and("loginname", "=", SecurityUtil.getUserLoginname()));
sysMsgUserService.deleteCache(SecurityUtil.getUserLoginname());
} else {
req.setAttribute("obj", null);
}
} else {
req.setAttribute("obj", null);
}
}
@At
@Ok("json")
@SaCheckPermission(value = {"sys.msg.all", "sys.msg.read", "sys.msg.unread"}, mode = SaMode.OR)
@ApiOperation("读取消息")
public Result readMsg(@Valid String msgId) {
sysMsgUserService.update(Chain.make("status", 1), Cnd.where("msgId", "=", msgId).and("loginname", "=", SecurityUtil.getUserLoginname()));
return Result.success();
}
}
@@ -0,0 +1,89 @@
package com.budwk.app.sys.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.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_office_template;
import com.budwk.app.sys.services.SysOfficeTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.boot.starter.ftp.FtpService;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
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 org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
/**
* office模板
*
* @author jug
* @date 2023/07/07
*/
@IocBean
@At("/platform/sys/officeTemplate")
@Ok("json:full")
@Slf4j
public class SysOfficeTemplateController {
@Inject
private Dao dao;
@Inject
private FtpService ftpService;
@Inject
private BaseService baseService;
@Inject
private SysOfficeTemplateService sysOfficeTemplateService;
@At("")
@Ok("beetl:/platform/sys/officeTemplate/index.html")
@SaCheckPermission("sys.manager.officeTemplate")
public void index(HttpServletRequest req) {
}
@At
@SaCheckPermission("sys.manager.officeTemplate")
public Object pageData(PageForm pageForm,
String templateName,
String templateCode) {
Cnd cnd = Cnd.NEW();
cnd.and(Cnd.likeEX("templateCode", templateCode));
Pagination pagination = sysOfficeTemplateService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.manager.officeTemplate")
public Object save(@Param("officeTemplate") Sys_office_template sysOfficeTemplate) {
if (StrUtil.isBlank(sysOfficeTemplate.getId())) {
int count = dao.count(Sys_office_template.class, Cnd.where("templateCode", "=", sysOfficeTemplate.getTemplateCode()));
if (count > 0) {
return Result.error("模板代码已存在!");
}
}
dao.insertOrUpdate(sysOfficeTemplate);
return Result.success();
}
@At
@SaCheckPermission("sys.manager.officeTemplate")
public Object delete(@Valid String id) {
// Sys_file sysFile = dao.fetch(Sys_file.class, Cnd.where("filepath", "=", sysOfficeTemplate.getTemplatePath()));
// if (Lang.isNotEmpty(sysFile)) {
// boolean delete = ftpService.delete(sysFile.getFilepath());
// if (!delete) {
// log.error("模板管理:文件删除失败,记录id:{}", sysOfficeTemplate.getId());
// throw new BaseException("模板管理:文件删除失败");
// }
// }
dao.delete(Sys_office_template.class, id);
return Result.success();
}
}
@@ -0,0 +1,27 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
@IocBean
@At("/platform/sys/quickEntry")
@Slf4j
@Ok("json:full")
@Api(tags = "系统首页快速入口管理")
public class SysQuickEntryController {
@At("")
@Ok("beetl:/platform/sys/quickEntry/index.html")
@SaCheckPermission("sys.manager.quickEntry")
public void index() {}
}
@@ -0,0 +1,562 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_menu;
import com.budwk.app.sys.models.Sys_module;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUnitService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
import org.nutz.aop.interceptor.ioc.TransAop;
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.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.GET;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wizzer on 2016/6/28.
*/
@IocBean
@At("/platform/sys/role")
public class SysRoleController {
private static final Log log = Logs.get();
@Inject
private SysUserService sysUserService;
@Inject
private SysMenuService sysMenuService;
@Inject
private SysUnitService sysUnitService;
@Inject
private SysRoleService sysRoleService;
@At("")
@Ok("beetl:/platform/sys/role/index.html")
@SaCheckPermission("sys.manager.role")
public void index() {
}
@At("/tree")
@Ok("json")
@SaCheckLogin
public Object tree(@Param("pid") String pid, HttpServletRequest req) {
try {
List<Sys_unit> list = new ArrayList<>();
List<NutMap> treeList = new ArrayList<>();
if (Strings.isBlank(pid)) {
NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择单位");
treeList.add(root);
}
if (StpUtil.hasRole("SYSADMIN")) {
if (Strings.isBlank(pid)) {
NutMap sys = NutMap.NEW().addv("value", "system").addv("label", "系统角色");
treeList.add(sys);
}
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
} else {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
if (user != null && Strings.isBlank(pid)) {
list = sysUnitService.query(Cnd.where("id", "=", user.getUnitId()).asc("path"));
} else {
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
}
}
for (Sys_unit unit : list) {
NutMap map = NutMap.NEW().addv("value", unit.getId()).addv("label", unit.getName());
if (unit.isHasChildren()) {
map.addv("children", new ArrayList<>());
}
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.role")
public Object pageData(@Param("searchUnit") String searchUnit,
@Param("moduleId") String moduleId,
@Param("searchName") String searchName,
@Param("searchKeyword") String searchKeyword,
@Param("searchName2") String searchName2,
@Param("searchKeyword2") String searchKeyword2,
@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize,
@Param("pageOrderName") String pageOrderName,
@Param("pageOrderBy") String pageOrderBy) {
try {
Sql sql = Sqls.create("""
SELECT
role.*, module.name AS moduleName
FROM
sys_role role
LEFT JOIN sys_module module ON module.id = role.moduleId
LEFT JOIN sys_user_role ur ON role.id = ur.roleId
LEFT JOIN sys_user u ON u.id = ur.userId
$condition
""");
Cnd cnd = Cnd.NEW();
if (StpUtil.hasRole("SYSADMIN")) {
if ("system".equals(searchUnit)) {
cnd.and("u.unitId", "=", "");
} else if (Strings.isNotBlank(searchUnit)) {
cnd.and("u.unitId", "=", searchUnit);
}
} else {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
if (Strings.isNotBlank(searchUnit)) {
Sys_unit unit = sysUnitService.fetch(searchUnit);
if (unit == null || !unit.getPath().startsWith(user.getUnit().getPath())) {
//防止有人越级访问
return Result.error("非法操作");
} else
cnd.and("u.unitId", "=", searchUnit);
} else {
cnd.and("u.unitId", "=", user.getUnitId());
}
}
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
cnd.and("role." + searchName, "like", "%" + searchKeyword + "%");
}
if (StrUtil.isAllNotBlank(searchName2, searchKeyword2)) {
cnd.and("u." + searchName2, "like", "%" + searchKeyword2 + "%");
}
if (StrUtil.isNotBlank(moduleId)) {
cnd.and("role.moduleId", "=", moduleId);
}
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
} else {
cnd.asc("role.sort");
}
cnd.groupBy("role.id");
sql.setCondition(cnd);
return Result.success().addData(sysRoleService.listPageMap(pageNumber, pageSize, sql));
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.role.edit")
@SLog(tag = "启用角色", msg = "角色名称:${args[1].getAttribute('name')}")
public Object enable(String roleId, HttpServletRequest req) {
try {
Sys_role role = sysRoleService.fetch(roleId);
sysRoleService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", roleId));
sysRoleService.clearCache();
sysUserService.clearCache();
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.role.edit")
@SLog(tag = "禁用角色", msg = "角色名称:${args[1].getAttribute('name')}")
public Object disable(String roleId, HttpServletRequest req) {
try {
Sys_role role = sysRoleService.fetch(roleId);
sysRoleService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", roleId));
sysRoleService.clearCache();
sysUserService.clearCache();
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
//加载当前用户所拥有的所有权限菜单
@At("/menuAll")
@Ok("json")
@SaCheckPermission("sys.manager.role")
public Object menuAll(HttpServletRequest req) {
try {
List<Sys_menu> list;
if (StpUtil.hasRole("SYSADMIN")) {
list = sysMenuService.query(Cnd.orderBy().asc("location").asc("path"));
} else {
list = sysUserService.getMenusAndButtons(SecurityUtil.getUserId());
}
NutMap menuMap = NutMap.NEW();
for (Sys_menu unit : list) {
List<Sys_menu> list1 = menuMap.getList(unit.getParentId(), Sys_menu.class);
if (list1 == null) {
list1 = new ArrayList<>();
}
list1.add(unit);
menuMap.put(unit.getParentId(), list1);
}
return Result.success().addData(getTree(menuMap, ""));
} catch (Exception e) {
return Result.error();
}
}
//加载可分配的权限菜单
@At("/menuRole/?/?")
@Ok("json")
@SaCheckPermission("sys.manager.role")
public Object menuRole(@Valid String roleId, @Valid String platform, HttpServletRequest req) {
try {
List<Sys_menu> hasList = sysRoleService.getMenusAndButtons(roleId, platform);
List<Sys_menu> list;
if (StpUtil.hasRole("SYSADMIN")) {
list = sysMenuService.query(Cnd.where(Sys_menu::getPlatform, "=", platform).asc("location").asc("path"));
} else {
list = sysUserService.getMenusAndButtons(SecurityUtil.getUserId());
}
NutMap menuMap = NutMap.NEW();
for (Sys_menu unit : list) {
List<Sys_menu> list1 = menuMap.getList(unit.getParentId(), Sys_menu.class);
if (list1 == null) {
list1 = new ArrayList<>();
}
list1.add(unit);
menuMap.put(unit.getParentId(), list1);
}
List<String> cmenu = new ArrayList<>();
for (Sys_menu menu : hasList) {
cmenu.add(menu.getId());
}
return Result.success().addData(NutMap.NEW().addv("menu", getTree(menuMap, "")).addv("cmenu", cmenu));
} catch (Exception e) {
return Result.error();
}
}
private List<NutMap> getTree(NutMap menuMap, String pid) {
List<NutMap> treeList = new ArrayList<>();
List<Sys_menu> subList = menuMap.getList(pid, Sys_menu.class);
for (Sys_menu menu : subList) {
NutMap map = Lang.obj2nutmap(menu);
map.put("label", menu.getName());
if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
map.put("children", getTree(menuMap, menu.getId()));
}
treeList.add(map);
}
return treeList;
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.role.add")
@SLog(tag = "添加角色", msg = "角色名称:${args[1].name}")
@Aop(TransAop.READ_COMMITTED)
public Object addDo(@Param("..") Sys_role role, HttpServletRequest req) {
try {
// 所属模块只允许选择已配置的 PC 端模块,避免角色关联无效或 H5 模块。
if (!isPcModule(role.getModuleId())) {
return Result.error("请选择所属模块");
}
int num = sysRoleService.count(Cnd.where("code", "=", role.getCode().trim()));
if (num > 0) {
return Result.error("角色编码已存在");
}
role.setCreatedBy(SecurityUtil.getUserId());
sysRoleService.insert(role);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
//查看角色拥有的权限
@At("/menu/?")
@Ok("json")
@SaCheckPermission("sys.manager.role")
public Object menu(String id, @Param("pid") String pid) {
try {
List<Sys_menu> list = sysRoleService.getRoleMenus(id, pid);
List<NutMap> treeList = new ArrayList<>();
for (Sys_menu unit : list) {
if (!unit.isHasChildren() && sysRoleService.hasChildren(id, unit.getId())) {
unit.setHasChildren(true);
}
NutMap map = Lang.obj2nutmap(unit);
map.addv("expanded", false);
map.addv("children", new ArrayList<>());
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.role.delete")
@SLog(tag = "删除角色", msg = "角色名称:${args[1].getAttribute('name')}")
public Object delete(String roleId, HttpServletRequest req) {
try {
Sys_role role = sysRoleService.fetch(roleId);
if ("SYSADMIN".equals(role.getCode()) || "PUBLIC".equals(role.getCode())) {
return Result.error("system.not.allow");
}
sysRoleService.del(roleId);
sysRoleService.clearCache();
sysUserService.clearCache();
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.role")
public Object edit(String roleId, HttpServletRequest req) {
try {
return Result.success().addData(sysRoleService.fetch(roleId));
} catch (Exception e) {
return Result.error();
}
}
//修改角色
@At
@Ok("json")
@SaCheckPermission("sys.manager.role.edit")
@SLog(tag = "修改角色", msg = "角色名称:${args[0].name}")
@Aop(TransAop.READ_COMMITTED)
public Object editDo(@Param("..") Sys_role role, HttpServletRequest req) {
try {
// 编辑时同样校验模块,保证历史角色补录后始终关联有效 PC 模块。
if (!isPcModule(role.getModuleId())) {
return Result.error("请选择所属模块");
}
Sys_role oldRole = sysRoleService.fetch(role.getId());
if (oldRole != null && !Strings.sBlank(oldRole.getCode()).equalsIgnoreCase(role.getCode())) {
int num = sysRoleService.count(Cnd.where("code", "=", role.getCode().trim()));
if (num > 0) {
return Result.error("sys.role.code");
}
}
role.setUpdatedBy(SecurityUtil.getUserId());
sysRoleService.updateIgnoreNull(role);
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
// @SaCheckPermission("sys.manager.role.menu")
@SLog(tag = "分配角色菜单", msg = "角色名称:${args[3].getAttribute('name')}")
public Object menuDo(@Param("menuIds") String menuIds, @Param("platform") String platform, @Param("roleId") String roleId, HttpServletRequest req) {
try {
String[] ids = StringUtils.split(menuIds, ",");
sysRoleService.saveMenu(ids, roleId, platform);
Sys_role role = sysRoleService.fetch(roleId);
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.role")
public Object user(@Param("roleId") String roleId, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword,
@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Sql sql = Sqls.create("SELECT a.*,c.name as unitname FROM sys_user a,sys_user_role b,sys_unit c WHERE a.unitid=c.id and a.id=b.userId and enable='1' and b.roleId=@roleId $s $o");
sql.params().set("roleId", roleId);
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
sql.vars().set("s", " and a." + searchName + " like '%" + searchKeyword + "%'");
}
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
sql.vars().set("o", " order by a." + pageOrderName + " " + PageUtil.getOrder(pageOrderBy));
}
return Result.success().addData(sysUserService.listPage(pageNumber, pageSize, sql));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.role")
public Object userSearch(@Param("query") String keyword, @Param("roleId") String roleId) {
try {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
return Result.success().addData(sysRoleService.userSearch(roleId, keyword, StpUtil.hasRole("SYSADMIN"), user.getUnit()));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.role.user")
@SLog(tag = "添加用户到角色", msg = "角色名称:${args[2].getAttribute('name')},用户ID:${args[0]}")
public Object usersAdd(@Param("users") String users, @Param("roleId") String roleId, HttpServletRequest req) {
try {
String[] ids = StringUtils.split(users, ",");
for (String s : ids) {
sysRoleService.insert("sys_user_role", org.nutz.dao.Chain.make("roleId", roleId).add("userId", s));
}
Sys_role role = sysRoleService.fetch(roleId);
sysRoleService.clearCache();
sysUserService.clearCache();
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.role.user")
@SLog(tag = "从角色中移除用户", msg = "角色名称:${args[2].getAttribute('name')},用户ID:${args[0]}")
public Object usersDel(@Param("users") String users, @Param("roleId") String roleId, HttpServletRequest req) {
try {
String superadminId = sysUserService.fetch(Cnd.where("loginname", "=", "superadmin")).getId();
String sysadminRoleid = sysRoleService.fetch(Cnd.where("code", "=", "SYSADMIN")).getId();
String[] ids = StringUtils.split(users, ",");
if (Lang.contains(ids, superadminId) && roleId.equals(sysadminRoleid)) {
return Result.error("超级管理员不能从[系统管理员]角色里删除");
}
sysRoleService.clear("sys_user_role", Cnd.where("userId", "in", ids).and("roleId", "=", roleId));
Sys_role role = sysRoleService.fetch(roleId);
sysRoleService.clearCache();
sysUserService.clearCache();
req.setAttribute("name", role.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.role")
@ApiOperation("排序数据")
public Result sortData() {
List<Sys_role> list = sysRoleService.query(Cnd.NEW().asc("sort"));
return Result.success(list);
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.role")
@ApiOperation("排序")
public Result doSort(@Param("roles") Sys_role[] roles) {
for (int i = 0; i < roles.length; i++) {
roles[i].setSort(i + 1);
}
sysRoleService.dao().update(roles, "sort");
return Result.success();
}
@At
@Ok("json:full")
@GET
@SaCheckLogin
public Result getMenuOptions() {
FieldFilter fieldFilter = FieldFilter.create(Sys_menu.class, "^id|name$");
Cnd cnd = Cnd.where("disabled", "=", 0);
cnd.and(Cnd.exps("parentId", "is", null).or("parentId", "=", ""));
return Result.success(Daos.ext(sysRoleService.dao(), fieldFilter).query(Sys_menu.class, cnd));
}
/**
* 查询角色可选择的 PC 端模块。
*
* @return PC 端模块列表,按模块排序编号升序返回,元素包含模块 ID 和模块名称
*/
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.role")
public Result listModule() {
List<Sys_module> modules = sysRoleService.dao().query(Sys_module.class,
Cnd.where(Sys_module::getPlatform, "=", "PC").asc(Sys_module::getSortNum));
return Result.success(modules);
}
/**
* 校验所属模块是否存在且属于 PC 平台。
*
* @param moduleId 模块主键,必须来自 sys_module 的 PC 端模块记录
* @return 模块有效时返回 true,否则返回 false
*/
private boolean isPcModule(String moduleId) {
if (StrUtil.isBlank(moduleId)) {
return false;
}
Sys_module module = sysRoleService.dao().fetch(Sys_module.class, moduleId);
return module != null && "PC".equals(module.getPlatform());
}
@At
@Ok("json:full")
@SaCheckLogin
public Result getRoleNames(){
// 首页身份与菜单、接口权限使用同一启用角色集合。
String roleNames = sysUserService.getEnabledRoleNames(SecurityUtil.getUserId());
return Result.success(NutMap.NEW().addv("roleNames", roleNames));
}
}
@@ -0,0 +1,145 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_route;
import com.budwk.app.sys.services.SysRouteService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
;
@IocBean
@At("/platform/sys/route")
public class SysRouteController {
private static final Log log = Logs.get();
@Inject
private SysRouteService routeService;
@Inject
private PubSubService pubSubService;
@At("")
@Ok("beetl:/platform/sys/route/index.html")
@SaCheckPermission("sys.manager.route")
public void index() {
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.route")
public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
}
return Result.success().addData(routeService.listPage(pageNumber, pageSize, cnd));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SLog(tag = "新建路由", msg = "URL:${args[0].url}")
@SaCheckPermission("sys.manager.route.add")
public Object addDo(@Param("..") Sys_route route, HttpServletRequest req) {
try {
route.setCreatedBy(SecurityUtil.getUserId());
routeService.insert(route);
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_route");
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.route")
public Object edit(String id) {
try {
return Result.success().addData(routeService.fetch(id));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SLog(tag = "修改路由", msg = "URL:${args[0].url}")
@SaCheckPermission("sys.manager.route.edit")
public Object editDo(@Param("..") Sys_route route, HttpServletRequest req) {
try {
route.setUpdatedBy(SecurityUtil.getUserId());
routeService.updateIgnoreNull(route);
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_route");
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SLog(tag = "删除路由", msg = "路由ID:${args[0]}")
@SaCheckPermission("sys.manager.route.delete")
public Object delete(String id, HttpServletRequest req) {
try {
routeService.delete(id);
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_route");
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.route.edit")
@SLog(tag = "启用路由", msg = "URL:${args[1].getAttribute('url')}")
public Object enable(String id, HttpServletRequest req) {
try {
Sys_route route = routeService.fetch(id);
req.setAttribute("url", route.getUrl());
routeService.update(Chain.make("disabled", false), Cnd.where("id", "=", id));
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_route");
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.route.edit")
@SLog(tag = "禁用路由", msg = "URL:${args[1].getAttribute('name')}")
public Object disable(String id, HttpServletRequest req) {
try {
Sys_route route = routeService.fetch(id);
req.setAttribute("url", route.getUrl());
routeService.update(Chain.make("disabled", true), Cnd.where("id", "=", id));
pubSubService.fire(RedisConstant.PLATFORM_REDIS_PREFIX + "web:platform", "sys_route");
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,156 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.enums.SysFileEngineTypeEnum;
import com.budwk.app.sys.models.Sys_user_signature;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.ext.websocket.WkWebSocketUtil;
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.Dao;
import org.nutz.integration.jedis.RedisService;
import org.nutz.integration.jedis.pubsub.PubSubService;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.upload.TempFile;
import org.nutz.mvc.upload.UploadAdaptor;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import javax.validation.Valid;
@IocBean
@At("/platform/signature")
@Ok("json")
@Slf4j
@Api("签字")
public class SysSignatureController {
@Inject
private Dao dao;
@Inject
private RedisService redisService;
@Inject
private SysFileService sysFileService;
@Inject
private PubSubService pubSubService;
@Inject
private WkWebSocketUtil wkWebSocketUtil;
@At
@Ok("re")
@Filters
@SaCheckLogin
@ApiOperation("手机扫描电脑端二维码签字页面")
public String scanPcCode() {
return "beetl:/platform/sys/signature.html";
}
@At
@SaCheckLogin
@Ok("beetl:/platform/zhghh5/sys/signature/index.html")
@ApiOperation("电脑端我的签名管理")
public void pc() {
}
@At
@SaCheckLogin
@Ok("beetl:/platform/zhghh5/sys/signature/index.html")
@ApiOperation("手机端我的签名管理")
public void h5() {
}
@At
@SaCheckLogin
@ApiOperation("手机扫描电脑端二维码签字-保存签字信息")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result saveSignature(@Valid String id, @Param("file") TempFile tempFile) {
if (ObjectUtil.isEmpty(tempFile)) {
return Result.error("保存错误,请联系管理员");
}
String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), tempFile);
redisService.setex(RedisConstant.SIGNATURE_PREFIX + SecurityUtil.getUserId() + ":" + id, 60 * 10, url);
ScanParams match = new ScanParams().match(RedisConstant.REDIS_KEY_WSROOM + SecurityUtil.getUserLoginname() + ":*");
ScanResult<String> scan = null;
do {
scan = redisService.scan(scan == null ? ScanParams.SCAN_POINTER_START : scan.getStringCursor(), match);
for (String key : scan.getResult()) {
NutMap data = NutMap.NEW().addv("action", "h5-scan-code-signature").addv("value", url).addv("id", id);
pubSubService.fire(key, Json.toJson(data));
}
} while (!scan.isCompleteIteration());
// wkWebSocketUtil.fire(SecurityUtil.getUserLoginname(),Json.toJson(NutMap.NEW().addv("action","h5-scan-code-signature").addv("value", url).addv("id", id)));
return Result.success();
}
@At
@SaCheckLogin
@ApiOperation("手机扫描电脑端二维码签字-电脑端获取签字信息")
public Result getSignature(@Valid String id) {
String signature = redisService.get(RedisConstant.SIGNATURE_PREFIX + SecurityUtil.getUserId() + ":" + id);
return Result.success().addData(signature);
}
@At
@SaCheckLogin
@ApiOperation("手机扫描电脑端二维码签字-电脑端清除签字信息")
public Result clearSignature(@Valid String id) {
redisService.del(RedisConstant.SIGNATURE_PREFIX + SecurityUtil.getUserId() + ":" + id);
return Result.success();
}
@At
@SaCheckLogin
@ApiOperation("手机端签字-保存签字信息(直接返回url)")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
public Result saveH5Signature(@Param("file") TempFile tempFile) {
String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), tempFile);
return Result.success().addData(url);
}
@At
@SaCheckLogin
@ApiOperation("更新用户签字")
@SLog(tag = "用户签字管理", msg = "更新用户签字")
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
@Aop(TransAop.READ_COMMITTED)
public Result update(@Param("file") TempFile tempFile) {
String url = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), tempFile);
// 签字记录必须按当前登录用户读取,避免后续用户更新时覆盖其他用户的签字。
Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class, Cnd.where(Sys_user_signature::getUserId, "=", SecurityUtil.getUserId()));
if (ObjectUtil.isNull(sysUserSignature)) {
sysUserSignature = new Sys_user_signature();
}
sysUserSignature.setSignature(url);
sysUserSignature.setUserId(SecurityUtil.getUserId());
dao.insertOrUpdate(sysUserSignature);
wkWebSocketUtil.fire(SecurityUtil.getUserLoginname(),Json.toJson(NutMap.NEW().addv("action","pc-scan-code-manage-signature").addv("url",url)));
return Result.success();
}
@At
@SaCheckLogin
@ApiOperation("电脑端我的电子签名获取用户签字")
public Result get() {
Sys_user_signature sysUserSignature = dao.fetch(Sys_user_signature.class, Cnd.where(Sys_user_signature::getUserId, "=", SecurityUtil.getUserId()));
return Result.success(sysUserSignature);
}
}
@@ -0,0 +1,184 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_task;
import com.budwk.app.sys.services.SysTaskService;
import com.budwk.app.task.services.TaskPlatformService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
;
@IocBean
@At("/platform/sys/task")
public class SysTaskController {
private static final Log log = Logs.get();
@Inject
private SysTaskService sysTaskService;
@Inject
private TaskPlatformService taskPlatformService;
@At("")
@Ok("beetl:/platform/sys/task/index.html")
@SaCheckPermission("sys.manager.task")
public void index() {
}
@At
@Ok("beetl:/platform/sys/task/cron.html")
@SaCheckPermission("sys.manager.task")
public void cron() {
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.task")
public Object cronExp(@Param("cron") String cron) {
try {
return Result.success().addData(taskPlatformService.getCronExeTimes(cron));
} catch (Exception e) {
return Result.error(e.getMessage());
}
}
@At
@Ok("json:full")
@SaCheckPermission("sys.manager.task")
public Object data(@Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Cnd cnd = Cnd.NEW();
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
}
return Result.success().addData(sysTaskService.listPage(pageNumber, pageSize, cnd));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SLog(tag = "新建任务", msg = "任务名称:${args[0].name}")
@SaCheckPermission("sys.manager.task.add")
@Aop(TransAop.READ_COMMITTED)
public Object addDo(@Param("..") Sys_task task, HttpServletRequest req) {
try {
task.setCreatedBy(SecurityUtil.getUserId());
Sys_task sysTask = sysTaskService.insert(task);
taskPlatformService.add(sysTask.getId(), sysTask.getId(), sysTask.getJobClass(), sysTask.getCron(),
sysTask.getNote(), sysTask.getData());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.task")
public Object edit(String id) {
try {
return Result.success().addData(sysTaskService.fetch(id));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SLog(tag = "修改任务", msg = "任务名称:${args[0].name}")
@SaCheckPermission("sys.manager.task.edit")
public Object editDo(@Param("..") Sys_task task, HttpServletRequest req) {
try {
task.setUpdatedBy(SecurityUtil.getUserId());
sysTaskService.updateIgnoreNull(task);
if (taskPlatformService.isExist(task.getId(), task.getId())) {
taskPlatformService.delete(task.getId(), task.getId());
}
if (!task.isDisabled()) {
taskPlatformService.add(task.getId(), task.getId(), task.getJobClass(), task.getCron(),
task.getNote(), task.getData());
}
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SLog(tag = "删除任务", msg = "任务名称:${args[1].getAttribute('name')}")
@SaCheckPermission("sys.manager.task.delete")
public Object delete(String id, HttpServletRequest req) {
try {
Sys_task sysTask = sysTaskService.fetch(id);
try {
if (taskPlatformService.isExist(sysTask.getId(), sysTask.getId())) {
taskPlatformService.delete(sysTask.getId(), sysTask.getId());
}
} catch (Exception e) {
log.error(e.getMessage());
}
sysTaskService.delete(id);
req.setAttribute("name", sysTask.getName());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.task.edit")
@SLog(tag = "启用任务", msg = "任务名:${args[1].getAttribute('name')}")
public Object enable(String id, HttpServletRequest req) {
try {
Sys_task sysTask = sysTaskService.fetch(id);
req.setAttribute("name", sysTask.getName());
sysTaskService.update(org.nutz.dao.Chain.make("disabled", false), Cnd.where("id", "=", id));
if (!taskPlatformService.isExist(sysTask.getId(), sysTask.getId())) {
taskPlatformService.add(sysTask.getId(), sysTask.getId(), sysTask.getJobClass(), sysTask.getCron(),
sysTask.getNote(), sysTask.getData());
}
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.task.edit")
@SLog(tag = "禁用任务", msg = "任务名:${args[1].getAttribute('name')}")
public Object disable(String id, HttpServletRequest req) {
try {
Sys_task sysTask = sysTaskService.fetch(id);
req.setAttribute("name", sysTask.getName());
sysTaskService.update(org.nutz.dao.Chain.make("disabled", true), Cnd.where("id", "=", id));
if (taskPlatformService.isExist(sysTask.getId(), sysTask.getId())) {
taskPlatformService.delete(sysTask.getId(), sysTask.getId());
}
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,128 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.sys.models.SysCommitteeMember;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.sys.views.View_user;
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.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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.validation.Valid;
import java.util.List;
/**
* @author zhf
* @date 2025/11/18 17:26
* @description 工会委员会
*/
@IocBean
@At("/platform/sys/committeeMember")
@Ok("json:full")
@Api(tags = "工会委员管理")
public class SysUnionCommitteeMemberController {
@Inject
private SysUserService sysUserService;
@Inject
private SysRoleService sysRoleService;
@At
@ApiOperation("分页查询")
@SaCheckPermission("sys.manager.union.committeeMember")
public Result pageData(PageForm pageForm, @Valid String sessionId) {
Sql sql = Sqls.create("""
SELECT * FROM `sys_committee_member` $condition
""");
Cnd cnd = Cnd.NEW();
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(SysCommitteeMember::getLoginName, pageForm.getSearchKeyword(), true);
seg.orLike(SysCommitteeMember::getUserName, pageForm.getSearchKeyword(), true);
// cnd.and(seg);
cnd.and(SysCommitteeMember::getSessionId, "=", sessionId);
sql.setCondition(cnd);
return Result.success(sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At
@ApiOperation("查询没有设置的人员")
@SaCheckPermission("sys.manager.union.committeeMember")
public Result listUserSelect(@Valid String keyWord, @Valid String sessionId) {
Sql sql = Sqls.create("select id,loginname,username,unitName from vw_user $condition");
Cnd cnd = Cnd.NEW();
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(View_user::getLoginname, keyWord, true);
seg.orLike(View_user::getUsername, keyWord, true);
cnd.and(seg);
cnd.and("id", "not in", "(select userId from sys_committee_member where sessionId='%s')".formatted(sessionId));
sql.setCondition(cnd);
Pagination pagination = sysUserService.listPageMap(1, 10, sql);
return Result.success(pagination.getList());
}
@At
@ApiOperation("添加委员")
@SaCheckPermission("sys.manager.union.committeeMember")
@Aop(TransAop.READ_COMMITTED)
public Result insert(SysCommitteeMember sysCommitteeMember) {
Sys_user user = sysUserService.fetch(sysCommitteeMember.getUserId());
sysCommitteeMember.setLoginName(user.getLoginname());
sysCommitteeMember.setUserName(user.getUsername());
sysUserService.insert(sysCommitteeMember);
Sys_role sys_role = sysRoleService.fetch(Cnd.where(Sys_role::getCode, "=", RoleConstant.UNION_COMMITTEE_MEMBER.name()));
Sys_user_role user_role = new Sys_user_role();
user_role.setRoleId(sys_role.getId());
user_role.setUserId(sysCommitteeMember.getUserId());
sysRoleService.insert(user_role);
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
@At
@ApiOperation("删除委员")
@SaCheckPermission("sys.manager.union.committeeMember")
@Aop(TransAop.READ_COMMITTED)
public Result delete(@Valid String id) {
SysCommitteeMember committeeMember = sysUserService.dao().fetch(SysCommitteeMember.class, id);
Sys_role sys_role = sysRoleService.fetch(Cnd.where(Sys_role::getCode, "=", RoleConstant.UNION_COMMITTEE_MEMBER.name()));
sysUserService.dao().delete(SysCommitteeMember.class, id);
sysRoleService.dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", committeeMember.getUserId())
.and(Sys_user_role::getRoleId, "=", sys_role.getId()));
return Result.success();
}
@At
@ApiOperation("删除委员角色")
@SaCheckPermission("sys.manager.union.committeeMember")
@Aop(TransAop.READ_COMMITTED)
public Result deleteRole(@Valid String sessionId) {
List<SysCommitteeMember> memberList = sysUserService.dao().query(SysCommitteeMember.class, Cnd.where(SysCommitteeMember::getSessionId, "=", sessionId));
Sys_role sys_role = sysRoleService.fetch(Cnd.where(Sys_role::getCode, "=", RoleConstant.UNION_COMMITTEE_MEMBER.name()));
List<String> userids = memberList.stream().map(SysCommitteeMember::getUserId).toList();
sysRoleService.dao().clear(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "in", userids)
.and(Sys_user_role::getRoleId, "=", sys_role.getId()));
return Result.success();
}
}
@@ -0,0 +1,751 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.constant.RoleConstant;
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.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.services.*;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
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.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
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 javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@IocBean
@Ok("json:full")
@Api(tags = "分工会管理")
@At("/platform/sys/union")
public class SysUnionController {
@Inject
private Dao dao;
@Inject
private FlowEngine flowEngine;
@Inject
private SysDictService sysDictService;
@Inject
private SysRoleService sysRoleService;
@Inject
private SysUserService sysUserService;
@Inject
private SysUnitService sysUnitService;
@Inject
private SysUnionService sysUnionService;
@At("")
@Ok("beetl:/platform/sys/union/index.html")
@SaCheckPermission("sys.manager.union")
public void index() {
}
@At
@SaCheckPermission("sys.manager.union.add")
@ApiOperation("新增分工会")
public Result insert(Sys_union union) {
try {
dao.insert(union);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@SaCheckPermission("sys.manager.union.edit")
@ApiOperation("编辑分工会")
public Result update(Sys_union union) {
try {
dao.updateIgnoreNull(union);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At
@SaCheckPermission("sys.manager.union")
public Result findOne(String id) {
Sys_union union = dao.fetch(Sys_union.class, id);
return Result.success(union);
}
@At
@ApiOperation("删除分工会")
@SaCheckPermission("sys.manager.union.delete")
public Result doDelete(String id) {
dao.delete(Sys_union.class, id);
return Result.success();
}
@At
@SaCheckPermission("sys.manager.union")
public Result tree() {
List<Tree<String>> treeList = null;
try {
boolean schoolUnionAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
List<TreeNode<String>> nodeList = CollUtil.newArrayList();
nodeList.add(new TreeNode<>("工会委员会", "0", "工会委员会", 1000));
List<Sys_union> list = new ArrayList<>();
if (schoolUnionAdmin) {
list = dao.query(Sys_union.class, Cnd.NEW().asc("unionCode"));
} else {
list = dao.query(Sys_union.class, Cnd.NEW().and("id", "=", SecurityUtil.getUnionId()));
}
for (int i = 0; i < list.size(); i++) {
nodeList.add(new TreeNode<>(list.get(i).getId(), "工会委员会", list.get(i).getName(), i));
}
treeList = TreeUtil.build(nodeList, "0");
return Result.success().addData(treeList);
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
@At
@SaCheckPermission("sys.manager.union")
public Result pageData(@Valid PageForm pageForm) {
Cnd cnd = Cnd.NEW();
Sql sql = Sqls.create("""
SELECT
gh.*,
GROUP_CONCAT( u.username,'(',u.loginname,')' ) AS chairman
FROM
sys_union gh
LEFT JOIN sys_user_role sur ON sur.unionId = gh.id
AND sur.roleId = 'fd753e8a8c5a404e8e00ef8e0b0c69da'
LEFT JOIN sys_user u ON u.id = sur.userId
$condition
""");
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(Cnd.likeEX("gh.name", pageForm.getSearchKeyword()));
}
cnd.asc("gh.unionCode");
cnd.groupBy("gh.id");
boolean schoolUnionAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
if (!schoolUnionAdmin && AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
cnd.and("gh.id", "=", SecurityUtil.getUnionId());
}
sql.setCondition(cnd);
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.manager.union")
public Result schoolUnionUserPageData(PageForm pageForm) {
List<Sys_dict> schoolRoles = sysDictService.getSubListByCode("SCHOOL_UNION_ROLES");
List<String> schoolRoleCodes = schoolRoles.stream().map(Sys_dict::getCode).toList();
if (Lang.isEmpty(schoolRoles)) {
return Result.success();
}
Sql sql = Sqls.create("""
SELECT
t1.userId,
t2.username,
t2.loginname,
t3.`code` AS roleCode,
t3.`name` AS roleName
FROM
sys_user_role t1
LEFT JOIN sys_user t2 ON t2.id = t1.userId
LEFT JOIN sys_role t3 ON t3.id = t1.roleId
LEFT JOIN sys_dict t4 ON t4.code = t3.code
$condition
""");
Cnd cnd = Cnd.where("t3.`code`", "in", schoolRoleCodes);
if (StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
switch (pageForm.getSearchName()) {
case "loginname" -> cnd.where().andLike("t2.loginname", pageForm.getSearchKeyword());
case "username" -> cnd.where().andLike("t2.username", pageForm.getSearchKeyword());
case "roleName" -> cnd.where().andLike("t3.`name`", pageForm.getSearchKeyword());
}
}
cnd.asc("t4.location");
cnd.asc("t2.username");
sql.setCondition(cnd);
List<NutMap> list = sysUserService.listMap(sql);
return Result.success(list);
}
@At
@SaCheckPermission("sys.manager.union.schoolOfficer")
@ApiModelProperty("添加校工会人员角色")
public Result insertSchoolUnionUserRole(String userId, String roleCode) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
return Result.error("无法找到" + roleCode + "对应编码的角色");
}
int count = dao.count(Sys_user_role.class, Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId));
if (count > 0) {
return Result.error("请勿重复添加");
}
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId));
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
@At
@SaCheckPermission("sys.manager.union.schoolOfficer")
@ApiOperation("删除校工会人员角色")
public Result deleteSchoolUnionUserRole(String userId, String roleCode) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
throw new BaseException("无法找到{}对应编码的角色", roleCode);
}
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
/**
* 分工会干部
*
* @param pageForm
* @return
*/
@At
@SaCheckPermission("sys.manager.union")
public Result branchUnionUserPageData(PageForm pageForm, String unionId, @Param("j") String j) {
List<Sys_dict> branchUnionRoles = sysDictService.getSubListByCode("BRANCH_UNION_ROLES");
if (Lang.isEmpty(branchUnionRoles)) {
return Result.success();
}
List<String> branchUnionRoleCodes = getBranchUnionRoleCodes(branchUnionRoles);
Sql sql = Sqls.create("""
SELECT
info.*,
COALESCE(jDict.`name`, info.j, curJDict.`name`, curSession.j) AS jName,
role.`name` AS roleName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
CASE
WHEN info.isServing = 0 THEN '离任'
WHEN t.id IS NOT NULL THEN t.displayName
ELSE '在任'
END AS displayStatus,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask' AND taskState in (10,20)) AS startTaskId
FROM
sys_union_cadre info
LEFT JOIN sys_role role ON role.`code` = info.roleCode
LEFT JOIN sys_dict jParent ON jParent.`code` = 'TEACHER_CONGRESS_J'
LEFT JOIN sys_dict jDict ON jDict.parentId = jParent.id AND jDict.`code` = info.j
LEFT JOIN (
SELECT j
FROM teacher_congress_session
WHERE enable = 1
ORDER BY startDate DESC
LIMIT 1
) curSession ON info.j IS NULL OR info.j = ''
LEFT JOIN sys_dict curJDict ON curJDict.parentId = jParent.id AND curJDict.`code` = curSession.j
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
$constructionSql
""");
Cnd cnd = Cnd.where("role.`code`", "in", branchUnionRoleCodes);
cnd.and("info.unionId", "=", unionId);
if (StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
switch (pageForm.getSearchName()) {
case "loginname" -> cnd.where().andLike("info.loginname", pageForm.getSearchKeyword());
case "username" -> cnd.where().andLike("info.username", pageForm.getSearchKeyword());
case "roleName" -> cnd.where().andLike("role.`name`", pageForm.getSearchKeyword());
}
}
if (StrUtil.isNotBlank(j)) {
cnd.and("COALESCE(NULLIF(info.j, ''), curSession.j)", "=", j);
}
sql.setVar("constructionSql",
new Static(" group by info.id order by field(role.code," + branchUnionRoleCodes.stream().map(code -> "'" + code + "'").collect(Collectors.joining(",")) + ")")
);
sql.setCondition(cnd);
List<NutMap> list = sysUserService.listMap(sql);
return Result.success(list);
}
@At
@SaCheckPermission("sys.manager.union")
public Result branchUnionUserUsedJData(String unionId) {
List<Sys_dict> branchUnionRoles = sysDictService.getSubListByCode("BRANCH_UNION_ROLES");
if (Lang.isEmpty(branchUnionRoles)) {
return Result.success(List.of());
}
List<String> branchUnionRoleCodes = getBranchUnionRoleCodes(branchUnionRoles);
Sql sql = Sqls.create("""
SELECT DISTINCT
COALESCE(NULLIF(info.j, ''), curSession.j) AS j,
COALESCE(jDict.location, curJDict.location, 0) AS jLocation
FROM
sys_union_cadre info
LEFT JOIN sys_role role ON role.`code` = info.roleCode
LEFT JOIN sys_dict jParent ON jParent.`code` = 'TEACHER_CONGRESS_J'
LEFT JOIN sys_dict jDict ON jDict.parentId = jParent.id AND jDict.`code` = info.j
LEFT JOIN (
SELECT j
FROM teacher_congress_session
WHERE enable = 1
ORDER BY startDate DESC
LIMIT 1
) curSession ON info.j IS NULL OR info.j = ''
LEFT JOIN sys_dict curJDict ON curJDict.parentId = jParent.id AND curJDict.`code` = curSession.j
$condition
ORDER BY jLocation DESC
""");
Cnd cnd = Cnd.where("role.`code`", "in", branchUnionRoleCodes);
cnd.and("info.unionId", "=", unionId);
sql.setCondition(cnd);
List<String> usedJCodes = sysUserService.listMap(sql).stream()
.map(item -> item.getString("j"))
.filter(StrUtil::isNotBlank)
.distinct()
.toList();
return Result.success(usedJCodes);
}
/**
* 查询分工会干部角色选项,并补充按单位授权的二级党委书记角色。
*
* @return 角色编码和名称
*/
@At
@SaCheckPermission("sys.manager.union.branchOfficer")
public Result branchUnionRoleOptions() {
List<NutMap> roleOptions = sysDictService.getSubListByCode("BRANCH_UNION_ROLES").stream()
.map(item -> NutMap.NEW().addv("code", item.getCode()).addv("name", item.getName()))
.collect(Collectors.toCollection(ArrayList::new));
if (sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY) != null
&& roleOptions.stream().noneMatch(item -> RoleConstant.UNIT_PARTY_SECRETARY.name().equals(item.getString("code")))) {
roleOptions.add(NutMap.NEW().addv("code", RoleConstant.UNIT_PARTY_SECRETARY.name()).addv("name", "二级党委书记"));
}
return Result.success(roleOptions);
}
/**
* 查询当前分工会可配置二级党委书记的组成单位。
*
* @param unionId 分工会ID
* @return 当前分工会的二级单位
*/
@At
@SaCheckPermission("sys.manager.union.branchOfficer")
public Result branchUnionPartySecretaryUnitOptions(String unionId) {
if (StrUtil.isBlank(unionId)) {
return Result.error("分工会参数不能为空");
}
List<Sys_unit> units = dao.query(Sys_unit.class, Cnd.where("unionId", "=", unionId)
.and("unitLevel", "=", 2).asc("unitcode"));
return Result.success(units);
}
@At
@SaCheckPermission("sys.manager.union.branchOfficer")
@ApiOperation("添加分工会人员角色")
@Aop(TransAop.READ_COMMITTED)
public Result insertBranchUnionUserRole(String userId, String roleCode, String unionId, String j) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
return Result.success("无法找到" + roleCode + "对应编码的角色");
}
int count = dao.count(Sys_user_role.class, Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId));
if (count > 0) {
return Result.error("请勿重复添加");
}
// Sys_branch_union_user_permission permission = new Sys_branch_union_user_permission();
// permission.setUserId(userId);
// permission.setRoleId(role.getId());
// permission.setUnionId(unionId);
// dao.insert(permission);
// Sys_union union = dao.fetch(Sys_union.class, unionId);
// Sys_user user = dao.fetch(Sys_user.class, userId);
// String instanceName = union.getName() + user.getUsername() + role.getName() + "的授权申请";
// bpmService.startSubmitProcessInstance(BpmProcessConstant.BRANCH_UNION_WEIYUAN_AUTHORIZATION.name(), instanceName, permission.getId(), List.of("24017"), null);
// sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unionId", "=", unionId));
// sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId).add("unionId", unionId));
// sysRoleService.clearCache();
// sysUserService.clearCache();
// 构建表结构存储
View_user user = dao.fetch(View_user.class, Cnd.where("id", "=", userId));
Sys_union_cadre unionCadre = new Sys_union_cadre();
unionCadre.setUserId(userId);
unionCadre.setUnionId(unionId);
unionCadre.setMobile(user.getMobile());
unionCadre.setUnionName(user.getUnionName());
unionCadre.setLoginName(user.getLoginname());
unionCadre.setUserName(user.getUsername());
unionCadre.setRoleCode(roleCode);
unionCadre.setJ(j);
unionCadre.setApplyDate(new Date());
unionCadre.setIsServing(true);
unionCadre.setIsJoin(true);
dao.insert(unionCadre);
// 校级管理员新增普通干部时直接授权,不生成无实际审核意义的流程数据。
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
if (isAdmin) {
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, List.of());
return Result.success();
}
// 非校级管理员仍按原业务发起基层干部授权审核流程。
Dict args = Dict.create();
args.set("submit", "branch");
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, unionCadre);
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JCGHWY", unionCadre.getId(), SecurityUtil.getUserId(), args);
// 自动完成第一个申请任务
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}
/**
* 新增二级党委书记授权。校级管理员直接按单位授权,其他用户发起审批,
* 审核通过后由流程拦截器按单位写入角色。
*
* @param userId 人员ID
* @param unionId 分工会ID
* @param unitIds 组成单位ID集合
* @param j 届次
* @return 处理结果
*/
@At
@SaCheckPermission("sys.manager.union.branchOfficer")
@ApiOperation("添加二级党委书记角色")
@Aop(TransAop.READ_COMMITTED)
public Result insertBranchUnionPartySecretaryRole(String userId, String unionId, @Param("unitIds") String[] unitIds, String j) {
if (StrUtil.isBlank(userId) || StrUtil.isBlank(unionId) || Lang.isEmpty(unitIds)) {
return Result.error("人员、分工会和所属单位不能为空");
}
Sys_role role = sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY);
if (role == null) {
return Result.error("未配置二级党委书记角色");
}
View_user user = dao.fetch(View_user.class, Cnd.where("id", "=", userId));
if (user == null || !unionId.equals(user.getUnionId())) {
return Result.error("所选人员不属于当前分工会");
}
List<String> distinctUnitIds = java.util.Arrays.stream(unitIds)
.filter(StrUtil::isNotBlank)
.distinct()
.toList();
List<Sys_unit> units = dao.query(Sys_unit.class, Cnd.where("id", "in", distinctUnitIds)
.and("unionId", "=", unionId).and("unitLevel", "=", 2));
if (units.size() != distinctUnitIds.size()) {
return Result.error("所属单位包含非当前分工会的单位");
}
int roleCount = dao.count(Sys_user_role.class, Cnd.where("roleId", "=", role.getId())
.and("userId", "=", userId).and("unionId", "=", unionId));
if (roleCount > 0) {
return Result.error("该人员已设置二级党委书记,请先删除后再重新设置");
}
Sys_union_cadre unionCadre = new Sys_union_cadre();
unionCadre.setUserId(userId);
unionCadre.setUnionId(unionId);
unionCadre.setMobile(user.getMobile());
unionCadre.setUnionName(user.getUnionName());
unionCadre.setLoginName(user.getLoginname());
unionCadre.setUserName(user.getUsername());
unionCadre.setRoleCode(RoleConstant.UNIT_PARTY_SECRETARY.name());
unionCadre.setJ(j);
unionCadre.setApplyDate(new Date());
unionCadre.setIsServing(true);
unionCadre.setIsJoin(true);
dao.insert(unionCadre);
boolean isAdmin = AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
if (isAdmin) {
// 校级管理员直接按所选单位授权,不创建 JCGHWY 流程实例和审核任务。
sysUnionService.assignBranchUnionRole(userId, role.getId(), unionId, distinctUnitIds);
return Result.success();
}
// 非校级管理员保留原审批流程,并将所选单位随表单传给审核通过拦截器。
JSONObject formData = JSONUtil.parseObj(unionCadre);
formData.set("unitIds", distinctUnitIds);
Dict args = Dict.create();
args.set("submit", "branch");
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
args.set(FlowConst.FORM_DATA, formData.toString());
ProcessInstance instance = flowEngine.startProcessInstanceByKey("JCGHWY", unionCadre.getId(), SecurityUtil.getUserId(), args);
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}
@At
@ApiOperation("分工会干部离任")
@SaCheckPermission("sys.manager.union.branchOfficer")
@Aop(TransAop.READ_COMMITTED)
public Result leaveBranchUnionUserRole(String id, String leaveDate) {
if (StrUtil.isBlank(id)) {
return Result.error("请选择离任人员");
}
if (StrUtil.isBlank(leaveDate)) {
return Result.error("请选择离任时间");
}
Sys_union_cadre unionCadre = dao.fetch(Sys_union_cadre.class, id);
if (Lang.isEmpty(unionCadre)) {
return Result.error("未找到对应干部记录");
}
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", unionCadre.getRoleCode()));
if (Lang.isEmpty(role)) {
throw new BaseException("无法找到{}对应编码的角色", unionCadre.getRoleCode());
}
Date parsedLeaveDate = cn.hutool.core.date.DateUtil.parseDate(leaveDate);
dao.update(Sys_union_cadre.class,
Chain.make("isServing", false).add("leaveDate", parsedLeaveDate),
Cnd.where("id", "=", id));
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId())
.and("userId", "=", unionCadre.getUserId())
.and("unionId", "=", unionCadre.getUnionId()));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
@At
@ApiOperation("删除分工会人员角色")
@SaCheckPermission("sys.manager.union.branchOfficer")
public Result deleteBranchUnionUserRole(String userId, String roleCode, String unionId) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
throw new BaseException("无法找到{}对应编码的角色", roleCode);
}
Cnd cnd = Cnd.NEW();
cnd.and("roleId", "=", role.getId());
if (StrUtil.isNotBlank(userId)) {
cnd.and("userId", "=", userId);
} else {
cnd.and("userId", "is", null);
}
cnd.and("unionId", "=", unionId);
sysRoleService.clear("sys_user_role", cnd);
dao.clear(Sys_union_cadre.class, Cnd.where("userId", "=", userId)
.and("unionId", "=", unionId).and("roleCode", "=", roleCode));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
/**
* 将字典维护的分工会角色与单位级二级党委书记角色合并为列表查询范围。
*/
private List<String> getBranchUnionRoleCodes(List<Sys_dict> branchUnionRoles) {
List<String> roleCodes = new ArrayList<>(branchUnionRoles.stream().map(Sys_dict::getCode).toList());
if (sysRoleService.getByCode(RoleConstant.UNIT_PARTY_SECRETARY) != null
&& !roleCodes.contains(RoleConstant.UNIT_PARTY_SECRETARY.name())) {
roleCodes.add(RoleConstant.UNIT_PARTY_SECRETARY.name());
}
return roleCodes;
}
/**
* 分页查询当前分工会的组成单位。
*
* @param pageForm 分页和查询参数;pageNumber 为页码,pageSize 为每页条数,searchKeyword 为单位编码或名称
* @param unionId 分工会ID,不能为空
* @return Resultdata 为 Paginationlist 是当前页单位列表,totalCount 是符合条件的单位总数
*/
@At
@ApiOperation("分工会组成单位分页")
@SaCheckPermission("sys.manager.union")
public Result branchUnionPartUnitPageData(@Valid PageForm pageForm, String unionId) {
if (StrUtil.isBlank(unionId)) {
return Result.error("分工会参数不能为空");
}
return Result.success(sysUnitService.pageBranchUnionPartUnits(pageForm, unionId));
}
@At
@ApiOperation("分工会组成单位穿梭框数据")
@SaCheckPermission("sys.manager.union.partUnit")
public Result branchUnionPartUnitTransferData(String unionId) {
// 组成单位仅允许选择二级单位,单位类别不能替代层级判断。
List<Sys_unit> units = dao.query(Sys_unit.class, Cnd.where("unitLevel", "=", 2).asc("unitcode"));
List<String> selectUnitIds = units.stream().filter(unit -> StrUtil.isNotBlank(unit.getUnionId()) && unit.getUnionId().equals(unionId)).map(Sys_unit::getId).toList();
List<Sys_unit> matchUnits = units.stream().filter(unit -> StrUtil.isBlank(unit.getUnionId()) || (StrUtil.isNotBlank(unit.getUnionId()) && unit.getUnionId().equals(unionId))).toList();
NutMap transferData = NutMap.NEW().addv("selectUnitIds", selectUnitIds).addv("allUnits", matchUnits);
return Result.success(transferData);
}
@At
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("删除分工会组成单位")
@SaCheckPermission("sys.manager.union.partUnit")
public Result branchUnionPartUnitSet(String unionId, @Param("unitIds") String[] unitIds) {
sysUnitService.update(Chain.make("unionId", null), Cnd.where("unionId", "=", unionId));
if (Lang.isNotEmpty(unitIds)) {
// 保存时再次限制单位层级,避免绕过穿梭框提交三级或其他层级单位。
sysUnitService.update(Chain.make("unionId", unionId), Cnd.where("id", "in", unitIds).and("unitLevel", "=", 2));
}
return Result.success();
}
@At
@ApiOperation("按关键字查询分工会下的人员")
@Ok("json:{ignoreNull:true}")
@SaCheckPermission("sys.manager.union")
public Result listUnion(@Valid String unionId, @Valid String keyWord) {
Sql sql = Sqls.create("select id,loginname,username,unitName from vw_user $condition");
Cnd cnd = Cnd.NEW();
cnd.and(View_user::getUnionId, "=", unionId);
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(View_user::getLoginname, keyWord, true);
seg.orLike(View_user::getUsername, keyWord, true);
cnd.and(seg);
sql.setCondition(cnd);
Pagination pagination = sysUnionService.listPageMap(1, 10, sql);
return Result.success(pagination.getList());
}
/**
* 基层干部审核相关
*/
@At
@ApiOperation("基层干部审核菜单")
@SaCheckPermission("sys.manager.union")
public Result cadrePageData(PageForm pageForm, @Param("isJoin") Boolean isJoin) {
Sql sql = Sqls.create("""
SELECT
info.*,
role.`name` AS roleName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName), '结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN sys_union_cadre info ON info.id = ins.businessNo
LEFT JOIN sys_role role ON role.`code` = info.roleCode
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("t.taskName", "=", "2978a74a-75c1-4f95-99f9-9c08c480f1b5");
if (pageForm.getAudit()) {
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.andEX("info.isJoin", "=", isJoin);
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("t.createdAt");
cnd.desc("info.applyDate");
} else {
cnd.orderBy("info." + pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination pagination = sysUnionService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
}
@@ -0,0 +1,123 @@
package com.budwk.app.sys.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.sys.models.Sys_union_group;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.services.SysUnionGroupService;
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.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.validation.Valid;
import java.util.Arrays;
import java.util.List;
@IocBean
@At("/platform/sys/unionGroup")
@Ok("json:full")
@Api(value = "工会小组")
@Slf4j
public class SysUnionGroupController {
@Inject
private Dao dao;
@Inject
private SysUnionGroupService sysUnionGroupService;
@At
@SaCheckPermission("sys.manager.union")
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("添加工会小组")
public Result insert(Sys_union_group group) {
sysUnionGroupService.insert(group);
return Result.success();
}
@At
@SaCheckPermission("sys.manager.union")
@ApiOperation("修改工会小组")
public Result update(Sys_union_group group) {
sysUnionGroupService.update(group);
return Result.success();
}
@At("/delete/?")
@SaCheckPermission("sys.manager.union")
@ApiOperation("删除工会小组")
@Aop(TransAop.READ_COMMITTED)
public Result delete(String id) {
sysUnionGroupService.delete(id);
return Result.success();
}
@At("/detail/?")
@SaCheckPermission("sys.manager.union")
@ApiOperation("获取工会小组详情")
public Result detail(String id) {
Sys_union_group group = dao.fetch(Sys_union_group.class, id);
return Result.success().addData(group);
}
@At
@SaCheckPermission("sys.manager.union")
@ApiOperation("获取工会小组列表")
public Result pageData(@Valid PageForm pageForm, @Valid String unionId) {
Pagination pagination = sysUnionGroupService.pageData(pageForm, unionId);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.manager.union")
@ApiOperation("获取非工会小组组长人员")
public Result listUser(@Valid @Param("unionId") String unionId,
@Param("keyword") String keyword,
@Param("userIds") String[] userIds) {
System.out.println(Arrays.toString(userIds));
List<NutMap> list = sysUnionGroupService.listNotLeader(unionId, keyword, Arrays.asList(userIds));
return Result.success(list);
}
@At
@SaCheckPermission("sys.manager.union")
@ApiOperation("获取组成单位")
public Result getUnits(String unionId, String groupId){
Sql sql = Sqls.create("""
SELECT
j.unitId
FROM
sys_union_group,
JSON_TABLE (unitIds, '$[*]' COLUMNS (unitId VARCHAR (50) PATH '$')) AS j
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("unionId", "=", unionId);
cnd.andEX("id", "!=", groupId);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.strList());
dao.execute(sql);
List<String> list = sql.getList(String.class);
List<Sys_unit> unitList = dao.query(Sys_unit.class,
Cnd.where("unionId", "=", unionId)
.and("unitTypeCode", "=", "1")
.andEX("id", "not in", list));
return Result.success(unitList);
}
}
@@ -0,0 +1,406 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
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.exception.BaseException;
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.sys.models.Sys_dict;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUnitService;
import com.budwk.app.sys.services.SysUserService;
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.democratic.proposal.models.ProposalConfig;
import io.swagger.annotations.ApiOperation;
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.Strings;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
;
/**
* Created by wizzer on 2016/6/24.
*/
@IocBean
@At("/platform/sys/unit")
public class SysUnitController {
private static final Log log = Logs.get();
@Inject
private SysUnitService sysUnitService;
@Inject
private SysUserService sysUserService;
@Inject
private SysDictService sysDictService;
@Inject
private SysRoleService sysRoleService;
@At("")
@Ok("beetl:/platform/sys/unit/index.html")
@SaCheckPermission("sys.manager.unit")
public void index() {
}
@At("/pageData")
@Ok("json")
@SaCheckLogin
public Object pageData(PageForm pageForm, String unitName, String unitId) {
Cnd cnd = Cnd.NEW();
// cnd.and("parentId", "is not", null).andEX("unitLevel", "=", unitLevel).asc("unitLevel").asc("unitcode");
cnd.and("parentId", "is not", null);
cnd.andEX("parentId", "=", unitId);
// cnd.and("unitTypeCode", "=", "1");
cnd.asc("unitcode");
cnd.and(Cnd.likeEX("name", unitName));
Pagination<Sys_unit> listPage = sysUnitService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), Sys_unit.class, cnd);
return Result.success(listPage);
}
@At("/userPageData")
@Ok("json")
@SaCheckLogin
public Object userPageData(PageForm pageForm, String unitId) {
Sql sql = Sqls.create("""
select username,loginname,sex,mobile,member from vw_user $condition
""").setParam("unitId", unitId);
Cnd cnd = Cnd.NEW();
cnd.and("unitid", "=", unitId);
if (Strings.isNotBlank(pageForm.getSearchName()) && Strings.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(pageForm.getSearchName(), "like", "%" + pageForm.getSearchKeyword() + "%");
}
cnd.desc("member");
sql.setCondition(cnd);
return Result.success(sysUnitService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql));
}
@At("/leaderPageData")
@Ok("json")
@SaCheckLogin
public Object leaderPageData(PageForm pageForm, String unitId) {
List<Sys_dict> unitRoles = sysDictService.getSubListByCode("UNIT_ROLES");
if (Lang.isEmpty(unitRoles)) {
return Result.success();
}
List<String> unitRoleCodes = unitRoles.stream().map(Sys_dict::getCode).toList();
Sql sql = Sqls.create("""
SELECT
t1.userId,
t2.username,
t2.loginname,
t3.`code` AS roleCode,
t3.`name` AS roleName
FROM
sys_user_role t1
LEFT JOIN sys_user t2 ON t2.id = t1.userId
LEFT JOIN sys_role t3 ON t3.id = t1.roleId
$condition
""");
Cnd cnd = Cnd.where("t3.`code`", "in", unitRoleCodes);
cnd.and("t1.unitId", "=", unitId);
if (StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
switch (pageForm.getSearchName()) {
case "loginname" -> cnd.where().andLike("t2.loginname", pageForm.getSearchKeyword());
case "username" -> cnd.where().andLike("t2.username", pageForm.getSearchKeyword());
case "roleName" -> cnd.where().andLike("t3.`name`", pageForm.getSearchKeyword());
}
}
cnd.asc("t2.username");
sql.setCondition(cnd);
Pagination pagination = sysUserService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At
@ApiOperation("按关键字查询单位下的人员")
@Ok("json:{ignoreNull:true}")
public Result listUserSelect(@Valid String unitId, @Valid String keyWord, @Valid String roleCode) {
Sql sql = Sqls.create("select id,loginname,username,unitname from vw_user $condition");
Cnd cnd = Cnd.NEW();
// 选择校领导角色时,人员范围来自提案配置中的校领导单位;其他角色仍限定当前单位。
if ("UNIT_SCHOOL_LEADER".equals(roleCode)) {
ProposalConfig proposalConfig = sysUnitService.dao().fetch(ProposalConfig.class, Cnd.NEW());
if (proposalConfig == null || Lang.isEmpty(proposalConfig.getSchoolLeaderUnitIds())) {
return Result.error("请在提案基础设置里配置校领导单位!");
}
cnd.and(View_user::getUnitId, "in", proposalConfig.getSchoolLeaderUnitIds());
} else {
cnd.and(View_user::getUnitId, "=", unitId);
}
cnd.and(View_user::getMember, "=", 1);
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(View_user::getLoginname, keyWord, true);
seg.orLike(View_user::getUsername, keyWord, true);
cnd.and(seg);
cnd.limit(1, 10);
sql.setCondition(cnd);
sql.setCallback(Sqls.callback.entities());
sql.setEntity(sysUnitService.dao().getEntity(View_user.class));
sysUnitService.dao().execute(sql);
List<View_user> list = sql.getList(View_user.class);
return Result.success(list);
}
@At
@Ok("json")
@Aop(TransAop.READ_COMMITTED)
public Result insertUnitUserRole(String userId, String roleCode, String unitId) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
throw new BaseException("无法找到{}对应编码的角色", roleCode);
}
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unitId", "=", unitId).and("underTakeId", "=", unitId));
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId()).add("userId", userId).add("unitId", unitId).add("underTakeId", unitId));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
@At
@Ok("json")
@Aop(TransAop.READ_COMMITTED)
public Result deleteUnitUserRole(String userId, String roleCode, String unitId) {
Sys_role role = sysRoleService.fetch(Cnd.where("code", "=", roleCode));
if (Lang.isEmpty(role)) {
throw new BaseException("无法找到{}对应编码的角色", roleCode);
}
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId()).and("userId", "=", userId).and("unitId", "=", unitId).and("underTakeId", "=", unitId));
sysRoleService.clearCache();
sysUserService.clearCache();
return Result.success();
}
@At("/child")
@Ok("json")
@SaCheckLogin
public Object child(@Param("pid") String pid, HttpServletRequest req) {
List<Sys_unit> list = new ArrayList<>();
List<NutMap> treeList = new ArrayList<>();
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
} else {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
if (user != null && Strings.isBlank(pid)) {
list = sysUnitService.query(Cnd.where("id", "=", user.getUnitId()).asc("path"));
} else {
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
}
}
for (Sys_unit unit : list) {
NutMap map = Lang.obj2nutmap(unit);
map.addv("expanded", false);
map.addv("children", new ArrayList<>());
treeList.add(map);
}
return Result.success().addData(treeList);
}
@At("/cascaderData")
@Ok("json")
@SaCheckLogin
public Object cascaderData(@Param("pid") String pid, HttpServletRequest req) {
try {
List<Sys_unit> list = new ArrayList<>();
List<NutMap> treeList = new ArrayList<>();
if (Strings.isBlank(pid)) {
NutMap root = NutMap.NEW().addv("value", "root").addv("label", "不选择单位").addv("leaf", true);
treeList.add(root);
}
if (StpUtil.hasRole("SYSADMIN")) {
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
} else {
Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
if (user != null && Strings.isBlank(pid)) {
list = sysUnitService.query(Cnd.where("id", "=", user.getUnitId()).asc("path"));
} else {
Cnd cnd = Cnd.NEW();
if (Strings.isBlank(pid)) {
cnd.and("parentId", "=", "").or("parentId", "is", null);
} else {
cnd.and("parentId", "=", pid);
}
cnd.asc("location").asc("path");
list = sysUnitService.query(cnd);
}
}
for (Sys_unit unit : list) {
NutMap map = NutMap.NEW().addv("value", unit.getId()).addv("label", unit.getName());
if (unit.isHasChildren()) {
map.addv("children", new ArrayList<>());
map.addv("leaf", false);
} else {
map.addv("leaf", true);
}
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At("/tree")
@Ok("json")
@SaCheckLogin
public Object tree(@Param("pid") String pid, HttpServletRequest req) {
try {
String rootId = StrUtil.blankToDefault(pid, "0");
String virtualRootId = "root";
Cnd cnd = Cnd.NEW();
cnd.asc("unitcode");
List<Sys_unit> list = sysUnitService.query(cnd);
List<TreeNode<String>> nodeList = CollUtil.newArrayList();
for (int i = 0; i < list.size(); i++) {
Sys_unit unit = list.get(i);
/*
* 单位根节点存在 id 与 parentId 都为 0 的自引用数据。
* 构建树时把当前查询根挂到虚拟根下,避免“中国地质大学”和 parentId=0 的学院被构造成同级。
*/
String parentId = rootId.equals(unit.getId()) ? virtualRootId : unit.getParentId();
nodeList.add(new TreeNode<>(unit.getId(), parentId, unit.getName(), i)
.setExtra(
Map.of(
"unitTypeCode", unit.getUnitTypeCode()
)
));
}
List<Tree<String>> treeList = TreeUtil.build(nodeList, virtualRootId);
return Result.success(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.unit.add")
@SLog(tag = "新建单位", msg = "单位名称:${args[0].name}")
public Object addDo(@Param("..") Sys_unit unit, @Param("parentId") String parentId, HttpServletRequest req) {
try {
if ("root".equals(parentId)) {
parentId = "";
}
unit.setCreatedBy(SecurityUtil.getUserId());
sysUnitService.save(unit, parentId);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
private List<NutMap> getTree(NutMap menuMap, String pid) {
List<NutMap> treeList = new ArrayList<>();
List<Sys_unit> subList = menuMap.getList(pid, Sys_unit.class);
for (Sys_unit menu : subList) {
NutMap map = Lang.obj2nutmap(menu);
map.put("label", menu.getName());
if (menu.isHasChildren() || (menuMap.get(menu.getId()) != null)) {
map.put("children", getTree(menuMap, menu.getId()));
}
treeList.add(map);
}
return treeList;
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.unit")
public Object edit(String id, HttpServletRequest req) {
try {
Sys_unit unit = sysUnitService.fetch(id);
return Result.success().addData(unit);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.unit.edit")
@SLog(tag = "编辑单位", msg = "单位名称:${args[0].name}")
public Object editDo(@Param("..") Sys_unit unit, @Param("parentId") String parentId, HttpServletRequest req) {
try {
unit.setUpdatedBy(SecurityUtil.getUserId());
sysUnitService.updateIgnoreNull(unit);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.unit.delete")
@SLog(tag = "删除单位", msg = "单位名称:${args[1].getAttribute('name')}")
public Object delete(String id, HttpServletRequest req) {
try {
Sys_unit unit = sysUnitService.fetch(id);
req.setAttribute("name", unit.getName());
if ("0001".equals(unit.getPath())) {
return Result.error("system.not.allow");
}
sysUnitService.deleteAndChild(unit);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
}
@@ -0,0 +1,127 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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.FieldFilter;
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.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@IocBean
@At("/platform/sys/userApproval/opinion")
@Ok("json:full")
@Api(tags = "用户审批意见")
public class SysUserApprovalOpinionController {
/**
* 系统内置的常用审批意见,统一提供给所有使用审核意见组件的页面。
*/
private static final List<String> DEFAULT_APPROVAL_OPINIONS = List.of("同意", "不同意");
@Inject
private Dao dao;
/**
* 保存当前用户的自定义审批意见。
*
* @param opinions 前端提交的意见数组,每项包含 id 和 text;系统内置的“同意”“不同意”不会写入用户数据
* @return Result,成功时不返回额外数据,失败时 msg 说明校验结果
*/
@At
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
@ApiOperation("保存审批意见")
public Result update(@Param("opinions")JSONObject[] opinions){
boolean hasBlank = Arrays.stream(opinions).anyMatch(v -> StrUtil.isBlank(v.getStr("text").trim()));
if(hasBlank){
return Result.error("内容不能为空,请删除后再提交!");
}
// 系统默认意见只参与页面展示,不占用用户自定义意见数量,也不写入用户表。
JSONObject[] customOpinions = Arrays.stream(opinions)
.filter(v -> !DEFAULT_APPROVAL_OPINIONS.contains(v.getStr("text").trim()))
.toArray(JSONObject[]::new);
Set<String> opinionTexts = Arrays.stream(customOpinions).map(v -> v.getStr("text").trim()).collect(Collectors.toSet());
if(opinionTexts.size() != customOpinions.length){
return Result.error("内容重复,请删除后再提交!");
}
boolean text = Arrays.stream(customOpinions).anyMatch(v -> v.getStr("text").trim().length() > 50);
if(text){
return Result.error("单条内容不能超过50个字!");
}
if(customOpinions.length > 5){
return Result.error("最多可添加10条审批意见!");
}
for (int i = 0; i < customOpinions.length; i++) {
customOpinions[i].set("id",i+1);
}
dao.update(Sys_user.class, Chain.make("customApprovalOpinions", Arrays.asList(customOpinions)), Cnd.where(Sys_user::getId,"=", SecurityUtil.getUserId()));
return Result.success();
}
/**
* 获取当前用户可选的审批意见。
*
* @return Resultdata 为意见数组,每项包含 id 和 text;系统默认意见排在用户自定义意见之前
*/
@At
@SaCheckLogin
@ApiOperation("获取审批意见")
public Result list(){
FieldFilter fieldFilter = FieldFilter.create(Sys_user.class, "^customApprovalOpinions");
Sys_user sysUser = Daos.ext(dao, fieldFilter).fetch(Sys_user.class, Cnd.where(Sys_user::getId, "=", SecurityUtil.getUserId()));
List<JSONObject> opinions = new ArrayList<>();
Set<String> opinionTexts = new HashSet<>();
// 默认意见始终置顶,并通过文本去重,避免与用户历史自定义意见重复。
for (String defaultOpinion : DEFAULT_APPROVAL_OPINIONS) {
JSONObject opinion = new JSONObject();
opinion.set("id", opinions.size() + 1);
opinion.set("text", defaultOpinion);
opinions.add(opinion);
opinionTexts.add(defaultOpinion);
}
List<JSONObject> customOpinions = Optional.ofNullable(sysUser.getCustomApprovalOpinions()).orElseGet(Collections::emptyList);
for (JSONObject customOpinion : customOpinions) {
String text = customOpinion.getStr("text");
if (StrUtil.isBlank(text) || !opinionTexts.add(text.trim())) {
continue;
}
JSONObject opinion = new JSONObject();
opinion.set("id", opinions.size() + 1);
opinion.set("text", text);
opinions.add(opinion);
}
return Result.success(opinions);
}
}
@@ -0,0 +1,401 @@
package com.budwk.app.sys.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.base.utils.PwdUtil;
import com.budwk.app.base.utils.SysMenuUtil;
import com.budwk.app.sys.models.Sys_menu;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysUnitService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.web.commons.base.Globals;
import org.nutz.dao.Chain;
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.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/**
* Created by wizzer on 2016/6/23.
*/
@IocBean
@At("/platform/sys/user")
public class SysUserController {
private static final Log log = Logs.get();
@Inject
private SysUserService sysUserService;
@Inject
private SysMenuService sysMenuService;
@Inject
private SysUnitService sysUnitService;
@At("")
@Ok("beetl:/platform/sys/user/index.html")
@SaCheckPermission("sys.manager.user")
public void index() {
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.user.add")
@SLog(tag = "新建用户", msg = "用户名:${user.loginname}")
public Object addDo(@Param("..") Sys_user user, HttpServletRequest req) {
try {
if (Strings.isNotBlank(user.getLoginname())) {
int num = sysUserService.count(Cnd.where("loginname", "=", Strings.trim(user.getLoginname())));
if (num > 0) {
return Result.error("用户名已存在!");
}
}
if (!ReUtil.isMatch("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()\\-_=+{};:,<.>]).{8,20}$", user.getPassword())) {
return Result.error("密码必须包含大小写字母、数字和特殊符号,且长度在8-20位之间!");
}
String salt = R.UU32();
user.setSalt(salt);
user.setPassword(PwdUtil.getPassword(user.getPassword(), salt));
user.setLoginCount(0);
user.setUnitPath(sysUnitService.fetch(user.getUnitId()).getPath());
sysUserService.insert(user);
sysUserService.clearCache();
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/edit/?")
@Ok("json")
@SaCheckPermission("sys.manager.user")
public Object edit(@Valid String id) {
try {
Sql sql = Sqls.create("""
SELECT
u.id,
u.loginname,
u.username,
u.sex,
n.`name` AS unitName
FROM
sys_user u
LEFT JOIN sys_unit n ON n.id = u.unitid
WHERE u.id = @id
""");
sql.setParam("id", id);
sql.setCallback(Sqls.callback.map());
sysUserService.execute(sql);
return Result.success().addData(sql.getResult());
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json")
@SaCheckPermission("sys.manager.user.edit")
@SLog(tag = "修改用户", msg = "用户名:${user.loginname}")
public Object editDo(@Param("..") Sys_user user, HttpServletRequest req) {
try {
// sysUserService.updateIgnoreNull(user);
sysUserService.dao().update(user, "username");
sysUserService.deleteCache(user.getId());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/resetPwd/?")
@Ok("json")
@SaCheckPermission("sys.manager.user.edit")
@SLog(tag = "重置密码", msg = "用户名:${args[1].getAttribute('loginname')}")
public Object resetPwd(String id, HttpServletRequest req) {
try {
Sys_user user = sysUserService.fetch(id);
// String pwd = PwdUtil.generate(12);
String pwd = "@dd3s#3618!";
String salt = R.UU32();
String encryptPwd = PwdUtil.getPassword(pwd, salt);
sysUserService.update(Chain.make("password", encryptPwd).add("salt", salt), Cnd.where("id", "=", id));
sysUserService.deleteCache(user.getId());
req.setAttribute("loginname", user.getLoginname());
return Result.success().addData(pwd);
} catch (Exception e) {
return Result.error();
}
}
@At("/delete/?")
@Ok("json")
@SaCheckPermission("sys.manager.user.delete")
@SLog(tag = "删除用户", msg = "用户名:${args[1].getAttribute('loginname')}")
public Object delete(String userId, HttpServletRequest req) {
try {
Sys_user user = sysUserService.fetch(userId);
if ("superadmin".equals(user.getLoginname())) {
return Result.error("system.not.allow");
}
sysUserService.deleteById(userId);
sysUserService.deleteCache(user.getId());
req.setAttribute("loginname", user.getLoginname());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/delete")
@Ok("json")
@SaCheckPermission("sys.manager.user.delete")
@SLog(tag = "批量删除用户", msg = "用户ID:${args[1].getAttribute('ids')}")
public Object deletes(@Param("ids") String[] userIds, HttpServletRequest req) {
try {
Sys_user user = sysUserService.fetch(Cnd.where("loginname", "=", "superadmin"));
StringBuilder sb = new StringBuilder();
for (String s : userIds) {
if (s.equals(user.getId())) {
return Result.error("system.not.allow");
}
sb.append(s).append(",");
}
sysUserService.deleteByIds(userIds);
sysUserService.clearCache();
req.setAttribute("ids", sb.toString());
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/enable/?")
@Ok("json")
@SaCheckPermission("sys.manager.user.edit")
@SLog(tag = "启用用户", msg = "用户名:${args[1].getAttribute('loginname')}")
public Object enable(String userId, HttpServletRequest req) {
try {
req.setAttribute("loginname", sysUserService.fetch(userId).getLoginname());
sysUserService.update(Chain.make("disabled", false), Cnd.where("id", "=", userId));
sysUserService.deleteCache(userId);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/disable/?")
@Ok("json")
@SaCheckPermission("sys.manager.user.edit")
@SLog(tag = "禁用用户", msg = "用户名:${req.getAttribute('loginname')}")
public Object disable(String userId, HttpServletRequest req) {
try {
String loginname = sysUserService.fetch(userId).getLoginname();
if ("superadmin".equals(loginname)) {
return Result.error("system.not.allow");
}
req.setAttribute("loginname", loginname);
sysUserService.update(Chain.make("disabled", true), Cnd.where("id", "=", userId));
sysUserService.deleteCache(userId);
return Result.success();
} catch (Exception e) {
return Result.error();
}
}
@At("/menu/?")
@Ok("json")
@SaCheckPermission("sys.manager.user")
public Object menu(String id, @Param("pid") String pid, HttpServletRequest req) {
try {
List<Sys_menu> list = sysUserService.getRoleMenus(id, pid);
List<NutMap> treeList = new ArrayList<>();
for (Sys_menu unit : list) {
if (!unit.isHasChildren() && sysUserService.hasChildren(id, unit.getId())) {
unit.setHasChildren(true);
}
NutMap map = Lang.obj2nutmap(unit);
map.addv("expanded", false);
map.addv("children", new ArrayList<>());
treeList.add(map);
}
return Result.success().addData(treeList);
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("json:{locked:'password|salt',ignoreNull:false}")
@SaCheckPermission("sys.manager.user")
public Object pageData(@Param("searchUnit") String searchUnit, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword, @Param("pageNumber") int pageNumber, @Param("pageSize") int pageSize, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy) {
try {
Sql sql = Sqls.create("""
SELECT
u.id,
u.loginname,
u.username,
u.sex,
n.`name` AS unitName
FROM
sys_user u
LEFT JOIN sys_unit n ON n.id = u.unitid
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("u.unitid", "=", searchUnit);
if (Strings.isNotBlank(searchName) && Strings.isNotBlank(searchKeyword)) {
cnd.and(searchName, "like", "%" + searchKeyword + "%");
}
if (Strings.isNotBlank(pageOrderName) && Strings.isNotBlank(pageOrderBy)) {
cnd.orderBy(pageOrderName, PageUtil.getOrder(pageOrderBy));
}
sql.setCondition(cnd);
return Result.success().addData(sysUserService.listPageMap(pageNumber, pageSize, sql));
} catch (Exception e) {
return Result.error();
}
}
@At
@Ok("void")
@SaCheckPermission("sys.manager.user")
public void export(@Param("searchUnit") String searchUnit, @Param("searchName") String searchName, @Param("searchKeyword") String searchKeyword, @Param("pageOrderName") String pageOrderName, @Param("pageOrderBy") String pageOrderBy, HttpServletResponse response) {
}
@At
@Ok("beetl:/platform/sys/user/pass.html")
@SaCheckLogin
public void pass() {
}
@At
@Ok("json")
@SaCheckLogin
public Object doChangePassword(@Param("oldPassword") String oldPassword, @Param("newPassword") String newPassword, HttpServletRequest req) {
if ("superadmin".equals(SecurityUtil.getUserLoginname()) && Globals.MyConfig.getBoolean("AppDemoEnv")) {
return Result.error("演示环境,不予操作");
}
// Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
// String old = PwdUtil.getPassword(oldPassword, user.getSalt());
// if (old.equals(user.getPassword())) {
// String salt = R.UU32();
// String hashedPasswordBase64 = PwdUtil.getPassword(newPassword, salt);
// user.setSalt(salt);
// user.setPassword(hashedPasswordBase64);
// sysUserService.update(Chain.make("salt", salt).add("password", hashedPasswordBase64), Cnd.where("id", "=", user.getId()));
// sysUserService.deleteCache(user.getId());
// return Result.success();
// } else {
// return Result.error();
// }
return Result.success();
}
@At
@Ok("json")
@SaCheckLogin
public Object doChangeInfo(@Param("username") String username, @Param("mobile") String mobile, @Param("email") String email, HttpServletRequest req) {
if ("superadmin".equals(SecurityUtil.getUserLoginname()) && Globals.MyConfig.getBoolean("AppDemoEnv")) {
return Result.error("演示环境,不予操作");
}
sysUserService.update(Chain.make("username", username).add("mobile", mobile).add("email", email), Cnd.where("id", "=", SecurityUtil.getUserId()));
sysUserService.deleteCache(SecurityUtil.getUserId());
return Result.success();
}
/**
* 获取子应用菜单
*
* @param appId
* @return
*/
@At
@Ok("json")
@SaCheckLogin
public Result subAppMenus(@Param("appId") String appId, @Param("platform") String platform) {
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
if (StrUtil.isNotBlank(platform)) {
menus = menus.stream().filter(menu -> platform.equals(menu.getPlatform())).toList();
}
List<Sys_menu> list = SysMenuUtil.createTreeMenus(menus, appId);
if (ObjectUtil.isEmpty(list)) {
List<Sys_menu> self = menus.stream().filter(menu -> menu.getId().equals(appId)).toList();
return Result.success().addData(self);
}
return Result.success(list);
}
/**
* 根据请求地址查询根菜单ID
*
* @return
*/
@At
@Ok("json")
@SaCheckLogin
public Result rootMenuByPath(@Param("pathname") String pathname, HttpServletResponse response) {
if (StrUtil.isBlank(pathname)) {
return Result.success();
}
try {
URI uri = new URI(pathname);
String path = uri.getPath();
// Sys_menu menu = sysMenuService.fetch(Cnd.where(Sys_menu::getHref, "like", pathname + "%"));
Sys_menu menu = sysMenuService.fetch(Cnd.where(Sys_menu::getHref, "=", path));
if (menu == null) {
return Result.success();
}
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
Sys_menu rootMenu = SysMenuUtil.getRootMenu(menus, menu);
return Result.success().addData(rootMenu);
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
/**
* 获取当前登录用户信息
*
* @return
*/
@At
@Ok("json")
@SaCheckLogin
public Result getLogonUser() {
Sys_user userAndMenuById = sysUserService.getUserAndMenuById(SecurityUtil.getUserId());
return Result.success().addData(userAndMenuById);
}
}
@@ -0,0 +1,129 @@
package com.budwk.app.sys.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.sys.models.Sys_home_template;
import com.budwk.app.sys.param.SysHomeTemplatePageForm;
import com.budwk.app.sys.services.SysHomeTemplateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
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 javax.validation.Valid;
@IocBean
@At("/platform/sys/worktemplate")
@Ok("json:full")
@Api(value = "首页工作模板")
public class SysWorkTemplateController {
@Inject
private SysHomeTemplateService sysHomeTemplateService;
@At("")
@Ok("beetl:/platform/sys/worktemplate/index.html")
@SaCheckPermission("sys.worktemplate")
public void index() {
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("分页数据")
public Result pageData(@Valid SysHomeTemplatePageForm pageForm) {
Cnd cnd = Cnd.NEW();
cnd.and(Cnd.likeEX(Sys_home_template::getName, pageForm.getName()));
cnd.asc(Sys_home_template::getSortNo);
Pagination pagination = sysHomeTemplateService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
return Result.success(pagination);
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("启用")
public Result enable(@Valid String id) {
sysHomeTemplateService.update(Chain.make("enable", 1), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("关闭")
public Result disable(@Valid String id) {
sysHomeTemplateService.update(Chain.make("enable", 0), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("修改模板名称")
public Result updateTemplateName(@Valid String id, String templateName) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
sysHomeTemplateService.update(Chain.make("templateName", templateName), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("修改模板图标")
public Result updateTemplateIcon(@Valid String id, String templateIcon) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
sysHomeTemplateService.update(Chain.make("templateIcon", templateIcon), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("修改模板文件")
public Result updateTemplateFile(@Valid String id, String templateFile) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
sysHomeTemplateService.update(Chain.make("templateFile", templateFile), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("修改排序")
public Result updateSortNo(@Valid String id, Integer sortNo) {
if (StrUtil.isBlank(id)) {
return Result.error("参数错误");
}
sysHomeTemplateService.update(Chain.make("sortNo", sortNo == null ? 0 : sortNo), Cnd.where("id", "=", id));
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("置顶")
public Result topUp(@Valid String id) {
Sys_home_template sysHomeTemplate = new Sys_home_template();
sysHomeTemplate.setId(id);
sysHomeTemplate.setTop(true);
sysHomeTemplateService.updateIgnoreNull(sysHomeTemplate);
return Result.success();
}
@At
@SaCheckPermission("sys.worktemplate")
@ApiOperation("取消置顶")
public Result cancelTopUp(@Valid String id) {
Sys_home_template sysHomeTemplate = new Sys_home_template();
sysHomeTemplate.setId(id);
sysHomeTemplate.setTop(false);
sysHomeTemplateService.updateIgnoreNull(sysHomeTemplate);
return Result.success();
}
}
@@ -0,0 +1,204 @@
package com.budwk.app.sys.controller.v4;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.sys.models.Sys_menu;
import com.budwk.app.sys.models.Sys_module;
import com.budwk.app.sys.models.Sys_user_favorite_app;
import com.budwk.app.sys.services.SysMenuService;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
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.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.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.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@IocBean
@At("/platform/v4/apps")
@Api(value = "应用中心接口", tags = "应用中心接口")
public class SysV4AppsController {
@Inject
private Dao dao;
@Inject
private SysMenuService sysMenuService;
@Inject
private SysUserService sysUserService;
@At("/categories")
@Ok("json")
@SaCheckLogin
@ApiOperation("获取应用分类")
public Result categories(@Param(value = "platform", df = "PC") String platform) {
List<Sys_module> list = dao.query(Sys_module.class, Cnd.where(Sys_module::getPlatform, "=", platform).asc(Sys_module::getSortNum));
List<Map<String, Object>> categories = list.stream().map(module -> {
Map<String, Object> category = new HashMap<>();
category.put("id", module.getId());
category.put("name", module.getName());
category.put("icon", module.getFaIcon());
category.put("picIcon", module.getIcon());
return category;
}).toList();
return Result.success("获取应用分类成功").addData(categories);
}
@At("/list")
@Ok("json:full")
@SaCheckLogin
@ApiOperation("获取应用列表")
public Result list(@Param("categoryId") String categoryId, @Param("letter") String letter, @Param("keyword") String keyword, @Param(value = "platform", df = "PC") String platform, HttpServletRequest req) {
List<Sys_menu> menus = sysUserService.getMenus(SecurityUtil.getUserId());
Sql sql = Sqls.create("""
SELECT
m.id,
m.`name`,
m.href,
m.icon,
m.picIcon,
m.location,
sm.`name` AS moduleName,
CASE
WHEN f.userId IS NOT NULL THEN
1 ELSE 0
END AS isFavorite
FROM
sys_menu m
LEFT JOIN sys_user_favorite_app f ON m.id = f.appId
AND f.userId = @userId
LEFT JOIN sys_module sm ON sm.id = m.moduleId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("m.platform", "=", platform);
cnd.and("m.disabled", "=", false);
cnd.and(Cnd.exps("m.parentId", "is", null).or("m.parentId", "=", ""));
cnd.and("m.id","in", menus.stream().map(Sys_menu::getId).toArray());
cnd.andEX("m.moduleId", "=", categoryId);
cnd.asc("m.location");
cnd.asc("m.id");
if (StrUtil.isNotBlank(keyword)) {
cnd.where().andLike("m.name", keyword);
}
cnd.andEX("m.initialPinyinName", "=", letter);
sql.setCondition(cnd);
sql.setParam("userId", SecurityUtil.getUserId());
List<NutMap> list = sysMenuService.listMap(sql);
return Result.success(list);
}
@At("/recommended")
@Ok("json")
@SaCheckLogin
@ApiOperation("获取推荐应用")
public Result recommended(HttpServletRequest req) {
// // 这里简单地返回前6个应用作为推荐应用
// int recommendCount = Math.min(6, APPS.size());
// List<Map<String, Object>> recommendedApps = new ArrayList<>();
//
// // 获取用户收藏状态
// String userId = getCurrentUserId(req);
// Set<String> favorites = FAVORITES.getOrDefault(userId, new HashSet<>());
//
// // 添加收藏状态
// for (int i = 0; i < recommendCount; i++) {
// Map<String, Object> app = APPS.get(i);
// Map<String, Object> appWithFavorite = new HashMap<>(app);
// String appId = String.valueOf(appWithFavorite.get("id"));
// appWithFavorite.put("isFavorite", favorites.contains(appId));
// recommendedApps.add(appWithFavorite);
// }
//
// Map<String, Object> data = new HashMap<>();
// data.put("list", recommendedApps);
// data.put("total", recommendedApps.size());
// data.put("pageNumber", 1);
// data.put("pageSize", recommendedApps.size());
// data.put("totalPage", 1);
return Result.success("获取推荐应用成功");
}
@At("/favorite")
@Ok("json:full")
@SaCheckLogin
@ApiOperation("获取收藏的应用")
public Result favorite(String platform, HttpServletRequest req) {
Sql sql = Sqls.create("""
SELECT
m.id,
m.`name`,
m.href,
m.icon,
m.picIcon,
m.location,
sm.`name` AS moduleName,
1 AS isFavorite
FROM
sys_user_favorite_app f
INNER JOIN
sys_menu m
ON
f.appId = m.id
LEFT JOIN sys_module sm ON sm.id = m.moduleId
WHERE
f.userId = @userId
AND m.platform = @platform
AND m.disabled = 0
ORDER BY
m.location ASC,
m.id ASC;
""");
sql.setParam("userId", SecurityUtil.getUserId());
sql.setParam("platform", platform);
List<NutMap> list = sysMenuService.listMap(sql);
return Result.success(list);
}
@At("/addFavorite")
@Ok("json")
@SaCheckLogin
@ApiOperation("添加收藏")
@Aop(TransAop.READ_COMMITTED)
public Result addFavorite(@Param("appId") String appId, HttpServletRequest req) {
if (Strings.isBlank(appId)) {
return Result.error("应用ID不能为空");
}
dao.clear(Sys_user_favorite_app.class, Cnd.where(Sys_user_favorite_app::getAppId, "=", appId).and(Sys_user_favorite_app::getUserId, "=", SecurityUtil.getUserId()));
Sys_user_favorite_app app = new Sys_user_favorite_app();
app.setAppId(appId);
app.setUserId(SecurityUtil.getUserId());
dao.insert(app);
return Result.success("收藏成功");
}
@At("/removeFavorite")
@Ok("json")
@SaCheckLogin
@ApiOperation("取消收藏")
public Result removeFavorite(@Param("appId") String appId, HttpServletRequest req) {
if (Strings.isBlank(appId)) {
return Result.error("应用ID不能为空");
}
dao.clear(Sys_user_favorite_app.class, Cnd.where(Sys_user_favorite_app::getAppId, "=", appId).and(Sys_user_favorite_app::getUserId, "=", SecurityUtil.getUserId()));
return Result.success("取消收藏成功");
}
}
@@ -0,0 +1,172 @@
package com.budwk.app.sys.controller.v4;
import cn.dev33.satoken.annotation.SaCheckLogin;
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.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.message.models.GlobalMessage;
import com.budwk.app.zhgh.dayofficework.message.models.GlobalMessageReceiver;
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageSendService;
import com.budwk.app.zhgh.dayofficework.message.service.GlobalMessageService;
import io.swagger.annotations.Api;
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;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@IocBean
@At("/platform/v4/msg")
@Api(value = "消息中心", tags = "消息中心接口")
@Ok("json:full")
public class SysV4MsgController {
@Inject
private Dao dao;
@Inject
private GlobalMessageService globalMessageService;
@Inject
private GlobalMessageSendService globalMessageSendService;
@At
@ApiOperation("获取消息列表")
@SaCheckLogin
public Result pageData(PageForm pageForm, @Param("isRead") int isRead, @Param("type") Integer type, HttpServletRequest req) {
Sql sql = Sqls.create("""
SELECT
m.id,
m.title,
m.content,
m.type,
m.sendTime,
r.isRead,
r.readTime
FROM
global_message m
INNER JOIN global_message_receiver r ON m.id = r.messageId
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("m.status", "=", 2);
cnd.and("r.receiverId", "=", SecurityUtil.getUserId());
if (isRead == 0) {
cnd.and("r.isRead", "=", 0);
} else if (isRead == 1) {
cnd.and("r.isRead", "=", 1);
}
cnd.andEX("m.type", "=", type);
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
String keyword = "%" + pageForm.getSearchKeyword() + "%";
cnd.and(Cnd.exps("m.title", "like", keyword).or("m.content", "like", keyword));
}
cnd.desc("m.sendTime");
sql.setCondition(cnd);
String title = "审批待办";
String content = "您有一个新的审批任务需要处理,请及时登录系统查看。";
List<String> receiverIds = Arrays.asList("17a7f8ad3ee947b4a26175049a9c253d");
// 自动发送到所有启用的渠道
// globalMessageSendService.sendMessage(title, content, 2, receiverIds, null);
Pagination pagination = globalMessageService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pagination);
}
@At("/stats")
@ApiOperation("获取消息统计信息")
@SaCheckLogin
public Result getStats() {
List<GlobalMessage> messageList = dao.query(GlobalMessage.class, Cnd.where(GlobalMessage::getStatus, "=", 2));
List<String> messageIds = messageList.stream().map(GlobalMessage::getId).toList();
// 查询总数
int totalCount = dao.count(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()).and(GlobalMessageReceiver::getMessageId, "in", messageIds));
// 查询未读数
int unreadCount = dao.count(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()).and(GlobalMessageReceiver::getIsRead, "=", 0).and(GlobalMessageReceiver::getMessageId, "in", messageIds));
// 查询已读数
int readCount = totalCount - unreadCount;
NutMap stats = NutMap.NEW()
.addv("total", totalCount)
.addv("unread", unreadCount)
.addv("read", readCount);
// .addv("typeStats", typeStats);
return Result.success(stats);
}
@At("/detail/?")
@ApiOperation("获取消息详情")
@SaCheckLogin
public Result getDetail(String messageId) {
GlobalMessageReceiver receiver = dao.fetch(GlobalMessageReceiver.class, Cnd.where(GlobalMessageReceiver::getMessageId, "=", messageId).and(GlobalMessageReceiver::getReceiverId, "=", SecurityUtil.getUserId()));
dao.fetchLinks(receiver, "globalMessage");
// 标记为已读
if (receiver != null && !receiver.getIsRead()) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
dao.update(receiver);
}
return Result.success(receiver);
}
@At("/read/?")
@ApiOperation("标记消息为已读")
public Result markAsRead(String messageId) {
GlobalMessageReceiver receiver = dao.fetch(GlobalMessageReceiver.class, Cnd.where("messageId", "=", messageId).and("receiverId", "=", SecurityUtil.getUserId()));
if (receiver != null && !receiver.getIsRead()) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
dao.update(receiver);
}
return Result.success();
}
@At("/read/batch")
@ApiOperation("批量标记消息为已读")
@SaCheckLogin
public Result batchMarkAsRead(@Param("messageIds") String[] messageIds) {
List<GlobalMessageReceiver> receivers = dao.query(GlobalMessageReceiver.class, Cnd.where("messageId", "in", messageIds).and("receiverId", "=", SecurityUtil.getUserId()));
for (GlobalMessageReceiver receiver : receivers) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
}
dao.update(receivers);
return Result.success();
}
@At("/read/all")
@ApiOperation("标记所有消息为已读")
@SaCheckLogin
public Result markAllAsRead() {
List<GlobalMessageReceiver> receivers = dao.query(GlobalMessageReceiver.class, Cnd.where("receiverId", "=", SecurityUtil.getUserId()));
for (GlobalMessageReceiver receiver : receivers) {
receiver.setIsRead(true);
receiver.setReadTime(new Date());
}
dao.update(receivers);
return Result.success();
}
}
@@ -0,0 +1,73 @@
package com.budwk.app.sys.controller.v4;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.entity.ProcessCategory;
import com.budwk.app.sys.services.SysMenuService;
import io.swagger.annotations.Api;
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;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@IocBean
@At("/platform/v4/serv")
@Api(value = "服务中心接口", tags = "服务中心接口")
public class SysV4ServController {
@Inject
private Dao dao;
@Inject
private SysMenuService sysMenuService;
@At("/categories")
@Ok("json")
@SaCheckLogin
@ApiOperation("获取分类")
public Result categories() {
List<ProcessCategory> list = dao.query(ProcessCategory.class, Cnd.NEW());
return Result.success(list);
}
@At("/list")
@Ok("json:full")
@SaCheckLogin
@ApiOperation("获取应用列表")
public Result list(@Param("categoryId") String categoryId, @Param("letter") String letter, @Param("keyword") String keyword, HttpServletRequest req) {
Sql sql = Sqls.create("""
SELECT t.*, d.picIcon, d.sortNo
FROM wf_process_define t
INNER JOIN (
SELECT name, MAX(id) AS max_id
FROM wf_process_define
GROUP BY name
) sub ON t.name = sub.name AND t.id = sub.max_id
LEFT JOIN wf_process_design d ON d.name = t.name
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(keyword)) {
cnd.where().andLike("t.disPlayName", keyword);
}
cnd.andEX("t.category", "=", categoryId);
cnd.andEX("t.pinyinName", "=", letter);
cnd.asc("d.sortNo");
cnd.asc("t.id");
sql.setCondition(cnd);
List<NutMap> list = sysMenuService.listMap(sql);
return Result.success(list);
}
}
@@ -0,0 +1,31 @@
package com.budwk.app.sys.enums;
import lombok.Getter;
/**
* @version 1.0
* @Author zzr
* @nameApi2FinanceFiledMap
* @Date 2025/9/16 9:51
* @注释 财务会费字段映射
*/
@Getter
public enum Api2FinanceFiledMap {
// 工号
RYDM("rydm", "loginname"),
// 人员名称
RYMC("rymc", "username"),
// 编制会费
HF("hf", "name"),
// 合同制会费
HF2("hf2", "unitType");
public final String apiField;
public final String dbColumn;
Api2FinanceFiledMap(String apiField, String dbColumn) {
this.apiField = apiField;
this.dbColumn = dbColumn;
}
}
@@ -0,0 +1,27 @@
package com.budwk.app.sys.enums;
import lombok.Getter;
/**
* @version 1.0
* @Author zzr
* @nameApi2UnitFiledMap
* @Date 2025/9/16 8:52
* @注释 单位接口转单位字段映射
*/
@Getter
public enum Api2UnitFiledMap {
ZZJGDM("dwdm", "id"),
ZZJGMC("dwmc", "name"),
BMLB("bmflmc", "unitType");
public final String apiField;
public final String dbColumn;
Api2UnitFiledMap(String apiField, String dbColumn) {
this.apiField = apiField;
this.dbColumn = dbColumn;
}
}
@@ -0,0 +1,123 @@
package com.budwk.app.sys.enums;
import com.budwk.app.base.annotation.DictEnum;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.utils.PwdUtil;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.sys.services.SysRoleService;
import lombok.Getter;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.lang.random.R;
import java.util.Date;
import java.util.Set;
/**
* 高级导入工具插件。
*/
@Getter
@DictEnum(key = "sysDataImportPlugin", name = "系统数据高级工具插件")
public enum SysDataImportPlugin {
USER_INIT(1, "初始化系统用户"),
MEMBER_INIT(2, "设置为会员");
private final int location;
private final String description;
SysDataImportPlugin(int location, String description) {
this.location = location;
this.description = description;
}
public void before(PluginContext context) {
if (!context.isSysUserTable()) {
return;
}
if (this == USER_INIT) {
String salt = R.UU32();
context.addValue("salt", salt);
context.addValue("password", PwdUtil.getPassword(PwdUtil.generate(12), salt));
context.addValue("loginCount", 0);
context.addValue("disabled", false);
return;
}
if (this == MEMBER_INIT) {
context.addValue("member", true);
context.addValue("memberTime", new Date());
}
}
public void after(PluginContext context) {
if (!context.isSysUserTable()) {
return;
}
if (this == USER_INIT) {
context.ensureRole(RoleConstant.PUBLIC);
return;
}
if (this == MEMBER_INIT) {
context.ensureRole(RoleConstant.MEMBER);
}
}
@Getter
public static class PluginContext {
private final String tableName;
private final Set<String> tableColumns;
private final Chain chain;
private final Object pk;
private final Dao dao;
private final SysRoleService sysRoleService;
public PluginContext(String tableName,
Set<String> tableColumns,
Chain chain,
Object pk,
Dao dao,
SysRoleService sysRoleService) {
this.tableName = tableName;
this.tableColumns = tableColumns;
this.chain = chain;
this.pk = pk;
this.dao = dao;
this.sysRoleService = sysRoleService;
}
public boolean isSysUserTable() {
return "sys_user".equalsIgnoreCase(tableName);
}
public boolean hasColumn(String columnName) {
return tableColumns.contains(columnName);
}
public void addValue(String columnName, Object value) {
if (hasColumn(columnName)) {
chain.add(columnName, value);
}
}
public void ensureRole(RoleConstant roleConstant) {
if (pk == null || !isSysUserTable()) {
return;
}
Sys_role sysRole = sysRoleService.getByCode(roleConstant);
if (sysRole == null) {
return;
}
int count = dao.count(Sys_user_role.class, Cnd.where("userId", "=", String.valueOf(pk))
.and("roleId", "=", sysRole.getId()));
if (count > 0) {
return;
}
Sys_user_role userRole = new Sys_user_role();
userRole.setUserId(String.valueOf(pk));
userRole.setRoleId(sysRole.getId());
dao.insert(userRole);
}
}
}
@@ -0,0 +1,22 @@
package com.budwk.app.sys.enums;
import com.budwk.app.base.annotation.DictEnum;
import com.budwk.app.sys.services.impl.SysDataUserAllUpdateServiceImpl;
import com.budwk.app.sys.services.impl.SysDataUserIncrUpdateServiceImpl;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Getter
@DictEnum(key = "sysDataUpdateMode", name = "系统数据更新")
@AllArgsConstructor
@Slf4j
public enum SysDataUpdateMode {
ALL("全量更新", SysDataUserAllUpdateServiceImpl.class),
INCR("增量更新", SysDataUserIncrUpdateServiceImpl.class);
private final String desc;
private final Class<?> clazz;
}
@@ -0,0 +1,24 @@
package com.budwk.app.sys.enums;
/**
* 文件存储桶的权限策略枚举
*
*/
public enum SysFileBucketAuthEnum {
/**
* 私有的(仅有 owner 可以读写)
*/
PRIVATE,
/**
* 公有读,私有写( owner 可以读写, 其他客户可以读)
*/
PUBLIC_READ,
/**
* 公共读写(即所有人都可以读写,慎用)
*/
PUBLIC_READ_WRITE
}
@@ -0,0 +1,31 @@
package com.budwk.app.sys.enums;
import lombok.Getter;
/**
* 文件存储引擎类型枚举
*
* @author xuyuxiang
* @date 2022/6/16 16:14
**/
@Getter
public enum SysFileEngineTypeEnum {
/** 本地 */
LOCAL("LOCAL"),
/** 阿里云 */
ALIYUN("ALIYUN"),
/** 腾讯云 */
TENCENT("TENCENT"),
/** MINIO */
MINIO("MINIO");
private final String value;
SysFileEngineTypeEnum(String value) {
this.value = value;
}
}
@@ -0,0 +1,83 @@
package com.budwk.app.sys.interceptor;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.constant.RoleConstant;
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.enums.ProcessSubmitTypeEnum;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_union_cadre;
import com.budwk.app.sys.services.SysRoleService;
import com.budwk.app.sys.services.SysUserService;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import java.util.ArrayList;
import java.util.List;
/**
* @version 1.0
* @Author FKY
* @nameSysUnionSchoolAuditInterceptor
* @Date 2025/10/28 10:15
* @注释
*/
public class SysUnionSchoolAuditInterceptor implements FlowInterceptor {
@Override
public void intercept(Execution execution) {
// 是否审核通过
boolean submitType = execution.getArgs().getInt("submitType").equals(ProcessSubmitTypeEnum.AGREE.getCode());
if (submitType) {
// 审核通过,添加相应的角色
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
SysRoleService sysRoleService = ServiceContext.find(SysRoleService.class);
SysUserService sysUserService = ServiceContext.find(SysUserService.class);
// 表单数据
JSONObject formData = JSONUtil.parseObj(formDataStr);
Sys_union_cadre unionBean = JSONUtil.toBean(formData, Sys_union_cadre.class);
// 清除对应角色然后再新增
Sys_role role = sysRoleService.getByCode(unionBean.getRoleCode());
sysRoleService.clear("sys_user_role", Cnd.where("roleId", "=", role.getId())
.and("userId", "=", unionBean.getUserId()).and("unionId", "=", unionBean.getUnionId()));
if (RoleConstant.UNIT_PARTY_SECRETARY.name().equals(unionBean.getRoleCode())) {
// 二级党委书记按申请中选定的单位分别授权,保障流程可按申请人所属单位找到办理人。
JSONArray unitIdArray = formData.getJSONArray("unitIds");
List<String> unitIds = new ArrayList<>();
if (unitIdArray != null) {
for (Object unitId : unitIdArray) {
String value = StrUtil.toString(unitId);
if (StrUtil.isNotBlank(value) && !unitIds.contains(value)) {
unitIds.add(value);
}
}
}
if (unitIds.isEmpty()) {
throw new IllegalArgumentException("二级党委书记未选择所属单位");
}
for (String unitId : unitIds) {
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId())
.add("userId", unionBean.getUserId()).add("unionId", unionBean.getUnionId()).add("unitId", unitId));
}
} else {
// 其他分工会角色保持原有按分工会单条授权的逻辑。
sysRoleService.insert("sys_user_role", Chain.make("roleId", role.getId())
.add("userId", unionBean.getUserId()).add("unionId", unionBean.getUnionId()));
}
// 清除缓存
sysRoleService.clearCache();
sysUserService.clearCache();
}
// 未审核通过,不作操作
}
}
@@ -0,0 +1,113 @@
package com.budwk.app.sys.listener;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.event.role.RoleEventListener;
import com.budwk.app.base.event.role.RoleEventMsg;
import com.budwk.app.sys.models.Sys_role;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.models.Sys_user_role;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import java.util.List;
/**
* @version 1.0
* @Author zzr
* @nameSysRoleEventListener
* @Date 2025/9/3 17:35
* @注释
*/
@IocBean
public class SysRoleEventListener implements RoleEventListener {
@Inject
private Dao dao;
@Override
@Aop(TransAop.READ_COMMITTED)
public void receive(RoleEventMsg message) {
if (ObjectUtil.isAllEmpty(message.getUserIds(), message.getUnitId(), message.getRoleCode())) {
return;
}
switch (message.getOperationType()) {
case RoleEventMsg.ADD_ROLE -> {
addRole(message);
}
case RoleEventMsg.REMOVE_ROLE -> {
removeRole(message);
}
case RoleEventMsg.RENEW_ROLE -> {
removeRole(message);
addRole(message);
}
}
}
/**
* 添加角色
* @param message 订阅消息
*/
private void addRole(RoleEventMsg message) {
Sys_role role = dao.fetch(Sys_role.class, Cnd.where("code", "=", message.getRoleCode()));
if (ObjectUtil.isAllNotEmpty(message.getUserIds(), message.getRoleCode())) {
List<Sys_user_role> roleList = message.getUserIds().stream().map(item -> {
Sys_user_role userRole = new Sys_user_role();
userRole.setUserId(item);
userRole.setUnitId(StrUtil.isNotBlank(message.getUnitId()) ? message.getUnitId() : null);
userRole.setRoleId(role.getId());
return userRole;
}).toList();
dao.insert(roleList);
} else if (ObjectUtil.isAllNotEmpty(message.getUnitId(), message.getRoleCode())) {
List<Sys_user> userList = dao.query(Sys_user.class, Cnd.where("unitId", "=", message.getUnitId()));
List<Sys_user_role> roleList = userList.stream().map(item -> {
Sys_user_role userRole = new Sys_user_role();
userRole.setUserId(item.getId());
userRole.setUnitId(item.getUnitId());
userRole.setRoleId(role.getId());
return userRole;
}).toList();
dao.insert(roleList);
}
}
/**
* 删除角色
* @param message 订阅消息
*/
private void removeRole(RoleEventMsg message) {
Sys_role role = dao.fetch(Sys_role.class, Cnd.where("code", "=", message.getRoleCode()));
if (ObjectUtil.isEmpty(role)) {
return;
}
// 判断传过来的东西
if (ObjectUtil.isAllNotEmpty(message.getUserIds(), message.getUnitId(), message.getRoleCode())) {
dao.clear(Sys_user_role.class,
Cnd.where("userId", "in", message.getUserIds())
.and("unitId", "=", message.getUnitId())
.and("roleId", "=", role.getId())
);
} else if (ObjectUtil.isAllNotEmpty(message.getUserIds(), message.getRoleCode())) {
dao.clear(Sys_user_role.class,
Cnd.where("userId", "in", message.getUserIds())
.and("roleId", "=", role.getId())
);
} else if (ObjectUtil.isAllNotEmpty(message.getUnitId(), message.getUnitId())) {
dao.clear(Sys_user_role.class,
Cnd.where("unitId", "=", message.getUnitId())
.and("roleId", "=", role.getId())
);
}
}
}
@@ -0,0 +1,60 @@
package com.budwk.app.sys.listener;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.event.user.UserChangeEventListener;
import com.budwk.app.base.event.user.UserChangeMsg;
import com.budwk.app.sys.models.Sys_user_role;
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.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;
/**
* @version 1.0
* @Author zzr
* @nameSysUserChangeListener
* @Date 2025/8/13 15:24
* @注释 有关系统人员的广播监听
*/
@IocBean
public class SysUserChangeListener implements UserChangeEventListener {
@Inject
private Dao dao;
@Override
@Aop(TransAop.READ_COMMITTED)
public void receive(UserChangeMsg message) {
if (ObjectUtil.equals(message.getOperationType(), UserChangeMsg.UNIT_CHANGE_OPERATION)) {
// 单位变动,删除原单位的角色
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", message.getUserIds()).and("unitId", "=", message.getSourceUnitId()));
// 判断这两个单位是不是在一个工会,如果不是,删除原来工会的所有角色
Sql sql = Sqls.create("""
SELECT
(SELECT unionId FROM sys_unit WHERE id = @sourceUnitId) AS sourceUnionId,
(SELECT unionId FROM sys_unit WHERE id = @targetUnitId) AS targetUnionId,
CASE
WHEN (SELECT unionId FROM sys_unit WHERE id = @sourceUnitId) IS NULL
AND (SELECT unionId FROM sys_unit WHERE id = @targetUnitId) IS NULL THEN true
WHEN (SELECT unionId FROM sys_unit WHERE id = @sourceUnitId) =
(SELECT unionId FROM sys_unit WHERE id = @targetUnitId) THEN true
ELSE false
END AS result
""").setParam("sourceUnitId", message.getSourceUnitId()).setParam("targetUnitId", message.getTargetUnitId());
sql.setCallback(Sqls.callback.map());
dao.execute(sql);
NutMap result = (NutMap) sql.getResult();
if (!result.getBoolean("result")) {
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", message.getUserIds()).and("unionId", "=", result.getString("sourceUnionId")));
}
}
}
}
@@ -0,0 +1,55 @@
package com.budwk.app.sys.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @author zhf
* @date 2025/11/19 09:25
* @description 工会委员
*/
@Data
@Table("sys_committee_member")
public class SysCommitteeMember {
@Name
@ColDefine
@Column
@PrevInsert(uu32 = true)
@Comment("id")
private String id;
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("工号")
@Column
private String loginName;
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("姓名")
@Column
private String userName;
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("userId")
@Column
private String userId;
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("职务")
@Column
private String position;
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("届次名称")
@Column
private String sessionName;
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("届次Id")
@Column
private String sessionId;
}
@@ -0,0 +1,38 @@
package com.budwk.app.sys.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
/**
* @Author: JyuHsin
* @Date: 2024/6/6 15:33
* @Version: v1.0.0
* @Description: TODO
**/
@Data
@Table("sys_holiday")
public class SysHoliday {
@Name
@ColDefine
@Column
@PrevInsert(uu32 = true)
@Comment("id")
private String id;
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("名称")
@Column
private String name;
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("日期")
@Column
private String day;
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("周几")
@Column
private String week;
}
@@ -0,0 +1,39 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* API密钥管理
* Created by wizzer on 2019/2/26.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_api")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_api extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
private String appid;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String appkey;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String name;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
}
@@ -0,0 +1,94 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* 应用管理--配置文件表
* Created by wizzer on 2019/2/27.
*/
@Table("sys_app_conf")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_app_conf extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("实例名")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String confName;
@Column
@Comment("版本号")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String confVersion;
@Column
@Comment("配置内容")
@ColDefine(type = ColType.TEXT)
private String confData;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
@One(field = "createdBy")
private Sys_user user;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getConfName() {
return confName;
}
public void setConfName(String confName) {
this.confName = confName;
}
public String getConfVersion() {
return confVersion;
}
public void setConfVersion(String confVersion) {
this.confVersion = confVersion;
}
public String getConfData() {
return confData;
}
public void setConfData(String confData) {
this.confData = confData;
}
public boolean isDisabled() {
return disabled;
}
public void setDisabled(boolean disabled) {
this.disabled = disabled;
}
public Sys_user getUser() {
return user;
}
public void setUser(Sys_user user) {
this.user = user;
}
}
@@ -0,0 +1,53 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* 应用管理--应用实例表
* Created by wizzer on 2019/2/27.
*/
@Data
@Table("sys_app_list")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_app_list extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Prev(els = {@EL("uuid()")})
private String id;
@Column
@Comment("实例名")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String appName;
@Column
@Comment("版本号")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String appVersion;
@Column
@Comment("文件大小")
private Long fileSize;
@Column
@Comment("文件路径")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String filePath;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
@One(field = "createdBy")
private Sys_user user;
}
@@ -0,0 +1,78 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* 应用管理--推送任务表
* Created by wizzer on 2019/2/27.
*/
@Data
@Table("sys_app_task")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_app_task extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@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 name;
@Column
@Comment("执行动作")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String action;
@Column
@Comment("APP版本")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String appVersion;
@Column
@Comment("配置版本")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String confVersion;
@Column
@Comment("进程ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String processId;
@Column
@Comment("推送主机")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String hostName;//主机名 如果是推送给全部主机则为多条
@Column
@Comment("主机IP")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String hostAddress;//只为展示用
@Column
@Comment("推送状态")
@ColDefine(type = ColType.INT, width = 1)
private Integer status;//0-待执行,1-执行中,2-执行成功,3-执行失败,4-撤销任务
@Column
@Comment("反馈时间")
private Long pushAt;
@Column
@Comment("反馈结果")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String pushResult;
@One(field = "createdBy")
private Sys_user user;
}
@@ -0,0 +1,36 @@
package com.budwk.app.sys.models;
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;
@EqualsAndHashCode(callSuper = true)
@Data
@Table("sys_branch_union_user_permission")
@Comment("分工会人员权限")
public class Sys_branch_union_user_permission extends BaseModel {
@Name
@Comment("ID")
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Column
@Comment("用户id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("权限id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String roleId;
@Column
@Comment("分工会id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
}
@@ -0,0 +1,32 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.io.Serializable;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_config")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_config extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Name
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
private String configKey;
@Column
@ColDefine(type = ColType.TEXT)
private String configValue;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
private String note;
}
@@ -0,0 +1,34 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
/**
* @version 1.0
* @Author zzr
* @nameSys_data_dict
* @Date 2025/9/22 16:43
* @注释
*/
@Data
@Table
@EqualsAndHashCode(callSuper = true)
public class Sys_data_dict extends BaseModel {
@Column
@Comment("父级编码")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String parentCode;
@Column
@Comment("名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String code;
}
@@ -0,0 +1,72 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.DB;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_dict")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_DICT_PATH", fields = {"path"}, unique = true)})
public class Sys_dict extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("父级ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String parentId;
@Column
@Comment("树路径")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String path;
@Column
@Comment("名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column
@Comment("备注")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String remark;
@Column
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String code;
@Column
@Comment("启用状态")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
@Column
@Comment("排序字段")
@Prev({
@SQL(db= DB.MYSQL,value = "SELECT IFNULL(MAX(location),0)+1 FROM sys_dict"),
@SQL(db= DB.ORACLE,value = "SELECT COALESCE(MAX(location),0)+1 FROM sys_dict")
})
private Integer location;
@Column
@Comment("有子节点")
private boolean hasChildren;
}
@@ -0,0 +1,79 @@
package com.budwk.app.sys.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@Table("sys_file")
@Comment("系统文件管理")
public class Sys_file extends BaseModel implements Serializable {
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Column
@Comment("存储引擎")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String engine;
@Column
@Comment("存储桶")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String bucket;
@Column
@Comment("文件名")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String name;
@Column
@Comment("文件后缀")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String suffix;
@Column
@Comment("文件大小kb")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String sizeKb;
@Column
@Comment("文件大小(格式化后)")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String sizeInfo;
@Column
@Comment("文件的对象名(唯一名称)")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String objName;
@Column
@Comment("文件存储路径")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String storagePath;
@Column
@Comment("文件下载路径")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String downloadPath;
@Column
@Comment("图片缩略图")
@ColDefine(type = ColType.TEXT)
private String thumbnail;
@Column
@Comment("扩展信息")
@ColDefine(type = ColType.MYSQL_JSON)
private JSONObject extJson;
}
@@ -0,0 +1,94 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.util.Date;
@EqualsAndHashCode(callSuper = true)
@Data
@Table
@Comment("首页活动")
public class Sys_home_activity extends BaseModel {
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("主键ID,和业务ID保持一致")
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("活动名称")
private String name;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
@Comment("活动封面")
private String cover;
@Column
@ColDefine(type = ColType.TEXT)
@Comment("活动内容")
private String content;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("活动链接")
private String url;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("h5活动链接")
private String h5Url;
@Column
@ColDefine(type = ColType.INT)
@Comment("面向人员分组ID")
private Integer allowUserGroupId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("允许查看的人员sql")
private String allowUserSql;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否启用")
@Default("0")
private Boolean enable;
@Column
@Comment("类路径")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String classPath;
@Column
@Comment("是否置顶")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean top;
@Column
@Comment("是否推送大图")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean push;
@Column
@Comment("排序号")
@Default("0")
private Integer sortNo;
@Column
@Comment("开始时间")
@ColDefine(type = ColType.DATETIME)
private Date startDate;
@Column
@Comment("结束时间")
@ColDefine(type = ColType.DATETIME)
private Date endDate;
}
@@ -0,0 +1,109 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import java.util.Date;
@EqualsAndHashCode(callSuper = true)
@Data
@Table
@Comment("首页工作模板")
public class Sys_home_template extends BaseModel {
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("主键ID,和业务ID保持一致")
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("模板名称")
private String name;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("展示模板名称")
private String templateName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
@Comment("模板图标")
private String templateIcon;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("模板文件")
private String templateFile;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
@Comment("模板封面")
private String cover;
@Column
@ColDefine(type = ColType.TEXT)
@Comment("模板内容")
private String content;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("模板链接")
private String url;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("h5模板链接")
private String h5Url;
@Column
@ColDefine(type = ColType.INT)
@Comment("面向人员分组ID")
private Integer allowUserGroupId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 1000)
@Comment("允许查看的人员sql")
private String allowUserSql;
@Column
@ColDefine(type = ColType.BOOLEAN)
@Comment("是否启用")
@Default("0")
private Boolean enable;
@Column
@Comment("类路径")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String classPath;
@Column
@Comment("是否置顶")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean top;
@Column
@Comment("是否推送大图")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean push;
@Column
@Comment("排序号")
@Default("0")
private Integer sortNo;
@Column
@Comment("开始时间")
@ColDefine(type = ColType.DATETIME)
private Date startDate;
@Column
@Comment("结束时间")
@ColDefine(type = ColType.DATETIME)
private Date endDate;
}
@@ -0,0 +1,73 @@
package com.budwk.app.sys.models;
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;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_log_${month}")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_log extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("操作人姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String username;
@Column
@Comment("操作人用户名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String loginname;
@Column
@Comment("日志类型")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String type;
@Column
@Comment("日志标识")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String tag;
@Column
@Comment("执行类")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String src;
@Column
@Comment("来源IP")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String ip;
@Column
@Comment("日志内容")
@ColDefine(type = ColType.TEXT)
private String msg;
@Column
@Comment("请求结果")
@ColDefine(customType = "MEDIUMTEXT")
private String param;
@Column
@Comment("执行结果")
@ColDefine(type = ColType.TEXT)
private String result;
}
@@ -0,0 +1,141 @@
package com.budwk.app.sys.models;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.DB;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_menu")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_MENU_PATH", fields = {"path"}, unique = true), @Index(name = "INDEX_SYS_MENU_PREM", fields = {"permission"}, unique = true)})
public class Sys_menu extends BaseModel implements Serializable {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("父级ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String parentId;
@Column
@Comment("树路径")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String path;
@Column
@Comment("菜单名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column
@Comment("菜单首字母")
@ColDefine(type = ColType.CHAR, width = 1)
private Character initialPinyinName;
@Column
@Comment("菜单别名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String aliasName;
@Column
@Comment("资源类型")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String type;
@Column
@Comment("菜单链接")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String href;
@Column
@Comment("打开方式")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String target;
@Column
@Comment("菜单图标")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String icon;
@Column
@Comment("图片图标")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String picIcon;
@Column
@Comment("是否显示")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean showit;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean disabled;
@Column
@Comment("权限标识")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String permission;
@Column
@Comment("菜单介绍")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String note;
@Column
@Comment("排序字段")
@Prev({@SQL(db = DB.MYSQL, value = "SELECT IFNULL(MAX(location),0)+1 FROM sys_menu"), @SQL(db = DB.ORACLE, value = "SELECT COALESCE(MAX(location),0)+1 FROM sys_menu")})
private Integer location;
@Column
@Comment("有子节点")
private boolean hasChildren;
@Column
@Comment("所属平台(pc、h5")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String platform;
@Column
@Comment("所属模块")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String moduleId;
@Column
@Comment("是否是推荐应用")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isRecommendApp;
@Column
@Comment("是否是推荐服务")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean isRecommendService;
//按钮权限
private List<Sys_menu> buttons;
//子菜单
private List<Sys_menu> children = new ArrayList<>();
}
@@ -0,0 +1,52 @@
package com.budwk.app.sys.models;
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.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_module")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("系统模块")
public class Sys_module extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("所属平台(pc、h5")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String platform;
@Column
@Comment("模块名称")
@ColDefine(type = ColType.VARCHAR, width = 8)
private String name;
@Column
@Comment("图标")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String icon;
@Column
@Comment("FontAwesome图标")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String faIcon;
@Column
@Comment("排序编号")
@ColDefine(type = ColType.INT)
private Integer sortNum;
//菜单
private List<Sys_menu> menus;
}
@@ -0,0 +1,75 @@
package com.budwk.app.sys.models;
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 org.nutz.dao.interceptor.annotation.PrevInsert;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_msg")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("系统消息")
public class Sys_msg extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("消息类型")
@ColDefine(type = ColType.VARCHAR, width = 32)
@NotBlank(message = "消息类型不能为空")
private String type;
@Column
@Comment("消息标题")
@ColDefine(type = ColType.VARCHAR, width = 255)
@NotBlank(message = "消息标题不能为空")
private String title;
@Column
@Comment("消息内容")
@ColDefine(type = ColType.TEXT)
@NotBlank(message = "消息内容不能为空")
private String note;
@Column
@Comment("消息URL")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String url;
@Column
@Comment("发送时间")
//Long不要用ColDefine定义,兼容oracle/mysql,支持2038年以后的时间戳
private Long sendAt;
@Many(field = "msgId")
private List<Sys_msg_user> userList;
@Column
@Comment("是否需要反馈")
@ColDefine(type = ColType.BOOLEAN)
private Boolean needBack;
@Column
@Comment("附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> files;
@Column
@Comment("发送模式(显示、隐式)show hide")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String sendType;
}
@@ -0,0 +1,86 @@
package com.budwk.app.sys.models;
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 org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
import java.util.List;
/**
* Created by wizzer on 2018/6/29.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_msg_user")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_msg_user extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("消息ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String msgId;
@Column
@Comment("用户名")
@ColDefine(type = ColType.VARCHAR, width = 120)
private String loginname;
@Column
@Comment("用户名称")
@ColDefine(type = ColType.VARCHAR, width = 120)
private String userName;
@Column
@Comment("单位ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@Column
@Comment("单位名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unitName;
@Column
@Comment("分工会ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("单位名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionName;
@Column
@Comment("消息状态")
@ColDefine(type = ColType.INT)
private int status;//0--未读 1--已读
@Column
@Comment("读取时间")
//Long不要用ColDefine定义,兼容oracle/mysql,支持2038年以后的时间戳
private Long readAt;
@One(field = "msgId")
private Sys_msg msg;
@Column
@Comment("反馈内容")
@ColDefine(type = ColType.VARCHAR, width = 500)
private String backText;
@Column
@Comment("反馈附件")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> backFiles;
}
@@ -0,0 +1,53 @@
package com.budwk.app.sys.models;
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 org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
@Table
@Comment("导出模板")
public class Sys_office_template extends BaseModel {
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("模板名称")
private String templateName;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("模板代码")
private String templateCode;
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
@Comment("模板大小")
private String templateSize;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
@Comment("模板路径")
private String templatePath;
@Column
@ColDefine(type = ColType.MYSQL_JSON)
@Comment("模板对象")
private List<JSONObject> file;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
@Comment("模板说明")
private String templateDesc;
}
@@ -0,0 +1,24 @@
package com.budwk.app.sys.models;
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;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_quick_entry")
@TableMeta("{'mysql-charset':'utf8mb4'}")
//@TableIndexes({@Index(name = "INDEX_SYS_QUICK_ENTRY_USERID", fields = {"userId"})})
public class Sys_quick_entry extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
}
@@ -0,0 +1,71 @@
package com.budwk.app.sys.models;
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.List;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_role")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_ROLE_CODE", fields = {"code"}, unique = true)})
public class Sys_role extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
private String name;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
private String code;
@Column
@ColDefine(type = ColType.VARCHAR, width = 50)
private String aliasName;
@Column
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitid;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("所属模块ID")
private String moduleId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 255)
private String note;
@Column
@ColDefine(type = ColType.INT)
@Comment("排序")
private Integer sort;
@One(field = "unitid")
public Sys_unit unit;
@ManyMany(from = "roleId", relation = "sys_role_menu", to = "menuId")
protected List<Sys_menu> menus;
@ManyMany(from = "roleId", relation = "sys_user_role", to = "userId")
private List<Sys_user> users;
}
@@ -0,0 +1,46 @@
package com.budwk.app.sys.models;
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;
/**
* Created by Wizzer on 2016/7/31.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_route")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_route extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("原始路径")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String url;
@Column
@Comment("跳转路径")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String toUrl;
@Column
@Comment("转发类型")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String type;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
}
@@ -0,0 +1,65 @@
package com.budwk.app.sys.models;
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;
/**
* Created by Wizzer on 2016/7/30.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_task")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_task extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(els = {@EL("uuid()")})
private String id;
@Column
@Comment("任务名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String name;
@Column
@Comment("执行类")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String jobClass;
@Column
@Comment("任务说明")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String note;
@Column
@Comment("定时规则")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String cron;
@Column
@Comment("执行参数")
@ColDefine(type = ColType.TEXT)
private String data;
@Column
@Comment("执行时间")
private Long exeAt;
@Column
@Comment("执行结果")
@ColDefine(type = ColType.TEXT)
private String exeResult;
@Column
@Comment("是否禁用")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
}
@@ -0,0 +1,43 @@
package com.budwk.app.sys.models;
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;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_union")
@TableMeta("{'mysql-charset':'utf8mb4'}")
//@TableIndexes({@Index(name = "INDEX_SYS_UNIT_PATH", fields = {"path"}, unique = true),
// @Index(name = "INDEX_SYS_UNIT_UNITCODE", fields = {"unitcode"}, unique = true)
//})
public class Sys_union extends BaseModel {
@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 name;
@Column
@Comment("编码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionCode;
@Column
@Comment("联系电话")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String telephone;
@Column
@Comment("校区")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String campus;
}
@@ -0,0 +1,88 @@
package com.budwk.app.sys.models;
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.util.Date;
/**
* @version 1.0
* @Author FKY
* @nameSys_union_cadre
* @Date 2025/10/28 10:22
* @注释
*/
@Data
@Table
@EqualsAndHashCode(callSuper = true)
public class Sys_union_cadre extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("工会Id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("工会名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unionName;
@Column
@Comment("用户Id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("用户名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String userName;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String loginName;
@Column
@Comment("联系方式")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String mobile;
@Column
@Comment("角色编码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String roleCode;
@Column
@Comment("届数")
@ColDefine(type = ColType.VARCHAR, width = 8)
private String j;
@Column
@Comment("添加时间")
@ColDefine(type = ColType.DATETIME)
private Date applyDate;
@Column
@Comment("离任时间")
@ColDefine(type = ColType.DATETIME)
private Date leaveDate;
@Column
@Comment("是否在任")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isServing;
@Column
@Comment("加入还是退出")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isJoin;
}
@@ -0,0 +1,48 @@
package com.budwk.app.sys.models;
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.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_union_group")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@Comment("工会小组")
public class Sys_union_group extends BaseModel {
@Comment("ID")
@Name
@PrevInsert(uu32 = true)
private String id;
@Comment("所属分工会ID")
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("绑定单位Id集合")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> unitIds;
@Comment("名称")
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Comment("编码")
@Column
@ColDefine(type = ColType.VARCHAR, width = 10)
private String code;
@Comment("小组长")
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private List<String> leaders;
}
@@ -0,0 +1,133 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.DB;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Table("sys_unit")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_UNIT_PATH", fields = {"path"}, unique = true),
@Index(name = "INDEX_SYS_UNIT_UNITCODE", fields = {"unitcode"}, unique = true)
})
public class Sys_unit extends BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
@Column
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
// @PrevInsert(uu32 = true)
private String id;
@Column
@Comment("父级ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String parentId;
@Column
@Comment("树路径")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String path;
@Column
@Comment("单位名称")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String name;
@Column
@Comment("单位别名")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String aliasName;
@Column
@Comment("机构编码")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitcode;
@Column
@Comment("单位介绍")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String note;
@Column
@Comment("单位地址")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String address;
@Column
@Comment("联系电话")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String telephone;
@Column
@Comment("单位邮箱")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String email;
@Column
@Comment("单位网站")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String website;
@Column
@Comment("排序字段")
@Prev({
@SQL(db = DB.MYSQL, value = "SELECT IFNULL(MAX(location),0)+1 FROM sys_unit"),
@SQL(db = DB.ORACLE, value = "SELECT COALESCE(MAX(location),0)+1 FROM sys_unit")
})
private Integer location;
@Column
@Comment("有子节点")
private boolean hasChildren;
@Column
@Comment("单位logo")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String logo;
@Column
@Comment("等级")
@ColDefine(type = ColType.INT)
private Integer unitLevel;
@Column
@Comment("工会id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@Comment("小组id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionGroupId;
@Column
@Comment("处级_院系单位号")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String divisionCollegeCode;
@Column
@Comment("机构类型")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String institutionType;
@Column
@Comment("部门类别")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String unitType;
@Column
@Comment("部门类别区分(部门类设置 1, 其他设置 0)")
@ColDefine(type = ColType.INT)
private Integer unitTypeCode;
}
@@ -0,0 +1,448 @@
package com.budwk.app.sys.models;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.sys.annotation.DataCenterColumn;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.json.JsonField;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
* Created by wizzer on 2016/6/21.
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@Table("sys_user")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({@Index(name = "INDEX_SYS_USER_LOGINNAMAE", fields = {"loginname"})})
public class Sys_user 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 = 120)
@DataCenterColumn(name = "工号", key = "ZGH")
private String loginname;
@Column
@Comment("姓名")
@ColDefine(type = ColType.VARCHAR, width = 100)
@DataCenterColumn(name = "姓名", key = "XM")
private String username;
@Column
@Comment("性别")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "性别", key = "XB", dict = "USER_SEX")
private String sex;
@Column
@Comment("密码")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String password;
@Column
@Comment("密码盐")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String salt;
@Column
@Comment("出生日期")
@ColDefine(type = ColType.DATE)
private Date birthday;
@Column
@Comment("政治面貌")
@ColDefine(type = ColType.VARCHAR, width = 100)
@DataCenterColumn(name = "政治面貌", key = "ZZMMM", dict = "USER_POLITICAL")
private String political;
@Column
@ColDefine(type = ColType.DATE)
@Comment("入党时间")
private Date joinPartyDate;
@Column
@Comment("民族")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "民族", key = "MZM", dict = "USER_NATION")
private String nation;
@Column
@Comment("籍贯")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String nativePlace;
@Column
@Comment("国籍")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String nationality;
@Column
@Comment("证件类型")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String idCardType;
@Column
@Comment("证件号码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "证件号码", key = "SFZJH")
private String idCard;
@Column
@Comment("手机号码")
@ColDefine(type = ColType.VARCHAR, width = 32)
@DataCenterColumn(name = "手机号码", key = "YDDH")
private String mobile;
@Column
@Comment("学历")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String education;
@Column
@Comment("婚姻状况")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String marriage;
@Column
@Comment("学位")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "学位", key = "zgxwmc")
private String academicDegree;
@Column
@Comment("岗位类别")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String jobCategory;
@Column
@Comment("职称")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String professionalTitle;
@Column
@Comment("职级")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String professionalLevel;
@Column
@Comment("职工来源")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "职工来源", key = "zgly")
private String employeeSource;
@Column
@Comment("行政级别(用于管理岗位)")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "行政级别(用于管理岗位)", key = "xzjb")
private String administrativeLevel;
@Column
@Comment("岗位系列")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "岗位系列", key = "gwxl")
private String positionSeries;
@Column
@Comment("岗级")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "岗级", key = "gj")
private String positionLevel;
@Column
@Comment("行政岗级")
@ColDefine(type = ColType.VARCHAR, width = 50)
// @DataCenterColumn(name = "行政岗级", key = "xzgj")
private String administrativePositionLevel;
@Column
@Comment("来校时间")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "来校时间", key = "LXNY")
private String arrivalAtSchoolDate;
@Column
@Comment("工作时间")
@ColDefine(type = ColType.VARCHAR, width = 10)
private String workDate;
@Column
@Comment("身份类型")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String identityType;
@Column
@Comment("在职状态")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "当前状态码", key = "DQZT", dict = "USER_STATE")
private String userState;
@Column
@Comment("人员属性")
@ColDefine(type = ColType.VARCHAR, width = 50)
@Size(max = 50)
private String userAttribute;
@Column
@Comment("在岗情况")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String dutySituation;
@Column
@Comment("教职工类别码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "教职工类别码", key = "RYLX", dict = "USER_PERSON_TYPE")
private String personType;
@Column
@Comment("待确认状态:0不用确认、1待确认、2已确认")
@ColDefine(type = ColType.INT, width = 1)
@Default("0")
private Integer pendingConfirmStatus;
@Column
@Comment("编制类别码")
@ColDefine(type = ColType.VARCHAR, width = 30)
private String preparedBy;
@Column
@Comment("从教年月")
@ColDefine(type = ColType.DATE)
private Date teachingTime;
@Column
@Comment("预计离校时间/最后离校时间")
@ColDefine(type = ColType.DATE)
private Date expectedLeaveSchoolDate;
@Column
@Comment("退休时间")
@ColDefine(type = ColType.DATE)
private Date retireDate;
@Column
@Comment("博士后进站时间")
@ColDefine(type = ColType.DATE)
private Date postDoctoralJoinDate;
@Column
@Comment("头像")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String avatar;
@Column
@Comment("电子邮箱")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String email;
@Column
@Comment("创建时间")
@PrevInsert(now = true)
private Long createAt;
@Column
@Comment("登陆时间")
private Long loginAt;
@Column
@Comment("登陆次数")
@ColDefine(type = ColType.INT)
@Default(value = "0")
private Integer loginCount;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@DataCenterColumn(name = "单位", key = "SZDWH")
private String unitId;
@Column
@Comment("三级单位ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String threeUnitId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
private String unitPath;
@Column
@Comment("是否双肩挑")
@ColDefine(type = ColType.BOOLEAN)
@Default(value = "0")
private Boolean manyUnit;
@Column
@Comment("是否会员")
@ColDefine(type = ColType.BOOLEAN)
@Default(value = "0")
private Boolean member;
@Column
@Comment("会员加入时间")
@ColDefine(type = ColType.DATETIME)
private Date memberTime;
@Column
@Comment("编制会费")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal preparationMemberFee;
@Column
@Comment("合同制会费")
@ColDefine(customType = "decimal(10,2)")
private BigDecimal contractMemberFee;
@Column
@Comment("是否福利会员")
@ColDefine(type = ColType.BOOLEAN)
@Default(value = "0")
private Boolean welfareMember;
@Column
@Comment("家庭主要成员及其工作单位")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> families;
@Column
@Comment("是否愿意加入大病互助基金会")
@ColDefine(type = ColType.BOOLEAN)
@Default(value = "0")
private Boolean wantJoinLoveMutualAidAssociation;
@Column
@Comment("个人简况")
@ColDefine(type = ColType.VARCHAR, customType = "text")
private String personalData;
@Column
@Comment("特长及获奖情况")
@ColDefine(type = ColType.VARCHAR, customType = "text")
private String specialty;
@Column
@Comment("家庭住址")
@ColDefine(type = ColType.VARCHAR, width = 100)
private String homeAddress;
@Column
@Comment("校区")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String campus;
@Column
@Comment("常用审批意见")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> customApprovalOpinions;
@Column
@Comment("微信openId")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String wxOpenId;
@Column
@Comment("是否教学30年以上教工")
@ColDefine(type = ColType.BOOLEAN)
private Boolean isThirtyTeach;
@Column
@Comment("荣誉证办理年月")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String thirtyCertificateProcessingTime;
@One(field = "unitId")
private Sys_unit unit;
//分工会
private Sys_union union;
@ManyMany(from = "userId", relation = "sys_user_role", to = "roleId")
private List<Sys_role> roles;
@ManyMany(from = "userId", relation = "sys_user_unit", to = "unitId")
protected List<Sys_unit> units;
//全部菜单
protected List<Sys_menu> menus;
//常用菜单
private List<Sys_menu> customMenus;
//前端树形菜单
private List<Sys_menu> treeMenus;
//权限
private List<String> permissions;
//新版模块菜单
private List<Sys_module> pcModuleMenus;
private List<Sys_module> h5ModuleMenus;
@Column
@Comment("总积分")
@Default(value = "0")
@ColDefine(type = ColType.INT)
private Integer totalIntegral;
@Column
@Comment("是否禁用")
@Default(value = "0")
@ColDefine(type = ColType.BOOLEAN)
private boolean disabled;
@Column
@Comment("openId")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String openId;
/**
* 基金会员
*/
@Column
@Comment("是否大病基金会员")
@ColDefine(type = ColType.BOOLEAN)
@Default(value = "0")
private Boolean aidFundMember;
@Column
@Comment("基金会员类型(人员分类)")
@ColDefine(type = ColType.VARCHAR,width = 10)
private String aidFundMemberUserType;
@Column
@Comment("基金会员起扣时间")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String aidFundDeductTime;
@Column
@Comment("指退休之前的工号")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String oldLoginName;
@Column
@Comment("基金会员加入时间")
@ColDefine(type = ColType.DATETIME)
private Date aidFundMemberJoinTime;
@Column
@Comment("基金会员退出时间")
@ColDefine(type = ColType.DATETIME)
private Date aidFundMemberQuitTime;
}
@@ -0,0 +1,77 @@
package com.budwk.app.sys.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 org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.List;
/**
* @version 1.0
* @Author zzr
* @nameSys_user_change_info
* @Date 2024/10/30 10:59
* @注释
*/
@Data
@Table
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
public class Sys_user_change_info extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 100)
@NotBlank(message = "工号不能为空")
@Size(max = 100)
private String loginname;
@Column
@Comment("用户名")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String username;
@Column
@Comment("人员历史记录id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userHistoryId;
@Column
@Comment("申请时间")
@ColDefine(type = ColType.DATETIME)
@PrevInsert(now = true)
private Date changeTime;
@Column
@Comment("变更来源")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String changeOrigin;
@Column
@Comment("详细变更记录,用于查询、列表展示")
@ColDefine(type = ColType.MYSQL_JSON)
private List<NutMap> changeInfos;
@Column
@Comment("详细变更记录,文本类型,可用于导出")
@ColDefine(type = ColType.TEXT)
private String changeInfosStr;
}
@@ -0,0 +1,32 @@
package com.budwk.app.sys.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 org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Table
@Data
@Accessors(chain = true)
public class Sys_user_entrance extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("用户id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("默认模块id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String defaultModuleId;
}
@@ -0,0 +1,31 @@
package com.budwk.app.sys.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 org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Table
@Data
@Accessors(chain = true)
public class Sys_user_entrance_module extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("用户id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
@Column
@Comment("默认模块id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String defaultModuleId;
}
@@ -0,0 +1,35 @@
package com.budwk.app.sys.models;
import com.budwk.app.base.model.BaseModel;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
@EqualsAndHashCode(callSuper = true)
@Table("sys_user_favorite_app")
@Comment("用户收藏应用")
@ApiModel(description = "用户收藏应用")
@Data
@TableIndexes(value = {@Index(name = "INDEX_SYS_USER_FAVORITE_APP_USERID", fields = "userId", unique = false),
@Index(name = "INDEX_SYS_USER_FAVORITE_APP_APPID", fields = "appId", unique = false)})
public class Sys_user_favorite_app extends BaseModel {
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Name
@PrevInsert(uu32 = true)
private String id;
@Comment("用户ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String userId;
@Comment("应用ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@Column
private String appId;
}
@@ -0,0 +1,68 @@
package com.budwk.app.sys.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@Table("sys_user_history")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({
@Index(name = "INDEX_HISTORY_USER_LOGINNAMAE", fields = {"loginname"}, unique = false),
@Index(name = "INDEX_HISTORY_USER_UNIT", fields = {"unitId"}, unique = false),
})
@Comment("用户历史记录")
public class Sys_user_history extends Sys_user {
@Name
@Column
@Comment("ID")
@PrevInsert(uu32 = true)
@ColDefine(type = ColType.VARCHAR, width = 32)
private String id;
@Column
@Comment("更新时间")
@ColDefine(type = ColType.DATETIME)
private Date changeTime;
/**
* @see com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeType
*/
@Column
@Comment("变更类型(多种)")
@ColDefine(type = ColType.MYSQL_JSON)
private List<String> changeTypes;
@Column
@Comment("变更来源")
@ColDefine(type = ColType.VARCHAR, width = 50)
private String changeOrigin;
@Column
@ColDefine(type = ColType.VARCHAR, width = 100)
@Comment("变更原因")
private String changeReason;
@Column
@Comment("会员变更表记录id")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String recordId;
@Column
@Comment("详细变更记录,用于查询、列表展示")
@ColDefine(type = ColType.MYSQL_JSON)
private List<NutMap> changeInfos;
@Column
@Comment("详细变更记录,文本类型,可用于导出")
@ColDefine(type = ColType.TEXT)
private String changeInfosStr;
}
@@ -0,0 +1,71 @@
package com.budwk.app.sys.models;
import lombok.Data;
import org.nutz.dao.entity.annotation.*;
@Table("sys_user_role")
@Data
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_user_role {
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String roleId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String userId;
/**
* 用户角色关系是否启用。普通角色默认启用,教代会届次切换时按届次统一刷新。
*/
@Column
@Comment("是否启用:1启用,0禁用")
@ColDefine(type = ColType.BOOLEAN)
@Default("1")
private Boolean enable = true;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unitId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
private String unionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工会小组ID")
private String unionGroupId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("教代会代表团ID")
private String tcDelegationId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("教代会届次ID")
private String tcSessionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工代会代表团ID")
private String wcDelegationId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("工代会届次ID")
private String wcSessionId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("社团ID")
private String clubId;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("承办单位ID")
private String underTakeId;
}
@@ -0,0 +1,33 @@
package com.budwk.app.sys.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 org.nutz.dao.interceptor.annotation.PrevInsert;
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@Table("sys_user_signature")
@TableMeta("{'mysql-charset':'utf8mb4'}")
public class Sys_user_signature extends BaseModel {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@ColDefine(type = ColType.VARCHAR,width = 32)
@Comment("用户id")
private String userId;
@Column
@ColDefine(type = ColType.VARCHAR,width = 255)
@Comment("签字数据路径")
private String signature;
}
@@ -0,0 +1,39 @@
package com.budwk.app.sys.models;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.util.Date;
@Table("sys_user_source")
@TableMeta("{'mysql-charset':'utf8mb4'}")
@TableIndexes({
@Index(name = "INDEX_SYS_USER_SOURCE_LOGINNAMAE", fields = {"loginname"}, unique = false),
@Index(name = "INDEX_SYS_USER_SOURCE_PULLTIME", fields = {"pullTime"}, unique = false)
})
@Comment("系统用户拉取数据表")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class Sys_user_source extends Sys_user {
@Name
@Comment("ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("单位名称")
@ColDefine(type = ColType.VARCHAR, width = 255)
private String unitName;
@Column
@Comment("拉取时间")
@ColDefine(type = ColType.DATETIME)
private Date pullTime;
}
@@ -0,0 +1,35 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("用户数据拉取分页参数")
public class SysDataUserPullPageForm extends PageForm {
@ApiModelProperty("拉取日期")
private String pullTime;
@ApiModelProperty("姓名")
private String userName;
@ApiModelProperty("工号")
private String loginName;
@ApiModelProperty("单位名称")
private String unitName;
@ApiModelProperty("在职状态")
private String userState;
@ApiModelProperty("教职工类别")
private String personType;
@ApiModelProperty("用人方式")
private String preparedBy;
}
@@ -0,0 +1,38 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("用户数据更新分页参数")
public class SysDataUserUpdatePageForm extends PageForm {
@ApiModelProperty("姓名")
private String userName;
@ApiModelProperty("工号")
private String loginName;
@ApiModelProperty("单位")
private String unitId;
@ApiModelProperty("教职工类别")
private String personType;
@ApiModelProperty("编制类别")
private String preparedBy;
@ApiModelProperty("在职状态")
private String userState;
@ApiModelProperty("异动类型")
private String changeTime;
@ApiModelProperty("异动类型")
private String changeType;
}
@@ -0,0 +1,24 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.ConditionGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
@ApiModel("用户数据更新参数")
public class SysDataUserUpdateParam {
@ApiModelProperty("拉取时间")
@NotBlank(message = "数据源不能为空")
private String pullTime;
@ApiModelProperty("更新方式")
@NotBlank(message = "更新方式不能为空")
private String updateMode;
@ApiModelProperty("条件组 (可选)")
private ConditionGroup conditionGroup;
}
@@ -0,0 +1,17 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("系统首页活动管理查询参数")
public class SysHomeActivityPageForm extends PageForm {
@ApiModelProperty("活动名称")
private String name;
}
@@ -0,0 +1,17 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel("系统首页工作模板管理查询参数")
public class SysHomeTemplatePageForm extends PageForm {
@ApiModelProperty("模板名称")
private String name;
}
@@ -0,0 +1,26 @@
package com.budwk.app.sys.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(description = "消息统计参数")
public class SysMsgSummaryPageForm extends PageForm {
@ApiModelProperty("消息ID")
private String msgId;
@ApiModelProperty("工会ID")
private String unionId;
@ApiModelProperty("单位ID")
private String unitId;
@ApiModelProperty("阅读状态")
private Integer readStatus;
}
@@ -0,0 +1,41 @@
package com.budwk.app.sys.services;
import com.budwk.app.sys.models.Sys_api;
import com.budwk.app.base.service.BaseService;
public interface SysApiService extends BaseService<Sys_api> {
/**
* 创建密钥
*/
void createAppkey(String name, String userId) throws Exception;
/**
* 删除密钥
*/
void deleteAppkey(String appid) throws Exception;
/**
* 启用禁用
*/
void updateAppkey(String appid, boolean disabled) throws Exception;
/**
* 通过appid获取appkey
*
* @param appid appid
* @return Sys_api
*/
String getAppkey(String appid);
/**
* 删除缓存
*
* @param appid appid
*/
void deleteCache(String appid);
/**
* 清空缓存
*/
void clearCache();
}
@@ -0,0 +1,11 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_app_conf;
import java.util.List;
public interface SysAppConfService extends BaseService<Sys_app_conf> {
List<String> getConfNameList();
}
@@ -0,0 +1,11 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_app_list;
import java.util.List;
public interface SysAppListService extends BaseService<Sys_app_list> {
List<String> getAppNameList();
}
@@ -0,0 +1,9 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_app_task;
public interface SysAppTaskService extends BaseService<Sys_app_task> {
}
@@ -0,0 +1,33 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.sys.models.Sys_config;
import com.budwk.app.base.service.BaseService;
import java.util.List;
/**
* Created by wizzer on 2016/12/23.
*/
public interface SysConfigService extends BaseService<Sys_config> {
/**
* 查询所有数据
* @return
*/
List<Sys_config> getAllList();
Sys_config getValueByKey(String key);
/**
* 分页查询系统参数,支持按参数名模糊查询和安全排序。
*
* @param pageNumber 页码
* @param pageSize 每页条数
* @param pageOrderName 排序字段
* @param pageOrderBy 排序方向
* @param configKey 参数名关键字
* @return 系统参数分页数据
*/
Pagination<Sys_config> pageData(int pageNumber, int pageSize, String pageOrderName,
String pageOrderBy, String configKey);
}
@@ -0,0 +1,16 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_dict;
/**
* @version 1.0
* @Author zzr
* @nameSysDataDictPullService
* @Date 2025/9/22 11:35
* @注释
*/
public interface SysDataDictPullService extends BaseService<Sys_dict> {
void pullDataDict();
}
@@ -0,0 +1,20 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_unit;
import java.util.List;
/**
* @version 1.0
* @Author zzr
* @nameSysDataUnitPullService
* @Date 2025/9/15 17:54
* @注释
*/
public interface SysDataUnitPullService extends BaseService<Sys_unit> {
void updateUnits();
void updateUnits(List<String> unitIds);
}
@@ -0,0 +1,41 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_user_source;
import org.nutz.lang.util.NutMap;
import java.util.Date;
import java.util.List;
import java.util.Map;
public interface SysDataUserPullService extends BaseService<Sys_user_source> {
/**
* 从信息中心拉取数据
*/
Date pull();
/**
* 拉取人员博士后的信息
*/
Map<String, Date> pullPostDoctoral();
/**
* 获取下拉框数据(单位、在职状态、编制类别、教职工类别)
*/
NutMap searchOptions();
/**
* 获取数据源拉取时间列表
*
* @return
*/
List<NutMap> pullTimeOptions();
/**
* 获取财务数据
* @return
*/
Map<String, NutMap> pullFinance();
}
@@ -0,0 +1,10 @@
package com.budwk.app.sys.services;
import com.budwk.app.sys.param.SysDataUserUpdateParam;
/**
* 信息中心数据更新
*/
public interface SysDataUserUpdateService {
String update(SysDataUserUpdateParam updateParam);
}
@@ -0,0 +1,101 @@
package com.budwk.app.sys.services;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.sys.models.Sys_dict;
import java.util.List;
import java.util.Map;
public interface SysDictService extends BaseService<Sys_dict> {
/**
* 通过code获取名称
*
* @param code
* @return
*/
String getNameByCode(String code);
/**
* 通过ID获取名称
*
* @param id
* @return
*/
String getNameById(String id);
/**
* 通过树PATH获取子级
*
* @param path
* @return
*/
List<Sys_dict> getSubListByPath(String path);
/**
* 通过ID获取子级
*
* @param id
* @return
*/
List<Sys_dict> getSubListById(String id);
/**
* 通过code获取子级
*
* @param code
* @return
*/
List<Sys_dict> getSubListByCode(String code);
/**
* 通过树PATH获取子级
*
* @param path
* @return
*/
Map getSubMapByPath(String path);
/**
* 通过ID获取子级
*
* @param id
* @return
*/
Map getSubMapById(String id);
/**
* 通过code获取子级
*
* @param code
* @return
*/
Map getSubMapByCode(String code);
/**
* 保存数据字典
*
* @param dict
* @param pid
*/
void save(Sys_dict dict, String pid);
/**
* 保存数据字典
*
* @param dict dict
* @param parentCode parentCode
*/
void saveByParentCode(Sys_dict dict, String parentCode);
/**
* 级联删除数据
*
* @param dict
*/
void deleteAndChild(Sys_dict dict);
/**
* 清空缓存
*/
void clearCache();
}

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