mirror of https://gitee.com/xiaonuobase/snowy
【更新】更新并升级v3.5.1版本
parent
3a5ecac001
commit
b7f164082b
|
@ -238,7 +238,9 @@ snowy
|
|||
|
||||
QQ技术群:732230670(已满)、685395081
|
||||
|
||||
微信技术群:因群达到200人以上,需加微信拉群
|
||||
微信技术群:
|
||||
|
||||
因群达到200人以上,需加微信拉群,禁止群内艾特群主及管理员,私信提问技术问题无时间精力回答(免开尊口),请群内互动互助才是建群的意义,否则我认为你没有加群的必要
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.common.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 通用性别枚举
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/13 17:48
|
||||
**/
|
||||
@Getter
|
||||
public enum CommonGenderEnum {
|
||||
|
||||
/** 未知 */
|
||||
UNKNOWN("未知"),
|
||||
|
||||
/** 男 */
|
||||
MAN("男"),
|
||||
|
||||
/** 女 */
|
||||
WOMAN("女");
|
||||
|
||||
private final String value;
|
||||
|
||||
CommonGenderEnum(String value) {
|
||||
this.value = value.toLowerCase();
|
||||
}
|
||||
}
|
|
@ -191,7 +191,7 @@ public class CommonDataChangeEventCenter {
|
|||
* @author xuyuxiang
|
||||
* @date 2023/3/3 10:22
|
||||
**/
|
||||
public static void doDeleteWithDataId(String dataType, List<String> dataIdList) {
|
||||
public static void doDeleteWithDataIdList(String dataType, List<String> dataIdList) {
|
||||
for (CommonDataChangeListener listener : listenerList) {
|
||||
listener.doDeleteWithDataIdList(dataType, dataIdList);
|
||||
}
|
||||
|
|
|
@ -19,4 +19,12 @@ package vip.xiaonuo.dev.api;
|
|||
* @date 2022/9/2 15:58
|
||||
*/
|
||||
public interface DevDictApi {
|
||||
|
||||
/**
|
||||
* 根据类型跟子类型获得翻译后的label
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2025/6/6 13:04
|
||||
*/
|
||||
String getDictLabel(String typeCode, String value);
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ import vip.xiaonuo.auth.core.annotation.SaClientCheckLogin;
|
|||
import vip.xiaonuo.auth.core.enums.SaClientTypeEnum;
|
||||
import vip.xiaonuo.auth.core.pojo.SaBaseClientLoginUser;
|
||||
import vip.xiaonuo.auth.core.util.StpClientUtil;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthAccountPasswordLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthGetPhoneValidCodeParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthPhoneValidCodeLoginParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.AuthRegisterParam;
|
||||
import vip.xiaonuo.auth.modular.login.param.*;
|
||||
import vip.xiaonuo.auth.modular.login.result.AuthPicValidCodeResult;
|
||||
import vip.xiaonuo.auth.modular.login.service.AuthService;
|
||||
import vip.xiaonuo.common.pojo.CommonResult;
|
||||
|
@ -65,25 +62,38 @@ public class AuthClientController {
|
|||
}
|
||||
|
||||
/**
|
||||
* C端获取手机验证码
|
||||
* C端获取手机登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@Operation(summary = "C端获取手机验证码")
|
||||
@Operation(summary = "C端获取手机登录验证码")
|
||||
@GetMapping("/auth/c/getPhoneValidCode")
|
||||
public CommonResult<String> getPhoneValidCode(@Valid AuthGetPhoneValidCodeParam authGetPhoneValidCodeParam) {
|
||||
return CommonResult.data(authService.getPhoneValidCode(authGetPhoneValidCodeParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端获取邮箱登录验证码
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/7/8 9:26
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@Operation(summary = "C端获取邮箱登录验证码")
|
||||
@GetMapping("/auth/c/getEmailValidCode")
|
||||
public CommonResult<String> getEmailValidCode(@Valid AuthGetEmailValidCodeParam authGetEmailValidCodeParam) {
|
||||
return CommonResult.data(authService.getEmailValidCode(authGetEmailValidCodeParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端账号密码登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperationSupport(order = 4)
|
||||
@Operation(summary = "C端账号密码登录")
|
||||
@PostMapping("/auth/c/doLogin")
|
||||
public CommonResult<String> doLogin(@RequestBody @Valid AuthAccountPasswordLoginParam authAccountPasswordLoginParam) {
|
||||
|
@ -96,20 +106,33 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperationSupport(order = 5)
|
||||
@Operation(summary = "C端手机验证码登录")
|
||||
@PostMapping("/auth/c/doLoginByPhone")
|
||||
public CommonResult<String> doLoginByPhone(@RequestBody @Valid AuthPhoneValidCodeLoginParam authPhoneValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByPhone(authPhoneValidCodeLoginParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端邮箱验证码登录
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@Operation(summary = "C端邮箱验证码登录")
|
||||
@PostMapping("/auth/c/doLoginByEmail")
|
||||
public CommonResult<String> doLoginByEmail(@RequestBody @Valid AuthEmailValidCodeLoginParam authEmailValidCodeLoginParam) {
|
||||
return CommonResult.data(authService.doLoginByEmail(authEmailValidCodeLoginParam, SaClientTypeEnum.C.getValue()));
|
||||
}
|
||||
|
||||
/**
|
||||
* C端退出
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperationSupport(order = 7)
|
||||
@Operation(summary = "C端退出")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/doLogout")
|
||||
|
@ -124,7 +147,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperationSupport(order = 8)
|
||||
@Operation(summary = "C端获取用户信息")
|
||||
@SaClientCheckLogin
|
||||
@GetMapping("/auth/c/getLoginUser")
|
||||
|
@ -138,7 +161,7 @@ public class AuthClientController {
|
|||
* @author xuyuxiang
|
||||
* @date 2021/10/15 13:12
|
||||
**/
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperationSupport(order = 9)
|
||||
@Operation(summary = "C端注册")
|
||||
@PostMapping("/auth/c/register")
|
||||
public CommonResult<String> register(@RequestBody @Valid AuthRegisterParam authRegisterParam) {
|
||||
|
|
|
@ -242,7 +242,7 @@ public class BizOrgServiceImpl extends ServiceImpl<BizOrgMapper, BizOrg> impleme
|
|||
this.removeByIds(toDeleteOrgIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(BizDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ public class BizPositionServiceImpl extends ServiceImpl<BizPositionMapper, BizPo
|
|||
this.removeByIds(positionIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.POSITION.getValue(), positionIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(BizDataTypeEnum.POSITION.getValue(), positionIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ public class BizUserServiceImpl extends ServiceImpl<BizUserMapper, BizUser> impl
|
|||
bizUserExtService.remove(new LambdaQueryWrapper<BizUserExt>().in(BizUserExt::getUserId, bizUserIdList));
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(BizDataTypeEnum.USER.getValue(), bizUserIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(BizDataTypeEnum.USER.getValue(), bizUserIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ import vip.xiaonuo.client.modular.user.service.ClientUserExtService;
|
|||
import vip.xiaonuo.client.modular.user.service.ClientUserPasswordService;
|
||||
import vip.xiaonuo.client.modular.user.service.ClientUserService;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
import vip.xiaonuo.common.enums.CommonGenderEnum;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||
|
@ -942,6 +943,7 @@ public class ClientUserServiceImpl extends ServiceImpl<ClientUserMapper, ClientU
|
|||
clientUserAddParam.setAccount(phone);
|
||||
clientUserAddParam.setName(phone);
|
||||
clientUserAddParam.setPhone(phone);
|
||||
clientUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(clientUserAddParam, ClientUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 获取用户信息
|
||||
|
@ -970,6 +972,7 @@ public class ClientUserServiceImpl extends ServiceImpl<ClientUserMapper, ClientU
|
|||
clientUserAddParam.setAccount(email);
|
||||
clientUserAddParam.setName(email);
|
||||
clientUserAddParam.setEmail(email);
|
||||
clientUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(clientUserAddParam, ClientUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 获取用户信息
|
||||
|
@ -1000,6 +1003,7 @@ public class ClientUserServiceImpl extends ServiceImpl<ClientUserMapper, ClientU
|
|||
clientUserAddParam.setAccount(account);
|
||||
clientUserAddParam.setName(account);
|
||||
clientUserAddParam.setPassword(password);
|
||||
clientUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(clientUserAddParam, ClientUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 返回用户
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
package vip.xiaonuo.dev.modular.config.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
||||
/**
|
||||
* 配置分类枚举
|
||||
|
@ -32,89 +31,11 @@ public enum DevConfigCategoryEnum {
|
|||
/**
|
||||
* 业务定义
|
||||
*/
|
||||
BIZ_DEFINE("BIZ_DEFINE"),
|
||||
|
||||
/**
|
||||
* 三方登录-码云
|
||||
*/
|
||||
THIRD_GITEE("THIRD_GITEE"),
|
||||
|
||||
/**
|
||||
* 三方登录-微信
|
||||
*/
|
||||
THIRD_WECHAT("THIRD_WECHAT"),
|
||||
|
||||
/**
|
||||
* 文件-本地
|
||||
*/
|
||||
FILE_LOCAL("FILE_LOCAL"),
|
||||
|
||||
/**
|
||||
* 文件-腾讯云
|
||||
*/
|
||||
FILE_TENCENT("FILE_TENCENT"),
|
||||
|
||||
/**
|
||||
* 文件-阿里云
|
||||
*/
|
||||
FILE_ALIYUN("FILE_ALIYUN"),
|
||||
|
||||
/**
|
||||
* 文件-MINIO
|
||||
*/
|
||||
FILE_MINIO("FILE_MINIO"),
|
||||
|
||||
/**
|
||||
* 邮件-本地
|
||||
*/
|
||||
EMAIL_LOCAL("EMAIL_LOCAL"),
|
||||
|
||||
/**
|
||||
* 邮件-腾讯云
|
||||
*/
|
||||
EMAIL_TENCENT("EMAIL_TENCENT"),
|
||||
|
||||
/**
|
||||
* 邮件-阿里云
|
||||
*/
|
||||
EMAIL_ALIYUN("EMAIL_ALIYUN"),
|
||||
|
||||
/**
|
||||
* 短信-腾讯云
|
||||
*/
|
||||
SMS_TENCENT("SMS_TENCENT"),
|
||||
|
||||
/**
|
||||
* 短信-阿里云
|
||||
*/
|
||||
SMS_ALIYUN("SMS_ALIYUN"),
|
||||
|
||||
/**
|
||||
* 支付-支付宝
|
||||
*/
|
||||
PAY_ALI("PAY_ALI"),
|
||||
|
||||
/**
|
||||
* 支付-微信
|
||||
*/
|
||||
PAY_WX("PAY_WX");
|
||||
BIZ_DEFINE("BIZ_DEFINE");
|
||||
|
||||
private final String value;
|
||||
|
||||
DevConfigCategoryEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static void validate(String value) {
|
||||
boolean flag = SYS_BASE.getValue().equals(value) || BIZ_DEFINE.getValue().equals(value) ||
|
||||
THIRD_GITEE.getValue().equals(value) || THIRD_WECHAT.getValue().equals(value) ||
|
||||
FILE_LOCAL.getValue().equals(value) || FILE_TENCENT.getValue().equals(value) ||
|
||||
FILE_ALIYUN.getValue().equals(value) || FILE_MINIO.getValue().equals(value) ||
|
||||
EMAIL_TENCENT.getValue().equals(value) || EMAIL_ALIYUN.getValue().equals(value) ||
|
||||
SMS_TENCENT.getValue().equals(value) || SMS_ALIYUN.getValue().equals(value) ||
|
||||
PAY_ALI.getValue().equals(value) || PAY_WX.getValue().equals(value);
|
||||
if(!flag) {
|
||||
throw new CommonException("不支持的配置分类:{}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import vip.xiaonuo.dev.modular.config.mapper.DevConfigMapper;
|
|||
import vip.xiaonuo.dev.modular.config.param.*;
|
||||
import vip.xiaonuo.dev.modular.config.service.DevConfigService;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -48,8 +49,27 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class DevConfigServiceImpl extends ServiceImpl<DevConfigMapper, DevConfig> implements DevConfigService {
|
||||
|
||||
/** 缓存前缀 */
|
||||
private static final String CONFIG_CACHE_KEY = "dev-config:";
|
||||
|
||||
/** B端注册是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B";
|
||||
|
||||
/** C端注册是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C";
|
||||
|
||||
/** B端手机号登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B";
|
||||
|
||||
/** C端手机号登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C";
|
||||
|
||||
/** B端邮箱登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B_KEY = "SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B";
|
||||
|
||||
/** C端邮箱登录是否开启 */
|
||||
private static final String SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C_KEY = "SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C";
|
||||
|
||||
@Resource
|
||||
private CommonCacheOperator commonCacheOperator;
|
||||
|
||||
|
@ -91,9 +111,20 @@ public class DevConfigServiceImpl extends ServiceImpl<DevConfigMapper, DevConfig
|
|||
|
||||
@Override
|
||||
public List<DevConfig> sysBaseList() {
|
||||
DevConfigListParam devConfigListParam = new DevConfigListParam();
|
||||
devConfigListParam.setCategory(DevConfigCategoryEnum.SYS_BASE.getValue());
|
||||
return this.list(devConfigListParam);
|
||||
LambdaQueryWrapper<DevConfig> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
// 查询部分字段
|
||||
lambdaQueryWrapper.select(DevConfig::getId, DevConfig::getConfigKey, DevConfig::getConfigValue,
|
||||
DevConfig::getCategory, DevConfig::getSortCode, DevConfig::getRemark);
|
||||
// 类型为系统基础的
|
||||
lambdaQueryWrapper.eq(DevConfig::getCategory, DevConfigCategoryEnum.SYS_BASE.getValue());
|
||||
// 或key为特殊的几个
|
||||
lambdaQueryWrapper.or().in(DevConfig::getConfigKey, CollectionUtil.newArrayList(SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_B_KEY,
|
||||
SNOWY_SYS_DEFAULT_ALLOW_REGISTER_FLAG_FOR_C_KEY,
|
||||
SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_B_KEY,
|
||||
SNOWY_SYS_DEFAULT_ALLOW_PHONE_LOGIN_FLAG_FOR_C_KEY,
|
||||
SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_B_KEY,
|
||||
SNOWY_SYS_DEFAULT_ALLOW_EMAIL_LOGIN_FLAG_FOR_C_KEY));
|
||||
return this.list(lambdaQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
*/
|
||||
package vip.xiaonuo.dev.modular.dict.provider;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import vip.xiaonuo.dev.api.DevDictApi;
|
||||
import vip.xiaonuo.dev.modular.dict.service.DevDictService;
|
||||
|
||||
/**
|
||||
* 字典API接口实现类
|
||||
|
@ -23,4 +25,17 @@ import vip.xiaonuo.dev.api.DevDictApi;
|
|||
*/
|
||||
@Service
|
||||
public class DevDictApiProvider implements DevDictApi {
|
||||
|
||||
@Resource
|
||||
private DevDictService devDictService;
|
||||
|
||||
/**
|
||||
* 根据类型跟子类型获得翻译后的label
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2025/6/6 13:04
|
||||
*/
|
||||
public String getDictLabel(String typeCode, String value) {
|
||||
return devDictService.getDictLabel(typeCode, value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,4 +91,12 @@ public interface DevDictService extends IService<DevDict> {
|
|||
* @date 2022/4/24 21:18
|
||||
*/
|
||||
DevDict queryEntity(String id);
|
||||
|
||||
/**
|
||||
* 根据类型跟子类型获得翻译后的label
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2025/6/6 13:04
|
||||
*/
|
||||
String getDictLabel(String typeCode, String value);
|
||||
}
|
||||
|
|
|
@ -235,4 +235,20 @@ public class DevDictServiceImpl extends ServiceImpl<DevDictMapper, DevDict> impl
|
|||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDictLabel(String typeCode, String value) {
|
||||
List<DevDict> devDictList = this.list(new LambdaQueryWrapper<DevDict>().eq(DevDict::getDictValue, typeCode));
|
||||
if (ObjectUtil.isNotEmpty(devDictList) && devDictList.size() == 1) {
|
||||
DevDict devDictClone = devDictList.get(0);
|
||||
DevDict devDict = this.getOne(new LambdaQueryWrapper<DevDict>().eq(DevDict::getParentId, devDictClone.getId())
|
||||
.eq(DevDict::getDictValue, value));
|
||||
if (ObjectUtil.isNotEmpty(devDict)) {
|
||||
return devDict.getDictLabel();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -240,13 +240,27 @@ public class DevFileController {
|
|||
devFileService.download(devFileIdParam, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载文件
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/21 15:44
|
||||
**/
|
||||
@ApiOperationSupport(order = 14)
|
||||
@Operation(summary = "授权下载文件")
|
||||
@CommonLog("授权下载文件")
|
||||
@GetMapping(value = "/dev/file/authDownload", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
public void authDownload(@Valid DevFileIdParam devFileIdParam, HttpServletResponse response) throws IOException {
|
||||
devFileService.authDownload(devFileIdParam, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/4/24 20:00
|
||||
*/
|
||||
@ApiOperationSupport(order = 14)
|
||||
@ApiOperationSupport(order = 15)
|
||||
@Operation(summary = "删除文件")
|
||||
@CommonLog("删除文件")
|
||||
@PostMapping(value = "/dev/file/delete")
|
||||
|
@ -262,6 +276,7 @@ public class DevFileController {
|
|||
* @author 每天一点
|
||||
* @date 2025/4/06 20:25
|
||||
*/
|
||||
@ApiOperationSupport(order = 16)
|
||||
@Operation(summary = "物理删除文件")
|
||||
@CommonLog("物理删除文件")
|
||||
@PostMapping(value = "/dev/file/deleteAbsolute")
|
||||
|
@ -276,7 +291,7 @@ public class DevFileController {
|
|||
* @author xuyuxiang
|
||||
* @date 2022/6/21 15:44
|
||||
**/
|
||||
@ApiOperationSupport(order = 15)
|
||||
@ApiOperationSupport(order = 17)
|
||||
@Operation(summary = "获取文件详情")
|
||||
@GetMapping("/dev/file/detail")
|
||||
public CommonResult<DevFile> detail(@Valid DevFileIdParam devFileIdParam) {
|
||||
|
@ -289,7 +304,7 @@ public class DevFileController {
|
|||
* @author yubaoshan
|
||||
* @date 2024/6/9 23:52
|
||||
**/
|
||||
@ApiOperationSupport(order = 16)
|
||||
@ApiOperationSupport(order = 18)
|
||||
@Operation(summary = "根据文件url集合获取文件集合")
|
||||
@PostMapping("/dev/file/getFileListByUrlList")
|
||||
public CommonResult<List<DevFile>> getFileListByUrlList(@RequestBody @Valid DevFileUrlListParam devFileUrlListParam) {
|
||||
|
|
|
@ -73,6 +73,10 @@ public class DevFile extends CommonEntity {
|
|||
@Schema(description = "文件下载路径")
|
||||
private String downloadPath;
|
||||
|
||||
/** 文件下载是否需要授权 */
|
||||
@Schema(description = "文件下载是否需要授权")
|
||||
private Boolean isDownloadAuth;
|
||||
|
||||
/** 图片缩略图 */
|
||||
@Schema(description = "图片缩略图")
|
||||
private String thumbnail;
|
||||
|
|
|
@ -73,6 +73,16 @@ public interface DevFileService extends IService<DevFile> {
|
|||
**/
|
||||
void download(DevFileIdParam devFileIdParam, HttpServletResponse response) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* 授权下载文件
|
||||
*
|
||||
* @author xuyuxiang
|
||||
* @date 2022/6/21 15:44
|
||||
**/
|
||||
void authDownload(DevFileIdParam devFileIdParam, HttpServletResponse response) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*
|
||||
|
|
|
@ -18,9 +18,11 @@ import cn.hutool.core.date.DateUtil;
|
|||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
|
@ -71,12 +73,12 @@ public class DevFileServiceImpl extends ServiceImpl<DevFileMapper, DevFile> impl
|
|||
|
||||
@Override
|
||||
public String uploadReturnId(String engine, MultipartFile file) {
|
||||
return this.storageFile(engine, file, true);
|
||||
return this.storageFile(engine, file, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadReturnUrl(String engine, MultipartFile file) {
|
||||
return this.storageFile(engine, file, false);
|
||||
return this.storageFile(engine, file, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -105,6 +107,33 @@ public class DevFileServiceImpl extends ServiceImpl<DevFileMapper, DevFile> impl
|
|||
|
||||
@Override
|
||||
public void download(DevFileIdParam devFileIdParam, HttpServletResponse response) throws IOException {
|
||||
unifiedDownload(devFileIdParam, response, false);
|
||||
// DevFile devFile;
|
||||
// try {
|
||||
// devFile = this.queryEntity(devFileIdParam.getId());
|
||||
// } catch (Exception e) {
|
||||
// CommonResponseUtil.renderError(response, e.getMessage());
|
||||
// return;
|
||||
// }
|
||||
// if(!devFile.getEngine().equals(DevFileEngineTypeEnum.LOCAL.getValue())) {
|
||||
// CommonResponseUtil.renderError(response, "非本地文件不支持此方式下载,id值为:" + devFile.getId());
|
||||
// return;
|
||||
// }
|
||||
// File file = FileUtil.file(devFile.getStoragePath());
|
||||
// if(!FileUtil.exist(file)) {
|
||||
// CommonResponseUtil.renderError(response, "找不到存储的文件,id值为:" + devFile.getId());
|
||||
// return;
|
||||
// }
|
||||
// CommonDownloadUtil.download(devFile.getName(), IoUtil.readBytes(FileUtil.getInputStream(file)), response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authDownload(DevFileIdParam devFileIdParam, HttpServletResponse response) throws IOException {
|
||||
unifiedDownload(devFileIdParam, response, true);
|
||||
}
|
||||
|
||||
// 统一下载
|
||||
private void unifiedDownload(DevFileIdParam devFileIdParam, HttpServletResponse response, boolean isDownloadAuth) throws IOException{
|
||||
DevFile devFile;
|
||||
try {
|
||||
devFile = this.queryEntity(devFileIdParam.getId());
|
||||
|
@ -112,16 +141,21 @@ public class DevFileServiceImpl extends ServiceImpl<DevFileMapper, DevFile> impl
|
|||
CommonResponseUtil.renderError(response, e.getMessage());
|
||||
return;
|
||||
}
|
||||
if(!devFile.getEngine().equals(DevFileEngineTypeEnum.LOCAL.getValue())) {
|
||||
CommonResponseUtil.renderError(response, "非本地文件不支持此方式下载,id值为:" + devFile.getId());
|
||||
if (BooleanUtil.isTrue(devFile.getIsDownloadAuth()) && !isDownloadAuth){
|
||||
CommonResponseUtil.renderError(response, "该文件需要授权下载,请使用授权接口authDownload进行下载!");
|
||||
return;
|
||||
}
|
||||
File file = FileUtil.file(devFile.getStoragePath());
|
||||
if(!FileUtil.exist(file)) {
|
||||
CommonResponseUtil.renderError(response, "找不到存储的文件,id值为:" + devFile.getId());
|
||||
return;
|
||||
if(devFile.getEngine().equals(DevFileEngineTypeEnum.LOCAL.getValue())) {
|
||||
File file = FileUtil.file(devFile.getStoragePath());
|
||||
if(!FileUtil.exist(file)) {
|
||||
CommonResponseUtil.renderError(response, "找不到存储的文件,id值为:" + devFile.getId());
|
||||
return;
|
||||
}
|
||||
CommonDownloadUtil.download(devFile.getName(), IoUtil.readBytes(FileUtil.getInputStream(file)), response);
|
||||
} else {
|
||||
String storagePath = devFile.getStoragePath();
|
||||
CommonDownloadUtil.download(devFile.getName(), HttpUtil.downloadBytes(storagePath), response);
|
||||
}
|
||||
CommonDownloadUtil.download(devFile.getName(), IoUtil.readBytes(FileUtil.getInputStream(file)), response);
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -165,7 +199,7 @@ public class DevFileServiceImpl extends ServiceImpl<DevFileMapper, DevFile> impl
|
|||
* @author xuyuxiang
|
||||
* @date 2022/6/16 16:24
|
||||
**/
|
||||
private String storageFile(String engine, MultipartFile file, boolean returnFileId) {
|
||||
private String storageFile(String engine, MultipartFile file, boolean returnFileId, Boolean isDownloadAuth) {
|
||||
|
||||
// 如果引擎为空,默认使用本地
|
||||
if(ObjectUtil.isEmpty(engine)) {
|
||||
|
@ -241,20 +275,32 @@ public class DevFileServiceImpl extends ServiceImpl<DevFileMapper, DevFile> impl
|
|||
|
||||
// 定义下载地址
|
||||
String downloadUrl;
|
||||
|
||||
// 下载路径,注意:本地文件下载地址设置为下载接口地址 + 文件id
|
||||
if(engine.equals(DevFileEngineTypeEnum.LOCAL.getValue())) {
|
||||
String apiUrl = commonProperties.getBackendUrl();
|
||||
if(ObjectUtil.isEmpty(apiUrl)) {
|
||||
throw new CommonException("后端域名地址未正确配置:snowy.config.common.backend-url为空");
|
||||
}
|
||||
downloadUrl= apiUrl + "/dev/file/download?id=" + fileId;
|
||||
devFile.setDownloadPath(downloadUrl);
|
||||
} else {
|
||||
// 阿里云、腾讯云、MINIO可以直接使用存储地址(公网)作为下载地址
|
||||
downloadUrl= storageUrl;
|
||||
devFile.setDownloadPath(devFile.getStoragePath());
|
||||
String apiUrl = commonProperties.getBackendUrl();
|
||||
if(ObjectUtil.isEmpty(apiUrl)) {
|
||||
throw new CommonException("后端域名地址未正确配置:snowy.config.common.backend-url为空");
|
||||
}
|
||||
if (BooleanUtil.isTrue(isDownloadAuth)){
|
||||
downloadUrl= apiUrl + "/dev/file/authDownload?id=" + fileId + "&tenCode=" + tenApi.getCurrentTenCode() + "&token=";
|
||||
}else {
|
||||
downloadUrl= apiUrl + "/dev/file/download?id=" + fileId;
|
||||
}
|
||||
devFile.setDownloadPath(downloadUrl);
|
||||
|
||||
// // 下载路径,注意:本地文件下载地址设置为下载接口地址 + 文件id
|
||||
// if(engine.equals(DevFileEngineTypeEnum.LOCAL.getValue())) {
|
||||
// String apiUrl = commonProperties.getBackendUrl();
|
||||
// if(ObjectUtil.isEmpty(apiUrl)) {
|
||||
// throw new CommonException("后端域名地址未正确配置:snowy.config.common.backend-url为空");
|
||||
// }
|
||||
// downloadUrl= apiUrl + "/dev/file/download?id=" + fileId + "&tenCode=" + tenApi.getCurrentTenCode();
|
||||
// devFile.setDownloadPath(downloadUrl);
|
||||
// } else {
|
||||
// // 阿里云、腾讯云、MINIO可以直接使用存储地址(公网)作为下载地址
|
||||
// downloadUrl= storageUrl;
|
||||
// devFile.setDownloadPath(devFile.getStoragePath());
|
||||
// }
|
||||
|
||||
devFile.setIsDownloadAuth(isDownloadAuth);
|
||||
|
||||
this.save(devFile);
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
private static final List<JSONObject> GEN_FRONT_FILE_LIST = CollectionUtil.newArrayList(
|
||||
JSONUtil.createObj().set("name", "Api.js.btl").set("path", "api"),
|
||||
JSONUtil.createObj().set("name", "form.vue.btl").set("path", "views"),
|
||||
JSONUtil.createObj().set("name", "index.vue.btl").set("path", "views"));
|
||||
JSONUtil.createObj().set("name", "index.vue.btl").set("path", "views"),
|
||||
JSONUtil.createObj().set("name", "importModel.vue.btl").set("path", "views"));
|
||||
|
||||
private static final List<JSONObject> GEN_MOBILE_FILE_LIST = CollectionUtil.newArrayList(
|
||||
JSONUtil.createObj().set("name", "page.json.btl"),
|
||||
|
@ -242,6 +243,7 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
}
|
||||
addParam.setWhetherRetract(GenYesNoEnum.N.getValue());
|
||||
addParam.setWhetherRequired(GenYesNoEnum.N.getValue());
|
||||
addParam.setWhetherUnique(GenYesNoEnum.N.getValue());
|
||||
addParam.setQueryWhether(GenYesNoEnum.N.getValue());
|
||||
addParam.setSortCode(i);
|
||||
GenConfig genConfig = BeanUtil.toBean(addParam, GenConfig.class);
|
||||
|
@ -330,27 +332,30 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
schema = metaData.getUserName();
|
||||
}
|
||||
List<GenBasicTableColumnResult> columns = new ArrayList<>();
|
||||
rs = metaData.getColumns(null, schema, genBasicTableColumnParam.getTableName(), "%");
|
||||
rs = metaData.getColumns(conn.getCatalog(), schema, genBasicTableColumnParam.getTableName(), "%");
|
||||
if(!rs.isBeforeFirst()) {
|
||||
rs = metaData.getColumns(null, schema, genBasicTableColumnParam.getTableName().toLowerCase(), "%");
|
||||
rs = metaData.getColumns(conn.getCatalog(), schema, genBasicTableColumnParam.getTableName().toLowerCase(), "%");
|
||||
}
|
||||
while (rs.next()) {
|
||||
String columnName = rs.getString("COLUMN_NAME").toUpperCase();
|
||||
GenBasicTableColumnResult genBasicTableColumnResult = new GenBasicTableColumnResult();
|
||||
genBasicTableColumnResult.setColumnName(columnName);
|
||||
String remarks = rs.getString("REMARKS");
|
||||
if(ObjectUtil.isEmpty(remarks)) {
|
||||
genBasicTableColumnResult.setColumnRemark(columnName);
|
||||
} else {
|
||||
genBasicTableColumnResult.setColumnRemark(remarks);
|
||||
boolean exist = columns.stream().anyMatch(dbsTableColumnResult -> dbsTableColumnResult.getColumnName().equals(columnName));
|
||||
if(!exist) {
|
||||
GenBasicTableColumnResult genBasicTableColumnResult = new GenBasicTableColumnResult();
|
||||
genBasicTableColumnResult.setColumnName(columnName);
|
||||
String remarks = rs.getString("REMARKS");
|
||||
if(ObjectUtil.isEmpty(remarks)) {
|
||||
genBasicTableColumnResult.setColumnRemark(columnName);
|
||||
} else {
|
||||
genBasicTableColumnResult.setColumnRemark(remarks);
|
||||
}
|
||||
String typeName = rs.getString("TYPE_NAME").toUpperCase();
|
||||
if(ObjectUtil.isEmpty(typeName)) {
|
||||
genBasicTableColumnResult.setTypeName("NONE");
|
||||
} else {
|
||||
genBasicTableColumnResult.setTypeName(typeName);
|
||||
}
|
||||
columns.add(genBasicTableColumnResult);
|
||||
}
|
||||
String typeName = rs.getString("TYPE_NAME").toUpperCase();
|
||||
if(ObjectUtil.isEmpty(typeName)) {
|
||||
genBasicTableColumnResult.setTypeName("NONE");
|
||||
} else {
|
||||
genBasicTableColumnResult.setTypeName(typeName);
|
||||
}
|
||||
columns.add(genBasicTableColumnResult);
|
||||
}
|
||||
return columns;
|
||||
} catch (SQLException sqlException) {
|
||||
|
@ -675,6 +680,10 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
bindingJsonObject.set("deleteButtonId", IdWorker.getIdStr());
|
||||
// 批量删除按钮ID
|
||||
bindingJsonObject.set("batchDeleteButtonId", IdWorker.getIdStr());
|
||||
// 导入按钮ID
|
||||
bindingJsonObject.set("importButtonId", IdWorker.getIdStr());
|
||||
// 导出按钮ID
|
||||
bindingJsonObject.set("exportButtonId", IdWorker.getIdStr());
|
||||
// 作者
|
||||
bindingJsonObject.set("authorName", genBasic.getAuthorName());
|
||||
// 生成时间
|
||||
|
@ -697,6 +706,7 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
configItem.set("needPage", false);
|
||||
configItem.set("needPageType", "none");
|
||||
configItem.set("required", true);
|
||||
configItem.set("unique", true);
|
||||
configItem.set("needTableId", true);
|
||||
bindingJsonObject.set("dbTableKeyJavaType", genConfig.getFieldJavaType());
|
||||
bindingJsonObject.set("dbTableKeyRemark", genConfig.getFieldRemark());
|
||||
|
@ -712,6 +722,7 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
configItem.set("needPage", false);
|
||||
configItem.set("needPageType", "none");
|
||||
configItem.set("required", false);
|
||||
configItem.set("unique", false);
|
||||
configItem.set("needTableId", false);
|
||||
} else {
|
||||
boolean needAddAndUpdate = genConfig.getWhetherAddUpdate().equalsIgnoreCase(GenYesNoEnum.Y.getValue());
|
||||
|
@ -720,6 +731,7 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
configItem.set("needPage", genConfig.getQueryWhether().equalsIgnoreCase(GenYesNoEnum.Y.getValue()));
|
||||
configItem.set("needPageType", genConfig.getQueryType());
|
||||
configItem.set("required", genConfig.getWhetherRequired().equalsIgnoreCase(GenYesNoEnum.Y.getValue()));
|
||||
configItem.set("unique", ObjectUtil.isNotEmpty(genConfig.getWhetherUnique()) && genConfig.getWhetherUnique().equalsIgnoreCase(GenYesNoEnum.Y.getValue()));
|
||||
configItem.set("needTableId", false);
|
||||
}
|
||||
}
|
||||
|
@ -754,6 +766,20 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
|||
});
|
||||
// 配置信息
|
||||
bindingJsonObject.set("configList", configList);
|
||||
// 获取必填字段
|
||||
List<JSONObject> requiredFieldList = configList.stream().filter(configItem -> configItem.getBool("required")).toList();
|
||||
// 必填字段列表
|
||||
bindingJsonObject.set("requiredFieldList", requiredFieldList);
|
||||
// 必填字段字符串
|
||||
bindingJsonObject.set("requiredFieldStr", StrUtil.join(StrUtil.COMMA + " ", requiredFieldList.stream().map(configItem ->
|
||||
configItem.getStr("fieldNameCamelCase")).collect(Collectors.toList())));
|
||||
// 获取唯一字段
|
||||
List<JSONObject> uniqueFieldList = configList.stream().filter(configItem -> configItem.getBool("unique")).toList();
|
||||
// 唯一字段列表
|
||||
bindingJsonObject.set("uniqueFieldList", uniqueFieldList);
|
||||
// 唯一字段字符串
|
||||
bindingJsonObject.set("uniqueFieldStr", StrUtil.join(StrUtil.COMMA + " ", uniqueFieldList.stream().map(configItem ->
|
||||
configItem.getStr("fieldNameCamelCase")).collect(Collectors.toList())));
|
||||
// 有排序字段
|
||||
bindingJsonObject.set("hasSortCodeField", hasSortCodeField.get());
|
||||
return bindingJsonObject;
|
||||
|
|
|
@ -81,6 +81,10 @@ public class GenConfig extends CommonEntity {
|
|||
@Schema(description = "必填")
|
||||
private String whetherRequired;
|
||||
|
||||
/** 唯一 */
|
||||
@Schema(description = "唯一")
|
||||
private String whetherUnique;
|
||||
|
||||
/** 查询 */
|
||||
@Schema(description = "查询")
|
||||
private String queryWhether;
|
||||
|
|
|
@ -80,6 +80,10 @@ public class GenConfigAddParam {
|
|||
@Schema(description = "必填")
|
||||
private String whetherRequired;
|
||||
|
||||
/** 唯一 */
|
||||
@Schema(description = "唯一")
|
||||
private String whetherUnique;
|
||||
|
||||
/** 查询 */
|
||||
@Schema(description = "查询")
|
||||
private String queryWhether;
|
||||
|
|
|
@ -91,6 +91,11 @@ public class GenConfigEditParam {
|
|||
@NotBlank(message = "whetherRequired不能为空")
|
||||
private String whetherRequired;
|
||||
|
||||
/** 唯一 */
|
||||
@Schema(description = "唯一")
|
||||
@NotBlank(message = "whetherUnique不能为空")
|
||||
private String whetherUnique;
|
||||
|
||||
/** 查询 */
|
||||
@Schema(description = "查询", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "queryWhether不能为空")
|
||||
|
|
|
@ -13,14 +13,15 @@
|
|||
package ${packageName}.${moduleName}.modular.${busName}.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ${packageName}.common.annotation.CommonLog;
|
||||
import ${packageName}.common.pojo.CommonResult;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
|
||||
|
@ -33,6 +34,7 @@ import ${packageName}.${moduleName}.modular.${busName}.service.${className}Servi
|
|||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -120,4 +122,43 @@ public class ${className}Controller {
|
|||
public CommonResult<${className}> detail(@Valid ${className}IdParam ${classNameFirstLower}IdParam) {
|
||||
return CommonResult.data(${classNameFirstLower}Service.detail(${classNameFirstLower}IdParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载${functionName}导入模板
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
*/
|
||||
@Operation(summary = "下载${functionName}导入模板")
|
||||
@GetMapping(value = "/${moduleName}/${busName}/downloadImportTemplate", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
public void downloadImportTemplate(HttpServletResponse response) throws IOException {
|
||||
${classNameFirstLower}Service.downloadImportTemplate(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入${functionName}
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
*/
|
||||
@Operation(summary = "导入${functionName}")
|
||||
@CommonLog("导入${functionName}")
|
||||
@SaCheckPermission("/${moduleName}/${busName}/importData")
|
||||
@PostMapping("/${moduleName}/${busName}/importData")
|
||||
public CommonResult<JSONObject> importData(@RequestPart("file") MultipartFile file) {
|
||||
return CommonResult.data(${classNameFirstLower}Service.importData(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出${functionName}
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
*/
|
||||
@Operation(summary = "导出${functionName}")
|
||||
@SaCheckPermission("/${moduleName}/${busName}/exportData")
|
||||
@PostMapping(value = "/${moduleName}/${busName}/exportData", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||
public void exportData(@RequestBody List<${className}IdParam> ${classNameFirstLower}IdParamList, HttpServletResponse response) throws IOException {
|
||||
${classNameFirstLower}Service.exportData(${classNameFirstLower}IdParamList, response);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
*/
|
||||
package ${packageName}.${moduleName}.modular.${busName}.param;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.format.DateTimeFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -34,6 +36,10 @@ public class ${className}EditParam {
|
|||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needEdit) { %>
|
||||
/** ${configList[i].fieldRemark} */
|
||||
<% if(configList[i].fieldJavaType == 'Date') { %>
|
||||
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
|
||||
<% } else { %><% } %>
|
||||
@ExcelProperty("${configList[i].fieldRemark}")
|
||||
@Schema(description = "${configList[i].fieldRemark}"<% if(configList[i].required) { %>, requiredMode = Schema.RequiredMode.REQUIRED<% } %>)
|
||||
<% if(configList[i].required) { %>
|
||||
<% if(configList[i].fieldJavaType == 'String') { %>@NotBlank<% } else { %>@NotNull<% } %>(message = "${configList[i].fieldNameCamelCase}不能为空")
|
||||
|
|
|
@ -12,14 +12,17 @@
|
|||
*/
|
||||
package ${packageName}.${moduleName}.modular.${busName}.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
|
||||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}AddParam;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}EditParam;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}IdParam;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}PageParam;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -76,5 +79,29 @@ public interface ${className}Service extends IService<${className}> {
|
|||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
**/
|
||||
${className} queryEntity(String id);
|
||||
${className} queryEntity(String ${dbTableKeyCamelCase});
|
||||
|
||||
/**
|
||||
* 下载${functionName}导入模板
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
*/
|
||||
void downloadImportTemplate(HttpServletResponse response) throws IOException;
|
||||
|
||||
/**
|
||||
* 导入${functionName}
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
**/
|
||||
JSONObject importData(MultipartFile file);
|
||||
|
||||
/**
|
||||
* 导出${functionName}
|
||||
*
|
||||
* @author ${authorName}
|
||||
* @date ${genTime}
|
||||
*/
|
||||
void exportData(List<${className}IdParam> ${classNameFirstLower}IdParamList, HttpServletResponse response) throws IOException;
|
||||
}
|
||||
|
|
|
@ -13,17 +13,31 @@
|
|||
package ${packageName}.${moduleName}.modular.${busName}.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.CollStreamUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import ${packageName}.common.enums.CommonSortOrderEnum;
|
||||
import ${packageName}.common.exception.CommonException;
|
||||
import ${packageName}.common.page.CommonPageRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.entity.${className};
|
||||
import ${packageName}.${moduleName}.modular.${busName}.mapper.${className}Mapper;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}AddParam;
|
||||
|
@ -32,6 +46,11 @@ import ${packageName}.${moduleName}.modular.${busName}.param.${className}IdParam
|
|||
import ${packageName}.${moduleName}.modular.${busName}.param.${className}PageParam;
|
||||
import ${packageName}.${moduleName}.modular.${busName}.service.${className}Service;
|
||||
|
||||
import vip.xiaonuo.common.util.CommonDownloadUtil;
|
||||
import vip.xiaonuo.common.util.CommonResponseUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -77,18 +96,28 @@ public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${c
|
|||
@Override
|
||||
public void add(${className}AddParam ${classNameFirstLower}AddParam) {
|
||||
${className} ${classNameFirstLower} = BeanUtil.toBean(${classNameFirstLower}AddParam, ${className}.class);
|
||||
<% for(var i = 0; i < uniqueFieldList.~size; i++) { %>
|
||||
<% if(!uniqueFieldList[i].needTableId) { %>
|
||||
if(this.count(new LambdaQueryWrapper<${className}>().eq(${className}::get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}, ${classNameFirstLower}.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}())) > 0) {
|
||||
throw new CommonException("存在重复的${uniqueFieldList[i].fieldRemark},值为:{}", ${classNameFirstLower}.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}());
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
this.save(${classNameFirstLower});
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void edit(${className}EditParam ${classNameFirstLower}EditParam) {
|
||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needTableId) { %>
|
||||
${className} ${classNameFirstLower} = this.queryEntity(${classNameFirstLower}EditParam.get${configList[i].fieldNameCamelCaseFirstUpper}());
|
||||
<% } %>
|
||||
<% } %>
|
||||
${className} ${classNameFirstLower} = this.queryEntity(${classNameFirstLower}EditParam.get${dbTableKeyFirstUpper}());
|
||||
BeanUtil.copyProperties(${classNameFirstLower}EditParam, ${classNameFirstLower});
|
||||
<% for(var i = 0; i < uniqueFieldList.~size; i++) { %>
|
||||
<% if(!uniqueFieldList[i].needTableId) { %>
|
||||
if(this.count(new LambdaQueryWrapper<${className}>().ne(${className}::get${dbTableKeyFirstUpper}, ${classNameFirstLower}.get${dbTableKeyFirstUpper}()).eq(${className}::get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}, ${classNameFirstLower}.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}())) > 0) {
|
||||
throw new CommonException("存在重复的${uniqueFieldList[i].fieldRemark},值为:{}", ${classNameFirstLower}.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}());
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
this.updateById(${classNameFirstLower});
|
||||
}
|
||||
|
||||
|
@ -96,20 +125,129 @@ public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${c
|
|||
@Override
|
||||
public void delete(List<${className}IdParam> ${classNameFirstLower}IdParamList) {
|
||||
// 执行删除
|
||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needTableId) { %>
|
||||
this.removeByIds(CollStreamUtil.toList(${classNameFirstLower}IdParamList, ${className}IdParam::get${configList[i].fieldNameCamelCaseFirstUpper}));
|
||||
<% } %>
|
||||
<% } %>
|
||||
this.removeByIds(CollStreamUtil.toList(${classNameFirstLower}IdParamList, ${className}IdParam::get${dbTableKeyFirstUpper}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${className} detail(${className}IdParam ${classNameFirstLower}IdParam) {
|
||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needTableId) { %>
|
||||
return this.queryEntity(${classNameFirstLower}IdParam.get${configList[i].fieldNameCamelCaseFirstUpper}());
|
||||
<% } %>
|
||||
return this.queryEntity(${classNameFirstLower}IdParam.get${dbTableKeyFirstUpper}());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${className} queryEntity(String ${dbTableKeyCamelCase}) {
|
||||
${className} ${classNameFirstLower} = this.getById(${dbTableKeyCamelCase});
|
||||
if(ObjectUtil.isEmpty(${classNameFirstLower})) {
|
||||
throw new CommonException("${functionName}不存在,${dbTableKeyCamelCase}值为:{}", ${dbTableKeyCamelCase});
|
||||
}
|
||||
return ${classNameFirstLower};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void downloadImportTemplate(HttpServletResponse response) throws IOException {
|
||||
File tempFile = null;
|
||||
try {
|
||||
List<${className}EditParam> dataList = CollectionUtil.newArrayList();
|
||||
String fileName = "${functionName}导入模板_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
|
||||
tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
|
||||
EasyExcel.write(tempFile.getPath(), ${className}EditParam.class).sheet("${functionName}").doWrite(dataList);
|
||||
CommonDownloadUtil.download(tempFile, response);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> ${functionName}导入模板下载失败:", e);
|
||||
CommonResponseUtil.renderError(response, "${functionName}导入模板下载失败");
|
||||
} finally {
|
||||
FileUtil.del(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public JSONObject importData(MultipartFile file) {
|
||||
try {
|
||||
int successCount = 0;
|
||||
int errorCount = 0;
|
||||
JSONArray errorDetail = JSONUtil.createArray();
|
||||
// 创建临时文件
|
||||
File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
|
||||
FileUtil.FILE_SEPARATOR + "${classNameFirstLower}ImportTemplate.xlsx"));
|
||||
// 读取excel
|
||||
List<${className}EditParam> ${classNameFirstLower}EditParamList = EasyExcel.read(tempFile).head(${className}EditParam.class).sheet()
|
||||
.headRowNumber(1).doReadSync();
|
||||
List<${className}> allDataList = this.list();
|
||||
for (int i = 0; i < ${classNameFirstLower}EditParamList.size(); i++) {
|
||||
JSONObject jsonObject = this.doImport(allDataList, ${classNameFirstLower}EditParamList.get(i), i);
|
||||
if(jsonObject.getBool("success")) {
|
||||
successCount += 1;
|
||||
} else {
|
||||
errorCount += 1;
|
||||
errorDetail.add(jsonObject);
|
||||
}
|
||||
}
|
||||
return JSONUtil.createObj()
|
||||
.set("totalCount", ${classNameFirstLower}EditParamList.size())
|
||||
.set("successCount", successCount)
|
||||
.set("errorCount", errorCount)
|
||||
.set("errorDetail", errorDetail);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> ${functionName}导入失败:", e);
|
||||
throw new CommonException("${functionName}导入失败");
|
||||
}
|
||||
}
|
||||
|
||||
public JSONObject doImport(List<${className}> allDataList, ${className}EditParam ${classNameFirstLower}EditParam, int i) {
|
||||
<% for(var i = 0; i < requiredFieldList.~size; i++) { %>
|
||||
${requiredFieldList[i].fieldJavaType} ${requiredFieldList[i].fieldNameCamelCase} = ${classNameFirstLower}EditParam.get${requiredFieldList[i].fieldNameCamelCaseFirstUpper}();
|
||||
<% } %>
|
||||
if(ObjectUtil.hasEmpty(${requiredFieldStr})) {
|
||||
return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
|
||||
} else {
|
||||
try {
|
||||
int index = CollStreamUtil.toList(allDataList, ${className}::get${dbTableKeyFirstUpper}).indexOf(${classNameFirstLower}EditParam.get${dbTableKeyFirstUpper}());
|
||||
${className} ${classNameFirstLower};
|
||||
boolean isAdd = false;
|
||||
if(index == -1) {
|
||||
isAdd = true;
|
||||
${classNameFirstLower} = new ${className}();
|
||||
} else {
|
||||
${classNameFirstLower} = allDataList.get(index);
|
||||
}
|
||||
<% if(uniqueFieldList.~size > 1) { %>
|
||||
if(isAdd) {
|
||||
<% for(var i = 0; i < uniqueFieldList.~size; i++) { %>
|
||||
<% if(!uniqueFieldList[i].needTableId) { %>
|
||||
boolean repeat${uniqueFieldList[i].fieldNameCamelCaseFirstUpper} = allDataList.stream().anyMatch(tempData -> ObjectUtil
|
||||
.isNotEmpty(tempData.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}()) && tempData.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}().equals(${classNameFirstLower}EditParam.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}()));
|
||||
if(repeat${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}) {
|
||||
return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "新增数据时字段【${uniqueFieldList[i].fieldRemark}(${uniqueFieldList[i].fieldNameCamelCase})】与数据库中数据重复,值为:" + ${classNameFirstLower}EditParam.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}());
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
} else {
|
||||
<% for(var i = 0; i < uniqueFieldList.~size; i++) { %>
|
||||
<% if(!uniqueFieldList[i].needTableId) { %>
|
||||
boolean repeat${uniqueFieldList[i].fieldNameCamelCaseFirstUpper} = allDataList.stream().anyMatch(tempData -> ObjectUtil
|
||||
.isNotEmpty(tempData.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}()) && tempData.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}()
|
||||
.equals(${classNameFirstLower}EditParam.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}()) && !tempData.get${dbTableKeyFirstUpper}().equals(${classNameFirstLower}.get${dbTableKeyFirstUpper}()));
|
||||
if(repeat${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}) {
|
||||
return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "更新数据时字段【${uniqueFieldList[i].fieldRemark}(${uniqueFieldList[i].fieldNameCamelCase})】与数据库中数据重复,值为:" + ${classNameFirstLower}EditParam.get${uniqueFieldList[i].fieldNameCamelCaseFirstUpper}());
|
||||
}
|
||||
<% } %>
|
||||
<% } %>
|
||||
}
|
||||
<% } %>
|
||||
BeanUtil.copyProperties(${classNameFirstLower}EditParam, ${classNameFirstLower});
|
||||
if(isAdd) {
|
||||
allDataList.add(${classNameFirstLower});
|
||||
} else {
|
||||
allDataList.remove(index);
|
||||
allDataList.add(index, ${classNameFirstLower});
|
||||
}
|
||||
this.saveOrUpdate(${classNameFirstLower});
|
||||
return JSONUtil.createObj().set("success", true);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> 数据导入异常:", e);
|
||||
return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -120,4 +258,27 @@ public class ${className}ServiceImpl extends ServiceImpl<${className}Mapper, ${c
|
|||
}
|
||||
return ${classNameFirstLower};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportData(List<${className}IdParam> ${classNameFirstLower}IdParamList, HttpServletResponse response) throws IOException {
|
||||
File tempFile = null;
|
||||
try {
|
||||
List<${className}EditParam> dataList;
|
||||
if(ObjectUtil.isNotEmpty(${classNameFirstLower}IdParamList)) {
|
||||
List<String> ${dbTableKeyCamelCase}List = CollStreamUtil.toList(${classNameFirstLower}IdParamList, ${className}IdParam::get${dbTableKeyFirstUpper});
|
||||
dataList = BeanUtil.copyToList(this.listByIds(${dbTableKeyCamelCase}List), ${className}EditParam.class);
|
||||
} else {
|
||||
dataList = BeanUtil.copyToList(this.list(), ${className}EditParam.class);
|
||||
}
|
||||
String fileName = "${functionName}_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
|
||||
tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
|
||||
EasyExcel.write(tempFile.getPath(), ${className}EditParam.class).sheet("${functionName}").doWrite(dataList);
|
||||
CommonDownloadUtil.download(tempFile, response);
|
||||
} catch (Exception e) {
|
||||
log.error(">>> ${functionName}导出失败:", e);
|
||||
CommonResponseUtil.renderError(response, "${functionName}导出失败");
|
||||
} finally {
|
||||
FileUtil.del(tempFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,5 +24,21 @@ export default {
|
|||
// 获取${functionName}详情
|
||||
${classNameFirstLower}Detail(data) {
|
||||
return request('detail', data, 'get')
|
||||
}
|
||||
},
|
||||
// 下载${functionName}导入模板
|
||||
${classNameFirstLower}DownloadTemplate(data) {
|
||||
return request('downloadImportTemplate', data, 'get', {
|
||||
responseType: 'blob'
|
||||
})
|
||||
},
|
||||
// 导入${functionName}
|
||||
${classNameFirstLower}Import(data) {
|
||||
return request('importData', data)
|
||||
},
|
||||
// 导出${functionName}
|
||||
${classNameFirstLower}Export(data) {
|
||||
return request('exportData', data, 'post', {
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<template>
|
||||
<xn-form-container title="导入导出" :width="700" :visible="visible" :destroy-on-close="true" @close="onClose">
|
||||
<span>导入数据格式严格按照系统模板进行数据录入,请点击 <a-button type="primary" size="small" @click="downloadImportTemplate">下载模板</a-button>
|
||||
</span>
|
||||
<a-divider dashed />
|
||||
<div>
|
||||
<a-spin :spinning="impUploadLoading">
|
||||
<a-upload-dragger :show-upload-list="false" :custom-request="customRequestLocal" :accept="uploadAccept">
|
||||
<p class="ant-upload-drag-icon">
|
||||
<inbox-outlined></inbox-outlined>
|
||||
</p>
|
||||
<p class="ant-upload-text">单击或拖动文件到此区域进行上传</p>
|
||||
<p class="ant-upload-hint">仅支持xls、xlsx格式文件</p>
|
||||
</a-upload-dragger>
|
||||
</a-spin>
|
||||
</div>
|
||||
<a-alert v-if="impAlertStatus" type="info" :show-icon="false" banner closable @close="onImpClose" class="mt-3">
|
||||
<template #description>
|
||||
<p>导入总数:{{ impResultData.totalCount }} 条</p>
|
||||
<p>导入成功:{{ impResultData.successCount }} 条</p>
|
||||
<div v-if="impResultData.errorCount > 0">
|
||||
<p><span class="xn-color-red">失败条数:</span>{{ impResultData.errorCount }} 条</p>
|
||||
<a-table :dataSource="impResultErrorDataSource" :columns="impErrorColumns" size="small" />
|
||||
</div>
|
||||
</template>
|
||||
</a-alert>
|
||||
</xn-form-container>
|
||||
</template>
|
||||
|
||||
<script setup name="${classNameFirstLower}ImportModel">
|
||||
import { message } from 'ant-design-vue'
|
||||
import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api'
|
||||
import downloadUtil from '@/utils/downloadUtil'
|
||||
|
||||
const impUploadLoading = ref(false)
|
||||
const impAlertStatus = ref(false)
|
||||
const impResultData = ref({})
|
||||
const impResultErrorDataSource = ref([])
|
||||
const impAccept = [
|
||||
{
|
||||
extension: '.xls',
|
||||
mimeType: 'application/vnd.ms-excel'
|
||||
},
|
||||
{
|
||||
extension: '.xlsx',
|
||||
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
}
|
||||
]
|
||||
// 指定能选择的文件类型
|
||||
const uploadAccept = String(
|
||||
impAccept.map((item) => {
|
||||
return item.mimeType
|
||||
})
|
||||
)
|
||||
// 导入
|
||||
const customRequestLocal = (data) => {
|
||||
impUploadLoading.value = true
|
||||
const fileData = new FormData()
|
||||
// 校验上传文件扩展名和文件类型是否为.xls、.xlsx
|
||||
const extension = '.'.concat(data.file.name.split('.').slice(-1).toString().toLowerCase())
|
||||
const mimeType = data.file.type
|
||||
// 提取允许的扩展名
|
||||
const extensionArr = impAccept.map((item) => item.extension)
|
||||
// 提取允许的MIMEType
|
||||
const mimeTypeArr = impAccept.map((item) => item.mimeType)
|
||||
if (!extensionArr.includes(extension) || !mimeTypeArr.includes(mimeType)) {
|
||||
message.warning('上传文件类型仅支持xls、xlsx格式文件!')
|
||||
impUploadLoading.value = false
|
||||
return false
|
||||
}
|
||||
fileData.append('file', data.file)
|
||||
return ${classNameFirstLower}Api
|
||||
.${classNameFirstLower}Import(fileData)
|
||||
.then((res) => {
|
||||
impAlertStatus.value = true
|
||||
impResultData.value = res
|
||||
impResultErrorDataSource.value = res.errorDetail
|
||||
})
|
||||
.finally(() => {
|
||||
impUploadLoading.value = false
|
||||
})
|
||||
}
|
||||
// 关闭导入提示
|
||||
const onImpClose = () => {
|
||||
impAlertStatus.value = false
|
||||
}
|
||||
const impErrorColumns = [
|
||||
{
|
||||
title: '索引',
|
||||
dataIndex: 'index',
|
||||
width: '80px'
|
||||
},
|
||||
{
|
||||
title: '原因',
|
||||
dataIndex: 'msg'
|
||||
}
|
||||
]
|
||||
// 定义emit事件
|
||||
const emit = defineEmits({ successful: null })
|
||||
// 默认是关闭状态
|
||||
const visible = ref(false)
|
||||
const submitLoading = ref(false)
|
||||
|
||||
// 打开抽屉
|
||||
const onOpen = () => {
|
||||
visible.value = true
|
||||
}
|
||||
// 关闭抽屉
|
||||
const onClose = () => {
|
||||
visible.value = false
|
||||
// 关闭导入的提示
|
||||
onImpClose()
|
||||
}
|
||||
// 下载导入模板
|
||||
const downloadImportTemplate = () => {
|
||||
${classNameFirstLower}Api.${classNameFirstLower}DownloadTemplate().then((res) => {
|
||||
downloadUtil.resultDownload(res)
|
||||
})
|
||||
}
|
||||
// 调用这个函数将子组件的一些数据和方法暴露出去
|
||||
defineExpose({
|
||||
onOpen
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.xn-color-red {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
|
@ -82,11 +82,7 @@
|
|||
:data="loadData"
|
||||
:alert="options.alert.show"
|
||||
bordered
|
||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needTableId) { %>
|
||||
:row-key="(record) => record.${configList[i].fieldNameCamelCase}"
|
||||
<% } %>
|
||||
<% } %>
|
||||
:row-key="(record) => record.${dbTableKeyCamelCase}"
|
||||
:tool-config="toolConfig"
|
||||
:row-selection="options.rowSelection"
|
||||
>
|
||||
|
@ -96,6 +92,14 @@
|
|||
<template #icon><plus-outlined /></template>
|
||||
新增
|
||||
</a-button>
|
||||
<a-button @click="importModelRef.onOpen()" v-if="hasPerm('${classNameFirstLower}Import')">
|
||||
<template #icon><import-outlined /></template>
|
||||
<span>导入</span>
|
||||
</a-button>
|
||||
<a-button @click="exportData" v-if="hasPerm('${classNameFirstLower}Export')">
|
||||
<template #icon><export-outlined /></template>
|
||||
<span>导出</span>
|
||||
</a-button>
|
||||
<xn-batch-button
|
||||
v-if="hasPerm('${classNameFirstLower}BatchDelete')"
|
||||
buttonName="批量删除"
|
||||
|
@ -140,6 +144,7 @@
|
|||
</template>
|
||||
</s-table>
|
||||
</a-card>
|
||||
<ImportModel ref="importModelRef" />
|
||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||
</template>
|
||||
|
||||
|
@ -161,12 +166,15 @@
|
|||
<% } %>
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import Form from './form.vue'
|
||||
import ImportModel from './importModel.vue'
|
||||
import downloadUtil from '@/utils/downloadUtil'
|
||||
import ${classNameFirstLower}Api from '@/api/${moduleName}/${classNameFirstLower}Api'
|
||||
<% if (searchCount > 0) { %>
|
||||
const searchFormState = ref({})
|
||||
const searchFormRef = ref()
|
||||
<% } %>
|
||||
const tableRef = ref()
|
||||
const importModelRef = ref()
|
||||
const formRef = ref()
|
||||
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
||||
<% if(searchCount > 3) { %>
|
||||
|
@ -245,17 +253,30 @@
|
|||
const delete${className} = (record) => {
|
||||
let params = [
|
||||
{
|
||||
<% for(var i = 0; i < configList.~size; i++) { %>
|
||||
<% if(configList[i].needTableId) { %>
|
||||
${configList[i].fieldNameCamelCase}: record.${configList[i].fieldNameCamelCase}
|
||||
<% } %>
|
||||
<% } %>
|
||||
${dbTableKeyCamelCase}: record.${dbTableKeyCamelCase}
|
||||
}
|
||||
]
|
||||
${classNameFirstLower}Api.${classNameFirstLower}Delete(params).then(() => {
|
||||
tableRef.value.refresh(true)
|
||||
})
|
||||
}
|
||||
// 导出
|
||||
const exportData = () => {
|
||||
if (selectedRowKeys.value.length > 0) {
|
||||
const params = selectedRowKeys.value.map((m) => {
|
||||
return {
|
||||
id: m
|
||||
}
|
||||
})
|
||||
${classNameFirstLower}Api.${classNameFirstLower}Export(params).then((res) => {
|
||||
downloadUtil.resultDownload(res)
|
||||
})
|
||||
} else {
|
||||
${classNameFirstLower}Api.${classNameFirstLower}Export([]).then((res) => {
|
||||
downloadUtil.resultDownload(res)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 批量删除
|
||||
const deleteBatch${className} = (params) => {
|
||||
${classNameFirstLower}Api.${classNameFirstLower}Delete(params).then(() => {
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
Date: ${genTime}
|
||||
*/
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${menuId}', '${parentId}', '${functionName}管理', '${busName}', '${menuCode}', 'MENU', '${moduleId}', 'MENU', '${menuPath}', '${menuComponent}', NULL, NULL, NULL, 99, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${menuId}', '${parentId}', '${functionName}管理', '${busName}', '${menuCode}', 'MENU', '${moduleId}', 'MENU', '${menuPath}', '${menuComponent}', NULL, NULL, NULL, NULL, NULL, 99, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${addButtonId}', '${menuId}', '新增${functionName}', NULL, '${classNameFirstLower}Add', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${addButtonId}', '${menuId}', '新增${functionName}', NULL, '${classNameFirstLower}Add', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${batchDeleteButtonId}', '${menuId}', '批量删除${functionName}', NULL, '${classNameFirstLower}BatchDelete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${batchDeleteButtonId}', '${menuId}', '批量删除${functionName}', NULL, '${classNameFirstLower}BatchDelete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 2, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${editButtonId}', '${menuId}', '编辑${functionName}', NULL, '${classNameFirstLower}Edit', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 3, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${editButtonId}', '${menuId}', '编辑${functionName}', NULL, '${classNameFirstLower}Edit', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 3, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${deleteButtonId}', '${menuId}', '删除${functionName}', NULL, '${classNameFirstLower}Delete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 4, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${deleteButtonId}', '${menuId}', '删除${functionName}', NULL, '${classNameFirstLower}Delete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 4, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${importButtonId}', '${menuId}', '导入${functionName}', NULL, '${classNameFirstLower}Import', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 5, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO `SYS_RESOURCE` VALUES ('${exportButtonId}', ${menuId}', '导出${functionName}', NULL, '${classNameFirstLower}Export', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 6, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
<% if (mobileModuleId != null && mobileModuleId != '') { %>
|
||||
INSERT INTO `MOBILE_RESOURCE` VALUES ('${menuId}', '0', '${functionName}管理', NULL, 'MENU', '${mobileModuleId}', 'MENU', '/pages/${moduleName}/${busName}/index', 'apartment-outlined', '#1890ff', 'YES', 'ENABLE', 99, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
Date: ${genTime}
|
||||
*/
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${menuId}', '${parentId}', '${functionName}管理', '${busName}', '${menuCode}', 'MENU', '${moduleId}', 'MENU', '${menuPath}', '${menuComponent}', NULL, NULL, NULL, '99', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${menuId}', '${parentId}', '${functionName}管理', '${busName}', '${menuCode}', 'MENU', '${moduleId}', 'MENU', '${menuPath}', '${menuComponent}', NULL, NULL, NULL, NULL, NULL, '99', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${addButtonId}', '${menuId}', '新增${functionName}', NULL, '${classNameFirstLower}Add', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '1', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${addButtonId}', '${menuId}', '新增${functionName}', NULL, '${classNameFirstLower}Add', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '1', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${batchDeleteButtonId}', '${menuId}', '批量删除${functionName}', NULL, '${classNameFirstLower}BatchDelete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${batchDeleteButtonId}', '${menuId}', '批量删除${functionName}', NULL, '${classNameFirstLower}BatchDelete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '2', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${editButtonId}', '${menuId}', '编辑${functionName}', NULL, '${classNameFirstLower}Edit', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '3', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${editButtonId}', '${menuId}', '编辑${functionName}', NULL, '${classNameFirstLower}Edit', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '3', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${deleteButtonId}', '${menuId}', '删除${functionName}', NULL, '${classNameFirstLower}Delete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, '4', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${deleteButtonId}', '${menuId}', '删除${functionName}', NULL, '${classNameFirstLower}Delete', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '4', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${importButtonId}', '${menuId}', '导入${functionName}', NULL, '${classNameFirstLower}Import', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '5', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
INSERT INTO "SNOWY"."SYS_RESOURCE" VALUES ('${exportButtonId}', '${menuId}', '导出${functionName}', NULL, '${classNameFirstLower}Export', 'BUTTON', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, '6', NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
||||
<% if (mobileModuleId != null && mobileModuleId != '') { %>
|
||||
INSERT INTO "SNOWY"."MOBILE_RESOURCE" VALUES ('${menuId}', '0', '${functionName}管理', NULL, 'MENU', '${mobileModuleId}', 'MENU', '/pages/${moduleName}/${busName}/index', 'apartment-outlined', '#1890ff', 'YES', 'ENABLE', 99, NULL, 'NOT_DELETE', NULL, NULL, NULL, NULL);
|
||||
|
|
|
@ -192,7 +192,7 @@ public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> impleme
|
|||
this.removeByIds(toDeleteOrgIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.ORG.getValue(), toDeleteOrgIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ public class SysPositionServiceImpl extends ServiceImpl<SysPositionMapper, SysPo
|
|||
this.removeByIds(positionIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.POSITION.getValue(), positionIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.POSITION.getValue(), positionIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,10 +24,13 @@ import vip.xiaonuo.sys.api.SysRelationApi;
|
|||
import vip.xiaonuo.sys.modular.relation.entity.SysRelation;
|
||||
import vip.xiaonuo.sys.modular.relation.enums.SysRelationCategoryEnum;
|
||||
import vip.xiaonuo.sys.modular.relation.service.SysRelationService;
|
||||
import vip.xiaonuo.sys.modular.user.entity.SysUser;
|
||||
import vip.xiaonuo.sys.modular.user.service.SysUserService;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 关系API接口实现类
|
||||
|
@ -41,16 +44,29 @@ public class SysRelationApiProvider implements SysRelationApi {
|
|||
@Resource
|
||||
private SysRelationService sysRelationService;
|
||||
|
||||
@Resource
|
||||
private SysUserService sysUserService;
|
||||
|
||||
@Override
|
||||
public List<String> getUserIdListByRoleIdList(List<String> roleIdList) {
|
||||
return sysRelationService.getRelationObjectIdListByTargetIdListAndCategory(roleIdList,
|
||||
List<String> userIdList = sysRelationService.getRelationObjectIdListByTargetIdListAndCategory(roleIdList,
|
||||
SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue());
|
||||
if(ObjectUtil.isEmpty(userIdList)){
|
||||
return sysUserService.listByIds(userIdList).stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getUserIdListByGroupIdList(List<String> groupIdList) {
|
||||
return sysRelationService.getRelationObjectIdListByTargetIdListAndCategory(groupIdList,
|
||||
List<String> userIdList = sysRelationService.getRelationObjectIdListByTargetIdListAndCategory(groupIdList,
|
||||
SysRelationCategoryEnum.SYS_USER_HAS_GROUP.getValue());
|
||||
if(ObjectUtil.isEmpty(userIdList)){
|
||||
return sysUserService.listByIds(userIdList).stream().map(SysUser::getId).collect(Collectors.toList());
|
||||
} else {
|
||||
return CollectionUtil.newArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -86,6 +86,14 @@ public class SysMenu extends CommonEntity {
|
|||
@Schema(description = "是否可见")
|
||||
private String visible;
|
||||
|
||||
/** 显示布局 */
|
||||
@Schema(description = "显示布局")
|
||||
private String displayLayout;
|
||||
|
||||
/** 缓存 */
|
||||
@Schema(description = "缓存")
|
||||
private String keepLive;
|
||||
|
||||
/** 排序码 */
|
||||
@Schema(description = "排序码")
|
||||
private Integer sortCode;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||
*
|
||||
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||
*
|
||||
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||
*/
|
||||
package vip.xiaonuo.sys.modular.resource.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 菜单是否与
|
||||
*
|
||||
* @author yubaoshan
|
||||
* @date 2024/9/17 00:14
|
||||
**/
|
||||
@Getter
|
||||
public enum SysMenuWhetherEnum {
|
||||
|
||||
/** 写入 */
|
||||
YES("YES"),
|
||||
|
||||
/** 不写入 */
|
||||
NO("NO");
|
||||
|
||||
private final String value;
|
||||
|
||||
SysMenuWhetherEnum(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -74,6 +74,14 @@ public class SysMenuAddParam {
|
|||
@Schema(description = "是否可见")
|
||||
private String visible;
|
||||
|
||||
/** 显示布局 */
|
||||
@Schema(description = "显示布局")
|
||||
private String displayLayout;
|
||||
|
||||
/** 缓存 */
|
||||
@Schema(description = "缓存")
|
||||
private String keepLive;
|
||||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
private String extJson;
|
||||
|
|
|
@ -79,6 +79,14 @@ public class SysMenuEditParam {
|
|||
@Schema(description = "是否可见")
|
||||
private String visible;
|
||||
|
||||
/** 显示布局 */
|
||||
@Schema(description = "显示布局")
|
||||
private String displayLayout;
|
||||
|
||||
/** 缓存 */
|
||||
@Schema(description = "缓存")
|
||||
private String keepLive;
|
||||
|
||||
/** 扩展信息 */
|
||||
@Schema(description = "扩展信息")
|
||||
private String extJson;
|
||||
|
|
|
@ -115,7 +115,9 @@ public class SysButtonServiceImpl extends ServiceImpl<SysButtonMapper, SysButton
|
|||
CollectionUtil.newArrayList(JSONUtil.createObj().set("title", "新增" + functionName).set("code", classNameFirstLower + "Add").set("sortCode", 1),
|
||||
JSONUtil.createObj().set("title", "编辑" + functionName).set("code", classNameFirstLower + "Edit").set("sortCode", 2),
|
||||
JSONUtil.createObj().set("title", "删除" + functionName).set("code", classNameFirstLower + "Delete").set("sortCode", 3),
|
||||
JSONUtil.createObj().set("title", "批量删除").set("code", classNameFirstLower + "BatchDelete").set("sortCode", 4)).forEach(jsonObject -> {
|
||||
JSONUtil.createObj().set("title", "批量删除").set("code", classNameFirstLower + "BatchDelete").set("sortCode", 4),
|
||||
JSONUtil.createObj().set("title", "导入" + functionName).set("code", classNameFirstLower + "Import").set("sortCode", 5),
|
||||
JSONUtil.createObj().set("title", "导出" + functionName).set("code", classNameFirstLower + "Export").set("sortCode", 6)).forEach(jsonObject -> {
|
||||
SysButtonAddParam sysButtonAddParam = new SysButtonAddParam();
|
||||
BeanUtil.copyProperties(jsonObject, sysButtonAddParam);
|
||||
sysButtonAddParam.setParentId(sysMenu.getId());
|
||||
|
@ -171,7 +173,7 @@ public class SysButtonServiceImpl extends ServiceImpl<SysButtonMapper, SysButton
|
|||
this.removeByIds(buttonIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), buttonIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.RESOURCE.getValue(), buttonIdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,7 +343,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
|
|||
this.removeByIds(toDeleteMenuIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@ public class SysModuleServiceImpl extends ServiceImpl<SysModuleMapper, SysModule
|
|||
this.removeByIds(toDeleteMenuIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.RESOURCE.getValue(), toDeleteMenuIdList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,6 +231,7 @@ public class SysRoleController {
|
|||
@CommonLog("给角色授权用户")
|
||||
@PostMapping("/sys/role/grantUser")
|
||||
public CommonResult<String> grantUser(@RequestBody @Valid SysRoleGrantUserParam sysRoleGrantUserParam) {
|
||||
sysRoleGrantUserParam.setRemoveFirst(true);
|
||||
sysRoleService.grantUser(sysRoleGrantUserParam);
|
||||
return CommonResult.ok();
|
||||
}
|
||||
|
|
|
@ -39,4 +39,7 @@ public class SysRoleGrantUserParam {
|
|||
@Schema(description = "授权用户信息")
|
||||
@NotNull(message = "grantInfoList不能为空")
|
||||
private List<String> grantInfoList;
|
||||
|
||||
/** 是否先清空授权信息 */
|
||||
private Boolean removeFirst = false;
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
this.removeByIds(sysRoleIdList);
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.ROLE.getValue(), sysRoleIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.ROLE.getValue(), sysRoleIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,8 +326,10 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
|
|||
public void grantUser(SysRoleGrantUserParam sysRoleGrantUserParam) {
|
||||
String id = sysRoleGrantUserParam.getId();
|
||||
List<String> grantInfoList = sysRoleGrantUserParam.getGrantInfoList();
|
||||
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getTargetId, id)
|
||||
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
||||
if(sysRoleGrantUserParam.getRemoveFirst()) {
|
||||
sysRelationService.remove(new LambdaQueryWrapper<SysRelation>().eq(SysRelation::getTargetId, id)
|
||||
.eq(SysRelation::getCategory, SysRelationCategoryEnum.SYS_USER_HAS_ROLE.getValue()));
|
||||
}
|
||||
sysRelationService.saveBatch(grantInfoList.stream().map(userId -> {
|
||||
SysRelation sysRelation = new SysRelation();
|
||||
sysRelation.setObjectId(userId);
|
||||
|
|
|
@ -41,9 +41,4 @@ public class SysUserBindEmailParam {
|
|||
@Schema(description = "验证码请求号")
|
||||
@NotBlank(message = "validCodeReqNo不能为空")
|
||||
private String validCodeReqNo;
|
||||
|
||||
/** 新密码 */
|
||||
@Schema(description = "新密码")
|
||||
@NotBlank(message = "newPassword不能为空")
|
||||
private String newPassword;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import org.springframework.web.multipart.MultipartFile;
|
||||
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
|
||||
import vip.xiaonuo.common.cache.CommonCacheOperator;
|
||||
import vip.xiaonuo.common.enums.CommonGenderEnum;
|
||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||
import vip.xiaonuo.common.excel.CommonExcelCustomMergeStrategy;
|
||||
import vip.xiaonuo.common.exception.CommonException;
|
||||
|
@ -93,6 +94,7 @@ import vip.xiaonuo.sys.modular.relation.service.SysRelationService;
|
|||
import vip.xiaonuo.sys.modular.resource.entity.SysButton;
|
||||
import vip.xiaonuo.sys.modular.resource.entity.SysMenu;
|
||||
import vip.xiaonuo.sys.modular.resource.entity.SysModule;
|
||||
import vip.xiaonuo.sys.modular.resource.enums.SysMenuWhetherEnum;
|
||||
import vip.xiaonuo.sys.modular.resource.enums.SysResourceCategoryEnum;
|
||||
import vip.xiaonuo.sys.modular.resource.enums.SysResourceMenuTypeEnum;
|
||||
import vip.xiaonuo.sys.modular.resource.service.SysButtonService;
|
||||
|
@ -447,7 +449,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
sysUserExtService.remove(new LambdaQueryWrapper<SysUserExt>().in(SysUserExt::getUserId, sysUserIdList));
|
||||
|
||||
// 发布删除事件
|
||||
CommonDataChangeEventCenter.doDeleteWithDataId(SysDataTypeEnum.USER.getValue(), sysUserIdList);
|
||||
CommonDataChangeEventCenter.doDeleteWithDataIdList(SysDataTypeEnum.USER.getValue(), sysUserIdList);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -992,7 +994,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
// 执行校验验证码
|
||||
validValidCode(null, sysUserGetEmailValidCodeParam.getValidCode(), sysUserGetEmailValidCodeParam.getValidCodeReqNo());
|
||||
// 根据邮箱获取用户信息,判断用户是否存在,如果存在则不能绑定该邮箱
|
||||
if (ObjectUtil.isEmpty(this.getUserByEmail(email))) {
|
||||
if (ObjectUtil.isNotEmpty(this.getUserByEmail(email))) {
|
||||
throw new CommonException("邮箱:{}已存在对应用户", email);
|
||||
}
|
||||
// 生成邮箱验证码的值,随机6为数字
|
||||
|
@ -1034,7 +1036,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
// 执行校验验证码
|
||||
validValidCode(null, sysUserGetEmailValidCodeParam.getValidCode(), sysUserGetEmailValidCodeParam.getValidCodeReqNo());
|
||||
// 根据邮箱获取用户信息,判断用户是否存在,如果存在则不能绑定该邮箱
|
||||
if (ObjectUtil.isEmpty(this.getUserByEmail(email))) {
|
||||
if (ObjectUtil.isNotEmpty(this.getUserByEmail(email))) {
|
||||
throw new CommonException("邮箱:{}已存在对应用户", email);
|
||||
}
|
||||
// 生成邮箱验证码的值,随机6为数字
|
||||
|
@ -1074,7 +1076,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
throw new CommonException("邮箱:{}格式错误", email);
|
||||
}
|
||||
// 根据邮箱获取用户信息,判断用户是否存在,如果存在则不能绑定该邮箱
|
||||
if (ObjectUtil.isEmpty(this.getUserByEmail(email))) {
|
||||
if (ObjectUtil.isNotEmpty(this.getUserByEmail(email))) {
|
||||
throw new CommonException("邮箱:{}已存在对应用户", email);
|
||||
}
|
||||
// 执行校验验证码
|
||||
|
@ -1253,6 +1255,20 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
// 如果是首页,则设置affix
|
||||
metaJsonObject.set("affix", true);
|
||||
}
|
||||
String menuMetaKeepLiveKey = "keepLive";
|
||||
String menuMetaDisplayLayoutKey = "displayLayout";
|
||||
// 设置缓存
|
||||
if (ObjectUtil.isEmpty(sysMenu.getKeepLive()) || sysMenu.getKeepLive().equals(SysMenuWhetherEnum.NO.getValue())) {
|
||||
metaJsonObject.set(menuMetaKeepLiveKey, false);
|
||||
} else if (sysMenu.getKeepLive().equals(SysMenuWhetherEnum.YES.getValue())) {
|
||||
metaJsonObject.set(menuMetaKeepLiveKey, true);
|
||||
}
|
||||
// 设置显示布局
|
||||
if (ObjectUtil.isEmpty(sysMenu.getDisplayLayout()) || sysMenu.getDisplayLayout().equals(SysMenuWhetherEnum.YES.getValue())) {
|
||||
metaJsonObject.set(menuMetaDisplayLayoutKey, true);
|
||||
} else if (sysMenu.getDisplayLayout().equals(SysMenuWhetherEnum.NO.getValue())) {
|
||||
metaJsonObject.set(menuMetaDisplayLayoutKey, false);
|
||||
}
|
||||
}
|
||||
// 如果设置了不可见,那么设置为false,为了兼容已有,所以只是false的为不显示
|
||||
if (ObjectUtil.isNotEmpty(sysMenu.getVisible()) && sysMenu.getVisible().equals("FALSE")) {
|
||||
|
@ -1347,10 +1363,10 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
}
|
||||
}
|
||||
}
|
||||
List<String> extJsonList = sysUserGrantResourceParam.getGrantInfoList().stream()
|
||||
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
||||
sysRelationService.saveRelationBatchWithClear(sysUserGrantResourceParam.getId(), menuIdList, SysRelationCategoryEnum.SYS_USER_HAS_RESOURCE.getValue(), extJsonList);
|
||||
}
|
||||
List<String> extJsonList = sysUserGrantResourceParam.getGrantInfoList().stream()
|
||||
.map(JSONUtil::toJsonStr).collect(Collectors.toList());
|
||||
sysRelationService.saveRelationBatchWithClear(sysUserGrantResourceParam.getId(), menuIdList, SysRelationCategoryEnum.SYS_USER_HAS_RESOURCE.getValue(), extJsonList);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1551,7 +1567,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
FileUtil.FILE_SEPARATOR + "userImportTemplate.xlsx"));
|
||||
// 读取excel
|
||||
List<SysUserImportParam> sysUserImportParamList = EasyExcel.read(tempFile).head(SysUserImportParam.class).sheet()
|
||||
.headRowNumber(2).doReadSync();
|
||||
.headRowNumber(3).doReadSync();
|
||||
List<SysUser> allUserList = this.list();
|
||||
for (int i = 0; i < sysUserImportParamList.size(); i++) {
|
||||
JSONObject jsonObject = this.doImport(allUserList, sysUserImportParamList.get(i), i);
|
||||
|
@ -2147,6 +2163,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
sysUserAddParam.setPhone(phone);
|
||||
sysUserAddParam.setOrgId(this.getDefaultNewUserOrgId());
|
||||
sysUserAddParam.setPositionId(this.getDefaultNewUserPositionId());
|
||||
sysUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(sysUserAddParam, SysUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 获取用户信息
|
||||
|
@ -2182,6 +2199,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
sysUserAddParam.setEmail(email);
|
||||
sysUserAddParam.setOrgId(this.getDefaultNewUserOrgId());
|
||||
sysUserAddParam.setPositionId(this.getDefaultNewUserPositionId());
|
||||
sysUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(sysUserAddParam, SysUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 获取用户信息
|
||||
|
@ -2219,6 +2237,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
|||
sysUserAddParam.setPassword(password);
|
||||
sysUserAddParam.setOrgId(this.getDefaultNewUserOrgId());
|
||||
sysUserAddParam.setPositionId(this.getDefaultNewUserPositionId());
|
||||
sysUserAddParam.setGender(CommonGenderEnum.UNKNOWN.getValue());
|
||||
// 保存用户
|
||||
this.add(sysUserAddParam, SysUserSourceFromTypeEnum.SYSTEM_REGISTER.getValue());
|
||||
// 获取用户信息
|
||||
|
|
|
@ -107,7 +107,7 @@ import java.util.Map;
|
|||
@MapperScan(basePackages = {"vip.xiaonuo.**.mapper"})
|
||||
public class GlobalConfigure implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
@Resource
|
||||
private SaTokenConfig saTokenConfig;
|
||||
|
||||
private static final String COMMON_REPEAT_SUBMIT_CACHE_KEY = "common-repeatSubmit:";
|
||||
|
@ -118,7 +118,6 @@ public class GlobalConfigure implements WebMvcConfigurer {
|
|||
public static final String[] NO_LOGIN_PATH_ARR = {
|
||||
/* 主入口 */
|
||||
"/",
|
||||
|
||||
/* 静态资源 */
|
||||
"/favicon.ico",
|
||||
"/doc.html",
|
||||
|
@ -133,11 +132,17 @@ public class GlobalConfigure implements WebMvcConfigurer {
|
|||
"/auth/c/getPhoneValidCode",
|
||||
"/auth/c/doLogin",
|
||||
"/auth/c/doLoginByPhone",
|
||||
"/auth/c/register",
|
||||
"/auth/c/getEmailValidCode",
|
||||
"/auth/c/doLoginByEmail",
|
||||
|
||||
"/auth/b/getPicCaptcha",
|
||||
"/auth/b/getPhoneValidCode",
|
||||
"/auth/b/doLogin",
|
||||
"/auth/b/doLoginByPhone",
|
||||
"/auth/b/register",
|
||||
"/auth/b/getEmailValidCode",
|
||||
"/auth/b/doLoginByEmail",
|
||||
|
||||
/* 三方登录相关 */
|
||||
"/auth/third/render",
|
||||
|
@ -154,7 +159,10 @@ public class GlobalConfigure implements WebMvcConfigurer {
|
|||
"/sys/userCenter/findPasswordGetPhoneValidCode",
|
||||
"/sys/userCenter/findPasswordGetEmailValidCode",
|
||||
"/sys/userCenter/findPasswordByPhone",
|
||||
"/sys/userCenter/findPasswordByEmail"
|
||||
"/sys/userCenter/findPasswordByEmail",
|
||||
|
||||
/* 文件下载 */
|
||||
"/dev/file/download"
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -587,6 +587,7 @@ CREATE TABLE `DEV_FILE` (
|
|||
`OBJ_NAME` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文件的对象名(唯一名称)',
|
||||
`STORAGE_PATH` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文件存储路径',
|
||||
`DOWNLOAD_PATH` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '文件下载路径',
|
||||
`IS_DOWNLOAD_AUTH` tinyint(1) NULL DEFAULT NULL COMMENT '文件下载是否需要授权',
|
||||
`THUMBNAIL` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '图片缩略图',
|
||||
`EXT_JSON` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '扩展信息',
|
||||
`DELETE_FLAG` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '删除标志',
|
||||
|
@ -847,6 +848,7 @@ CREATE TABLE `GEN_CONFIG` (
|
|||
`WHETHER_RETRACT` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列省略',
|
||||
`WHETHER_ADD_UPDATE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否增改',
|
||||
`WHETHER_REQUIRED` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '必填',
|
||||
`WHETHER_UNIQUE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '唯一',
|
||||
`QUERY_WHETHER` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '查询',
|
||||
`QUERY_TYPE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '查询方式',
|
||||
`SORT_CODE` int(11) NULL DEFAULT NULL COMMENT '排序',
|
||||
|
@ -1196,6 +1198,8 @@ CREATE TABLE `SYS_RESOURCE` (
|
|||
`ICON` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '图标',
|
||||
`COLOR` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '颜色',
|
||||
`VISIBLE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否可见',
|
||||
`DISPLAY_LAYOUT` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '显示布局',
|
||||
`KEEP_LIVE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '页签缓存',
|
||||
`SORT_CODE` int(11) NULL DEFAULT NULL COMMENT '排序码',
|
||||
`EXT_JSON` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '扩展信息',
|
||||
`DELETE_FLAG` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '删除标志',
|
||||
|
|
Loading…
Reference in New Issue