feat: (feature/REQ-3167) 实现前端资源同步,新增资源管理批量upsert接口,重构原upsert接口
This commit is contained in:
parent
944c0d099b
commit
164ea1361a
@ -2,8 +2,26 @@ package cn.axzo.tyr.client.feign;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiPageResult;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.model.req.*;
|
||||
import cn.axzo.tyr.client.model.res.*;
|
||||
import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.DeletePageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.GetPageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.IdReq;
|
||||
import cn.axzo.tyr.client.model.req.ModifyPageElementRelationDTO;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementImportDataReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementReportReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.PageQueryElementReq;
|
||||
import cn.axzo.tyr.client.model.req.PageQueryElementV2Req;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.SyncPageElementReq;
|
||||
import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementResp;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -75,4 +93,12 @@ public interface PageElementApi {
|
||||
/** 查询页面元素关联关系 **/
|
||||
@PostMapping("/api/pageElement/importData")
|
||||
ApiResult<Void> importData(@RequestBody @Valid List<PageElementImportDataReq> req);
|
||||
|
||||
/**
|
||||
* 从基准环境把前端资源元素同步到当前环境
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/pageElement/sync")
|
||||
ApiResult<Void> syncPageElement(@RequestBody @Valid SyncPageElementReq req);
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package cn.axzo.tyr.client.feign;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = "tyr", url = "${axzo.service.tyr:http://tyr:8080}")
|
||||
public interface PageElementCategoryApi {
|
||||
|
||||
/**
|
||||
* 从基准环境查询分类信息
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/api/pageElementCategory/base/list")
|
||||
ApiResult<List<ListPageElementCategoryResp>> listFromBase(@RequestBody PageElementCategoryReq req);
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package cn.axzo.tyr.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BatchUpsertPageElementCategoryReq {
|
||||
|
||||
@NotEmpty(message = "upsertPageElementCategories不能为空")
|
||||
private List<UpsertPageElementCategory> upsertPageElementCategories;
|
||||
|
||||
@NotNull(message = "操作人不能为空")
|
||||
private Long operatorId;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class UpsertPageElementCategory {
|
||||
|
||||
private Long id;
|
||||
|
||||
/** 项目编码 **/
|
||||
private String itemCode;
|
||||
|
||||
/** 项目名称 **/
|
||||
@NotBlank(message = "项目名称不能为空")
|
||||
private String itemName;
|
||||
|
||||
/** 登录端 **/
|
||||
@NotBlank(message = "所属端不能为空")
|
||||
private String terminal;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
package cn.axzo.tyr.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class BatchUpsertPageElementReq {
|
||||
|
||||
@NotEmpty(message = "upsertPageElementReqs不能为空")
|
||||
private List<UpsertPageElementReq> upsertPageElementReqs;
|
||||
|
||||
@NotNull(message = "操作人不能为空")
|
||||
private Long operatorId;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class UpsertPageElementReq {
|
||||
|
||||
private Long id;
|
||||
|
||||
/** 项目编码 **/
|
||||
private String itemCode;
|
||||
|
||||
/** 分组ID **/
|
||||
private String groupCode;
|
||||
|
||||
/** 页面元素类型:PAGE/COMPONENT **/
|
||||
@NotBlank(message = "页面元素类型不能为空")
|
||||
private String type;
|
||||
|
||||
/** 项目编码 **/
|
||||
@NotBlank(message = "项目编码不能为空")
|
||||
private String code;
|
||||
|
||||
/** 元素名称 **/
|
||||
@NotBlank(message = "元素名称不能为空")
|
||||
private String name;
|
||||
|
||||
/** app类型(APP:原生,H5:h5页面, PC:web页面) **/
|
||||
private String appType;
|
||||
|
||||
/** H5的appId **/
|
||||
private String appId;
|
||||
|
||||
/** pc/h5路由地址 **/
|
||||
private String linkUrl;
|
||||
|
||||
/** ios跳转地址 **/
|
||||
private String iosRouterUrl;
|
||||
|
||||
/** android跳转地址 **/
|
||||
private String androidRouterUrl;
|
||||
|
||||
/**
|
||||
* 已经作废,不能再使用,现在分ios,android的版本号
|
||||
*/
|
||||
@Deprecated
|
||||
private Integer version;
|
||||
|
||||
/** 操作人personId **/
|
||||
private Long operatorId;
|
||||
|
||||
/**
|
||||
* ios 最低版本要求
|
||||
*/
|
||||
private Integer iosMinVersion;
|
||||
|
||||
/**
|
||||
* ios 最高版本要求
|
||||
*/
|
||||
private Integer iosMaxVersion;
|
||||
|
||||
/**
|
||||
* ios 是否开启最高版本要求:true-开启;false-关闭
|
||||
*/
|
||||
private Boolean iosMaxVersionEnabled;
|
||||
|
||||
/**
|
||||
* android 最低版本要求
|
||||
*/
|
||||
private Integer androidMinVersion;
|
||||
|
||||
/**
|
||||
* android 最高版本要求
|
||||
*/
|
||||
private Integer androidMaxVersion;
|
||||
|
||||
/**
|
||||
* android 是否开启最高版本要求:true-开启;false-关闭
|
||||
*/
|
||||
private Boolean androidMaxVersionEnabled;
|
||||
}
|
||||
}
|
||||
@ -41,4 +41,13 @@ public class PageElementReq implements IPageReq {
|
||||
|
||||
@CriteriaField(field = "type", operator = Operator.IN)
|
||||
private Set<PageElementTypeEnum> types;
|
||||
|
||||
@CriteriaField(field = "id", operator = Operator.IN)
|
||||
private Set<Long> ids;
|
||||
|
||||
@CriteriaField(ignore = true)
|
||||
private Boolean needChildren;
|
||||
|
||||
@CriteriaField(ignore = true)
|
||||
private Boolean needPageElementCategory;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package cn.axzo.tyr.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SyncPageElementReq {
|
||||
|
||||
/**
|
||||
* 分组下类型是PAGE的pageElement记录id,同步时会把PAGE下的COMPONENT信息也一起同步
|
||||
*/
|
||||
@NotEmpty(message = "资源页面元素id不能为空")
|
||||
private Set<Long> pageElementIds;
|
||||
|
||||
@NotNull(message = "操作人不能为空")
|
||||
private Long operatorId;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
package cn.axzo.tyr.client.model.res;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PageElementCategoryResp {
|
||||
|
||||
private Long id;
|
||||
|
||||
private Date createAt;
|
||||
|
||||
private Date updateAt;
|
||||
|
||||
private Long isDelete;
|
||||
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 项目code(H5会拉取项目下所有的元素)
|
||||
*/
|
||||
private String itemCode;
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
private String itemName;
|
||||
|
||||
/**
|
||||
* 所属端
|
||||
*/
|
||||
private String terminal;
|
||||
}
|
||||
@ -127,6 +127,11 @@ public class PageElementResp {
|
||||
*/
|
||||
private Boolean androidMaxVersionEnabled;
|
||||
|
||||
/**
|
||||
* 所属的itemCode的分类
|
||||
*/
|
||||
private PageElementCategoryResp pageElementCategory;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
|
||||
@ -17,10 +17,17 @@ public enum BizResultCode implements IResultCode {
|
||||
REMOVE_USER_ROLE_ERROR("100007", "删除用户角色数据异常"),
|
||||
DATA_ERROR("100008", "数据异常"),
|
||||
FEATURE_CODE_EXIST("100009", "featureCode已经存在"),
|
||||
PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "页面元素不存在"),
|
||||
PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "项目编码不能为空"),
|
||||
PAGE_ELEMENT_ITEM_CODE_NOT_FOUND("100010", "资源分组不存在:{}"),
|
||||
PAGE_ELEMENT_ITEM_CODE_NOT_NULL("100011", "资源分组数据不存在"),
|
||||
PAGE_ELEMENT_GROUP_CODE_NOT_NULL("100012", "分组编码不能为空"),
|
||||
PAGE_ELEMENT_GROUP_CODE_NOT_FOUND("100013", "页面元素不存在");
|
||||
PAGE_ELEMENT_GROUP_CODE_NOT_FOUND("100013", "页面元素不存在:{}"),
|
||||
ITEM_NAME_DUPLICATE("100014", "资源分组名字重复,重复的名字:{}"),
|
||||
ITEM_CODE_DUPLICATE("100015", "资源分组code重复,重复的code:{}"),
|
||||
PAGE_ELEMENT_CATEGORY_NOT_FOUND("100016", "资源分组数据不存在"),
|
||||
PAGE_ELEMENT_ERROR("100017", "资源分组错误:{}"),
|
||||
PAGE_CODE_DUPLICATE("100018", "资源元素code重复,重复的code:{}"),
|
||||
PARAM_ERROR("100019", "参数错误");
|
||||
|
||||
|
||||
private String errorCode;
|
||||
private String errorMessage;
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package cn.axzo.tyr.server.controller.permission;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.feign.PageElementCategoryApi;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import cn.axzo.tyr.server.inner.feign.BasePageElementCategoryApi;
|
||||
import cn.axzo.tyr.server.util.RpcInternalUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class PageElementCategoryController implements PageElementCategoryApi {
|
||||
|
||||
@Autowired
|
||||
private BasePageElementCategoryApi basePageElementCategoryApi;
|
||||
|
||||
@Override
|
||||
public ApiResult<List<ListPageElementCategoryResp>> listFromBase(PageElementCategoryReq req) {
|
||||
return RpcInternalUtil.rpcProcessor(() -> basePageElementCategoryApi.listPageElementCategory(req),
|
||||
"list pageElementCategory from base env", req);
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,6 +17,7 @@ import cn.axzo.tyr.client.model.req.PageQueryElementReq;
|
||||
import cn.axzo.tyr.client.model.req.PageQueryElementV2Req;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.SyncPageElementReq;
|
||||
import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp;
|
||||
@ -118,4 +119,10 @@ public class PageElementController implements PageElementApi {
|
||||
saasPageElementService.importData(req);
|
||||
return ApiResult.ok();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResult<Void> syncPageElement(SyncPageElementReq req) {
|
||||
saasPageElementService.syncPageElement(req);
|
||||
return ApiResult.ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package cn.axzo.tyr.server.inner.feign;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.model.req.PageElementReq;
|
||||
import cn.axzo.tyr.client.model.res.PageElementResp;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}")
|
||||
public interface BasePageElementApi {
|
||||
|
||||
@PostMapping("/api/pageElement/list")
|
||||
ApiResult<List<PageElementResp>> list(PageElementReq param);
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package cn.axzo.tyr.server.inner.feign;
|
||||
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@FeignClient(name = "tyr", url = "${axzo.service.base.tyr:https://pre-api.axzo.cn/tyr}")
|
||||
public interface BasePageElementCategoryApi {
|
||||
|
||||
/** 查询页面元素类型(按端分组) **/
|
||||
@PostMapping("/api/pageElementCategory/list")
|
||||
ApiResult<List<ListPageElementCategoryResp>> listPageElementCategory(@RequestBody PageElementCategoryReq req);
|
||||
}
|
||||
@ -71,14 +71,4 @@ public class SaasPageElementDao extends ServiceImpl<SaasPageElementMapper, SaasP
|
||||
.set(SaasPageElement::getIsDelete, DeleteEnum.DELETE.getValue())
|
||||
.update();
|
||||
}
|
||||
|
||||
public void updateComponentsGroupCode(String oldGroupCode, String newGroupCode, String terminal) {
|
||||
lambdaUpdate()
|
||||
.eq(SaasPageElement::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.eq(SaasPageElement::getTerminal, terminal)
|
||||
.eq(SaasPageElement::getType, PageElementTypeEnum.COMPONENT.getCode())
|
||||
.eq(SaasPageElement::getGroupCode, oldGroupCode)
|
||||
.set(SaasPageElement::getGroupCode, newGroupCode)
|
||||
.update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,8 @@ public class SaasPageElement extends BaseEntity<SaasPageElement> {
|
||||
|
||||
/**
|
||||
* 元素的组编码
|
||||
* type = PAGE时,code跟groupCode一样
|
||||
* type = COMPONENT时,groupCode是对应 type = PAGE的code
|
||||
*/
|
||||
@TableField("group_code")
|
||||
private String groupCode;
|
||||
@ -100,6 +102,7 @@ public class SaasPageElement extends BaseEntity<SaasPageElement> {
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
@Deprecated
|
||||
@TableField("item_name")
|
||||
private String itemName;
|
||||
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
package cn.axzo.tyr.server.service;
|
||||
|
||||
import cn.axzo.foundation.page.PageResp;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.res.ListPageElementCategoryResp;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -12,11 +17,13 @@ import java.util.List;
|
||||
* @version 1.0
|
||||
* @date 2024/8/20
|
||||
*/
|
||||
public interface SaasPageElementCategoryService {
|
||||
public interface SaasPageElementCategoryService extends IService<SaasPageElementCategory> {
|
||||
|
||||
List<ListPageElementCategoryResp> listGroupByTerminal(PageElementCategoryReq req);
|
||||
|
||||
Long saveOrUpdate(SaveOrUpdatePageElementCategoryReq req);
|
||||
|
||||
void delete(DeletePageElementCategoryReq req);
|
||||
|
||||
void batchUpsert(BatchUpsertPageElementCategoryReq req);
|
||||
}
|
||||
|
||||
@ -92,4 +92,8 @@ public interface SaasPageElementService extends IService<SaasPageElement> {
|
||||
List<PageElementRelationFeatureResourceResp> getFeatureResourceRelations(Long pageElementId);
|
||||
|
||||
void importData(List<PageElementImportDataReq> req);
|
||||
|
||||
void syncPageElement(SyncPageElementReq req);
|
||||
|
||||
List<Long> batchUpsert(BatchUpsertPageElementReq req);
|
||||
}
|
||||
|
||||
@ -2,10 +2,12 @@ package cn.axzo.tyr.server.service.impl;
|
||||
|
||||
import cn.axzo.basics.common.constant.enums.DeleteEnum;
|
||||
import cn.axzo.basics.common.util.AssertUtil;
|
||||
import cn.axzo.foundation.exception.Axssert;
|
||||
import cn.axzo.framework.rocketmq.Event;
|
||||
import cn.axzo.pokonyan.config.mybatisplus.BaseEntity;
|
||||
import cn.axzo.tyr.client.common.enums.PageElementTypeEnum;
|
||||
import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.DeletePageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.PageElementReq;
|
||||
@ -20,9 +22,12 @@ import cn.axzo.tyr.server.repository.dao.SaasPageElementDao;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasPageElementFeatureResourceRelationDao;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasPageElement;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasPageElementCategory;
|
||||
import cn.axzo.tyr.server.repository.mapper.SaasPageElementCategoryMapper;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementCategoryService;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementService;
|
||||
import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.common.collect.Sets;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -36,8 +41,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_CODE_DUPLICATE;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_CATEGORY_NOT_FOUND;
|
||||
import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT;
|
||||
|
||||
/**
|
||||
@ -48,7 +57,8 @@ import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_
|
||||
@Slf4j
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SaasPageElementCategoryServiceImpl implements SaasPageElementCategoryService {
|
||||
public class SaasPageElementCategoryServiceImpl extends ServiceImpl<SaasPageElementCategoryMapper, SaasPageElementCategory>
|
||||
implements SaasPageElementCategoryService {
|
||||
|
||||
public static final String PAGE_ELEMENT_CATEGORY_TABLE_NAME = "saas_page_element_category";
|
||||
private static final String TARGET_TYPE = "pageElementFeatureResourceId";
|
||||
@ -156,6 +166,147 @@ public class SaasPageElementCategoryServiceImpl implements SaasPageElementCatego
|
||||
return baseCategory.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchUpsert(BatchUpsertPageElementCategoryReq req) {
|
||||
check(req);
|
||||
List<SaasPageElementCategory> saasPageElementCategories = req.getUpsertPageElementCategories().stream()
|
||||
.map(e -> {
|
||||
SaasPageElementCategory saasPageElementCategory = SaasPageElementCategory.builder()
|
||||
.itemCode(e.getItemCode())
|
||||
.itemName(e.getItemName())
|
||||
.terminal(e.getTerminal())
|
||||
.createBy(Objects.nonNull(e.getId()) ? null : req.getOperatorId())
|
||||
.updateBy(req.getOperatorId())
|
||||
.build();
|
||||
saasPageElementCategory.setId(e.getId());
|
||||
return saasPageElementCategory;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
saasPageElementCategoryDao.updateBatchById(saasPageElementCategories);
|
||||
|
||||
try {
|
||||
saveOrUpdateOperateLog(req, saasPageElementCategories);
|
||||
} catch (Exception e) {
|
||||
log.warn("save operate log error", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkItemName(BatchUpsertPageElementCategoryReq req) {
|
||||
// check入参中重复的名字
|
||||
Set<String> duplicateItemNames = req.getUpsertPageElementCategories().stream()
|
||||
.collect(Collectors.groupingBy(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().size() > 1)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Axssert.check(CollectionUtils.isEmpty(duplicateItemNames), ITEM_NAME_DUPLICATE,
|
||||
ITEM_NAME_DUPLICATE.getErrorMessage(), duplicateItemNames);
|
||||
|
||||
// check新增或者更新的itemName是否已经存在
|
||||
List<String> itemNames = req.getUpsertPageElementCategories().stream()
|
||||
.map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName)
|
||||
.collect(Collectors.toList());
|
||||
List<SaasPageElementCategory> saasPageElementCategories = this.lambdaQuery()
|
||||
.in(SaasPageElementCategory::getItemName, itemNames)
|
||||
.eq(SaasPageElementCategory::getIsDelete, DeleteEnum.NORMAL.value)
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(saasPageElementCategories)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, SaasPageElementCategory> itemNameMap = saasPageElementCategories.stream()
|
||||
.collect(Collectors.toMap(SaasPageElementCategory::getItemName, Function.identity()));
|
||||
|
||||
List<String> dbDuplicateItemNames = req.getUpsertPageElementCategories().stream()
|
||||
.filter(e -> {
|
||||
SaasPageElementCategory oldSaasPageElementCategory = itemNameMap.get(e.getItemName());
|
||||
if (Objects.isNull(oldSaasPageElementCategory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 新增里重复的itemName
|
||||
if (Objects.isNull(e.getId())) {
|
||||
return true;
|
||||
}
|
||||
// 更新里重复的itemName
|
||||
return !Objects.equals(e.getId(), oldSaasPageElementCategory.getId());
|
||||
})
|
||||
.map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Axssert.check(CollectionUtils.isEmpty(dbDuplicateItemNames), ITEM_NAME_DUPLICATE,
|
||||
ITEM_NAME_DUPLICATE.getErrorMessage(), dbDuplicateItemNames);
|
||||
}
|
||||
|
||||
private void checkItemCode(BatchUpsertPageElementCategoryReq req) {
|
||||
// check入参中重复的ItemCode
|
||||
Set<String> duplicateItemCodes = req.getUpsertPageElementCategories().stream()
|
||||
.collect(Collectors.groupingBy(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().size() > 1)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Axssert.check(CollectionUtils.isEmpty(duplicateItemCodes), ITEM_CODE_DUPLICATE,
|
||||
ITEM_CODE_DUPLICATE.getErrorMessage(), duplicateItemCodes);
|
||||
|
||||
// check新增或者更新的itemCode是否已经存在
|
||||
List<String> itemCodes = req.getUpsertPageElementCategories().stream()
|
||||
.map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode)
|
||||
.collect(Collectors.toList());
|
||||
List<SaasPageElementCategory> saasPageElementCategories = this.lambdaQuery()
|
||||
.in(SaasPageElementCategory::getItemCode, itemCodes)
|
||||
.eq(SaasPageElementCategory::getIsDelete, DeleteEnum.NORMAL.value)
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(saasPageElementCategories)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, SaasPageElementCategory> itemCodeMap = saasPageElementCategories.stream()
|
||||
.collect(Collectors.toMap(SaasPageElementCategory::getItemCode, Function.identity()));
|
||||
|
||||
List<String> dbDuplicateItemCodes = req.getUpsertPageElementCategories().stream()
|
||||
.filter(e -> {
|
||||
SaasPageElementCategory oldSaasPageElementCategory = itemCodeMap.get(e.getItemName());
|
||||
if (Objects.isNull(oldSaasPageElementCategory)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 新增里重复的itemName
|
||||
if (Objects.isNull(e.getId())) {
|
||||
return true;
|
||||
}
|
||||
// 更新里重复的itemName
|
||||
return !Objects.equals(e.getId(), oldSaasPageElementCategory.getId());
|
||||
})
|
||||
.map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getItemCode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Axssert.check(CollectionUtils.isEmpty(dbDuplicateItemCodes), ITEM_CODE_DUPLICATE,
|
||||
ITEM_CODE_DUPLICATE.getErrorMessage(), dbDuplicateItemCodes);
|
||||
}
|
||||
|
||||
private void check(BatchUpsertPageElementCategoryReq req) {
|
||||
checkItemName(req);
|
||||
|
||||
checkItemCode(req);
|
||||
|
||||
List<Long> ids = req.getUpsertPageElementCategories().stream()
|
||||
.map(BatchUpsertPageElementCategoryReq.UpsertPageElementCategory::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(ids)) {
|
||||
List<SaasPageElementCategory> saasPageElementCategories = saasPageElementCategoryDao.listByIds(ids);
|
||||
Axssert.check(ids.size() == saasPageElementCategories.size(), PAGE_ELEMENT_CATEGORY_NOT_FOUND);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(DeletePageElementCategoryReq req) {
|
||||
@ -223,6 +374,20 @@ public class SaasPageElementCategoryServiceImpl implements SaasPageElementCatego
|
||||
.build());
|
||||
}
|
||||
|
||||
private void saveOrUpdateOperateLog(BatchUpsertPageElementCategoryReq req,
|
||||
List<SaasPageElementCategory> saasPageElementCategories) {
|
||||
|
||||
saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder()
|
||||
.tableName(PAGE_ELEMENT_CATEGORY_TABLE_NAME)
|
||||
.operatorId(req.getOperatorId())
|
||||
.scene(PermissionRelationOperateLogSceneEnum.OMS_UPSERT_PAGE_ELEMENT_CATEGORY.getValue())
|
||||
// 批量更新,记录id会超长,后续提供统一的更基础的日志记录表,先暂时用
|
||||
.sceneId(UuidUtils.generateUuid())
|
||||
.requestData(req)
|
||||
.operateData(saasPageElementCategories)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void saveDeleteOperateLog(DeletePageElementCategoryReq req, SaasPageElementCategory baseCategory) {
|
||||
saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder()
|
||||
.tableName(PAGE_ELEMENT_CATEGORY_TABLE_NAME)
|
||||
|
||||
@ -19,6 +19,8 @@ import cn.axzo.tyr.client.common.enums.PageElementAppTypeEnum;
|
||||
import cn.axzo.tyr.client.common.enums.PageElementFeatureResourceRelationTypeEnum;
|
||||
import cn.axzo.tyr.client.common.enums.PageElementTypeEnum;
|
||||
import cn.axzo.tyr.client.common.enums.PermissionRelationOperateLogSceneEnum;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.DeletePageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.GetPageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.GetUserHasPermissionPageElementReq;
|
||||
@ -33,15 +35,18 @@ import cn.axzo.tyr.client.model.req.PageQueryElementV2Req;
|
||||
import cn.axzo.tyr.client.model.req.PageSaasFeatureResourceReq;
|
||||
import cn.axzo.tyr.client.model.req.PermissionOperateLogReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq;
|
||||
import cn.axzo.tyr.client.model.req.SyncPageElementReq;
|
||||
import cn.axzo.tyr.client.model.res.GetUserHasPermissionPageElementResp;
|
||||
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
|
||||
import cn.axzo.tyr.client.model.res.PageElementBasicDTO;
|
||||
import cn.axzo.tyr.client.model.res.PageElementCategoryAndElementResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementCategoryResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementRelationFeatureResourceResp;
|
||||
import cn.axzo.tyr.client.model.res.PageElementResp;
|
||||
import cn.axzo.tyr.client.model.res.SaasFeatureResourceResp;
|
||||
import cn.axzo.tyr.server.config.MqProducer;
|
||||
import cn.axzo.tyr.server.event.payload.PageElementFeatureResourceUpsertPayload;
|
||||
import cn.axzo.tyr.server.inner.feign.BasePageElementApi;
|
||||
import cn.axzo.tyr.server.model.RelationOperateLogResourceBindElementDO;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasFeatureResourceDao;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasPageElementCategoryDao;
|
||||
@ -54,6 +59,7 @@ import cn.axzo.tyr.server.repository.entity.SaasPageElementFeatureResourceRelati
|
||||
import cn.axzo.tyr.server.repository.entity.SaasPgroupPermissionRelationOperateLog;
|
||||
import cn.axzo.tyr.server.repository.mapper.SaasPageElementMapper;
|
||||
import cn.axzo.tyr.server.service.SaasFeatureResourceService;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementCategoryService;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementFeatureResourceRelationService;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementService;
|
||||
import cn.axzo.tyr.server.service.SaasPgroupPermissionRelationOperateLogService;
|
||||
@ -62,6 +68,7 @@ import cn.axzo.tyr.server.util.RpcInternalUtil;
|
||||
import cn.azxo.framework.common.constatns.Constants;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
@ -82,10 +89,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.data.util.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -97,10 +106,13 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_CODE_DUPLICATE;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_FOUND;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_GROUP_CODE_NOT_NULL;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_FOUND;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ITEM_CODE_NOT_NULL;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PARAM_ERROR;
|
||||
import static cn.axzo.tyr.server.event.inner.EventTypeEnum.PAGE_ELEMENT_FEATURE_RESOURCE_UPSERT;
|
||||
|
||||
/**
|
||||
@ -125,6 +137,8 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
private final SaasFeatureResourceService saasFeatureResourceService;
|
||||
private final SaasPageElementFeatureResourceRelationService saasPageElementFeatureResourceRelationService;
|
||||
private final SaasPageElementCategoryDao saasPageElementCategoryDao;
|
||||
private final BasePageElementApi basePageElementApi;
|
||||
private final SaasPageElementCategoryService saasPageElementCategoryService;
|
||||
|
||||
@Qualifier("asyncExecutor")
|
||||
@Autowired
|
||||
@ -544,7 +558,11 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
|
||||
Map<String, List<SaasFeatureResourceResp>> featureResources = listFeatureResource(page.getRecords(), param);
|
||||
|
||||
return PageConverter.toResp(page, e -> from(e, featureResources));
|
||||
Map<String, List<PageElementResp>> childrenPageElements = listChildrenPageElement(page.getRecords(), param);
|
||||
|
||||
Map<String, PageElementCategoryResp> pageElementCategories = listPageElementCategory(page.getRecords(), param);
|
||||
|
||||
return PageConverter.toResp(page, e -> from(e, featureResources, childrenPageElements, pageElementCategories));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -618,6 +636,37 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
return result;
|
||||
}
|
||||
|
||||
private SaasPageElement.Ext resolveExt(BatchUpsertPageElementReq.UpsertPageElementReq req) {
|
||||
List<SaasPageElement.Application> applications = Lists.newArrayList();
|
||||
if (Objects.nonNull(req.getIosMinVersion())
|
||||
|| Objects.nonNull(req.getIosMaxVersion())
|
||||
|| Objects.nonNull(req.getIosMaxVersionEnabled())) {
|
||||
SaasPageElement.Application application = SaasPageElement.Application.builder()
|
||||
.type(SaasPageElement.ApplicationTypeEnum.IOS)
|
||||
.minVersion(req.getIosMinVersion())
|
||||
.maxVersion(req.getIosMaxVersion())
|
||||
.maxVersionEnabled(req.getIosMaxVersionEnabled())
|
||||
.build();
|
||||
applications.add(application);
|
||||
}
|
||||
|
||||
if (Objects.nonNull(req.getAndroidMaxVersion())
|
||||
|| Objects.nonNull(req.getAndroidMinVersion())
|
||||
|| Objects.nonNull(req.getAndroidMaxVersionEnabled())) {
|
||||
SaasPageElement.Application application = SaasPageElement.Application.builder()
|
||||
.type(SaasPageElement.ApplicationTypeEnum.ANDROID)
|
||||
.minVersion(req.getAndroidMinVersion())
|
||||
.maxVersion(req.getAndroidMaxVersion())
|
||||
.maxVersionEnabled(req.getAndroidMaxVersionEnabled())
|
||||
.build();
|
||||
applications.add(application);
|
||||
}
|
||||
|
||||
return SaasPageElement.Ext.builder()
|
||||
.applications(applications)
|
||||
.build();
|
||||
}
|
||||
|
||||
private SaasPageElement.Ext resolveExt(SaveOrUpdatePageElementReq req) {
|
||||
List<SaasPageElement.Application> applications = Lists.newArrayList();
|
||||
if (Objects.nonNull(req.getIosMinVersion())
|
||||
@ -652,84 +701,17 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long saveOrUpdate(SaveOrUpdatePageElementReq req) {
|
||||
SaasPageElement basePageElement = SaasPageElement.builder()
|
||||
.version(req.getVersion())
|
||||
.groupCode(req.getCode())
|
||||
.code(req.getCode())
|
||||
.name(req.getName())
|
||||
.type(req.getType())
|
||||
.linkUrl(req.getLinkUrl())
|
||||
.linkExt(getLinkExtStr(req.getIosRouterUrl(), req.getAndroidRouterUrl()))
|
||||
.appType(req.getAppType())
|
||||
.appId(req.getAppId())
|
||||
.itemCode(req.getItemCode())
|
||||
|
||||
BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = BatchUpsertPageElementReq.UpsertPageElementReq.builder().build();
|
||||
BeanUtils.copyProperties(req, upsertPageElementReq);
|
||||
|
||||
BatchUpsertPageElementReq batchUpsertPageElementReq = BatchUpsertPageElementReq.builder()
|
||||
.operatorId(req.getOperatorId())
|
||||
.upsertPageElementReqs(Lists.newArrayList(upsertPageElementReq))
|
||||
.build();
|
||||
SaasPageElement.Ext ext = resolveExt(req);
|
||||
List<Long> ids = batchUpsert(batchUpsertPageElementReq);
|
||||
|
||||
if (Objects.nonNull(req.getId())) {
|
||||
SaasPageElement dbPageElement = saasPageElementDao.getById(req.getId());
|
||||
AssertUtil.notNull(dbPageElement, "页面元素资源不存在");
|
||||
basePageElement.setId(dbPageElement.getId());
|
||||
basePageElement.setExt(dbPageElement.buildMergedExt(ext));
|
||||
basePageElement.setUpdateBy(req.getOperatorId());
|
||||
if (!dbPageElement.getCode().equals(basePageElement.getCode())) {
|
||||
// 校验code唯一
|
||||
validCode(basePageElement.getCode());
|
||||
if (PageElementTypeEnum.PAGE.getCode().equals(req.getType())) {
|
||||
// 更新子元素的group_code
|
||||
saasPageElementDao.updateComponentsGroupCode(dbPageElement.getCode(), basePageElement.getCode(), dbPageElement.getTerminal());
|
||||
}
|
||||
// 更新关联关系的page_element_code
|
||||
saasPageElementFeatureResourceRelationDao.updateGroupCode(dbPageElement.getCode(), basePageElement.getCode(), dbPageElement.getTerminal());
|
||||
}
|
||||
// page的groupCode是自己的code,但是component的groupCode是父级页面的code
|
||||
// 原来component在更新时会把自己的groupCode更新成自己的code
|
||||
if (PageElementTypeEnum.COMPONENT.getCode().equals(req.getType())) {
|
||||
basePageElement.setGroupCode(req.getGroupCode());
|
||||
}
|
||||
saasPageElementDao.updateById(basePageElement);
|
||||
} else {
|
||||
if (PageElementTypeEnum.PAGE.getCode().equals(req.getType())) {
|
||||
AssertUtil.isTrue(StringUtils.isNotBlank(req.getItemCode()), "页面元素不存在");
|
||||
List<SaasPageElementCategory> categories = saasPageElementCategoryDao.lambdaQuery()
|
||||
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.eq(SaasPageElementCategory::getItemCode, req.getItemCode()).list();
|
||||
AssertUtil.notEmpty(categories, "元素分类不存在。");
|
||||
SaasPageElementCategory category = categories.get(0);
|
||||
basePageElement.setTerminal(category.getTerminal());
|
||||
basePageElement.setItemName(category.getItemName());
|
||||
} else if (PageElementTypeEnum.COMPONENT.getCode().equals(req.getType())) {
|
||||
AssertUtil.isTrue(StringUtils.isNotBlank(req.getGroupCode()), "页面元素不存在");
|
||||
List<SaasPageElement> pageElements = saasPageElementDao.lambdaQuery()
|
||||
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.eq(SaasPageElement::getCode, req.getGroupCode()).list();
|
||||
AssertUtil.notEmpty(pageElements, "父级元素不存在。");
|
||||
|
||||
SaasPageElement pageElement = pageElements.get(0);
|
||||
basePageElement.setVersion(pageElement.getVersion());
|
||||
basePageElement.setGroupCode(pageElement.getCode());
|
||||
basePageElement.setTerminal(pageElement.getTerminal());
|
||||
basePageElement.setAppType(pageElement.getAppType());
|
||||
basePageElement.setAppId(pageElement.getAppId());
|
||||
basePageElement.setItemCode(pageElement.getItemCode());
|
||||
basePageElement.setItemName(pageElement.getItemName());
|
||||
}
|
||||
// 校验code唯一
|
||||
validCode(basePageElement.getCode());
|
||||
basePageElement.setCreateBy(req.getOperatorId());
|
||||
basePageElement.setUpdateBy(req.getOperatorId());
|
||||
basePageElement.setExt(basePageElement.buildMergedExt(ext));
|
||||
saasPageElementDao.save(basePageElement);
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
try {
|
||||
saveOrUpdateOperateLog(req, basePageElement);
|
||||
} catch (Exception e) {
|
||||
log.warn("save operate log error", e);
|
||||
}
|
||||
|
||||
return basePageElement.getId();
|
||||
return ids.stream().findFirst().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -869,11 +851,17 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
}
|
||||
|
||||
private PageElementResp from(SaasPageElement saasPageElement,
|
||||
Map<String, List<SaasFeatureResourceResp>> featureResources) {
|
||||
Map<String, List<SaasFeatureResourceResp>> featureResources,
|
||||
Map<String, List<PageElementResp>> childrenPageElements,
|
||||
Map<String, PageElementCategoryResp> pageElementCategories) {
|
||||
PageElementResp pageElementResp = PageElementResp.builder().build();
|
||||
|
||||
BeanUtils.copyProperties(saasPageElement, pageElementResp);
|
||||
pageElementResp.setFeatureResources(featureResources.get(saasPageElement.getCode()));
|
||||
|
||||
pageElementResp.setChildren(childrenPageElements.get(saasPageElement.getCode()));
|
||||
|
||||
pageElementResp.setPageElementCategory(pageElementCategories.get(saasPageElement.getItemCode()));
|
||||
return pageElementResp;
|
||||
}
|
||||
|
||||
@ -957,6 +945,18 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOrUpdateOperateLog(BatchUpsertPageElementReq req, List<SaasPageElement> basePageElement) {
|
||||
saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder()
|
||||
.tableName(PAGE_ELEMENT_TABLE_NAME)
|
||||
.operatorId(req.getOperatorId())
|
||||
.scene(PermissionRelationOperateLogSceneEnum.OMS_UPSERT_PAGE_ELEMENT.getValue())
|
||||
// 批量更新,记录id会超长,后续提供统一的更基础的日志记录表,先暂时用
|
||||
.sceneId(UuidUtils.generateUuid())
|
||||
.requestData(req)
|
||||
.operateData(basePageElement)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void saveOrUpdateOperateLog(SaveOrUpdatePageElementReq req, SaasPageElement basePageElement) {
|
||||
saasPgroupPermissionRelationOperateLogService.save(PermissionOperateLogReq.builder()
|
||||
.tableName(PAGE_ELEMENT_TABLE_NAME)
|
||||
@ -1016,4 +1016,444 @@ public class SaasPageElementServiceImpl extends ServiceImpl<SaasPageElementMappe
|
||||
.list();
|
||||
}
|
||||
|
||||
private Map<String, List<PageElementResp>> listChildrenPageElement(List<SaasPageElement> pageElements,
|
||||
PageElementReq param) {
|
||||
|
||||
if (CollectionUtils.isEmpty(pageElements) || BooleanUtils.isNotTrue(param.getNeedChildren())) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> codes = pageElements.stream()
|
||||
.map(SaasPageElement::getCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 因为现在的数据结构,type为PAGE的和type为COMPONENT的groupCode一样,所以要排除type=PAGE的记录
|
||||
return this.lambdaQuery()
|
||||
.in(SaasPageElement::getGroupCode, codes)
|
||||
.ne(SaasPageElement::getType, PageElementTypeEnum.PAGE)
|
||||
.list()
|
||||
.stream()
|
||||
.map(e -> {
|
||||
PageElementResp pageElementResp = PageElementResp.builder().build();
|
||||
BeanUtils.copyProperties(e, pageElementResp);
|
||||
return pageElementResp;
|
||||
})
|
||||
.collect(Collectors.groupingBy(PageElementResp::getGroupCode));
|
||||
}
|
||||
|
||||
private Map<String, PageElementCategoryResp> listPageElementCategory(List<SaasPageElement> pageElements,
|
||||
PageElementReq param) {
|
||||
|
||||
if (CollectionUtils.isEmpty(pageElements) || BooleanUtils.isNotTrue(param.getNeedPageElementCategory())) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
Set<String> itemCodes = pageElements.stream()
|
||||
.map(SaasPageElement::getItemCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return saasPageElementCategoryDao.lambdaQuery()
|
||||
.in(SaasPageElementCategory::getItemCode, itemCodes)
|
||||
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.value)
|
||||
.list()
|
||||
.stream()
|
||||
.map(e -> {
|
||||
PageElementCategoryResp pageElementCategoryResp = PageElementCategoryResp.builder().build();
|
||||
BeanUtils.copyProperties(e, pageElementCategoryResp);
|
||||
return pageElementCategoryResp;
|
||||
})
|
||||
.collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 资源对应的category如果不存在,则需要补上对应的category
|
||||
* @param req
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void syncPageElement(SyncPageElementReq req) {
|
||||
PageElementReq pageElementReq = PageElementReq.builder()
|
||||
.ids(req.getPageElementIds())
|
||||
.needPageElementCategory(true)
|
||||
.needChildren(true)
|
||||
.build();
|
||||
List<PageElementResp> prePageElements = RpcInternalUtil.rpcProcessor(() -> basePageElementApi.list(pageElementReq),
|
||||
"list pageElement from base env", pageElementReq).getData();
|
||||
if (CollectionUtils.isEmpty(prePageElements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, PageElementResp> localDBPageElements = listLocalDBPageElement(prePageElements);
|
||||
|
||||
// upsert pageElementCategory
|
||||
upsertPageElementCategory(prePageElements, localDBPageElements, req);
|
||||
|
||||
BatchUpsertPageElementReq batchUpsertPageElementReq = BatchUpsertPageElementReq.builder()
|
||||
.upsertPageElementReqs(prePageElements.stream()
|
||||
.map(e -> {
|
||||
BatchUpsertPageElementReq.UpsertPageElementReq upsertPageElementReq = BatchUpsertPageElementReq.UpsertPageElementReq.builder().build();
|
||||
BeanUtils.copyProperties(e, upsertPageElementReq);
|
||||
return upsertPageElementReq;
|
||||
})
|
||||
.collect(Collectors.toList()))
|
||||
.operatorId(req.getOperatorId())
|
||||
.build();
|
||||
batchUpsert(batchUpsertPageElementReq);
|
||||
}
|
||||
|
||||
private void upsertPageElementCategory(List<PageElementResp> prePageElements,
|
||||
Map<String, PageElementResp> localDBPageElements,
|
||||
SyncPageElementReq req) {
|
||||
|
||||
List<PageElementCategoryResp> prePageElementCategories = prePageElements.stream()
|
||||
.map(PageElementResp::getPageElementCategory)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(prePageElementCategories)) {
|
||||
log.info("no pageElementCategory need sync");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, PageElementCategoryResp> localDBPageElementCategories = localDBPageElements.values().stream()
|
||||
.map(PageElementResp::getPageElementCategory)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(PageElementCategoryResp::getItemCode, Function.identity()));
|
||||
|
||||
List<BatchUpsertPageElementCategoryReq.UpsertPageElementCategory> upsert = prePageElementCategories.stream()
|
||||
.map(e -> {
|
||||
PageElementCategoryResp localDBPageElementCategory = localDBPageElementCategories.get(e.getItemCode());
|
||||
return BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder()
|
||||
.id(Objects.nonNull(localDBPageElementCategory) ? localDBPageElementCategory.getId() : null)
|
||||
.terminal(e.getTerminal())
|
||||
.itemCode(e.getItemCode())
|
||||
.itemName(e.getItemName())
|
||||
.build();
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
BatchUpsertPageElementCategoryReq batchUpsertPageElementCategoryReq = BatchUpsertPageElementCategoryReq.builder()
|
||||
.operatorId(req.getOperatorId())
|
||||
.upsertPageElementCategories(upsert)
|
||||
.build();
|
||||
saasPageElementCategoryService.batchUpsert(batchUpsertPageElementCategoryReq);
|
||||
}
|
||||
|
||||
private Map<String, PageElementResp> listLocalDBPageElement(List<PageElementResp> pageElements) {
|
||||
|
||||
Set<String> codes = pageElements.stream()
|
||||
.map(PageElementResp::getCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
Set<String> childrenCodes = pageElements.stream()
|
||||
.map(PageElementResp::getChildren)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(Collection::stream)
|
||||
.map(PageElementResp::getCode)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
codes.addAll(childrenCodes);
|
||||
|
||||
return this.list(PageElementReq.builder()
|
||||
.codes(codes)
|
||||
.needPageElementCategory(true)
|
||||
.build())
|
||||
.stream()
|
||||
.collect(Collectors.toMap(PageElementResp::getCode, Function.identity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public List<Long> batchUpsert(BatchUpsertPageElementReq req) {
|
||||
|
||||
Axssert.checkNotEmpty(req.getUpsertPageElementReqs(), PARAM_ERROR);
|
||||
|
||||
Map<String, SaasPageElementCategory> cagetories = checkItemCode(req);
|
||||
|
||||
Map<String, SaasPageElement> parentPageElements = checkGroupCode(req);
|
||||
|
||||
checkCode(req);
|
||||
|
||||
Map<Long, SaasPageElement> oldSaasPageElements = checkId(req);
|
||||
|
||||
// first:oldCode second:newCode
|
||||
Map<String, BatchUpsertPageElementReq.UpsertPageElementReq> updatedCodePageElements = req.getUpsertPageElementReqs().stream()
|
||||
.map(e -> {
|
||||
if (Objects.isNull(e.getId())) {
|
||||
return null;
|
||||
}
|
||||
SaasPageElement oldPageElement = oldSaasPageElements.get(e.getId());
|
||||
if (Objects.equals(oldPageElement.getCode(), e.getCode())) {
|
||||
return null;
|
||||
}
|
||||
return Pair.of(oldPageElement.getCode(), e);
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(Pair::getFirst, Pair::getSecond));
|
||||
|
||||
// 原来设计问题点
|
||||
// 1、组件的groupCode是父级页面的code,页面的groupCode是页面的code
|
||||
// 2、组件的itemCode使用父级页面的itemCode,并且冗余了itemName
|
||||
// 3、新增页面,需要根据itemCode找到category设置terminal、itemCode、itemName
|
||||
// 4、新增组件,需要根据页面的信息设置terminal、itemCode、itemName、appType、appId等
|
||||
|
||||
List<SaasPageElement> upsert = req.getUpsertPageElementReqs().stream()
|
||||
.map(e -> {
|
||||
SaasPageElement saasPageElement = SaasPageElement.builder()
|
||||
.version(e.getVersion())
|
||||
.groupCode(e.getCode())
|
||||
.code(e.getCode())
|
||||
.name(e.getName())
|
||||
.type(e.getType())
|
||||
.linkUrl(e.getLinkUrl())
|
||||
.linkExt(getLinkExtStr(e.getIosRouterUrl(), e.getAndroidRouterUrl()))
|
||||
.appType(e.getAppType())
|
||||
.appId(e.getAppId())
|
||||
.itemCode(e.getItemCode())
|
||||
.createBy(Objects.nonNull(e.getId()) ? null : req.getOperatorId())
|
||||
.updateBy(req.getOperatorId())
|
||||
.build();
|
||||
if (Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType()) && Objects.nonNull(e.getItemCode())) {
|
||||
SaasPageElementCategory category = cagetories.get(e.getItemCode());
|
||||
Axssert.notNull(category, PAGE_ELEMENT_ITEM_CODE_NOT_FOUND);
|
||||
saasPageElement.setTerminal(category.getTerminal());
|
||||
saasPageElement.setItemCode(category.getItemCode());
|
||||
saasPageElement.setItemName(category.getItemName());
|
||||
} else if (Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType()) && Objects.nonNull(e.getGroupCode())) {
|
||||
SaasPageElement parentPageElement = parentPageElements.get(e.getGroupCode());
|
||||
Axssert.notNull(parentPageElement, PAGE_ELEMENT_GROUP_CODE_NOT_FOUND);
|
||||
|
||||
saasPageElement.setVersion(parentPageElement.getVersion());
|
||||
saasPageElement.setGroupCode(parentPageElement.getCode());
|
||||
saasPageElement.setTerminal(parentPageElement.getTerminal());
|
||||
saasPageElement.setAppType(parentPageElement.getAppType());
|
||||
saasPageElement.setAppId(parentPageElement.getAppId());
|
||||
saasPageElement.setItemCode(parentPageElement.getItemCode());
|
||||
saasPageElement.setItemName(parentPageElement.getItemName());
|
||||
}
|
||||
|
||||
SaasPageElement.Ext ext = resolveExt(e);
|
||||
if (Objects.nonNull(e.getId())) {
|
||||
SaasPageElement dbPageElement = oldSaasPageElements.get(e.getId());
|
||||
Axssert.notNull(dbPageElement, PAGE_ELEMENT_ERROR);
|
||||
saasPageElement.setExt(dbPageElement.buildMergedExt(ext));
|
||||
} else {
|
||||
saasPageElement.setExt(saasPageElement.buildMergedExt(ext));
|
||||
}
|
||||
return saasPageElement;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
this.updateBatchById(upsert);
|
||||
|
||||
// 1、更新页面的code时,需要把对应组件的groupCode都更新、需要把菜单资源关联表的pageCode进行更新
|
||||
// 2、更新组件的code时,需要把菜单资源关联表的pageCode进行更新
|
||||
if (!updatedCodePageElements.isEmpty()) {
|
||||
|
||||
// TODO 待统一的更新接口收口后,切换
|
||||
updateComponentGroupCode(updatedCodePageElements);
|
||||
// 更新关联关系的page_element_code
|
||||
updatePageElementFeatureResource(updatedCodePageElements);
|
||||
}
|
||||
|
||||
// 记录操作日志
|
||||
try {
|
||||
saveOrUpdateOperateLog(req, upsert);
|
||||
} catch (Exception e) {
|
||||
log.warn("save operate log error", e);
|
||||
}
|
||||
|
||||
return upsert.stream()
|
||||
.map(BaseEntity::getId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void updateComponentGroupCode(Map<String, BatchUpsertPageElementReq.UpsertPageElementReq> updatedCodePageElementMap) {
|
||||
if (Objects.isNull(updatedCodePageElementMap) || updatedCodePageElementMap.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<BatchUpsertPageElementReq.UpsertPageElementReq> updatedCodePageElements = updatedCodePageElementMap.values().stream()
|
||||
.filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (CollectionUtils.isEmpty(updatedCodePageElements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<SaasPageElement> components = this.lambdaQuery()
|
||||
.in(SaasPageElement::getGroupCode, updatedCodePageElementMap.keySet())
|
||||
.eq(SaasPageElement::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.eq(SaasPageElement::getType, PageElementTypeEnum.COMPONENT.getCode())
|
||||
.list();
|
||||
|
||||
if (CollectionUtils.isEmpty(components)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateBatchById(components.stream()
|
||||
.map(e -> {
|
||||
SaasPageElement saasPageElement = SaasPageElement.builder()
|
||||
.groupCode(updatedCodePageElementMap.get(e.getGroupCode()).getGroupCode())
|
||||
.build();
|
||||
saasPageElement.setId(e.getId());
|
||||
return saasPageElement;
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private void updatePageElementFeatureResource(Map<String, BatchUpsertPageElementReq.UpsertPageElementReq> updatedCodePageElements) {
|
||||
if (Objects.isNull(updatedCodePageElements) || updatedCodePageElements.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<SaasPageElementFeatureResourceRelation> pageElementFeatureResourceRelations = saasPageElementFeatureResourceRelationDao.lambdaQuery()
|
||||
.in(SaasPageElementFeatureResourceRelation::getPageElementCode, updatedCodePageElements.keySet())
|
||||
.eq(SaasPageElementFeatureResourceRelation::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.list();
|
||||
|
||||
if (CollectionUtils.isEmpty(pageElementFeatureResourceRelations)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<SaasPageElementFeatureResourceRelation> updates = pageElementFeatureResourceRelations.stream()
|
||||
.map(e -> {
|
||||
SaasPageElementFeatureResourceRelation result = SaasPageElementFeatureResourceRelation.builder()
|
||||
.pageElementCode(updatedCodePageElements.get(e.getPageElementCode()).getCode())
|
||||
.build();
|
||||
result.setId(e.getId());
|
||||
return result;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
saasPageElementFeatureResourceRelationDao.updateBatchById(updates);
|
||||
}
|
||||
|
||||
private Map<Long, SaasPageElement> checkId(BatchUpsertPageElementReq req) {
|
||||
Set<Long> ids = req.getUpsertPageElementReqs().stream()
|
||||
.map(BatchUpsertPageElementReq.UpsertPageElementReq::getId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<SaasPageElement> pageElements = saasPageElementDao.listByIds(ids);
|
||||
|
||||
if (!Objects.equals(ids.size(), pageElements.size())) {
|
||||
ids.removeAll(pageElements.stream().map(SaasPageElement::getId).collect(Collectors.toSet()));
|
||||
throw PAGE_ELEMENT_ERROR.toException(PAGE_ELEMENT_ERROR.getErrorMessage(), ids);
|
||||
}
|
||||
|
||||
return pageElements.stream()
|
||||
.collect(Collectors.toMap(SaasPageElement::getId, Function.identity()));
|
||||
}
|
||||
|
||||
private Map<String, SaasPageElement> checkGroupCode(BatchUpsertPageElementReq req) {
|
||||
|
||||
// 组件一定要传groupCode
|
||||
List<BatchUpsertPageElementReq.UpsertPageElementReq> componentElements = req.getUpsertPageElementReqs().stream()
|
||||
.filter(e -> Objects.equals(PageElementTypeEnum.COMPONENT.getCode(), e.getType()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(componentElements)) {
|
||||
List<BatchUpsertPageElementReq.UpsertPageElementReq> blankGroupCodes = componentElements.stream()
|
||||
.filter(e -> StringUtils.isBlank(e.getGroupCode()))
|
||||
.collect(Collectors.toList());
|
||||
Axssert.check(CollectionUtils.isEmpty(blankGroupCodes), PAGE_ELEMENT_GROUP_CODE_NOT_NULL);
|
||||
}
|
||||
|
||||
// 后续如果有其他类型也需要传groupCode,这里就不按照组件来过滤
|
||||
Set<String> groupCodes = req.getUpsertPageElementReqs().stream()
|
||||
.map(BatchUpsertPageElementReq.UpsertPageElementReq::getGroupCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
if (CollectionUtils.isEmpty(groupCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<SaasPageElement> pageElements = saasPageElementDao.lambdaQuery()
|
||||
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.eq(SaasPageElement::getCode, groupCodes)
|
||||
.list();
|
||||
|
||||
if (!Objects.equals(groupCodes.size(), pageElements.size())) {
|
||||
groupCodes.removeAll(pageElements.stream().map(SaasPageElement::getCode).collect(Collectors.toSet()));
|
||||
throw PAGE_ELEMENT_GROUP_CODE_NOT_FOUND.toException(PAGE_ELEMENT_GROUP_CODE_NOT_FOUND.getErrorMessage(), groupCodes);
|
||||
}
|
||||
|
||||
return pageElements.stream()
|
||||
.collect(Collectors.toMap(SaasPageElement::getCode, Function.identity()));
|
||||
}
|
||||
|
||||
private Map<String, SaasPageElementCategory> checkItemCode(BatchUpsertPageElementReq req) {
|
||||
// 页面一定要选分组
|
||||
List<BatchUpsertPageElementReq.UpsertPageElementReq> pageElements = req.getUpsertPageElementReqs().stream()
|
||||
.filter(e -> Objects.equals(PageElementTypeEnum.PAGE.getCode(), e.getType()))
|
||||
.collect(Collectors.toList());
|
||||
if (CollectionUtils.isNotEmpty(pageElements)) {
|
||||
List<BatchUpsertPageElementReq.UpsertPageElementReq> blankItemCodes = pageElements.stream()
|
||||
.filter(e -> StringUtils.isBlank(e.getItemCode()))
|
||||
.collect(Collectors.toList());
|
||||
Axssert.check(CollectionUtils.isEmpty(blankItemCodes), PAGE_ELEMENT_ITEM_CODE_NOT_NULL);
|
||||
}
|
||||
|
||||
Set<String> itemCodes = req.getUpsertPageElementReqs().stream()
|
||||
.map(BatchUpsertPageElementReq.UpsertPageElementReq::getItemCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
if (CollectionUtils.isEmpty(itemCodes)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
List<SaasPageElementCategory> categories = saasPageElementCategoryDao.lambdaQuery()
|
||||
.eq(BaseEntity::getIsDelete, DeleteEnum.NORMAL.getValue())
|
||||
.in(SaasPageElementCategory::getItemCode, itemCodes)
|
||||
.list();
|
||||
|
||||
if (!Objects.equals(itemCodes.size(), categories.size())) {
|
||||
itemCodes.removeAll(categories.stream().map(SaasPageElementCategory::getItemCode).collect(Collectors.toSet()));
|
||||
throw PAGE_ELEMENT_ITEM_CODE_NOT_FOUND.toException(PAGE_ELEMENT_ITEM_CODE_NOT_FOUND.getErrorMessage(), itemCodes);
|
||||
}
|
||||
|
||||
return categories.stream()
|
||||
.collect(Collectors.toMap(SaasPageElementCategory::getItemCode, Function.identity()));
|
||||
}
|
||||
|
||||
private void checkCode(BatchUpsertPageElementReq req) {
|
||||
|
||||
// check新增或者更新的itemCode是否已经存在
|
||||
List<String> codes = req.getUpsertPageElementReqs().stream()
|
||||
.map(BatchUpsertPageElementReq.UpsertPageElementReq::getCode)
|
||||
.collect(Collectors.toList());
|
||||
List<SaasPageElement> saasPageElements = this.lambdaQuery()
|
||||
.in(SaasPageElement::getCode, codes)
|
||||
.eq(SaasPageElement::getIsDelete, DeleteEnum.NORMAL.value)
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(saasPageElements)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, SaasPageElement> codeMap = saasPageElements.stream()
|
||||
.collect(Collectors.toMap(SaasPageElement::getCode, Function.identity()));
|
||||
|
||||
List<String> dbDuplicateCodes = req.getUpsertPageElementReqs().stream()
|
||||
.filter(e -> {
|
||||
SaasPageElement oldSaasPageElement = codeMap.get(e.getCode());
|
||||
if (Objects.isNull(oldSaasPageElement)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 新增里重复的code
|
||||
if (Objects.isNull(e.getId())) {
|
||||
return true;
|
||||
}
|
||||
// 更新里重复的code
|
||||
return !Objects.equals(e.getId(), oldSaasPageElement.getId());
|
||||
})
|
||||
.map(BatchUpsertPageElementReq.UpsertPageElementReq::getCode)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Axssert.check(CollectionUtils.isEmpty(dbDuplicateCodes), PAGE_CODE_DUPLICATE,
|
||||
PAGE_CODE_DUPLICATE.getErrorMessage(), dbDuplicateCodes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,127 +0,0 @@
|
||||
package cn.axzo.tyr.server.service.impl;
|
||||
|
||||
import cn.axzo.thrones.client.saas.ServicePkgClient;
|
||||
import cn.axzo.thrones.client.saas.entity.serivicepgkproduct.ServicePkgProduct;
|
||||
import cn.axzo.thrones.client.saas.entity.servicepkg.ServicePkgDetailRes;
|
||||
import cn.axzo.tyr.base.BaseTest;
|
||||
import cn.axzo.tyr.base.MysqlDataLoader;
|
||||
import cn.axzo.tyr.client.model.req.IdentityAuthReq;
|
||||
import cn.axzo.tyr.client.model.req.PermissionCheckReq;
|
||||
import cn.axzo.tyr.client.model.res.IdentityAuthRes;
|
||||
import cn.axzo.tyr.server.repository.dao.ProductModuleDao;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasFeatureDao;
|
||||
import cn.axzo.tyr.server.repository.entity.ProductModule;
|
||||
import cn.axzo.tyr.server.service.PermissionQueryService;
|
||||
import cn.axzo.tyr.server.service.TyrSaasAuthService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
class PermissionQueryServiceImplTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
private PermissionQueryService permissionQueryService;
|
||||
@Autowired
|
||||
private MysqlDataLoader mysqlDataLoader;
|
||||
@Autowired
|
||||
private TyrSaasAuthService tyrSaasAuthService;
|
||||
@Autowired
|
||||
private SaasFeatureDao saasFeatureDao;
|
||||
@Autowired
|
||||
private ServicePkgClient servicePkgClient;
|
||||
|
||||
@Autowired
|
||||
private ProductModuleDao productModuleDao;
|
||||
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
mysqlDataLoader.loadFromClassName(getClass().getSimpleName());
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasPermissionNew() {
|
||||
ServicePkgDetailRes servicePkgDetailRes = new ServicePkgDetailRes();
|
||||
ServicePkgProduct servicePkgProduct = new ServicePkgProduct();
|
||||
servicePkgProduct.setProductId(1L);
|
||||
|
||||
ServicePkgProduct servicePkgProduct2 = new ServicePkgProduct();
|
||||
servicePkgProduct2.setProductId(6L);
|
||||
servicePkgDetailRes.setProducts(Lists.newArrayList(
|
||||
servicePkgProduct,
|
||||
servicePkgProduct2
|
||||
));
|
||||
Mockito.when(servicePkgClient.getServicePkgDetailBySpaceId(Mockito.any()))
|
||||
.thenReturn(CommonResponse.success(Lists.newArrayList(servicePkgDetailRes)));
|
||||
// 普通角色和产品有旧权限码权限:begin
|
||||
PermissionCheckReq permissionCheckReq = PermissionCheckReq.builder()
|
||||
.personId(80792L)
|
||||
.featureCodes(Lists.newArrayList("cms:ent_contact", "cms:ent_contact_new"))
|
||||
.ouId(5154L)
|
||||
.workspaceId(205L)
|
||||
.build();
|
||||
List<ProductModule> list = productModuleDao.list();
|
||||
log.info("size:{}", list.size());
|
||||
System.out.println("size+" + list.size());
|
||||
|
||||
new Thread(() -> {
|
||||
synchronized (this) {
|
||||
List<ProductModule> productModules = productModuleDao.list();
|
||||
log.info("inner size:{}", productModules.size());
|
||||
System.out.println("inner size+" + list.size());
|
||||
}
|
||||
}).start();
|
||||
|
||||
boolean result = authPermission(permissionCheckReq);
|
||||
boolean resultOld = authPermissionOld(permissionCheckReq);
|
||||
Assertions.assertTrue(result);
|
||||
Assertions.assertTrue(resultOld);
|
||||
// 普通角色和产品有旧权限码权限:end
|
||||
|
||||
// 管理员角色和产品有旧权限码权限:begin
|
||||
permissionCheckReq = PermissionCheckReq.builder()
|
||||
.personId(80792L)
|
||||
.featureCodes(Lists.newArrayList("cms:ent_contact", "cms:ent_contact_new"))
|
||||
.ouId(5154L)
|
||||
.workspaceId(290L)
|
||||
.build();
|
||||
|
||||
result = authPermission(permissionCheckReq);
|
||||
resultOld = authPermissionOld(permissionCheckReq);
|
||||
Assertions.assertTrue(result);
|
||||
Assertions.assertTrue(resultOld);
|
||||
// 管理员角色和产品有旧权限码权限:end
|
||||
}
|
||||
|
||||
private boolean authPermission(PermissionCheckReq permissionCheckReq) {
|
||||
return tyrSaasAuthService.authPermission(permissionCheckReq) || tyrSaasAuthService.authNewPermission(permissionCheckReq);
|
||||
}
|
||||
|
||||
private boolean authPermissionOld(PermissionCheckReq req) {
|
||||
IdentityAuthReq authReq = IdentityAuthReq.builder()
|
||||
.personId(req.getPersonId())
|
||||
.workspaceOusPairs(Collections.singletonList(IdentityAuthReq.WorkspaceOuPair.builder()
|
||||
.workspaceId(req.getWorkspaceId())
|
||||
.ouId(req.getOuId()).build()))
|
||||
.featureCode(new HashSet<>(req.getFeatureCodes()))
|
||||
.terminal(StringUtils.isBlank(req.getTerminal()) ? null : Collections.singletonList(req.getTerminal()))
|
||||
.build();
|
||||
IdentityAuthRes.WorkspacePermission permissions = tyrSaasAuthService.findIdentityAuthMix(authReq).getPermissions().get(0);
|
||||
return CollectionUtil.isNotEmpty(permissions.getPermissionPoint());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package cn.axzo.tyr.server.service.impl;
|
||||
|
||||
import cn.axzo.foundation.exception.BusinessException;
|
||||
import cn.axzo.tyr.base.BaseTest;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementCategoryReq;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementCategoryService;
|
||||
import cn.axzo.tyr.server.service.SaasRoleUserRelationService;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.REMOVE_USER_ROLE_ERROR;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SaasPageElementCategoryServiceImplTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
private SaasPageElementCategoryService saasPageElementCategoryService;
|
||||
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
}
|
||||
|
||||
@Test
|
||||
void batchUpsert() {
|
||||
BusinessException businessException = assertThrows(BusinessException.class, ()->{
|
||||
List<BatchUpsertPageElementCategoryReq.UpsertPageElementCategory> req = Lists.newArrayList(
|
||||
BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("A1").build(),
|
||||
BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("A1").build(),
|
||||
BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("B1").build(),
|
||||
BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("B1").build(),
|
||||
BatchUpsertPageElementCategoryReq.UpsertPageElementCategory.builder().itemName("C1").build()
|
||||
);
|
||||
BatchUpsertPageElementCategoryReq batchUpsertPageElementCategoryReq = BatchUpsertPageElementCategoryReq.builder()
|
||||
.upsertPageElementCategories(req)
|
||||
.operatorId(11L)
|
||||
.build();
|
||||
saasPageElementCategoryService.batchUpsert(batchUpsertPageElementCategoryReq);
|
||||
});
|
||||
assertEquals(businessException.getErrorCode(), ITEM_NAME_DUPLICATE.getErrorCode());
|
||||
assertEquals(businessException.getErrorMsg(), "资源分组名字重复,重复的名字:[A1, B1]");
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package cn.axzo.tyr.server.service.impl;
|
||||
|
||||
import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi;
|
||||
import cn.axzo.foundation.exception.BusinessException;
|
||||
import cn.axzo.tyr.base.BaseTest;
|
||||
import cn.axzo.tyr.base.MysqlDataLoader;
|
||||
import cn.axzo.tyr.client.model.req.BatchUpsertPageElementCategoryReq;
|
||||
import cn.axzo.tyr.client.model.req.SaveOrUpdatePageElementReq;
|
||||
import cn.axzo.tyr.server.service.SaasPageElementService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.ITEM_NAME_DUPLICATE;
|
||||
import static cn.axzo.tyr.server.config.exception.BizResultCode.PAGE_ELEMENT_ERROR;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class SaasPageElementServiceImplTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
private MysqlDataLoader mysqlDataLoader;
|
||||
@Autowired
|
||||
private SaasPageElementService saasPageElementService;
|
||||
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
mysqlDataLoader.loadFromClassName(getClass().getSimpleName());
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveOrUpdate() {
|
||||
|
||||
// 更新时id是错的
|
||||
BusinessException businessException = assertThrows(BusinessException.class, ()->{
|
||||
SaveOrUpdatePageElementReq saveOrUpdatePageElementReq = SaveOrUpdatePageElementReq.builder()
|
||||
.id(1L)
|
||||
.build();
|
||||
saasPageElementService.saveOrUpdate(saveOrUpdatePageElementReq);
|
||||
});
|
||||
assertEquals(businessException.getErrorCode(), PAGE_ELEMENT_ERROR.getErrorCode());
|
||||
assertEquals(businessException.getErrorMsg(), "资源分组错误:[1]");
|
||||
}
|
||||
|
||||
@Test
|
||||
void batchUpsert() {
|
||||
}
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
package cn.axzo.tyr.server.service.impl;
|
||||
|
||||
import cn.axzo.tyr.base.BaseTest;
|
||||
import cn.axzo.tyr.base.MysqlDataLoader;
|
||||
import cn.axzo.tyr.client.model.req.PermissionCheckReq;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasFeatureDao;
|
||||
import cn.axzo.tyr.server.repository.dao.SaasRoleDao;
|
||||
import cn.axzo.tyr.server.repository.entity.SaasFeature;
|
||||
import cn.axzo.tyr.server.service.TyrSaasAuthService;
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class TyrSaasAuthServiceImplTest extends BaseTest {
|
||||
|
||||
@Autowired
|
||||
private MysqlDataLoader mysqlDataLoader;
|
||||
@Autowired
|
||||
private TyrSaasAuthService tyrSaasAuthService;
|
||||
@Autowired
|
||||
private SaasFeatureDao saasFeatureDao;
|
||||
|
||||
@BeforeEach
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
mysqlDataLoader.loadFromClassName(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void authPermission() {
|
||||
|
||||
saasFeatureDao.save(SaasFeature.builder()
|
||||
.featureCode("CMS_001")
|
||||
.terminal("CMS")
|
||||
.build());
|
||||
|
||||
PermissionCheckReq permissionCheckReq = PermissionCheckReq.builder()
|
||||
.ouId(5708L)
|
||||
.workspaceId(300L)
|
||||
.personId(42642L)
|
||||
.featureCodes(Lists.newArrayList("dfff"))
|
||||
.build();
|
||||
boolean result = tyrSaasAuthService.authPermission(permissionCheckReq);
|
||||
Assertions.assertFalse(result);
|
||||
|
||||
result = tyrSaasAuthService.authPermission(PermissionCheckReq.builder()
|
||||
.ouId(5708L)
|
||||
.workspaceId(300L)
|
||||
.personId(42642L)
|
||||
.featureCodes(Lists.newArrayList("CMS_001"))
|
||||
.terminal("sdf")
|
||||
.build());
|
||||
Assertions.assertFalse(result);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
#-->DEFAULT
|
||||
|
||||
INSERT INTO saas_page_element (id, group_code, code, name, type, link_url, terminal, create_at, update_at, is_delete, create_name, app_type, version, item_code, link_ext, app_id, item_name, ext, create_by, update_by) VALUES (364184, 'h5:cmp_invite_team_page', 'h5:cmp_invite_team_page', '项目通讯录-邀请班组', 'PAGE', '__UNI__33771704#/inviteTeam', 'NT_CMP_APP_GENERAL', '2024-09-02 11:19:33', '2024-11-22 15:55:22', 0, '', 'H5', 0, 'h5:member_33771704', '', '__UNI__33771704', '通讯录H5', '{"applications": [{"type": "IOS", "minVersion": 0}, {"type": "ANDROID", "minVersion": 0}]}', null, null);
|
||||
INSERT INTO saas_page_element (id, group_code, code, name, type, link_url, terminal, create_at, update_at, is_delete, create_name, app_type, version, item_code, link_ext, app_id, item_name, ext, create_by, update_by) VALUES (364185, 'h5:cmp_invite_team_page', 'h5:cmp_invite_qr_code_btn', '项目通讯录-邀请班组-二维码邀请', 'COMPONENT', '', 'NT_CMP_APP_GENERAL', '2024-09-02 11:19:33', '2024-11-22 15:55:22', 0, '', 'H5', 0, 'h5:member_33771704', '', '__UNI__33771704', '通讯录H5', '{"applications": [{"type": "IOS", "minVersion": 0}, {"type": "ANDROID", "minVersion": 0}]}', null, null);
|
||||
|
||||
|
||||
#-->SaasRoleUserRelationServiceImplTest.sql
|
||||
@ -188,6 +188,13 @@ CREATE TABLE `saas_page_element` (
|
||||
`create_at` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标识',
|
||||
`create_name` varchar(64) NOT NULL DEFAULT '' COMMENT '创建人名',
|
||||
`app_type` varchar(32) NOT NULL DEFAULT '' COMMENT 'app类型(APP:原生,H5:h5页面)',
|
||||
`version` bigint NOT NULL DEFAULT '0' COMMENT '客户端版本号',
|
||||
`item_code` varchar(64) NOT NULL DEFAULT '' COMMENT '项目code',
|
||||
`link_ext` varchar(4096) NOT NULL DEFAULT '' COMMENT 'APP适配参数',
|
||||
`app_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'AppID',
|
||||
`item_name` varchar(64) NOT NULL DEFAULT '' COMMENT '项目名称',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_page_element_gcode` (`group_code`),
|
||||
KEY `idx_page_element_code` (`code`)
|
||||
@ -314,5 +321,28 @@ CREATE TABLE `permission_rule` (
|
||||
|
||||
alter table saas_role_group add column `path` varchar(255) DEFAULT '0' COMMENT 'ID层级路径, 逗号分隔';
|
||||
|
||||
CREATE TABLE `saas_page_element_category` (
|
||||
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
`item_code` varchar(64) NOT NULL DEFAULT '' COMMENT '项目编码',
|
||||
`item_name` varchar(128) NOT NULL DEFAULT '' COMMENT '项目名称',
|
||||
`terminal` varchar(64) NOT NULL DEFAULT '' COMMENT '端',
|
||||
`is_delete` bigint NOT NULL DEFAULT '0' COMMENT '删除标志',
|
||||
`create_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`create_by` bigint NOT NULL DEFAULT '0' COMMENT '创建人',
|
||||
`update_by` bigint NOT NULL DEFAULT '0' COMMENT '更新人',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `saas_page_element_category_item_code` (`item_code`),
|
||||
KEY `saas_page_element_category_item_name` (`item_name`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=41 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='前端元素类型';
|
||||
|
||||
-- alter table saas_page_element add column `ext` JSON NULL COMMENT '额外信息, 使用json便于查询';
|
||||
alter table saas_page_element add column `ext` VARCHAR(2048) NOT NULL DEFAULT '{}' COMMENT '额外信息';
|
||||
|
||||
|
||||
alter table saas_page_element add column `create_by` bigint DEFAULT NULL COMMENT '创建人';
|
||||
alter table saas_page_element add column `update_by` bigint DEFAULT NULL COMMENT '更新人';
|
||||
|
||||
|
||||
alter table saas_feature_resource modify column feature_code varchar(100) not null comment '资源编码-权限码';
|
||||
alter table saas_feature_resource modify column uni_code varchar(100) default '' not null comment '唯一编码,用于pre环境菜单同步';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user