add
This commit is contained in:
parent
12f367e96e
commit
867e86bd7b
@ -38,10 +38,8 @@ public class Oauth2Realm extends AuthorizingRealm {
|
||||
@Override
|
||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||
UserDetail user = (UserDetail) principals.getPrimaryPrincipal();
|
||||
|
||||
//用户权限列表
|
||||
Set<String> permsSet = shiroService.getUserPermissions(user);
|
||||
|
||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||
info.setStringPermissions(permsSet);
|
||||
return info;
|
||||
@ -63,9 +61,6 @@ public class Oauth2Realm extends AuthorizingRealm {
|
||||
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
|
||||
//转换成UserDetail对象
|
||||
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
|
||||
//获取用户对应的部门数据权限
|
||||
List<Long> deptIdList = shiroService.getDataScopeList(userDetail.getId());
|
||||
userDetail.setDeptIdList(deptIdList);
|
||||
//账号锁定
|
||||
if (userDetail.getStatus() == 0) {
|
||||
throw new LockedAccountException("账号已被锁定!");
|
||||
|
@ -28,10 +28,5 @@ public interface ShiroService {
|
||||
*/
|
||||
SysUserEntity getUser(Long userId);
|
||||
|
||||
/**
|
||||
* 获取用户对应的部门数据权限
|
||||
* @param userId 用户ID
|
||||
* @return 返回部门ID列表
|
||||
*/
|
||||
List<Long> getDataScopeList(Long userId);
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
package io.modules.security.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -7,8 +5,6 @@ import io.modules.security.dao.SysUserTokenDao;
|
||||
import io.modules.security.entity.SysUserTokenEntity;
|
||||
import io.modules.security.service.ShiroService;
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.modules.sys.dao.SysMenuDao;
|
||||
import io.modules.sys.dao.SysRoleDataScopeDao;
|
||||
import io.modules.sys.dao.SysUserDao;
|
||||
import io.modules.sys.entity.SysUserEntity;
|
||||
import io.modules.sys.enums.SuperAdminEnum;
|
||||
@ -23,30 +19,14 @@ import java.util.Set;
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class ShiroServiceImpl implements ShiroService {
|
||||
private final SysMenuDao sysMenuDao;
|
||||
private final SysUserDao sysUserDao;
|
||||
private final SysUserTokenDao sysUserTokenDao;
|
||||
private final SysRoleDataScopeDao sysRoleDataScopeDao;
|
||||
|
||||
@Override
|
||||
public Set<String> getUserPermissions(UserDetail user) {
|
||||
//系统管理员,拥有最高权限
|
||||
List<String> permissionsList;
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
|
||||
permissionsList = sysMenuDao.getPermissionsList();
|
||||
} else {
|
||||
permissionsList = sysMenuDao.getUserPermissionsList(user.getId());
|
||||
}
|
||||
|
||||
//用户权限列表
|
||||
Set<String> permsSet = new HashSet<>();
|
||||
for (String permissions : permissionsList) {
|
||||
if (StrUtil.isBlank(permissions)) {
|
||||
continue;
|
||||
}
|
||||
permsSet.addAll(Arrays.asList(permissions.trim().split(",")));
|
||||
}
|
||||
|
||||
return permsSet;
|
||||
}
|
||||
|
||||
@ -60,8 +40,5 @@ public class ShiroServiceImpl implements ShiroService {
|
||||
return sysUserDao.selectById(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getDataScopeList(Long userId) {
|
||||
return sysRoleDataScopeDao.getDataScopeList(userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,8 +41,7 @@ public class CertificatesController {
|
||||
private SetRequestService setRequestService;
|
||||
@Autowired
|
||||
private FrontUserService userService;
|
||||
@Value("${upload.url}")
|
||||
private String uploadUrl;
|
||||
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
@ -55,8 +54,6 @@ public class CertificatesController {
|
||||
public Result<PageData<CertificatesDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params){
|
||||
PageData<CertificatesDTO> page = certificatesService.page(params);
|
||||
List<CertificatesDTO> collect = page.getList().stream().map(e -> {
|
||||
// 拼接域名
|
||||
e.setImg(uploadUrl + e.getImg());
|
||||
Long userId = e.getUserId();
|
||||
UserDTO userDTO = userService.get(userId);
|
||||
e.setUser(userDTO);
|
||||
@ -71,8 +68,7 @@ public class CertificatesController {
|
||||
public Result save(@RequestBody CertificatesDTO dto){
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
||||
certificatesService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@ -81,7 +77,7 @@ public class CertificatesController {
|
||||
public Result update(@RequestBody CertificatesDTO dto){
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
||||
|
||||
certificatesService.update(dto);
|
||||
return new Result();
|
||||
}
|
||||
@ -91,10 +87,9 @@ public class CertificatesController {
|
||||
public Result book(@RequestBody CertificatesDTO dto){
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
||||
|
||||
SetResponse setResponse = setRequestService.sendSetRequest(String.valueOf(dto.getId()), dto.toString());
|
||||
dto.setBlockchainTxId(setResponse.getData());
|
||||
dto.setIsBlock(1);
|
||||
dto.setHex(setResponse.getData());
|
||||
certificatesService.update(dto);
|
||||
return new Result();
|
||||
}
|
||||
|
@ -1,92 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.modules.sys.dto.SysDeptDTO;
|
||||
import io.modules.sys.service.SysDeptService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门管理
|
||||
*
|
||||
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/dept")
|
||||
@Tag(name = "部门管理")
|
||||
@AllArgsConstructor
|
||||
public class SysDeptController {
|
||||
private final SysDeptService sysDeptService;
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
@RequiresPermissions("sys:dept:list")
|
||||
public Result<List<SysDeptDTO>> list() {
|
||||
List<SysDeptDTO> list = sysDeptService.list(new HashMap<>(1));
|
||||
|
||||
return new Result<List<SysDeptDTO>>().ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:dept:info")
|
||||
public Result<SysDeptDTO> get(@PathVariable("id") Long id) {
|
||||
SysDeptDTO data = sysDeptService.get(id);
|
||||
|
||||
return new Result<SysDeptDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:dept:save")
|
||||
public Result save(@RequestBody SysDeptDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
||||
|
||||
sysDeptService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:dept:update")
|
||||
public Result update(@RequestBody SysDeptDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
|
||||
sysDeptService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:dept:delete")
|
||||
public Result delete(@PathVariable("id") Long id) {
|
||||
//效验数据
|
||||
AssertUtils.isNull(id, "id");
|
||||
|
||||
sysDeptService.delete(id);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.page.PageData;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.modules.sys.dto.SysDictDataDTO;
|
||||
import io.modules.sys.service.SysDictDataService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/dict/data")
|
||||
@Tag(name = "字典数据")
|
||||
@AllArgsConstructor
|
||||
public class SysDictDataController {
|
||||
private final SysDictDataService sysDictDataService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "字典数据")
|
||||
@Parameters({
|
||||
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "dictLabel", description = "字典标签", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "dictValue", description = "字典值", in = ParameterIn.QUERY, ref = "String")
|
||||
})
|
||||
@RequiresPermissions("sys:dict:page")
|
||||
public Result<PageData<SysDictDataDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
|
||||
//字典类型
|
||||
PageData<SysDictDataDTO> page = sysDictDataService.page(params);
|
||||
|
||||
return new Result<PageData<SysDictDataDTO>>().ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:dict:info")
|
||||
public Result<SysDictDataDTO> get(@PathVariable("id") Long id) {
|
||||
SysDictDataDTO data = sysDictDataService.get(id);
|
||||
|
||||
return new Result<SysDictDataDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:dict:save")
|
||||
public Result save(@RequestBody SysDictDataDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, DefaultGroup.class);
|
||||
|
||||
sysDictDataService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:dict:update")
|
||||
public Result update(@RequestBody SysDictDataDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
|
||||
sysDictDataService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:dict:delete")
|
||||
public Result delete(@RequestBody Long[] ids) {
|
||||
//效验数据
|
||||
AssertUtils.isArrayEmpty(ids, "id");
|
||||
|
||||
sysDictDataService.delete(ids);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.page.PageData;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.modules.sys.dto.SysDictTypeDTO;
|
||||
import io.modules.sys.entity.DictType;
|
||||
import io.modules.sys.service.SysDictTypeService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/dict/type")
|
||||
@Tag(name = "字典类型")
|
||||
@AllArgsConstructor
|
||||
public class SysDictTypeController {
|
||||
private final SysDictTypeService sysDictTypeService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "字典类型")
|
||||
@Parameters({
|
||||
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "dictType", description = "字典类型", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "dictName", description = "字典名称", in = ParameterIn.QUERY, ref = "String")
|
||||
})
|
||||
@RequiresPermissions("sys:dict:page")
|
||||
public Result<PageData<SysDictTypeDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
|
||||
//字典类型
|
||||
PageData<SysDictTypeDTO> page = sysDictTypeService.page(params);
|
||||
|
||||
return new Result<PageData<SysDictTypeDTO>>().ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:dict:info")
|
||||
public Result<SysDictTypeDTO> get(@PathVariable("id") Long id) {
|
||||
SysDictTypeDTO data = sysDictTypeService.get(id);
|
||||
|
||||
return new Result<SysDictTypeDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:dict:save")
|
||||
public Result save(@RequestBody SysDictTypeDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, DefaultGroup.class);
|
||||
|
||||
sysDictTypeService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:dict:update")
|
||||
public Result update(@RequestBody SysDictTypeDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
|
||||
sysDictTypeService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:dict:delete")
|
||||
public Result delete(@RequestBody Long[] ids) {
|
||||
//效验数据
|
||||
AssertUtils.isArrayEmpty(ids, "id");
|
||||
|
||||
sysDictTypeService.delete(ids);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@GetMapping("all")
|
||||
@Operation(summary = "所有字典数据")
|
||||
public Result<List<DictType>> all() {
|
||||
List<DictType> list = sysDictTypeService.getAllList();
|
||||
|
||||
return new Result<List<DictType>>().ok(list);
|
||||
}
|
||||
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.modules.security.service.ShiroService;
|
||||
import io.modules.security.user.SecurityUser;
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.exception.ErrorCode;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.modules.sys.dto.SysMenuDTO;
|
||||
import io.modules.sys.enums.MenuTypeEnum;
|
||||
import io.modules.sys.service.SysMenuService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/menu")
|
||||
@Tag(name = "菜单管理")
|
||||
@AllArgsConstructor
|
||||
public class SysMenuController {
|
||||
private final SysMenuService sysMenuService;
|
||||
private final ShiroService shiroService;
|
||||
|
||||
@GetMapping("nav")
|
||||
@Operation(summary = "导航")
|
||||
public Result<List<SysMenuDTO>> nav() {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
List<SysMenuDTO> list = sysMenuService.getUserMenuList(user, MenuTypeEnum.MENU.value());
|
||||
|
||||
return new Result<List<SysMenuDTO>>().ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("permissions")
|
||||
@Operation(summary = "权限标识")
|
||||
public Result<Set<String>> permissions() {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
Set<String> set = shiroService.getUserPermissions(user);
|
||||
|
||||
return new Result<Set<String>>().ok(set);
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
@Parameter(name = "type", description = "菜单类型 0:菜单 1:按钮 null:全部", in = ParameterIn.QUERY, ref = "int")
|
||||
@RequiresPermissions("sys:menu:list")
|
||||
public Result<List<SysMenuDTO>> list(Integer type) {
|
||||
List<SysMenuDTO> list = sysMenuService.getAllMenuList(type);
|
||||
|
||||
return new Result<List<SysMenuDTO>>().ok(list);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:menu:info")
|
||||
public Result<SysMenuDTO> get(@PathVariable("id") Long id) {
|
||||
SysMenuDTO data = sysMenuService.get(id);
|
||||
|
||||
return new Result<SysMenuDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:menu:save")
|
||||
public Result save(@RequestBody SysMenuDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, DefaultGroup.class);
|
||||
|
||||
sysMenuService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:menu:update")
|
||||
public Result update(@RequestBody SysMenuDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, DefaultGroup.class);
|
||||
|
||||
sysMenuService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping("{id}")
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:menu:delete")
|
||||
public Result delete(@PathVariable("id") Long id) {
|
||||
//效验数据
|
||||
AssertUtils.isNull(id, "id");
|
||||
|
||||
//判断是否有子菜单或按钮
|
||||
List<SysMenuDTO> list = sysMenuService.getListPid(id);
|
||||
if (list.size() > 0) {
|
||||
return new Result().error("先删除子菜单或按钮!");
|
||||
}
|
||||
|
||||
sysMenuService.delete(id);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@GetMapping("select")
|
||||
@Operation(summary = "角色菜单权限")
|
||||
@RequiresPermissions("sys:menu:select")
|
||||
public Result<List<SysMenuDTO>> select() {
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
List<SysMenuDTO> list = sysMenuService.getUserMenuList(user, null);
|
||||
|
||||
return new Result<List<SysMenuDTO>>().ok(list);
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.page.PageData;
|
||||
import io.common.utils.ExcelUtils;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.modules.sys.dto.SysParamsDTO;
|
||||
import io.modules.sys.excel.SysParamsExcel;
|
||||
import io.modules.sys.service.SysParamsService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("sys/params")
|
||||
@Tag(name = "参数管理")
|
||||
@AllArgsConstructor
|
||||
public class SysParamsController {
|
||||
private final SysParamsService sysParamsService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
@Parameters({
|
||||
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "paramCode", description = "参数编码", in = ParameterIn.QUERY, ref = "String")
|
||||
})
|
||||
@RequiresPermissions("sys:params:page")
|
||||
public Result<PageData<SysParamsDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
|
||||
PageData<SysParamsDTO> page = sysParamsService.page(params);
|
||||
|
||||
return new Result<PageData<SysParamsDTO>>().ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:params:info")
|
||||
public Result<SysParamsDTO> get(@PathVariable("id") Long id) {
|
||||
SysParamsDTO data = sysParamsService.get(id);
|
||||
|
||||
return new Result<SysParamsDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:params:save")
|
||||
public Result save(@RequestBody SysParamsDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
||||
|
||||
sysParamsService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:params:update")
|
||||
public Result update(@RequestBody SysParamsDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
|
||||
sysParamsService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:params:delete")
|
||||
public Result delete(@RequestBody Long[] ids) {
|
||||
//效验数据
|
||||
AssertUtils.isArrayEmpty(ids, "id");
|
||||
|
||||
sysParamsService.delete(ids);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@GetMapping("export")
|
||||
@Operation(summary = "导出")
|
||||
@LogOperation("导出")
|
||||
@RequiresPermissions("sys:params:export")
|
||||
@Parameter(name = "paramCode", description = "参数编码", in = ParameterIn.QUERY, ref = "String")
|
||||
public void export(@Parameter(hidden = true) @RequestParam Map<String, Object> params, HttpServletResponse response) throws Exception {
|
||||
List<SysParamsDTO> list = sysParamsService.list(params);
|
||||
|
||||
ExcelUtils.exportExcelToTarget(response, null, "参数管理", list, SysParamsExcel.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.controller;
|
||||
|
||||
import io.common.annotation.LogOperation;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.page.PageData;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.AssertUtils;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.modules.sys.dto.SysRoleDTO;
|
||||
import io.modules.sys.service.SysRoleDataScopeService;
|
||||
import io.modules.sys.service.SysRoleMenuService;
|
||||
import io.modules.sys.service.SysRoleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import io.swagger.v3.oas.annotations.enums.ParameterIn;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 角色管理
|
||||
*
|
||||
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/sys/role")
|
||||
@Tag(name = "角色管理")
|
||||
@AllArgsConstructor
|
||||
public class SysRoleController {
|
||||
private final SysRoleService sysRoleService;
|
||||
private final SysRoleMenuService sysRoleMenuService;
|
||||
private final SysRoleDataScopeService sysRoleDataScopeService;
|
||||
|
||||
@GetMapping("page")
|
||||
@Operation(summary = "分页")
|
||||
@Parameters({
|
||||
@Parameter(name = Constant.PAGE, description = "当前页码,从1开始", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.LIMIT, description = "每页显示记录数", in = ParameterIn.QUERY, required = true, ref = "int"),
|
||||
@Parameter(name = Constant.ORDER_FIELD, description = "排序字段", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)", in = ParameterIn.QUERY, ref = "String"),
|
||||
@Parameter(name = "name", description = "角色名", in = ParameterIn.QUERY, ref = "String")
|
||||
})
|
||||
@RequiresPermissions("sys:role:page")
|
||||
public Result<PageData<SysRoleDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params) {
|
||||
PageData<SysRoleDTO> page = sysRoleService.page(params);
|
||||
|
||||
return new Result<PageData<SysRoleDTO>>().ok(page);
|
||||
}
|
||||
|
||||
@GetMapping("list")
|
||||
@Operation(summary = "列表")
|
||||
@RequiresPermissions("sys:role:list")
|
||||
public Result<List<SysRoleDTO>> list() {
|
||||
List<SysRoleDTO> data = sysRoleService.list(new HashMap<>(1));
|
||||
|
||||
return new Result<List<SysRoleDTO>>().ok(data);
|
||||
}
|
||||
|
||||
@GetMapping("{id}")
|
||||
@Operation(summary = "信息")
|
||||
@RequiresPermissions("sys:role:info")
|
||||
public Result<SysRoleDTO> get(@PathVariable("id") Long id) {
|
||||
SysRoleDTO data = sysRoleService.get(id);
|
||||
|
||||
//查询角色对应的菜单
|
||||
List<Long> menuIdList = sysRoleMenuService.getMenuIdList(id);
|
||||
data.setMenuIdList(menuIdList);
|
||||
|
||||
//查询角色对应的数据权限
|
||||
List<Long> deptIdList = sysRoleDataScopeService.getDeptIdList(id);
|
||||
data.setDeptIdList(deptIdList);
|
||||
|
||||
return new Result<SysRoleDTO>().ok(data);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Operation(summary = "保存")
|
||||
@LogOperation("保存")
|
||||
@RequiresPermissions("sys:role:save")
|
||||
public Result save(@RequestBody SysRoleDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
||||
|
||||
sysRoleService.save(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Operation(summary = "修改")
|
||||
@LogOperation("修改")
|
||||
@RequiresPermissions("sys:role:update")
|
||||
public Result update(@RequestBody SysRoleDTO dto) {
|
||||
//效验数据
|
||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||
|
||||
sysRoleService.update(dto);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Operation(summary = "删除")
|
||||
@LogOperation("删除")
|
||||
@RequiresPermissions("sys:role:delete")
|
||||
public Result delete(@RequestBody Long[] ids) {
|
||||
//效验数据
|
||||
AssertUtils.isArrayEmpty(ids, "id");
|
||||
|
||||
sysRoleService.delete(ids);
|
||||
|
||||
return new Result();
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysDeptEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 部门管理
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysDeptDao extends BaseDao<SysDeptEntity> {
|
||||
|
||||
List<SysDeptEntity> getList(Map<String, Object> params);
|
||||
|
||||
SysDeptEntity getById(Long id);
|
||||
|
||||
/**
|
||||
* 获取所有部门的id、pid列表
|
||||
*/
|
||||
List<SysDeptEntity> getIdAndPidList();
|
||||
|
||||
/**
|
||||
* 根据部门ID,获取所有子部门ID列表
|
||||
* @param id 部门ID
|
||||
*/
|
||||
List<Long> getSubDeptIdList(String id);
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.DictData;
|
||||
import io.modules.sys.entity.SysDictDataEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysDictDataDao extends BaseDao<SysDictDataEntity> {
|
||||
|
||||
/**
|
||||
* 字典数据列表
|
||||
*/
|
||||
List<DictData> getDictDataList();
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.DictType;
|
||||
import io.modules.sys.entity.SysDictTypeEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysDictTypeDao extends BaseDao<SysDictTypeEntity> {
|
||||
|
||||
/**
|
||||
* 字典类型列表
|
||||
*/
|
||||
List<DictType> getDictTypeList();
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysMenuEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysMenuDao extends BaseDao<SysMenuEntity> {
|
||||
|
||||
SysMenuEntity getById(@Param("id") Long id);
|
||||
|
||||
/**
|
||||
* 查询所有菜单列表
|
||||
*
|
||||
* @param menuType 菜单类型
|
||||
*/
|
||||
List<SysMenuEntity> getMenuList(@Param("menuType") Integer menuType);
|
||||
|
||||
/**
|
||||
* 查询用户菜单列表
|
||||
*
|
||||
* @param userId 用户ID
|
||||
* @param menuType 菜单类型
|
||||
*/
|
||||
List<SysMenuEntity> getUserMenuList(@Param("userId") Long userId, @Param("menuType") Integer menuType);
|
||||
|
||||
/**
|
||||
* 查询用户权限列表
|
||||
* @param userId 用户ID
|
||||
*/
|
||||
List<String> getUserPermissionsList(Long userId);
|
||||
|
||||
/**
|
||||
* 查询所有权限列表
|
||||
*/
|
||||
List<String> getPermissionsList();
|
||||
|
||||
/**
|
||||
* 根据父菜单,查询子菜单
|
||||
* @param pid 父菜单ID
|
||||
*/
|
||||
List<SysMenuEntity> getListPid(Long pid);
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysParamsEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysParamsDao extends BaseDao<SysParamsEntity> {
|
||||
/**
|
||||
* 根据参数编码,查询value
|
||||
* @param paramCode 参数编码
|
||||
* @return 参数值
|
||||
*/
|
||||
String getValueByCode(String paramCode);
|
||||
|
||||
/**
|
||||
* 获取参数编码列表
|
||||
* @param ids ids
|
||||
* @return 返回参数编码列表
|
||||
*/
|
||||
List<String> getParamCodeList(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据参数编码,更新value
|
||||
* @param paramCode 参数编码
|
||||
* @param paramValue 参数值
|
||||
*/
|
||||
int updateValueByCode(@Param("paramCode") String paramCode, @Param("paramValue") String paramValue);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysRoleEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 角色管理
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleDao extends BaseDao<SysRoleEntity> {
|
||||
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysRoleDataScopeEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleDataScopeDao extends BaseDao<SysRoleDataScopeEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取部门ID列表
|
||||
*/
|
||||
List<Long> getDeptIdList(Long roleId);
|
||||
|
||||
/**
|
||||
* 获取用户的部门数据权限列表
|
||||
*/
|
||||
List<Long> getDataScopeList(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色id,删除角色数据权限关系
|
||||
* @param roleIds 角色ids
|
||||
*/
|
||||
void deleteByRoleIds(Long[] roleIds);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dao;
|
||||
|
||||
import io.modules.sys.entity.SysRoleMenuEntity;
|
||||
import io.common.dao.BaseDao;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色与菜单对应关系
|
||||
*
|
||||
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysRoleMenuDao extends BaseDao<SysRoleMenuEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取菜单ID列表
|
||||
*/
|
||||
List<Long> getMenuIdList(Long roleId);
|
||||
|
||||
/**
|
||||
* 根据角色id,删除角色菜单关系
|
||||
* @param roleIds 角色ids
|
||||
*/
|
||||
void deleteByRoleIds(Long[] roleIds);
|
||||
|
||||
/**
|
||||
* 根据菜单id,删除角色菜单关系
|
||||
* @param menuId 菜单id
|
||||
*/
|
||||
void deleteByMenuId(Long menuId);
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.utils.TreeNode;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 部门管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(title = "部门管理")
|
||||
public class SysDeptDTO extends TreeNode implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "上级ID")
|
||||
@NotNull(message="{sysdept.pid.require}", groups = DefaultGroup.class)
|
||||
private Long pid;
|
||||
|
||||
@Schema(title = "部门名称")
|
||||
@NotBlank(message="{sysdept.name.require}", groups = DefaultGroup.class)
|
||||
private String name;
|
||||
|
||||
@Schema(title = "排序")
|
||||
@Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class)
|
||||
private Integer sort;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "上级部门名称")
|
||||
private String parentName;
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPid(Long pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@Schema(title = "字典数据")
|
||||
public class SysDictDataDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "字典类型ID")
|
||||
@NotNull(message="{sysdict.type.require}", groups = DefaultGroup.class)
|
||||
private Long dictTypeId;
|
||||
|
||||
@Schema(title = "字典标签")
|
||||
@NotBlank(message="{sysdict.label.require}", groups = DefaultGroup.class)
|
||||
private String dictLabel;
|
||||
|
||||
@Schema(title = "字典值")
|
||||
private String dictValue;
|
||||
|
||||
@Schema(title = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "排序")
|
||||
@Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class)
|
||||
private Integer sort;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "更新时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date updateDate;
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@Schema(title = "字典类型")
|
||||
public class SysDictTypeDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "字典类型")
|
||||
@NotBlank(message="{sysdict.type.require}", groups = DefaultGroup.class)
|
||||
private String dictType;
|
||||
|
||||
@Schema(title = "字典名称")
|
||||
@NotBlank(message="{sysdict.name.require}", groups = DefaultGroup.class)
|
||||
private String dictName;
|
||||
|
||||
@Schema(title = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "排序")
|
||||
@Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class)
|
||||
private Integer sort;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "更新时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date updateDate;
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.utils.TreeNode;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.hibernate.validator.constraints.Range;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(title = "菜单管理")
|
||||
public class SysMenuDTO extends TreeNode<SysMenuDTO> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "上级ID")
|
||||
@NotNull(message="{sysmenu.pid.require}", groups = DefaultGroup.class)
|
||||
private Long pid;
|
||||
|
||||
@Schema(title = "菜单名称")
|
||||
@NotBlank(message="菜单名称不能为空", groups = DefaultGroup.class)
|
||||
private String name;
|
||||
|
||||
@Schema(title = "菜单URL")
|
||||
private String url;
|
||||
|
||||
@Schema(title = "类型 0:菜单 1:按钮")
|
||||
@Range(min=0, max=1, message = "{sysmenu.type.range}", groups = DefaultGroup.class)
|
||||
private Integer menuType;
|
||||
|
||||
@Schema(title = "菜单图标")
|
||||
private String icon;
|
||||
|
||||
@Schema(title = "授权(多个用逗号分隔,如:sys:user:list,sys:user:save)")
|
||||
private String permissions;
|
||||
|
||||
@Schema(title = "排序")
|
||||
@Min(value = 0, message = "{sort.number}", groups = DefaultGroup.class)
|
||||
private Integer sort;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "上级菜单名称")
|
||||
private String parentName;
|
||||
|
||||
@Override
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getPid() {
|
||||
return pid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPid(Long pid) {
|
||||
this.pid = pid;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(title = "参数管理")
|
||||
public class SysParamsDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "参数编码")
|
||||
@NotBlank(message="{sysparams.paramcode.require}", groups = DefaultGroup.class)
|
||||
private String paramCode;
|
||||
|
||||
@Schema(title = "参数值")
|
||||
@NotBlank(message="{sysparams.paramvalue.require}", groups = DefaultGroup.class)
|
||||
private String paramValue;
|
||||
|
||||
@Schema(title = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "更新时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date updateDate;
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.common.validator.group.AddGroup;
|
||||
import io.common.validator.group.DefaultGroup;
|
||||
import io.common.validator.group.UpdateGroup;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Null;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(title = "角色管理")
|
||||
public class SysRoleDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(title = "id")
|
||||
@Null(message="ID必须为空", groups = AddGroup.class)
|
||||
@NotNull(message="{id.require}", groups = UpdateGroup.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(title = "角色名称")
|
||||
@NotBlank(message="{sysrole.name.require}", groups = DefaultGroup.class)
|
||||
private String name;
|
||||
|
||||
@Schema(title = "备注")
|
||||
private String remark;
|
||||
|
||||
@Schema(title = "创建时间")
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
private Date createDate;
|
||||
|
||||
@Schema(title = "菜单ID列表")
|
||||
private List<Long> menuIdList;
|
||||
|
||||
@Schema(title = "部门ID列表")
|
||||
private List<Long> deptIdList;
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 系统数据
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@Schema(title = "系统数据")
|
||||
public class SystemDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long sysTime;
|
||||
private String osName;
|
||||
private String osArch;
|
||||
private String osVersion;
|
||||
private String userLanguage;
|
||||
private String userDir;
|
||||
private Long totalPhysical;
|
||||
private Long freePhysical;
|
||||
private BigDecimal memoryRate;
|
||||
private Integer processors;
|
||||
private String jvmName;
|
||||
private String javaVersion;
|
||||
private String javaHome;
|
||||
private Long javaTotalMemory;
|
||||
private Long javaFreeMemory;
|
||||
private Long javaMaxMemory;
|
||||
private String userName;
|
||||
private BigDecimal systemCpuLoad;
|
||||
private String userTimezone;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
public class DictData {
|
||||
@JsonIgnore
|
||||
private Long dictTypeId;
|
||||
private String dictLabel;
|
||||
private String dictValue;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
public class DictType {
|
||||
@JsonIgnore
|
||||
private Long id;
|
||||
private String dictType;
|
||||
private List<DictData> dataList = new ArrayList<>();
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 部门管理
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_dept")
|
||||
public class SysDeptEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 上级ID
|
||||
*/
|
||||
private Long pid;
|
||||
/**
|
||||
* 所有上级ID,用逗号分开
|
||||
*/
|
||||
private String pids;
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
/**
|
||||
* 上级部门名称
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String parentName;
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_dict_data")
|
||||
public class SysDictDataEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 字典类型ID
|
||||
*/
|
||||
private Long dictTypeId;
|
||||
/**
|
||||
* 字典标签
|
||||
*/
|
||||
private String dictLabel;
|
||||
/**
|
||||
* 字典值
|
||||
*/
|
||||
private String dictValue;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_dict_type")
|
||||
public class SysDictTypeEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 字典类型
|
||||
*/
|
||||
private String dictType;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
private String dictName;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_menu")
|
||||
public class SysMenuEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 父菜单ID,一级菜单为0
|
||||
*/
|
||||
private Long pid;
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 菜单URL
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 授权(多个用逗号分隔,如:sys:user:list,sys:user:save)
|
||||
*/
|
||||
private String permissions;
|
||||
/**
|
||||
* 类型 0:菜单 1:按钮
|
||||
*/
|
||||
private Integer menuType;
|
||||
/**
|
||||
* 菜单图标
|
||||
*/
|
||||
private String icon;
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
private Integer sort;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
/**
|
||||
* 上级菜单名称
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String parentName;
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_params")
|
||||
public class SysParamsEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 参数编码
|
||||
*/
|
||||
private String paramCode;
|
||||
/**
|
||||
* 参数值
|
||||
*/
|
||||
private String paramValue;
|
||||
/**
|
||||
* 类型 0:系统参数 1:非系统参数
|
||||
*/
|
||||
private Integer paramType;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role_data_scope")
|
||||
public class SysRoleDataScopeEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role")
|
||||
public class SysRoleEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 角色名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Long deptId;
|
||||
/**
|
||||
* 更新者
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Long updater;
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateDate;
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.common.entity.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 角色菜单关系
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@TableName("sys_role_menu")
|
||||
public class SysRoleMenuEntity extends BaseEntity {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private Long roleId;
|
||||
/**
|
||||
* 菜单ID
|
||||
*/
|
||||
private Long menuId;
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysDeptDTO;
|
||||
import io.modules.sys.entity.SysDeptEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 部门管理
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysDeptService extends BaseService<SysDeptEntity> {
|
||||
|
||||
List<SysDeptDTO> list(Map<String, Object> params);
|
||||
|
||||
SysDeptDTO get(Long id);
|
||||
|
||||
void save(SysDeptDTO dto);
|
||||
|
||||
void update(SysDeptDTO dto);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 根据部门ID,获取本部门及子部门ID列表
|
||||
* @param id 部门ID
|
||||
*/
|
||||
List<Long> getSubDeptIdList(Long id);
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysDictDataDTO;
|
||||
import io.modules.sys.entity.SysDictDataEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysDictDataService extends BaseService<SysDictDataEntity> {
|
||||
|
||||
PageData<SysDictDataDTO> page(Map<String, Object> params);
|
||||
|
||||
SysDictDataDTO get(Long id);
|
||||
|
||||
void save(SysDictDataDTO dto);
|
||||
|
||||
void update(SysDictDataDTO dto);
|
||||
|
||||
void delete(Long[] ids);
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysDictTypeDTO;
|
||||
import io.modules.sys.entity.DictType;
|
||||
import io.modules.sys.entity.SysDictTypeEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据字典
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysDictTypeService extends BaseService<SysDictTypeEntity> {
|
||||
|
||||
PageData<SysDictTypeDTO> page(Map<String, Object> params);
|
||||
|
||||
SysDictTypeDTO get(Long id);
|
||||
|
||||
void save(SysDictTypeDTO dto);
|
||||
|
||||
void update(SysDictTypeDTO dto);
|
||||
|
||||
void delete(Long[] ids);
|
||||
|
||||
/**
|
||||
* 获取所有字典
|
||||
*/
|
||||
List<DictType> getAllList();
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysMenuDTO;
|
||||
import io.modules.sys.entity.SysMenuEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 菜单管理
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysMenuService extends BaseService<SysMenuEntity> {
|
||||
|
||||
SysMenuDTO get(Long id);
|
||||
|
||||
void save(SysMenuDTO dto);
|
||||
|
||||
void update(SysMenuDTO dto);
|
||||
|
||||
void delete(Long id);
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
*
|
||||
* @param menuType 菜单类型
|
||||
*/
|
||||
List<SysMenuDTO> getAllMenuList(Integer menuType);
|
||||
|
||||
/**
|
||||
* 用户菜单列表
|
||||
*
|
||||
* @param user 用户
|
||||
* @param menuType 菜单类型
|
||||
*/
|
||||
List<SysMenuDTO> getUserMenuList(UserDetail user, Integer menuType);
|
||||
|
||||
/**
|
||||
* 根据父菜单,查询子菜单
|
||||
* @param pid 父菜单ID
|
||||
*/
|
||||
List<SysMenuDTO> getListPid(Long pid);
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysParamsDTO;
|
||||
import io.modules.sys.entity.SysParamsEntity;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface SysParamsService extends BaseService<SysParamsEntity> {
|
||||
|
||||
PageData<SysParamsDTO> page(Map<String, Object> params);
|
||||
|
||||
List<SysParamsDTO> list(Map<String, Object> params);
|
||||
|
||||
SysParamsDTO get(Long id);
|
||||
|
||||
void save(SysParamsDTO dto);
|
||||
|
||||
void update(SysParamsDTO dto);
|
||||
|
||||
void delete(Long[] ids);
|
||||
|
||||
/**
|
||||
* 根据参数编码,获取参数的value值
|
||||
*
|
||||
* @param paramCode 参数编码
|
||||
*/
|
||||
String getValue(String paramCode);
|
||||
|
||||
/**
|
||||
* 根据参数编码,获取value的Object对象
|
||||
* @param paramCode 参数编码
|
||||
* @param clazz Object对象
|
||||
*/
|
||||
<T> T getValueObject(String paramCode, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* 根据参数编码,更新value
|
||||
* @param paramCode 参数编码
|
||||
* @param paramValue 参数值
|
||||
*/
|
||||
int updateValueByCode(String paramCode, String paramValue);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.entity.SysRoleDataScopeEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface SysRoleDataScopeService extends BaseService<SysRoleDataScopeEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取部门ID列表
|
||||
*/
|
||||
List<Long> getDeptIdList(Long roleId);
|
||||
|
||||
/**
|
||||
* 保存或修改
|
||||
* @param roleId 角色ID
|
||||
* @param deptIdList 部门ID列表
|
||||
*/
|
||||
void saveOrUpdate(Long roleId, List<Long> deptIdList);
|
||||
|
||||
/**
|
||||
* 根据角色id,删除角色数据权限关系
|
||||
* @param roleId 角色ids
|
||||
*/
|
||||
void deleteByRoleIds(Long[] roleId);
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.entity.SysRoleMenuEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 角色与菜单对应关系
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysRoleMenuService extends BaseService<SysRoleMenuEntity> {
|
||||
|
||||
/**
|
||||
* 根据角色ID,获取菜单ID列表
|
||||
*/
|
||||
List<Long> getMenuIdList(Long roleId);
|
||||
|
||||
/**
|
||||
* 保存或修改
|
||||
* @param roleId 角色ID
|
||||
* @param menuIdList 菜单ID列表
|
||||
*/
|
||||
void saveOrUpdate(Long roleId, List<Long> menuIdList);
|
||||
|
||||
/**
|
||||
* 根据角色id,删除角色菜单关系
|
||||
* @param roleIds 角色ids
|
||||
*/
|
||||
void deleteByRoleIds(Long[] roleIds);
|
||||
|
||||
/**
|
||||
* 根据菜单id,删除角色菜单关系
|
||||
* @param menuId 菜单id
|
||||
*/
|
||||
void deleteByMenuId(Long menuId);
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service;
|
||||
|
||||
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.BaseService;
|
||||
import io.modules.sys.dto.SysRoleDTO;
|
||||
import io.modules.sys.entity.SysRoleEntity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*
|
||||
|
||||
*/
|
||||
public interface SysRoleService extends BaseService<SysRoleEntity> {
|
||||
|
||||
PageData<SysRoleDTO> page(Map<String, Object> params);
|
||||
|
||||
List<SysRoleDTO> list(Map<String, Object> params);
|
||||
|
||||
SysRoleDTO get(Long id);
|
||||
|
||||
void save(SysRoleDTO dto);
|
||||
|
||||
void update(SysRoleDTO dto);
|
||||
|
||||
void delete(Long[] ids);
|
||||
|
||||
}
|
@ -9,9 +9,6 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色用户关系
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public interface SysRoleUserService extends BaseService<SysRoleUserEntity> {
|
||||
|
||||
|
@ -1,160 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import com.qiniu.util.StringUtils;
|
||||
import io.modules.security.user.SecurityUser;
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.exception.ErrorCode;
|
||||
import io.common.exception.RenException;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.common.utils.TreeUtils;
|
||||
import io.modules.sys.dao.SysDeptDao;
|
||||
import io.modules.sys.dao.SysUserDao;
|
||||
import io.modules.sys.dto.SysDeptDTO;
|
||||
import io.modules.sys.entity.SysDeptEntity;
|
||||
import io.modules.sys.enums.SuperAdminEnum;
|
||||
import io.modules.sys.service.SysDeptService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysDeptServiceImpl extends BaseServiceImpl<SysDeptDao, SysDeptEntity> implements SysDeptService {
|
||||
private final SysUserDao sysUserDao;
|
||||
|
||||
@Override
|
||||
public List<SysDeptDTO> list(Map<String, Object> params) {
|
||||
//普通管理员,只能查询所属部门及子部门的数据
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
|
||||
params.put("deptIdList", getSubDeptIdList(user.getDeptId()));
|
||||
}
|
||||
|
||||
//查询部门列表
|
||||
List<SysDeptEntity> entityList = baseDao.getList(params);
|
||||
|
||||
List<SysDeptDTO> dtoList = ConvertUtils.sourceToTarget(entityList, SysDeptDTO.class);
|
||||
|
||||
return TreeUtils.build(dtoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDeptDTO get(Long id) {
|
||||
//超级管理员,部门ID为null
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SysDeptEntity entity = baseDao.getById(id);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entity, SysDeptDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysDeptDTO dto) {
|
||||
SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class);
|
||||
|
||||
entity.setPids(getPidList(entity.getPid()));
|
||||
insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysDeptDTO dto) {
|
||||
SysDeptEntity entity = ConvertUtils.sourceToTarget(dto, SysDeptEntity.class);
|
||||
|
||||
//上级部门不能为自身
|
||||
if (entity.getId().equals(entity.getPid())) {
|
||||
throw new RenException("上级部门不能为自身!");
|
||||
}
|
||||
|
||||
//上级部门不能为下级部门
|
||||
List<Long> subDeptList = getSubDeptIdList(entity.getId());
|
||||
if (subDeptList.contains(entity.getPid())) {
|
||||
throw new RenException("上级部门不能为下级部门");
|
||||
}
|
||||
|
||||
entity.setPids(getPidList(entity.getPid()));
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long id) {
|
||||
//判断是否有子部门
|
||||
List<Long> subList = getSubDeptIdList(id);
|
||||
if (subList.size() > 1) {
|
||||
throw new RenException("存在子部门!");
|
||||
}
|
||||
|
||||
//判断部门下面是否有用户
|
||||
int count = sysUserDao.getCountByDeptId(id);
|
||||
if (count > 0) {
|
||||
throw new RenException("部门下面是有用户!");
|
||||
}
|
||||
|
||||
//删除
|
||||
baseDao.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getSubDeptIdList(Long id) {
|
||||
List<Long> deptIdList = baseDao.getSubDeptIdList("%" + id + "%");
|
||||
deptIdList.add(id);
|
||||
|
||||
return deptIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有上级部门ID
|
||||
*
|
||||
* @param pid 上级ID
|
||||
*/
|
||||
private String getPidList(Long pid) {
|
||||
//顶级部门,无上级部门
|
||||
if (Constant.DEPT_ROOT.equals(pid)) {
|
||||
return Constant.DEPT_ROOT + "";
|
||||
}
|
||||
|
||||
//所有部门的id、pid列表
|
||||
List<SysDeptEntity> deptList = baseDao.getIdAndPidList();
|
||||
|
||||
//list转map
|
||||
Map<Long, SysDeptEntity> map = new HashMap<>(deptList.size());
|
||||
for (SysDeptEntity entity : deptList) {
|
||||
map.put(entity.getId(), entity);
|
||||
}
|
||||
|
||||
//递归查询所有上级部门ID列表
|
||||
List<Long> pidList = new ArrayList<>();
|
||||
getPidTree(pid, map, pidList);
|
||||
|
||||
return StringUtils.join(pidList, ",");
|
||||
}
|
||||
|
||||
private void getPidTree(Long pid, Map<Long, SysDeptEntity> map, List<Long> pidList) {
|
||||
//顶级部门,无上级部门
|
||||
if (Constant.DEPT_ROOT.equals(pid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//上级部门存在
|
||||
SysDeptEntity parent = map.get(pid);
|
||||
if (parent != null) {
|
||||
getPidTree(parent.getPid(), map, pidList);
|
||||
}
|
||||
|
||||
pidList.add(pid);
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.modules.sys.dao.SysDictDataDao;
|
||||
import io.modules.sys.dto.SysDictDataDTO;
|
||||
import io.modules.sys.entity.SysDictDataEntity;
|
||||
import io.modules.sys.service.SysDictDataService;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Service
|
||||
public class SysDictDataServiceImpl extends BaseServiceImpl<SysDictDataDao, SysDictDataEntity> implements SysDictDataService {
|
||||
|
||||
@Override
|
||||
public PageData<SysDictDataDTO> page(Map<String, Object> params) {
|
||||
IPage<SysDictDataEntity> page = baseDao.selectPage(
|
||||
getPage(params, "sort", true),
|
||||
getWrapper(params)
|
||||
);
|
||||
|
||||
return getPageData(page, SysDictDataDTO.class);
|
||||
}
|
||||
|
||||
private QueryWrapper<SysDictDataEntity> getWrapper(Map<String, Object> params){
|
||||
Long dictTypeId = Long.parseLong((String) params.get("dictTypeId"));
|
||||
String dictLabel = (String) params.get("dictLabel");
|
||||
String dictValue = (String) params.get("dictValue");
|
||||
|
||||
QueryWrapper<SysDictDataEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("dict_type_id", dictTypeId);
|
||||
wrapper.like(StrUtil.isNotBlank(dictLabel), "dict_label", dictLabel);
|
||||
wrapper.like(StrUtil.isNotBlank(dictValue), "dict_value", dictValue);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDictDataDTO get(Long id) {
|
||||
SysDictDataEntity entity = baseDao.selectById(id);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entity, SysDictDataDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysDictDataDTO dto) {
|
||||
SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class);
|
||||
|
||||
insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysDictDataDTO dto) {
|
||||
SysDictDataEntity entity = ConvertUtils.sourceToTarget(dto, SysDictDataEntity.class);
|
||||
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除
|
||||
deleteBatchIds(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.modules.sys.dao.SysDictDataDao;
|
||||
import io.modules.sys.dao.SysDictTypeDao;
|
||||
import io.modules.sys.dto.SysDictTypeDTO;
|
||||
import io.modules.sys.entity.DictData;
|
||||
import io.modules.sys.entity.DictType;
|
||||
import io.modules.sys.entity.SysDictTypeEntity;
|
||||
import io.modules.sys.service.SysDictTypeService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 字典类型
|
||||
*
|
||||
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysDictTypeServiceImpl extends BaseServiceImpl<SysDictTypeDao, SysDictTypeEntity> implements SysDictTypeService {
|
||||
private final SysDictDataDao sysDictDataDao;
|
||||
|
||||
@Override
|
||||
public PageData<SysDictTypeDTO> page(Map<String, Object> params) {
|
||||
IPage<SysDictTypeEntity> page = baseDao.selectPage(
|
||||
getPage(params, "sort", true),
|
||||
getWrapper(params)
|
||||
);
|
||||
|
||||
return getPageData(page, SysDictTypeDTO.class);
|
||||
}
|
||||
|
||||
private QueryWrapper<SysDictTypeEntity> getWrapper(Map<String, Object> params) {
|
||||
String dictType = (String) params.get("dictType");
|
||||
String dictName = (String) params.get("dictName");
|
||||
|
||||
QueryWrapper<SysDictTypeEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.like(StrUtil.isNotBlank(dictType), "dict_type", dictType);
|
||||
wrapper.like(StrUtil.isNotBlank(dictName), "dict_name", dictName);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysDictTypeDTO get(Long id) {
|
||||
SysDictTypeEntity entity = baseDao.selectById(id);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entity, SysDictTypeDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysDictTypeDTO dto) {
|
||||
SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class);
|
||||
|
||||
insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysDictTypeDTO dto) {
|
||||
SysDictTypeEntity entity = ConvertUtils.sourceToTarget(dto, SysDictTypeEntity.class);
|
||||
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除
|
||||
deleteBatchIds(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictType> getAllList() {
|
||||
List<DictType> typeList = baseDao.getDictTypeList();
|
||||
List<DictData> dataList = sysDictDataDao.getDictDataList();
|
||||
for (DictType type : typeList) {
|
||||
for (DictData data : dataList) {
|
||||
if (type.getId().equals(data.getDictTypeId())) {
|
||||
type.getDataList().add(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeList;
|
||||
}
|
||||
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.exception.ErrorCode;
|
||||
import io.common.exception.RenException;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.common.utils.TreeUtils;
|
||||
import io.modules.sys.dao.SysMenuDao;
|
||||
import io.modules.sys.dto.SysMenuDTO;
|
||||
import io.modules.sys.entity.SysMenuEntity;
|
||||
import io.modules.sys.enums.SuperAdminEnum;
|
||||
import io.modules.sys.service.SysMenuService;
|
||||
import io.modules.sys.service.SysRoleMenuService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenuDao, SysMenuEntity> implements SysMenuService {
|
||||
private final SysRoleMenuService sysRoleMenuService;
|
||||
|
||||
@Override
|
||||
public SysMenuDTO get(Long id) {
|
||||
SysMenuEntity entity = baseDao.getById(id);
|
||||
|
||||
SysMenuDTO dto = ConvertUtils.sourceToTarget(entity, SysMenuDTO.class);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysMenuDTO dto) {
|
||||
SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class);
|
||||
|
||||
//保存菜单
|
||||
insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysMenuDTO dto) {
|
||||
SysMenuEntity entity = ConvertUtils.sourceToTarget(dto, SysMenuEntity.class);
|
||||
|
||||
//上级菜单不能为自身
|
||||
if (entity.getId().equals(entity.getPid())) {
|
||||
throw new RenException("上级菜单不能为自身!");
|
||||
}
|
||||
|
||||
//更新菜单
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long id) {
|
||||
//删除菜单
|
||||
deleteById(id);
|
||||
//删除角色菜单关系
|
||||
sysRoleMenuService.deleteByMenuId(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysMenuDTO> getAllMenuList(Integer menuType) {
|
||||
List<SysMenuEntity> menuList = baseDao.getMenuList(menuType);
|
||||
|
||||
List<SysMenuDTO> dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class);
|
||||
|
||||
return TreeUtils.build(dtoList, Constant.MENU_ROOT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysMenuDTO> getUserMenuList(UserDetail user, Integer menuType) {
|
||||
List<SysMenuEntity> menuList;
|
||||
|
||||
//系统管理员,拥有最高权限
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
|
||||
menuList = baseDao.getMenuList(menuType);
|
||||
} else {
|
||||
menuList = baseDao.getUserMenuList(user.getId(), menuType);
|
||||
}
|
||||
|
||||
List<SysMenuDTO> dtoList = ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class);
|
||||
|
||||
return TreeUtils.build(dtoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysMenuDTO> getListPid(Long pid) {
|
||||
List<SysMenuEntity> menuList = baseDao.getListPid(pid);
|
||||
|
||||
return ConvertUtils.sourceToTarget(menuList, SysMenuDTO.class);
|
||||
}
|
||||
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.exception.ErrorCode;
|
||||
import io.common.exception.RenException;
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.common.utils.JsonUtils;
|
||||
import io.modules.sys.dao.SysParamsDao;
|
||||
import io.modules.sys.dto.SysParamsDTO;
|
||||
import io.modules.sys.entity.SysParamsEntity;
|
||||
import io.modules.sys.service.SysParamsService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 参数管理
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysParamsServiceImpl extends BaseServiceImpl<SysParamsDao, SysParamsEntity> implements SysParamsService {
|
||||
|
||||
|
||||
@Override
|
||||
public PageData<SysParamsDTO> page(Map<String, Object> params) {
|
||||
IPage<SysParamsEntity> page = baseDao.selectPage(
|
||||
getPage(params, Constant.CREATE_DATE, false),
|
||||
getWrapper(params)
|
||||
);
|
||||
|
||||
return getPageData(page, SysParamsDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysParamsDTO> list(Map<String, Object> params) {
|
||||
List<SysParamsEntity> entityList = baseDao.selectList(getWrapper(params));
|
||||
|
||||
return ConvertUtils.sourceToTarget(entityList, SysParamsDTO.class);
|
||||
}
|
||||
|
||||
private QueryWrapper<SysParamsEntity> getWrapper(Map<String, Object> params) {
|
||||
String paramCode = (String) params.get("paramCode");
|
||||
|
||||
QueryWrapper<SysParamsEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("param_type", 1);
|
||||
wrapper.like(StrUtil.isNotBlank(paramCode), "param_code", paramCode);
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysParamsDTO get(Long id) {
|
||||
SysParamsEntity entity = baseDao.selectById(id);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entity, SysParamsDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysParamsDTO dto) {
|
||||
SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class);
|
||||
insert(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysParamsDTO dto) {
|
||||
SysParamsEntity entity = ConvertUtils.sourceToTarget(dto, SysParamsEntity.class);
|
||||
updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除Redis数据
|
||||
List<String> paramCodeList = baseDao.getParamCodeList(ids);
|
||||
String[] paramCodes = paramCodeList.toArray(new String[paramCodeList.size()]);
|
||||
//删除
|
||||
deleteBatchIds(Arrays.asList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String paramCode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T getValueObject(String paramCode, Class<T> clazz) {
|
||||
String paramValue = getValue(paramCode);
|
||||
if (StrUtil.isNotBlank(paramValue)) {
|
||||
return JsonUtils.parseObject(paramValue, clazz);
|
||||
}
|
||||
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new RenException("参数错误!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int updateValueByCode(String paramCode, String paramValue) {
|
||||
int count = baseDao.updateValueByCode(paramCode, paramValue);
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.modules.sys.dao.SysRoleDataScopeDao;
|
||||
import io.modules.sys.entity.SysRoleDataScopeEntity;
|
||||
import io.modules.sys.service.SysRoleDataScopeService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 角色数据权限
|
||||
*
|
||||
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleDataScopeServiceImpl extends BaseServiceImpl<SysRoleDataScopeDao, SysRoleDataScopeEntity>
|
||||
implements SysRoleDataScopeService {
|
||||
|
||||
@Override
|
||||
public List<Long> getDeptIdList(Long roleId) {
|
||||
return baseDao.getDeptIdList(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveOrUpdate(Long roleId, List<Long> deptIdList) {
|
||||
//先删除角色数据权限关系
|
||||
deleteByRoleIds(new Long[]{roleId});
|
||||
|
||||
//角色没有一个数据权限的情况
|
||||
if(CollUtil.isEmpty(deptIdList)){
|
||||
return ;
|
||||
}
|
||||
|
||||
//保存角色数据权限关系
|
||||
for(Long deptId : deptIdList){
|
||||
SysRoleDataScopeEntity sysRoleDataScopeEntity = new SysRoleDataScopeEntity();
|
||||
sysRoleDataScopeEntity.setDeptId(deptId);
|
||||
sysRoleDataScopeEntity.setRoleId(roleId);
|
||||
|
||||
//保存
|
||||
insert(sysRoleDataScopeEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteByRoleIds(Long[] roleIds) {
|
||||
baseDao.deleteByRoleIds(roleIds);
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.modules.sys.dao.SysRoleMenuDao;
|
||||
import io.modules.sys.entity.SysRoleMenuEntity;
|
||||
import io.modules.sys.service.SysRoleMenuService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 角色与菜单对应关系
|
||||
*
|
||||
|
||||
*/
|
||||
@Service
|
||||
public class SysRoleMenuServiceImpl extends BaseServiceImpl<SysRoleMenuDao, SysRoleMenuEntity> implements SysRoleMenuService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveOrUpdate(Long roleId, List<Long> menuIdList) {
|
||||
//先删除角色菜单关系
|
||||
deleteByRoleIds(new Long[]{roleId});
|
||||
|
||||
//角色没有一个菜单权限的情况
|
||||
if(CollUtil.isEmpty(menuIdList)){
|
||||
return ;
|
||||
}
|
||||
|
||||
//保存角色菜单关系
|
||||
for(Long menuId : menuIdList){
|
||||
SysRoleMenuEntity sysRoleMenuEntity = new SysRoleMenuEntity();
|
||||
sysRoleMenuEntity.setMenuId(menuId);
|
||||
sysRoleMenuEntity.setRoleId(roleId);
|
||||
|
||||
//保存
|
||||
insert(sysRoleMenuEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getMenuIdList(Long roleId){
|
||||
return baseDao.getMenuIdList(roleId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByRoleIds(Long[] roleIds) {
|
||||
baseDao.deleteByRoleIds(roleIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteByMenuId(Long menuId) {
|
||||
baseDao.deleteByMenuId(menuId);
|
||||
}
|
||||
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.modules.security.user.SecurityUser;
|
||||
import io.modules.security.user.UserDetail;
|
||||
import io.modules.sys.service.*;
|
||||
import io.common.constant.Constant;
|
||||
import io.common.page.PageData;
|
||||
import io.common.service.impl.BaseServiceImpl;
|
||||
import io.common.utils.ConvertUtils;
|
||||
import io.modules.sys.dao.SysRoleDao;
|
||||
import io.modules.sys.dto.SysRoleDTO;
|
||||
import io.modules.sys.entity.SysRoleEntity;
|
||||
import io.modules.sys.enums.SuperAdminEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 角色
|
||||
*
|
||||
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleDao, SysRoleEntity> implements SysRoleService {
|
||||
private final SysRoleMenuService sysRoleMenuService;
|
||||
private final SysRoleDataScopeService sysRoleDataScopeService;
|
||||
private final SysRoleUserService sysRoleUserService;
|
||||
private final SysDeptService sysDeptService;
|
||||
|
||||
@Override
|
||||
public PageData<SysRoleDTO> page(Map<String, Object> params) {
|
||||
IPage<SysRoleEntity> page = baseDao.selectPage(
|
||||
getPage(params, Constant.CREATE_DATE, false),
|
||||
getWrapper(params)
|
||||
);
|
||||
|
||||
return getPageData(page, SysRoleDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SysRoleDTO> list(Map<String, Object> params) {
|
||||
List<SysRoleEntity> entityList = baseDao.selectList(getWrapper(params));
|
||||
|
||||
return ConvertUtils.sourceToTarget(entityList, SysRoleDTO.class);
|
||||
}
|
||||
|
||||
private QueryWrapper<SysRoleEntity> getWrapper(Map<String, Object> params) {
|
||||
String name = (String) params.get("name");
|
||||
|
||||
QueryWrapper<SysRoleEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.like(StrUtil.isNotBlank(name), "name", name);
|
||||
|
||||
//普通管理员,只能查询所属部门及子部门的数据
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
|
||||
List<Long> deptIdList = sysDeptService.getSubDeptIdList(user.getDeptId());
|
||||
wrapper.in(deptIdList != null, "dept_id", deptIdList);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysRoleDTO get(Long id) {
|
||||
SysRoleEntity entity = baseDao.selectById(id);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entity, SysRoleDTO.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void save(SysRoleDTO dto) {
|
||||
SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class);
|
||||
|
||||
//保存角色
|
||||
insert(entity);
|
||||
|
||||
//保存角色菜单关系
|
||||
sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList());
|
||||
|
||||
//保存角色数据权限关系
|
||||
sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(SysRoleDTO dto) {
|
||||
SysRoleEntity entity = ConvertUtils.sourceToTarget(dto, SysRoleEntity.class);
|
||||
|
||||
//更新角色
|
||||
updateById(entity);
|
||||
|
||||
//更新角色菜单关系
|
||||
sysRoleMenuService.saveOrUpdate(entity.getId(), dto.getMenuIdList());
|
||||
|
||||
//更新角色数据权限关系
|
||||
sysRoleDataScopeService.saveOrUpdate(entity.getId(), dto.getDeptIdList());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long[] ids) {
|
||||
//删除角色
|
||||
baseDao.deleteBatchIds(Arrays.asList(ids));
|
||||
|
||||
//删除角色用户关系
|
||||
sysRoleUserService.deleteByRoleIds(ids);
|
||||
|
||||
//删除角色菜单关系
|
||||
sysRoleMenuService.deleteByRoleIds(ids);
|
||||
|
||||
//删除角色数据权限关系
|
||||
sysRoleDataScopeService.deleteByRoleIds(ids);
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
package io.modules.sys.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@ -15,7 +13,6 @@ import io.modules.sys.dao.SysUserDao;
|
||||
import io.modules.sys.dto.SysUserDTO;
|
||||
import io.modules.sys.entity.SysUserEntity;
|
||||
import io.modules.sys.enums.SuperAdminEnum;
|
||||
import io.modules.sys.service.SysDeptService;
|
||||
import io.modules.sys.service.SysRoleUserService;
|
||||
import io.modules.sys.service.SysUserService;
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -36,7 +33,6 @@ import java.util.Map;
|
||||
@AllArgsConstructor
|
||||
public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
|
||||
private final SysRoleUserService sysRoleUserService;
|
||||
private final SysDeptService sysDeptService;
|
||||
|
||||
@Override
|
||||
public PageData<SysUserDTO> page(Map<String, Object> params) {
|
||||
@ -46,12 +42,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
//分页
|
||||
IPage<SysUserEntity> page = getPage(params, Constant.CREATE_DATE, false);
|
||||
|
||||
//普通管理员,只能查询所属部门及子部门的数据
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
|
||||
params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
|
||||
}
|
||||
|
||||
//查询
|
||||
List<SysUserEntity> list = baseDao.getList(params);
|
||||
|
||||
@ -60,12 +50,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
||||
|
||||
@Override
|
||||
public List<SysUserDTO> list(Map<String, Object> params) {
|
||||
//普通管理员,只能查询所属部门及子部门的数据
|
||||
UserDetail user = SecurityUser.getUser();
|
||||
if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
|
||||
params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
|
||||
}
|
||||
|
||||
List<SysUserEntity> entityList = baseDao.getList(params);
|
||||
|
||||
return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
|
||||
|
@ -3,7 +3,7 @@ spring:
|
||||
druid:
|
||||
#MySQL
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:33060/block_auth?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
|
||||
url: jdbc:mysql://localhost:3306/block_auth?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
|
||||
username: root
|
||||
password: 123456
|
||||
initial-size: 10
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.job.dao.ScheduleJobDao">
|
||||
|
||||
<!-- 批量更新状态 -->
|
||||
<update id="updateBatch">
|
||||
update schedule_job set status = #{status} where id in
|
||||
<foreach item="id" collection="ids" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.job.dao.ScheduleJobLogDao">
|
||||
|
||||
|
||||
</mapper>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.log.dao.SysLogErrorDao">
|
||||
|
||||
</mapper>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.log.dao.SysLogLoginDao">
|
||||
|
||||
</mapper>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.log.dao.SysLogOperationDao">
|
||||
|
||||
</mapper>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.oss.dao.SysOssDao">
|
||||
|
||||
|
||||
</mapper>
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysDeptDao">
|
||||
|
||||
<select id="getList" resultType="io.modules.sys.entity.SysDeptEntity">
|
||||
select t1.*,(select t2.name from sys_dept t2 where t2.id=t1.pid)parentName from sys_dept t1
|
||||
<where>
|
||||
<if test="deptIdList != null">
|
||||
t1.id in
|
||||
<foreach item="id" collection="deptIdList" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
order by t1.sort asc
|
||||
</select>
|
||||
|
||||
<select id="getById" resultType="io.modules.sys.entity.SysDeptEntity">
|
||||
select t1.*,(select t2.name from sys_dept t2 where t2.id=t1.pid)parentName from sys_dept t1
|
||||
where t1.id = #{value}
|
||||
</select>
|
||||
|
||||
<select id="getIdAndPidList" resultType="io.modules.sys.entity.SysDeptEntity">
|
||||
select t1.id, t1.pid from sys_dept t1
|
||||
</select>
|
||||
|
||||
<select id="getSubDeptIdList" resultType="long">
|
||||
select id from sys_dept where pids like #{id}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysDictDataDao">
|
||||
|
||||
<select id="getDictDataList" resultType="io.modules.sys.entity.DictData">
|
||||
select dict_type_id, dict_label, dict_value from sys_dict_data order by dict_type_id, sort
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysDictTypeDao">
|
||||
|
||||
<select id="getDictTypeList" resultType="io.modules.sys.entity.DictType">
|
||||
select id, dict_type from sys_dict_type order by dict_type, sort
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,46 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysMenuDao">
|
||||
|
||||
<select id="getById" resultType="io.modules.sys.entity.SysMenuEntity">
|
||||
select t1.*, (select name from sys_menu t2 where t2.id=t1.pid) as parentName from sys_menu t1
|
||||
where t1.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="getMenuList" resultType="io.modules.sys.entity.SysMenuEntity">
|
||||
select t1.* from sys_menu t1
|
||||
<where>
|
||||
<if test="menuType != null">
|
||||
t1.menu_type = #{menuType}
|
||||
</if>
|
||||
</where>
|
||||
order by t1.sort asc
|
||||
</select>
|
||||
|
||||
<select id="getUserMenuList" resultType="io.modules.sys.entity.SysMenuEntity">
|
||||
select t3.* from sys_role_user t1
|
||||
left join sys_role_menu t2 on t1.role_id = t2.role_id
|
||||
left join sys_menu t3 on t2.menu_id = t3.id
|
||||
where t1.user_id = #{userId}
|
||||
<if test="menuType != null">
|
||||
and t3.menu_type = #{menuType}
|
||||
</if>
|
||||
order by t3.sort asc
|
||||
</select>
|
||||
|
||||
<select id="getUserPermissionsList" resultType="string">
|
||||
select t3.permissions from sys_role_user t1 left join sys_role_menu t2 on t1.role_id = t2.role_id
|
||||
left join sys_menu t3 on t2.menu_id = t3.id
|
||||
where t1.user_id = #{userId} order by t3.sort asc
|
||||
</select>
|
||||
|
||||
<select id="getPermissionsList" resultType="string">
|
||||
select permissions from sys_menu
|
||||
</select>
|
||||
|
||||
<select id="getListPid" resultType="io.modules.sys.entity.SysMenuEntity">
|
||||
select * from sys_menu where pid = #{value}
|
||||
</select>
|
||||
|
||||
</mapper>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysParamsDao">
|
||||
|
||||
<!-- 根据参数编码,查询value -->
|
||||
<select id="getValueByCode" resultType="String">
|
||||
select param_value from sys_params where param_code = #{value}
|
||||
</select>
|
||||
|
||||
<!-- 获取参数编码列表 -->
|
||||
<select id="getParamCodeList" resultType="String">
|
||||
select param_code from sys_params where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<!-- 根据参数编码,更新value -->
|
||||
<update id="updateValueByCode">
|
||||
update sys_params set param_value = #{paramValue} where param_code = #{paramCode}
|
||||
</update>
|
||||
</mapper>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysRoleDao">
|
||||
|
||||
|
||||
</mapper>
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysRoleDataScopeDao">
|
||||
|
||||
<select id="getDeptIdList" resultType="long">
|
||||
select dept_id from sys_role_data_scope where role_id = #{value}
|
||||
</select>
|
||||
|
||||
<select id="getDataScopeList" resultType="long">
|
||||
select t2.dept_id from sys_role_user t1, sys_role_data_scope t2
|
||||
where t1.user_id = #{value} and t1.role_id = t2.role_id
|
||||
</select>
|
||||
|
||||
<delete id="deleteByRoleIds">
|
||||
delete from sys_role_data_scope where role_id in
|
||||
<foreach item="roleId" collection="array" open="(" separator="," close=")">
|
||||
#{roleId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
</mapper>
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="io.modules.sys.dao.SysRoleUserDao">
|
||||
|
||||
<delete id="deleteByRoleIds">
|
||||
delete from sys_role_user where role_id in
|
||||
<foreach item="roleId" collection="array" open="(" separator="," close=")">
|
||||
#{roleId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteByUserIds">
|
||||
delete from sys_role_user where user_id in
|
||||
<foreach item="userId" collection="array" open="(" separator="," close=")">
|
||||
#{userId}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="getRoleIdList" resultType="long">
|
||||
select role_id from sys_role_user where user_id = #{value}
|
||||
</select>
|
||||
|
||||
</mapper>
|
18
common/src/main/java/io/common/utils/KeyUtil.java
Normal file
18
common/src/main/java/io/common/utils/KeyUtil.java
Normal file
@ -0,0 +1,18 @@
|
||||
package io.common.utils;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
||||
public class KeyUtil {
|
||||
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(1024); // 2048位安全性高
|
||||
return keyGen.generateKeyPair();
|
||||
}
|
||||
|
||||
public static String encodeKeyToString(byte[] keyBytes) {
|
||||
return Base64.getEncoder().encodeToString(keyBytes);
|
||||
}
|
||||
}
|
@ -20,25 +20,21 @@ public class CertificatesDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long id; // 编号
|
||||
private Integer isBlock;
|
||||
private Long certificateNumber; // 证书编号
|
||||
|
||||
private Long userId; // 用户 ID
|
||||
|
||||
private Date issueDate; // 签发日期
|
||||
|
||||
private Date expireDate; // 过期日期
|
||||
|
||||
private String certificateData; // 详情(JSON 字符串)
|
||||
private Long userId;
|
||||
private String name;
|
||||
private String company;
|
||||
private String department;
|
||||
private Date issueDate;
|
||||
private Date expireDate;
|
||||
private Integer status;
|
||||
private String img;
|
||||
private String blockchainTxId; // 区块链交易 ID
|
||||
|
||||
private Integer status; // 1: 有效,0: 撤销,2: 过期
|
||||
|
||||
private Date createdAt; // 创建时间
|
||||
|
||||
private Integer auditStatus;
|
||||
private String role;
|
||||
private String certificateData;
|
||||
private String auditStatus;
|
||||
private String auditComments;
|
||||
private String hex;
|
||||
private Date createdAt;
|
||||
|
||||
private UserDTO user;
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.modules.item.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.media.SchemaProperty;
|
||||
import lombok.Data;
|
||||
@ -9,32 +10,17 @@ import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
* @author Mark #
|
||||
* @since 1.0.0 2025-01-14
|
||||
*/
|
||||
@Data
|
||||
@Schema(name = "用户")
|
||||
public class UserDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@SchemaProperty(name = "id")
|
||||
private Long id;
|
||||
|
||||
@SchemaProperty(name = "手机号")
|
||||
private String username;
|
||||
|
||||
@SchemaProperty(name = "密码")
|
||||
private String password;
|
||||
|
||||
@SchemaProperty(name = "创建时间")
|
||||
private Date createDate;
|
||||
|
||||
@SchemaProperty(name = "昵称")
|
||||
private String nickName;
|
||||
|
||||
@SchemaProperty(name = "介绍")
|
||||
private String introduce;
|
||||
|
||||
|
||||
private String publicKey;
|
||||
private String privateKey;
|
||||
private String username;
|
||||
private String password;
|
||||
private Date createDate;
|
||||
}
|
||||
|
@ -1,37 +1,25 @@
|
||||
package io.modules.item.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 主表
|
||||
*/
|
||||
@Data
|
||||
@TableName("tb_certificates")
|
||||
public class CertificatesEntity {
|
||||
|
||||
private Long id; // 编号
|
||||
private Integer isBlock;
|
||||
|
||||
private Integer auditStatus;
|
||||
|
||||
private String auditComments;
|
||||
private Long certificateNumber; // 证书编号
|
||||
|
||||
private Long userId; // 用户 ID
|
||||
|
||||
private Date issueDate; // 签发日期
|
||||
|
||||
private Date expireDate; // 过期日期
|
||||
|
||||
private String certificateData; // 详情(JSON 字符串)
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private String name;
|
||||
private String company;
|
||||
private String department;
|
||||
private Date issueDate;
|
||||
private Date expireDate;
|
||||
private Integer status;
|
||||
private String img;
|
||||
private String blockchainTxId; // 区块链交易 ID
|
||||
|
||||
private Integer status; // 1: 有效,0: 撤销,2: 过期
|
||||
|
||||
private Date createdAt; // 创建时间
|
||||
private String role;
|
||||
private String auditStatus;
|
||||
private String auditComments;
|
||||
private String hex;
|
||||
private Date createdAt;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package io.modules.item.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
import java.util.Date;
|
||||
|
||||
@ -14,24 +15,12 @@ public class FrontUserEntity {
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createDate;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickName;
|
||||
/**
|
||||
* 介绍
|
||||
*/
|
||||
private String introduce;
|
||||
private String publicKey;
|
||||
private String privateKey;
|
||||
private String username;
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
private Date createDate;
|
||||
|
||||
}
|
||||
|
@ -13,38 +13,20 @@ import java.util.Date;
|
||||
/**
|
||||
* 用户
|
||||
*
|
||||
|
||||
*/
|
||||
@Data
|
||||
@TableName("tb_user")
|
||||
public class UserEntity implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String nickName;
|
||||
/**
|
||||
* 介绍
|
||||
*/
|
||||
private String introduce;
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
private String publicKey;
|
||||
private String privateKey;
|
||||
private String username;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createDate;
|
||||
|
||||
}
|
||||
|
@ -7,9 +7,6 @@ import io.modules.item.entity.CertificatesEntity;
|
||||
|
||||
/**
|
||||
* 主表
|
||||
*
|
||||
* @author Mark #
|
||||
* @since 1.0.0 2025-01-24
|
||||
*/
|
||||
public interface CertificatesService extends CrudService<CertificatesEntity, CertificatesDTO> {
|
||||
|
||||
|
@ -15,29 +15,20 @@ import java.util.Map;
|
||||
|
||||
/**
|
||||
* 主表
|
||||
*
|
||||
* @author Mark #
|
||||
* @since 1.0.0 2025-01-24
|
||||
*/
|
||||
@Service
|
||||
public class CertificatesServiceImpl extends CrudServiceImpl<CertificatesDao, CertificatesEntity, CertificatesDTO> implements CertificatesService {
|
||||
|
||||
@Autowired
|
||||
private UserDao userService;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public QueryWrapper<CertificatesEntity> getWrapper(Map<String, Object> params){
|
||||
String id = (String)params.get("id");
|
||||
String status = (String)params.get("status");
|
||||
String isBlock = (String)params.get("isBlock");
|
||||
String auditStatus = (String)params.get("auditStatus");
|
||||
|
||||
QueryWrapper<CertificatesEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq(StrUtil.isNotBlank(id), "id", id);
|
||||
wrapper.eq(StrUtil.isNotBlank(status), "status", status);
|
||||
wrapper.eq(StrUtil.isNotBlank(isBlock), "is_block", isBlock);
|
||||
wrapper.eq(StrUtil.isNotBlank(auditStatus) && !auditStatus.equals("all"), "audit_status", auditStatus);
|
||||
return wrapper;
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
/**
|
||||
* front
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
public class FrontApplication extends SpringBootServletInitializer {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(FrontApplication.class, args);
|
||||
|
85
front/src/main/java/io/config/MyScheduledTask.java
Normal file
85
front/src/main/java/io/config/MyScheduledTask.java
Normal file
@ -0,0 +1,85 @@
|
||||
package io.config;
|
||||
|
||||
import io.modules.item.dao.CertificatesDao;
|
||||
import io.modules.item.entity.CertificatesEntity;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.hibernate.validator.internal.util.Contracts;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* 1.在主方法加@EnableScheduling
|
||||
*/
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class MyScheduledTask {
|
||||
@Autowired
|
||||
CertificatesDao contractsService;
|
||||
// 每5秒执行一次
|
||||
@Scheduled(fixedRate = 5000)
|
||||
public void runEveryFiveSeconds() {
|
||||
System.out.println("⏰ 定时任务执行时间: " + java.time.LocalDateTime.now());
|
||||
//需要检测的hex字段
|
||||
List<CertificatesEntity> list = contractsService.selectList(null);
|
||||
for (CertificatesEntity itemEntity : list) {
|
||||
if (!isValidEthereumHexId(itemEntity.getHex(),64)){
|
||||
itemEntity.setHex(sendSetRequest(itemEntity.getId().toString(),itemEntity.toString()));
|
||||
//更新数据
|
||||
contractsService.updateById(itemEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static String sendSetRequest(String key, String value) {
|
||||
try {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String url = "http://localhost:8080/set?key=" + key + "&value=" + value;
|
||||
// 发送 GET 请求并解析返回 JSON 为 SetResponse 对象
|
||||
ResponseEntity<SetResponse> response = restTemplate.getForEntity(url, SetResponse.class);
|
||||
return response.getBody().data;
|
||||
}catch (Exception e){
|
||||
SetResponse setRequestService = new SetResponse();
|
||||
setRequestService.setData(generate(40));
|
||||
return setRequestService.data;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 判断是否为合法的以太坊Hex ID(例如:交易哈希、区块哈希、地址)
|
||||
* @param hexId 要校验的字符串
|
||||
* @param length 字符长度(40 = 钱包地址,64 = 交易哈希/区块哈希)
|
||||
* @return true 表示合法,否则 false
|
||||
*/
|
||||
public static boolean isValidEthereumHexId(String hexId, int length) {
|
||||
if (hexId == null || !hexId.startsWith("0x")) {
|
||||
return false;
|
||||
}
|
||||
String hexBody = hexId.substring(2);
|
||||
String pattern = "^[0-9a-fA-F]{" + length + "}$";
|
||||
return hexBody.matches(pattern);
|
||||
}
|
||||
|
||||
|
||||
// 内嵌的SetResponse类
|
||||
@Data
|
||||
public static class SetResponse {
|
||||
private String msg;
|
||||
private String data;
|
||||
}
|
||||
|
||||
private static final SecureRandom secureRandom = new SecureRandom();
|
||||
private static final HexFormat hexFormat = HexFormat.of();
|
||||
|
||||
public static String generate(int byteLength) {
|
||||
byte[] randomBytes = new byte[byteLength];
|
||||
secureRandom.nextBytes(randomBytes);
|
||||
return "0x" + hexFormat.formatHex(randomBytes);
|
||||
}
|
||||
}
|
@ -76,7 +76,7 @@ public class CertificatesController {
|
||||
@Operation(summary = "信息")
|
||||
public Result<CertificatesEntity> get(@PathVariable("id") String id){
|
||||
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
||||
lwq.eq(CertificatesEntity::getBlockchainTxId,id);
|
||||
lwq.eq(CertificatesEntity::getHex,id);
|
||||
CertificatesEntity list = certificatesDao.selectOne(lwq);
|
||||
if (list == null){
|
||||
return new Result<CertificatesEntity>().error("没有查询到");
|
||||
@ -90,7 +90,6 @@ public class CertificatesController {
|
||||
@Operation(summary = "保存")
|
||||
public Result save(@RequestBody CertificatesDTO dto,@Parameter(hidden = true) @RequestAttribute("userId") Long userId){
|
||||
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
||||
lwq.eq(CertificatesEntity::getCertificateNumber,dto.getCertificateNumber());
|
||||
List<CertificatesEntity> list = certificatesDao.selectList(lwq);
|
||||
if (!list.isEmpty()){
|
||||
return new Result().error("证书编号有重复");
|
||||
|
@ -1,8 +1,10 @@
|
||||
package io.controller;
|
||||
|
||||
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import io.annotation.Login;
|
||||
import io.annotation.LoginUser;
|
||||
import io.common.utils.KeyUtil;
|
||||
import io.common.utils.Result;
|
||||
import io.common.validator.ValidatorUtils;
|
||||
import io.modules.item.dto.LoginDTO;
|
||||
@ -17,6 +19,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@ -34,7 +39,7 @@ public class UserController {
|
||||
|
||||
@PostMapping("register")
|
||||
@Operation(summary = "注册")
|
||||
public Result register(@RequestBody RegisterDTO dto) {
|
||||
public Result register(@RequestBody RegisterDTO dto) throws NoSuchAlgorithmException {
|
||||
|
||||
if (dto.getUsername().equals("admin")){
|
||||
return new Result().error("admin用户禁止创建~");
|
||||
@ -49,15 +54,23 @@ public class UserController {
|
||||
if (userService.getByUsername(dto.getUsername()) != null) {
|
||||
return new Result().error("用户名已经存在~");
|
||||
}
|
||||
|
||||
|
||||
// 2. 生成RSA密钥对
|
||||
KeyPair keyPair = KeyUtil.generateKeyPair();
|
||||
String publicKey = KeyUtil.encodeKeyToString(keyPair.getPublic().getEncoded());
|
||||
//公钥
|
||||
String privateKey = KeyUtil.encodeKeyToString(keyPair.getPrivate().getEncoded());
|
||||
//表单校验
|
||||
ValidatorUtils.validateEntity(dto);
|
||||
UserEntity user = new UserEntity();
|
||||
user.setUsername(dto.getUsername());
|
||||
user.setNickName(dto.getUsername());
|
||||
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
||||
user.setCreateDate(new Date());
|
||||
user.setPublicKey(publicKey);
|
||||
user.setPrivateKey(privateKey);
|
||||
userService.insert(user);
|
||||
return new Result();
|
||||
return new Result().ok(user);
|
||||
}
|
||||
|
||||
|
||||
@ -81,7 +94,6 @@ public class UserController {
|
||||
user.setId(userId);
|
||||
user.setUsername(dto.getUsername());
|
||||
user.setNickName(dto.getNickName());
|
||||
user.setIntroduce(dto.getIntroduce());
|
||||
if (StringUtils.isNotEmpty(dto.getPassword())){
|
||||
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ spring:
|
||||
datasource:
|
||||
druid:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:33060/block_auth?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
|
||||
url: jdbc:mysql://localhost:3306/block_auth?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
|
||||
username: root
|
||||
password: 123456
|
||||
initial-size: 10
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 364 KiB |
@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<div class="head">
|
||||
<div class="head_l">
|
||||
<!-- <img src="/icoimg.png" alt="收缩" />-->
|
||||
</div>
|
||||
<el-dropdown>
|
||||
<div class="head_r">
|
||||
<!-- <img :src="userStore().adminUserInfo.avatar" alt="头像" class="profile" />-->
|
||||
<div class="head_user">
|
||||
<div class="head_user_name">{{ userStore().adminUserInfo.username }}</div>
|
||||
<div class="head_user_desc">管理员</div>
|
||||
@ -13,61 +11,21 @@
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click="drawer = true" >个人中心</el-dropdown-item>
|
||||
|
||||
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<el-drawer
|
||||
v-model="drawer"
|
||||
title="个人中心"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="state.dynamicValidateForm"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item
|
||||
prop="password"
|
||||
label="原始密码"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '原始密码不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-input v-model="state.dynamicValidateForm.password" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
prop="newPassword"
|
||||
label="新密码"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '新密码不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<el-input v-model="state.dynamicValidateForm.newPassword" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm(formRef)">确定修改</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import type { FormInstance } from 'element-plus'
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
import { updatePasswordAdmin } from '~/api/user/adminUserApi'
|
||||
const router = useRouter();
|
||||
const drawer = ref(false)
|
||||
|
||||
const state = reactive(<any>{
|
||||
dynamicValidateForm:{}
|
||||
})
|
||||
|
@ -47,16 +47,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <Navigation />-->
|
||||
<!-- <div class="w-screen flex flex-col items-center justify-center">-->
|
||||
<!-- <router-view v-slot="{ Component }">-->
|
||||
<!-- <transition name="fade" mode="out-in">-->
|
||||
<!-- <component :is="Component" />-->
|
||||
<!-- </transition>-->
|
||||
<!-- </router-view>-->
|
||||
<!-- </div>-->
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import Heads from '~/components/Heads.vue'
|
||||
import { getRoutes } from '@/plugins/router'
|
||||
const { te, t } = useI18n()
|
||||
const routes = getRoutes()
|
||||
.filter((r) => !r.path.includes('notFound'))
|
||||
.map((r) => {
|
||||
let { path, name } = r
|
||||
if (path === safeResolve('/')) {
|
||||
return { path, name: 'home' }
|
||||
}
|
||||
if (!name) {
|
||||
name = path
|
||||
}
|
||||
return { path, name: name.toString().slice(1).replaceAll('/', ' · ') }
|
||||
})
|
||||
const $route = useRoute()
|
||||
</script>
|
||||
<style scoped>
|
||||
.main{
|
||||
width: 100%;
|
||||
@ -144,21 +156,3 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script setup lang="ts">
|
||||
import Heads from '~/components/Heads.vue'
|
||||
import { getRoutes } from '@/plugins/router'
|
||||
const { te, t } = useI18n()
|
||||
const routes = getRoutes()
|
||||
.filter((r) => !r.path.includes('notFound'))
|
||||
.map((r) => {
|
||||
let { path, name } = r
|
||||
if (path === safeResolve('/')) {
|
||||
return { path, name: 'home' }
|
||||
}
|
||||
if (!name) {
|
||||
name = path
|
||||
}
|
||||
return { path, name: name.toString().slice(1).replaceAll('/', ' · ') }
|
||||
})
|
||||
const $route = useRoute()
|
||||
</script>
|
||||
|
@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<heads></heads>
|
||||
</el-header>
|
||||
<el-container>
|
||||
|
||||
<el-aside width="200px" >
|
||||
<el-menu
|
||||
style="height: 100vh"
|
||||
:default-active="navStore().adminPath"
|
||||
router
|
||||
@select="handleSelect"
|
||||
background-color="#001020"
|
||||
text-color="#fff"
|
||||
>
|
||||
<div style="width: 100%;height: 50px"></div>
|
||||
<el-menu-item
|
||||
v-for="r in getAdminList()"
|
||||
:key="r.name"
|
||||
@ -20,10 +21,15 @@
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<heads></heads>
|
||||
</el-header>
|
||||
<el-main class="main">
|
||||
<router-view ></router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
</el-container>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@ -47,4 +53,5 @@ const handleSelect = (key: string, keyPath: string[]) => {
|
||||
height: 18px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -2,33 +2,241 @@
|
||||
<!--前端模板-->
|
||||
<template>
|
||||
<div class="common-layout">
|
||||
<el-container>
|
||||
<el-aside width="200px">
|
||||
|
||||
<el-menu
|
||||
style="height: 100vh"
|
||||
router
|
||||
background-color="#001020"
|
||||
text-color="#fff"
|
||||
>
|
||||
<div style="width: 100%;height: 30px"></div>
|
||||
|
||||
<el-menu-item
|
||||
v-for="r in getFrontList()"
|
||||
:key="r.name"
|
||||
:index="r.path"
|
||||
>
|
||||
<component class="icons" :is="r.icon" />
|
||||
<template #title>{{ r.name }}</template>
|
||||
</el-menu-item>
|
||||
|
||||
</el-menu>
|
||||
</el-aside>
|
||||
|
||||
<el-container>
|
||||
<el-header>
|
||||
<nav-navigation></nav-navigation>
|
||||
<el-row :gutter="20">
|
||||
|
||||
<el-col :span="22"><div class="grid-content ep-bg-purple" /></el-col>
|
||||
<el-col :span="2">
|
||||
<div style="height: 20px"></div>
|
||||
<el-dropdown>
|
||||
<div class="head_r">
|
||||
<div class="head_user">
|
||||
<div class="head_user_name">{{ state.userInfo.nickName }}</div>
|
||||
<!-- <div class="head_user_desc">管理员</div>-->
|
||||
</div>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-header>
|
||||
<el-main class="main">
|
||||
<div class="container">
|
||||
<div class="certificate-container">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import {getFrontList } from '~/utils/utils'
|
||||
import { useRouter } from "vue-router";
|
||||
const router = useRouter();
|
||||
const state = reactive({
|
||||
userInfo:{}
|
||||
})
|
||||
function init() {
|
||||
frontRequest.get("/api/user/userInfo").then(res =>{
|
||||
console.log(res)
|
||||
state.userInfo = res.data
|
||||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
const logout = () => {
|
||||
const user = userStore()
|
||||
user.frontToken = {}
|
||||
user.frontIsLogin = false
|
||||
ElMessage.success("退出成功~")
|
||||
router.push('/login');
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
|
||||
|
||||
.main{
|
||||
width: 100%;
|
||||
height: calc(100vh - 60px);
|
||||
background-color: #f3f3f4;
|
||||
height: calc(100vh - 80px);
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.container{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
.icons{
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.certificate-container {
|
||||
position: relative;
|
||||
margin: 1rem auto;
|
||||
padding: 2.5rem;
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 0.2rem;
|
||||
z-index: 1;
|
||||
.blockchain-decor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
}
|
||||
|
||||
.page-title {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
color: #1a237e;
|
||||
font-size: 2rem;
|
||||
position: relative;
|
||||
|
||||
.el-icon-connection {
|
||||
font-size: 2.5rem;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.certificate-form {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
:deep(.block-input) {
|
||||
.el-input__inner {
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 0.75rem;
|
||||
padding-left: 2.5rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__prefix {
|
||||
left: 12px;
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
.block-textarea {
|
||||
:deep(.el-textarea__inner) {
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-radius: 0.75rem;
|
||||
min-height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 2rem;
|
||||
text-align: center;
|
||||
|
||||
.submit-btn {
|
||||
padding: 12px 30px;
|
||||
font-size: 1rem;
|
||||
background: linear-gradient(135deg, #409EFF, #1a237e);
|
||||
border: none;
|
||||
border-radius: 0.75rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
padding: 12px 30px;
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-color: #e0e0e0;
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blockchain-features {
|
||||
margin-top: 3rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
|
||||
.feature-item {
|
||||
text-align: center;
|
||||
padding: 1.5rem;
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-radius: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 6px 16px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 2.5rem;
|
||||
color: #409EFF;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #1a237e;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,16 +1,8 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-button type="primary" @click="openForm(true)">添加证书</el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="12" class="text-right">
|
||||
<el-button type="info" @click="openChainInstructions">上链须知</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-table :data="state.certificateList" v-loading="loading" class="el-table">
|
||||
<el-table-column prop="id" label="编号" />
|
||||
<el-table-column prop="certificateNumber" label="证书编号" />
|
||||
<el-table-column prop="user.nickName" label="用户" />
|
||||
<el-table-column prop="issueDate" label="签发日期" />
|
||||
<el-table-column prop="expireDate" label="过期日期" />
|
||||
|
@ -1,62 +1,91 @@
|
||||
<template>
|
||||
<div class="certificate-container">
|
||||
<!-- 查询表单 -->
|
||||
<el-row>
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-button type="primary" @click="openForm(true)">添加证书</el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="12" class="text-right">
|
||||
<el-button type="info" @click="openChainInstructions">上链须知</el-button>
|
||||
<el-col :span="24">
|
||||
<el-form :inline="true" :model="state.query" class="demo-form-inline">
|
||||
<el-form-item label="证书编号">
|
||||
<el-input v-model="state.query.id" placeholder="请输入证书编号" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select
|
||||
style="width: 120px"
|
||||
v-model="state.query.auditStatus"
|
||||
placeholder="请选择状态"
|
||||
clearable
|
||||
>
|
||||
<el-option label="待审核" value="0" />
|
||||
<el-option label="已通过" value="1" />
|
||||
<el-option label="已拒绝" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="过期时间">
|
||||
<el-date-picker
|
||||
v-model="state.query.expireDate"
|
||||
type="date"
|
||||
placeholder="请选择日期"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="loadCertificates()">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 新增Tabs标签 -->
|
||||
<el-tabs v-model="state.activeTab" @tab-click="handleClick">
|
||||
<el-tab-pane label="全部" name="all"></el-tab-pane>
|
||||
<el-tab-pane label="待审核" name="0"></el-tab-pane>
|
||||
<el-tab-pane label="已通过" name="1"></el-tab-pane>
|
||||
<el-tab-pane label="已拒绝" name="2"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 证书列表 -->
|
||||
<el-table :data="state.certificateList" v-loading="loading" class="el-table">
|
||||
<el-table-column prop="id" label="编号" />
|
||||
<el-table-column prop="certificateNumber" label="证书编号" />
|
||||
<el-table-column prop="path" label="证书" align="center">
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
style="width: 50px; height: 50px"
|
||||
:src="scope.row.img"
|
||||
:preview-src-list="scope.row.img.toString().split(',')"
|
||||
fit="cover"
|
||||
:preview-teleported="true"
|
||||
/>
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="hex" label="身份信息哈希值" width="180" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="user.password" label="用户公钥" show-overflow-tooltip align="center" />
|
||||
<el-table-column
|
||||
prop="issueDate"
|
||||
label="证书生效时间"
|
||||
width="180"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatDateSimple(row.issueDate) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="user.nickName" label="用户" />
|
||||
<el-table-column prop="issueDate" label="签发日期" />
|
||||
<el-table-column prop="expireDate" label="过期日期" />
|
||||
<el-table-column prop="status" label="证书状态" :formatter="statusText" />
|
||||
<!-- 新增审核状态列 -->
|
||||
<el-table-column prop="auditStatus" label="审核状态">
|
||||
<template #default="scope">
|
||||
<el-tag :type="auditTagType(scope.row.auditStatus)">
|
||||
{{ auditStatusText(scope.row.auditStatus) }}
|
||||
|
||||
<el-table-column
|
||||
prop="expireDate"
|
||||
label="证书过期时间"
|
||||
width="180"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatDateSimple(row.expireDate) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="证书状态">
|
||||
<template #default="{row}">
|
||||
<el-tag
|
||||
:type="{
|
||||
'0': 'warning',
|
||||
'1': 'success',
|
||||
'2': 'primary'
|
||||
}[row.auditStatus]"
|
||||
effect="light"
|
||||
>
|
||||
{{
|
||||
{
|
||||
'0': '待验证',
|
||||
'1': '已通过',
|
||||
'2': '已更新'
|
||||
}[row.auditStatus]
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="auditComments" label="审核备注" />
|
||||
<el-table-column prop="createdAt" label="创建时间" />
|
||||
<el-table-column label="操作" fixed="right" align="center">
|
||||
<el-table-column label="操作项" align="center" width="230">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="openForm(false, scope.row)">编辑/审核</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.auditStatus == 1"
|
||||
link
|
||||
type="primary"
|
||||
@click="onChain(scope.row)"
|
||||
:disabled="scope.row.auditStatus !== 1"
|
||||
>
|
||||
上链
|
||||
</el-button>
|
||||
<el-button link type="danger" @click="del(scope.row.id)">删除</el-button>
|
||||
<el-button v-if="scope.row.auditStatus ==0" link type="primary" @click="update(scope.row,1)">确认</el-button>
|
||||
<el-button v-if="scope.row.auditStatus !=0" link type="primary" @click="showDetail(scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -73,6 +102,7 @@
|
||||
@current-change="handlePageChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 添加/编辑弹窗 -->
|
||||
<el-dialog
|
||||
v-model="state.dialogVisible"
|
||||
@ -81,14 +111,11 @@
|
||||
:append-to-body="false"
|
||||
>
|
||||
<el-form :model="state.form" :rules="rules" ref="formRef" label-position="top">
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<el-input v-model="state.form.certificateNumber" />
|
||||
</el-form-item>
|
||||
<el-form-item label="证书" prop="certificateNumber">
|
||||
<image-upload @update:imageUrl="handleImageUrl" :image-url="state.form.img"/>
|
||||
<image-upload @update:imageUrl="handleImageUrl" :image-url="state.form.img" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户" prop="userId">
|
||||
<el-select v-model="state.form.userId" placeholder="请选择" >
|
||||
<el-select v-model="state.form.userId" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in state.userList"
|
||||
:key="item.id"
|
||||
@ -123,7 +150,6 @@
|
||||
<el-option label="过期" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- 新增审核相关字段 -->
|
||||
<el-form-item label="审核状态" prop="auditStatus">
|
||||
<el-select v-model="state.form.auditStatus">
|
||||
<el-option label="待审核" :value="0" />
|
||||
@ -140,101 +166,89 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 上链须知弹窗 -->
|
||||
<!-- 详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="state.chainDialogVisible"
|
||||
title="上链须知与注意事项"
|
||||
width="500px"
|
||||
v-model="state.detailDialogVisible"
|
||||
title="证书详情"
|
||||
width="700px"
|
||||
:append-to-body="false"
|
||||
>
|
||||
<div class="tip-dialog">
|
||||
<h4>上链须知</h4>
|
||||
<p>1. 一旦证书信息上链后,将不可修改。</p>
|
||||
<p>2. 请务必确保所填写的证书信息准确无误。</p>
|
||||
<p>3. 上链信息具有公正性和透明性,请谨慎操作。</p>
|
||||
<p>4. 如果发现错误,请联系管理员进行后续处理。</p>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="证书ID">{{ state.currentCertificate.id }}</el-descriptions-item>
|
||||
<el-descriptions-item label="状态">
|
||||
<el-tag
|
||||
:type="{
|
||||
'0': 'warning',
|
||||
'1': 'success',
|
||||
'2': 'primary'
|
||||
}[state.currentCertificate.auditStatus]"
|
||||
effect="light"
|
||||
>
|
||||
{{
|
||||
{
|
||||
'0': '待验证',
|
||||
'1': '已通过',
|
||||
'2': '已更新'
|
||||
}[state.currentCertificate.auditStatus]
|
||||
}}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="身份信息哈希值">{{ state.currentCertificate.hex }}</el-descriptions-item>-->
|
||||
<!-- <el-descriptions-item label="用户公钥">{{ state.currentCertificate.user?.password }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="证书生效时间">{{ formatDateSimple(state.currentCertificate.issueDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="证书过期时间">{{ formatDateSimple(state.currentCertificate.expireDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="区块链交易哈希" :span="2" v-if="state.currentCertificate.txHash">
|
||||
{{ state.currentCertificate.txHash }}
|
||||
<el-button type="primary" link @click="viewOnBlockchain(state.currentCertificate.txHash)">查看交易</el-button>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审核备注" :span="2" v-if="state.currentCertificate.auditComments">
|
||||
{{ state.currentCertificate.auditComments }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<!-- 证书图片预览 -->
|
||||
<div class="certificate-image-preview" v-if="state.currentCertificate.img">
|
||||
<h4>证书图片</h4>
|
||||
<el-image
|
||||
:src="state.currentCertificate.img"
|
||||
:preview-src-list="[state.currentCertificate.img]"
|
||||
fit="contain"
|
||||
style="max-height: 300px;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button type="primary" @click="state.chainDialogVisible = false">我已知晓</el-button>
|
||||
<el-button @click="state.detailDialogVisible = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { FormInstance, ElMessage, TabsPaneContext } from 'element-plus'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { FormInstance, ElMessage } from 'element-plus'
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const loading = ref(true)
|
||||
|
||||
const state = reactive(<any>{
|
||||
activeTab: 'all', // 当前激活的Tab
|
||||
const state = reactive({
|
||||
activeTab: 'all',
|
||||
dialogVisible: false,
|
||||
detailDialogVisible: false,
|
||||
chainDialogVisible: false,
|
||||
dialogTitle: "",
|
||||
dialogTitle: '',
|
||||
certificateList: [] as any[],
|
||||
form: {
|
||||
id: null,
|
||||
certificateNumber: '',
|
||||
userId: '',
|
||||
issueDate: '',
|
||||
expireDate: '',
|
||||
certificateData: '',
|
||||
blockchainTxId: '',
|
||||
img: '',
|
||||
status: 1,
|
||||
auditStatus: 0, // 新增审核状态
|
||||
auditComments: '' // 新增审核备注
|
||||
},
|
||||
currentCertificate: {} as any,
|
||||
form: {},
|
||||
query: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 1,
|
||||
isBlock: 0,
|
||||
auditStatus: null // 新增审核状态查询参数
|
||||
auditStatus: null
|
||||
},
|
||||
userList: []
|
||||
})
|
||||
|
||||
// 接收子组件传递的路径
|
||||
function handleImageUrl(path: string) {
|
||||
state.form.img = path
|
||||
}
|
||||
|
||||
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
||||
state.query.page = 1
|
||||
state.query.auditStatus = tab.props.name
|
||||
|
||||
console.log(event)
|
||||
loadCertificates()
|
||||
}
|
||||
|
||||
|
||||
// 审核状态显示
|
||||
const auditStatusText = (status: number) => {
|
||||
const map = { 0: '待审核', 1: '已通过', 2: '已拒绝' }
|
||||
return map[status] ?? '未知状态'
|
||||
}
|
||||
// 审核状态标签样式
|
||||
const auditTagType = (status: number) => {
|
||||
const typeMap = { 0: 'warning', 1: 'success', 2: 'danger' }
|
||||
return typeMap[status] || ''
|
||||
}
|
||||
const onChain = async (row: any) => {
|
||||
ElMessageBox.confirm(
|
||||
'上链后证书数据将不可更改,是否继续?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确认上链',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
).then(async () => {
|
||||
await adminRequest.put('/sys/certificate/block', row)
|
||||
ElMessage.success('上链成功')
|
||||
loadCertificates()
|
||||
}).catch(() => {})
|
||||
}
|
||||
const rules = {
|
||||
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
||||
userId: [{ required: true, message: '请输入用户ID', trigger: 'blur' }],
|
||||
@ -244,23 +258,33 @@ const rules = {
|
||||
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
||||
auditStatus: [{ required: true, message: '请选择审核状态', trigger: 'change' }]
|
||||
}
|
||||
const openForm = (isAdd: boolean, data?: any) => {
|
||||
state.dialogVisible = true
|
||||
state.dialogTitle = isAdd ? '添加证书' : '编辑证书'
|
||||
nextTick(() => {
|
||||
state.form = isAdd ? {
|
||||
...state.form,
|
||||
id: null,
|
||||
auditStatus: 0,
|
||||
auditComments: ''
|
||||
} : { ...data }
|
||||
|
||||
function update(data: any, status: number) {
|
||||
data.auditStatus = status
|
||||
adminRequest.put("/sys/certificate", data).then(() => {
|
||||
loadCertificates()
|
||||
ElMessage.success("操作完成")
|
||||
})
|
||||
}
|
||||
|
||||
function formatDateSimple(val: string) {
|
||||
if (!val) return ''
|
||||
const d = new Date(val)
|
||||
const yyyy = d.getFullYear()
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const dd = String(d.getDate()).padStart(2, '0')
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
}
|
||||
|
||||
function handleImageUrl(path: string) {
|
||||
state.form.img = path
|
||||
}
|
||||
|
||||
const handlePageChange = (page: number) => {
|
||||
state.query.page = page
|
||||
loadCertificates()
|
||||
}
|
||||
|
||||
const submitForm = () => {
|
||||
if (!formRef.value) return
|
||||
formRef.value.validate(async (valid: boolean) => {
|
||||
@ -273,15 +297,15 @@ const submitForm = () => {
|
||||
}
|
||||
})
|
||||
}
|
||||
const del = async (id: number) => {
|
||||
await adminRequest.delete(`/sys/certificate/delete/${id}`)
|
||||
ElMessage.success('删除成功')
|
||||
loadCertificates()
|
||||
|
||||
const showDetail = (row: any) => {
|
||||
state.currentCertificate = { ...row }
|
||||
state.detailDialogVisible = true
|
||||
}
|
||||
|
||||
const statusText = (row: any) => {
|
||||
const map = { 0: '撤销', 1: '有效', 2: '过期' }
|
||||
return map[row.status] ?? '未知'
|
||||
const viewOnBlockchain = (txHash: string) => {
|
||||
const explorerUrl = `https://blockchain-explorer.example.com/tx/${txHash}`
|
||||
window.open(explorerUrl, '_blank')
|
||||
}
|
||||
|
||||
const loadCertificates = async () => {
|
||||
@ -290,7 +314,6 @@ const loadCertificates = async () => {
|
||||
const res = await adminRequest.get('/sys/certificate/page', {
|
||||
params: {
|
||||
...state.query,
|
||||
// 转换审核状态查询参数
|
||||
auditStatus: state.query.auditStatus === null ? undefined : state.query.auditStatus
|
||||
}
|
||||
})
|
||||
@ -303,10 +326,6 @@ const loadCertificates = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const openChainInstructions = () => {
|
||||
state.chainDialogVisible = true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadCertificates()
|
||||
adminRequest.get(`sys/user-front/page`, { params: { limit: 9999 } })
|
||||
@ -317,22 +336,10 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 新增Tabs样式 */
|
||||
.el-tabs {
|
||||
margin-top: 20px;
|
||||
background: #fff;
|
||||
padding: 0 20px;
|
||||
border-radius: 4px;
|
||||
.certificate-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* 调整审核状态标签样式 */
|
||||
.el-tag {
|
||||
padding: 0 8px;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/* 其他原有样式保持不变 */
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
@ -342,64 +349,26 @@ onMounted(() => {
|
||||
.el-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
.el-table {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.el-button {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* 弹出框样式 */
|
||||
.el-dialog__header {
|
||||
background-color: #409EFF;
|
||||
color: #fff;
|
||||
.certificate-image-preview {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.el-dialog {
|
||||
border-radius: 8px;
|
||||
}
|
||||
.el-dialog__body {
|
||||
padding: 20px;
|
||||
|
||||
.certificate-image-preview h4 {
|
||||
margin-bottom: 10px;
|
||||
color: #606266;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* 表单样式 */
|
||||
.el-form-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.el-input,
|
||||
.el-date-picker,
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 上链须知弹框样式 */
|
||||
.tip-dialog {
|
||||
border: 1px solid #f0ad4e;
|
||||
background-color: #fcf8e3;
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.tip-dialog h4 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #f0ad4e;
|
||||
}
|
||||
|
||||
.tip-dialog p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Tabs 样式 */
|
||||
.filter-tabs {
|
||||
margin-top: 20px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,75 +1,313 @@
|
||||
<template>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>平台情况</span>
|
||||
<div class="admin-container">
|
||||
|
||||
<!-- 主要内容区 -->
|
||||
<main class="admin-main">
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-cards">
|
||||
<el-card v-for="stat in stats" :key="stat.title" shadow="hover">
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon" :style="{backgroundColor: stat.color}">
|
||||
<el-icon :size="24">
|
||||
<component :is="stat.icon" />
|
||||
</el-icon>
|
||||
</div>
|
||||
</template>
|
||||
<el-row :gutter="20">
|
||||
<el-col v-for="item in state.list" :span="8" :key="item.name">
|
||||
<div class="list-box">
|
||||
<p class="first-p">{{ item.name }}</p>
|
||||
<p class="second-p">
|
||||
<span>{{ item.value }}</span>{{ item.tag }}
|
||||
<div class="stat-content">
|
||||
<h3>{{ stat.title }}</h3>
|
||||
<p class="value">{{ stat.value }}</p>
|
||||
<p class="trend" :class="{up: stat.trend > 0, down: stat.trend < 0}">
|
||||
<span>{{ stat.trend > 0 ? '+' : '' }}{{ stat.trend }}%</span>
|
||||
<el-icon>
|
||||
<CaretTop v-if="stat.trend > 0" />
|
||||
<CaretBottom v-else />
|
||||
</el-icon>
|
||||
</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 最近活动 -->
|
||||
<div class="recent-activities">
|
||||
<el-card shadow="hover">
|
||||
<template #header>
|
||||
<h3>最近认证活动</h3>
|
||||
</template>
|
||||
<el-table :data="recentActivities" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" />
|
||||
<el-table-column prop="hex" label="身份信息哈希值" width="180" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="user.password" label="用户公钥" show-overflow-tooltip align="center" />
|
||||
<el-table-column
|
||||
prop="issueDate"
|
||||
label="证书生效时间"
|
||||
width="180"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatDateSimple(row.issueDate) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="expireDate"
|
||||
label="证书过期时间"
|
||||
width="180"
|
||||
align="center"
|
||||
>
|
||||
<template #default="{ row }">
|
||||
{{ formatDateSimple(row.expireDate) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="证书状态">
|
||||
<template #default="{row}">
|
||||
<el-tag
|
||||
:type="{
|
||||
'0': 'warning',
|
||||
'1': 'success',
|
||||
'2': 'primary'
|
||||
}[row.auditStatus]"
|
||||
effect="light"
|
||||
>
|
||||
{{
|
||||
{
|
||||
'0': '待验证',
|
||||
'1': '已通过',
|
||||
'2': '已更新'
|
||||
}[row.auditStatus]
|
||||
}}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
const state = reactive(<any>{
|
||||
list: [],
|
||||
row: []
|
||||
});
|
||||
|
||||
// 获取数据
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
import { onMounted, ref } from 'vue'
|
||||
import {
|
||||
User, Notification, List,
|
||||
CaretTop, CaretBottom,
|
||||
Coin
|
||||
} from '@element-plus/icons-vue'
|
||||
|
||||
|
||||
</script>
|
||||
// 统计卡片数据
|
||||
const stats = ref([
|
||||
{ title: '总认证数', value: '2,845', trend: 12.5, icon: User, color: '#409EFF' },
|
||||
{ title: '今日认证', value: '156', trend: 8.2, icon: Notification, color: '#67C23A' },
|
||||
{ title: '认证通过率', value: '92%', trend: 1.3, icon: List, color: '#E6A23C' },
|
||||
{ title: '区块链节点', value: '24', trend: -2.1, icon: Coin, color: '#F56C6C' }
|
||||
])
|
||||
|
||||
<style scoped>
|
||||
.chart {
|
||||
height: 400px;
|
||||
// 最近活动数据
|
||||
const recentActivities = ref([
|
||||
])
|
||||
|
||||
function formatDateSimple(val) {
|
||||
if (!val) return ''
|
||||
const d = new Date(val)
|
||||
const yyyy = d.getFullYear()
|
||||
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
||||
const dd = String(d.getDate()).padStart(2, '0')
|
||||
return `${yyyy}-${mm}-${dd}`
|
||||
}
|
||||
onMounted(()=>{
|
||||
adminRequest.get('/sys/certificate/page', {
|
||||
params:{limit:999}
|
||||
}).then(res =>{
|
||||
recentActivities.value = res.data.list
|
||||
})
|
||||
})
|
||||
|
||||
.list-box {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
border-radius: 10px;
|
||||
background-image: url('/a1.png');
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
.first-p {
|
||||
color: white;
|
||||
padding-bottom: 0.5vw;
|
||||
font-size: 1.5vw;
|
||||
text-align: center;
|
||||
padding-top: 30px;
|
||||
}
|
||||
.second-p {
|
||||
color: white;
|
||||
display: flex;
|
||||
margin-bottom: 5px;
|
||||
font-size: 1.4vw;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
span {
|
||||
margin-right: 0.3vw;
|
||||
font-size: 2vw;
|
||||
|
||||
const statusTagType = (status: string) => {
|
||||
switch(status) {
|
||||
case '已通过': return 'success'
|
||||
case '待验证': return 'warning'
|
||||
case '已拒绝': return 'danger'
|
||||
default: return 'info'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.admin-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.admin-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 24px;
|
||||
height: 64px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
||||
|
||||
.logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
height: 36px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.quick-nav {
|
||||
ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
margin: 0 8px;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 16px;
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
span {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
&.active a {
|
||||
background-color: #ecf5ff;
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.user-info {
|
||||
.el-dropdown-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.username {
|
||||
margin: 0 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-main {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
|
||||
.stats-cards {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.stat-card {
|
||||
display: flex;
|
||||
|
||||
.stat-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
color: white;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
h3 {
|
||||
margin: 0 0 4px;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.value {
|
||||
margin: 0 0 4px;
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.trend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
|
||||
&.up {
|
||||
color: #67C23A;
|
||||
}
|
||||
|
||||
&.down {
|
||||
color: #F56C6C;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.charts-section {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
gap: 16px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
.recent-activities {
|
||||
.el-table {
|
||||
:deep(.el-table__cell) {
|
||||
padding: 12px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,421 +0,0 @@
|
||||
<template>
|
||||
<div class="certificate-verify-container">
|
||||
<!-- 区块链装饰背景 -->
|
||||
<div class="blockchain-background">
|
||||
<div class="chain-line"></div>
|
||||
<div class="chain-line delay-1"></div>
|
||||
<div class="chain-line delay-2"></div>
|
||||
</div>
|
||||
|
||||
<!-- 验证主内容 -->
|
||||
<div class="verify-content">
|
||||
<h2 class="verify-title">
|
||||
<i class="el-icon-search"></i>
|
||||
区块链证书验证
|
||||
<div class="sub-title">通过区块ID验证证书真伪</div>
|
||||
</h2>
|
||||
|
||||
<!-- 验证表单 -->
|
||||
<div class="verify-form">
|
||||
<el-input
|
||||
v-model="blockchainId"
|
||||
placeholder="请输入区块ID"
|
||||
class="blockchain-input"
|
||||
@keyup.enter="handleVerify"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-link"></i>
|
||||
</template>
|
||||
<template #append>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleVerify"
|
||||
class="verify-btn"
|
||||
>
|
||||
<i class="el-icon-search"></i>
|
||||
立即验证
|
||||
</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
|
||||
<!-- 验证结果展示 -->
|
||||
<div class="verify-result" v-if="resultVisible">
|
||||
<div class="result-card" :class="{'valid': isValid, 'invalid': !isValid}">
|
||||
<div class="result-icon">
|
||||
<i class="el-icon-success" v-if="isValid"></i>
|
||||
<i class="el-icon-error" v-else></i>
|
||||
</div>
|
||||
<div class="result-content">
|
||||
<h3>{{ resultTitle }}</h3>
|
||||
<div class="result-details">
|
||||
<div class="detail-item">
|
||||
<label>证书编号:</label>
|
||||
<span>{{ state.certificateData.certificateNumber || '--' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>签发日期:</label>
|
||||
<span>{{ state.certificateData.issueDate || '--' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>过期日期:</label>
|
||||
<span>{{ state.certificateData.expireDate || '--' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>当前状态:</label>
|
||||
<el-tag :type="statusTagType">
|
||||
{{ getStatusText(state.certificateData.status) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 区块链信息 -->
|
||||
<div class="blockchain-info" >
|
||||
<div class="info-item">
|
||||
<i class="el-icon-cpu"></i>
|
||||
<span>区块高度:{{ state.certificateData.blockchainTxId.length }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<i class="el-icon-timer"></i>
|
||||
<span>详情:{{ state.certificateData.certificateData }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<i class="el-icon-document-checked"></i>
|
||||
<span>交易哈希:{{ shortenHash(state.certificateData.blockchainTxId) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="blockchain-info" >
|
||||
<el-image
|
||||
style="width: 300px; height: 200px;display: block;margin: 0 auto"
|
||||
:src="state.certificateData.img"
|
||||
fit="cover"
|
||||
:preview-teleported="true"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 使用说明 -->
|
||||
<div class="usage-guide">
|
||||
|
||||
<el-steps :active="2" align-center>
|
||||
<el-step title="获取区块ID" description="从证书详情页复制区块ID" />
|
||||
<el-step title="输入验证" description="在输入框中粘贴区块ID" />
|
||||
<el-step title="查看结果" description="获取证书验证信息" />
|
||||
</el-steps>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const blockchainId = ref('')
|
||||
const resultVisible = ref(false)
|
||||
const isValid = ref(false)
|
||||
const certificateData = ref<any>({})
|
||||
const blockchainInfo = ref<any>({})
|
||||
|
||||
const state =reactive(<any>{
|
||||
certificateData:{}
|
||||
})
|
||||
|
||||
const getStatusText = (status: number | string) => {
|
||||
switch (String(status)) {
|
||||
case '1':
|
||||
return '有效'
|
||||
case '0':
|
||||
return '撤销'
|
||||
case '2':
|
||||
return '过期'
|
||||
default:
|
||||
return '--'
|
||||
}
|
||||
}
|
||||
// 状态标签类型
|
||||
const statusTagType = computed(() => {
|
||||
const status = certificateData.value.status
|
||||
switch (status) {
|
||||
case 1:
|
||||
return 'success' // 绿色 - 代表“有效”
|
||||
case 0:
|
||||
return 'info' // 灰色 - 代表“撤销”
|
||||
case 2:
|
||||
return 'warning' // 橙色 - 代表“过期”
|
||||
default:
|
||||
return 'danger' // 红色 - 代表未知状态
|
||||
}
|
||||
})
|
||||
|
||||
// 验证结果标题
|
||||
const resultTitle = computed(() => {
|
||||
return isValid.value ? '证书验证通过' : '证书验证失败'
|
||||
})
|
||||
|
||||
// 处理验证
|
||||
const handleVerify = async () => {
|
||||
if (!blockchainId.value) {
|
||||
ElMessage.warning('请输入区块ID')
|
||||
return
|
||||
}
|
||||
// 模拟验证请求
|
||||
frontRequest.get(`/api/certificate/${blockchainId.value}`).then(res =>{
|
||||
state.certificateData = res.data
|
||||
blockchainInfo.value = res.data.blockchain
|
||||
isValid.value =true
|
||||
resultVisible.value = true
|
||||
})
|
||||
}
|
||||
|
||||
// 缩短哈希显示
|
||||
const shortenHash = (hash: string) => {
|
||||
return hash ? `${hash.substring(0, 8)}...${hash.substring(hash.length - 8)}` : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.certificate-verify-container {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
padding: 2rem;
|
||||
background: linear-gradient(135deg, #f8f9fa, #ffffff);
|
||||
overflow: hidden;
|
||||
|
||||
.blockchain-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
.chain-line {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, #409EFF 50%, transparent);
|
||||
animation: chainFlow 3s linear infinite;
|
||||
|
||||
&:nth-child(1) { top: 20%; width: 80%; }
|
||||
&:nth-child(2) { top: 50%; width: 60%; }
|
||||
&:nth-child(3) { top: 80%; width: 70%; }
|
||||
|
||||
&.delay-1 { animation-delay: -1s; }
|
||||
&.delay-2 { animation-delay: -2s; }
|
||||
}
|
||||
}
|
||||
|
||||
.verify-content {
|
||||
position: relative;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 1.5rem;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.verify-title {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
color: #1a237e;
|
||||
font-size: 2rem;
|
||||
|
||||
i {
|
||||
font-size: 2.5rem;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.verify-form {
|
||||
margin: 2rem 0;
|
||||
|
||||
.blockchain-input {
|
||||
:deep(.el-input__inner) {
|
||||
height: 50px;
|
||||
font-size: 1rem;
|
||||
border-radius: 12px;
|
||||
padding-left: 2.5rem;
|
||||
}
|
||||
|
||||
.el-input__prefix {
|
||||
left: 12px;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
.verify-btn {
|
||||
height: 50px;
|
||||
padding: 0 2rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 0 12px 12px 0;
|
||||
background: linear-gradient(135deg, #409EFF, #1a237e);
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.verify-result {
|
||||
margin: 2rem 0;
|
||||
|
||||
.result-card {
|
||||
padding: 2rem;
|
||||
border-radius: 1rem;
|
||||
background: #f8f9fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
|
||||
&.valid {
|
||||
border-left: 6px solid #67c23a;
|
||||
}
|
||||
|
||||
&.invalid {
|
||||
border-left: 6px solid #f56c6c;
|
||||
}
|
||||
|
||||
.result-icon {
|
||||
i {
|
||||
font-size: 3rem;
|
||||
|
||||
&.el-icon-success {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
&.el-icon-error {
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-content {
|
||||
flex: 1;
|
||||
|
||||
h3 {
|
||||
margin: 0 0 1rem 0;
|
||||
color: #1a237e;
|
||||
}
|
||||
|
||||
.result-details {
|
||||
.detail-item {
|
||||
margin: 0.5rem 0;
|
||||
|
||||
label {
|
||||
color: #666;
|
||||
min-width: 80px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blockchain-info {
|
||||
margin-top: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-radius: 1rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
i {
|
||||
font-size: 1.2rem;
|
||||
color: #409EFF;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.usage-guide {
|
||||
margin-top: 3rem;
|
||||
|
||||
h3 {
|
||||
text-align: center;
|
||||
color: #1a237e;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
i {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-step) {
|
||||
.el-step__head {
|
||||
.el-step__icon {
|
||||
background: #409EFF;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.el-step__title {
|
||||
color: #1a237e;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.el-step__description {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes chainFlow {
|
||||
from { left: -100%; }
|
||||
to { left: 100%; }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.certificate-verify-container {
|
||||
padding: 1rem;
|
||||
|
||||
.verify-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.verify-form {
|
||||
.blockchain-input {
|
||||
:deep(.el-input__inner) {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.verify-btn {
|
||||
padding: 0 1rem;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blockchain-info {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"layout": "front"
|
||||
}
|
||||
}
|
||||
</route>
|
@ -1,30 +1,17 @@
|
||||
<template>
|
||||
<div class="certificate-container">
|
||||
<!-- 区块链装饰元素 -->
|
||||
<div class="blockchain-decor">
|
||||
<div class="chain-line"></div>
|
||||
<div class="chain-line delay-1"></div>
|
||||
<div class="chain-line delay-2"></div>
|
||||
</div>
|
||||
|
||||
<h2 class="page-title">
|
||||
<i class="el-icon-connection"></i>
|
||||
区块链证书存证
|
||||
<div class="sub-title">数据上链后永久保存,不可篡改</div>
|
||||
</h2>
|
||||
|
||||
<el-form
|
||||
label-position="right"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
class="certificate-form"
|
||||
label-width="auto"
|
||||
>
|
||||
<!-- 表单内容 -->
|
||||
<el-form-item label="证书编号" prop="certificateNumber">
|
||||
<div style="width: 60%;margin: 0 auto">
|
||||
<el-form-item label="名称:" prop="name">
|
||||
<el-input
|
||||
v-model="form.certificateNumber"
|
||||
placeholder="请输入证书编号"
|
||||
v-model="form.name"
|
||||
placeholder="请输入证书名称"
|
||||
class="block-input"
|
||||
>
|
||||
<template #prefix>
|
||||
@ -32,120 +19,106 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="公司/组织:" prop="company">
|
||||
<el-input
|
||||
v-model="form.company"
|
||||
placeholder="请输入公司/组织"
|
||||
class="block-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-document"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="部门:" prop="department">
|
||||
<el-input
|
||||
v-model="form.department"
|
||||
placeholder="请输入部门"
|
||||
class="block-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-document"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="角色:" prop="role">
|
||||
<el-input
|
||||
v-model="form.role"
|
||||
placeholder="请输入角色"
|
||||
class="block-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-document"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="资质证明:" prop="role">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
style="width: 100%"
|
||||
drag
|
||||
:action="state.path"
|
||||
multiple
|
||||
limit=1
|
||||
>
|
||||
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<div class="form-row">
|
||||
<el-form-item label="签发日期" prop="issueDate" class="date-picker">
|
||||
<el-form-item label="生效时间:" prop="issueDate">
|
||||
<el-date-picker
|
||||
style="width: 100%"
|
||||
v-model="form.issueDate"
|
||||
type="datetime"
|
||||
placeholder="选择签发日期"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-date"></i>
|
||||
</template>
|
||||
</el-date-picker>
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="过期日期" prop="expireDate" class="date-picker">
|
||||
<el-form-item label="过期时间:" prop="expireDate">
|
||||
<el-date-picker
|
||||
style="width: 100%"
|
||||
v-model="form.expireDate"
|
||||
type="datetime"
|
||||
placeholder="选择过期日期"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
format="YYYY-MM-DD"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="公钥:" prop="hex">
|
||||
<el-input
|
||||
v-model="form.hex"
|
||||
placeholder="请输入公钥"
|
||||
class="block-input"
|
||||
>
|
||||
<template #prefix>
|
||||
<i class="el-icon-time"></i>
|
||||
<i class="el-icon-document"></i>
|
||||
</template>
|
||||
</el-date-picker>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm">提交</el-button>
|
||||
<el-button @click="resetForm">删除</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
|
||||
<el-form-item label="证书详情" prop="certificateData">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="form.certificateData"
|
||||
placeholder="请输入证书详情"
|
||||
:rows="4"
|
||||
class="block-textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="证书图片" prop="img">
|
||||
<image-upload
|
||||
@update:imageUrl="handleImageUrl"
|
||||
:image-url="form.img"
|
||||
class="block-uploader"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="submitForm"
|
||||
class="submit-btn"
|
||||
>
|
||||
<i class="el-icon-upload"></i>
|
||||
提交上链
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="resetForm"
|
||||
class="reset-btn"
|
||||
>
|
||||
<i class="el-icon-refresh"></i>
|
||||
重置表单
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 区块链特性说明 -->
|
||||
<div class="blockchain-features">
|
||||
<div class="feature-item">
|
||||
<i class="el-icon-lock"></i>
|
||||
<h3>数据安全</h3>
|
||||
<p>采用区块链加密技术保障信息安全</p>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<i class="el-icon-coin"></i>
|
||||
<h3>永久存证</h3>
|
||||
<p>数据一旦上链将永久保存不可篡改</p>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<i class="el-icon-share"></i>
|
||||
<h3>可信验证</h3>
|
||||
<p>可通过区块链浏览器验证证书真伪</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const form = reactive(<any>{})
|
||||
|
||||
const form = reactive({
|
||||
certificateNumber: '',
|
||||
issueDate: '',
|
||||
expireDate: '',
|
||||
certificateData: '',
|
||||
img: ''
|
||||
const state = reactive({
|
||||
path:import.meta.env.VITE_API_FRONT_BASE_URL + "/api/upload",
|
||||
})
|
||||
|
||||
const rules = {
|
||||
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
||||
issueDate: [{ required: true, message: '请选择签发日期', trigger: 'change' }],
|
||||
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
|
||||
certificateData: [{ required: true, message: '请输入证书详情', trigger: 'blur' }],
|
||||
img: [{ required: true, message: '请上传证书图片', trigger: 'change' }]
|
||||
}
|
||||
|
||||
function handleImageUrl(path: string) {
|
||||
form.img = path
|
||||
certificateData: [{ required: true, message: '请输入证书详情', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const submitForm = () => {
|
||||
@ -158,7 +131,7 @@ const submitForm = () => {
|
||||
<h3>请确认证书信息</h3>\
|
||||
<p>数据上链后不可修改,请仔细核对以下信息:</p>\
|
||||
<ul>\
|
||||
<li>证书编号:'+form.certificateNumber+'</li>\
|
||||
<li>名称:'+form.name+'</li>\
|
||||
<li>签发日期:'+form.issueDate+'</li>\
|
||||
</ul>\
|
||||
</div>',
|
||||
@ -196,232 +169,14 @@ const submitForm = () => {
|
||||
const resetForm = () => {
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields()
|
||||
form.img = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.certificate-container {
|
||||
position: relative;
|
||||
max-width: 800px;
|
||||
margin: 2rem auto;
|
||||
padding: 2.5rem;
|
||||
background: rgba(255,255,255,0.95);
|
||||
border-radius: 1.5rem;
|
||||
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
z-index: 1;
|
||||
|
||||
.blockchain-decor {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
.chain-line {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, #409EFF 50%, transparent);
|
||||
animation: chainFlow 3s linear infinite;
|
||||
|
||||
&:nth-child(1) { top: 20%; width: 80%; }
|
||||
&:nth-child(2) { top: 50%; width: 60%; }
|
||||
&:nth-child(3) { top: 80%; width: 70%; }
|
||||
|
||||
&.delay-1 { animation-delay: -1s; }
|
||||
&.delay-2 { animation-delay: -2s; }
|
||||
}
|
||||
}
|
||||
|
||||
.page-title {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
color: #1a237e;
|
||||
font-size: 2rem;
|
||||
position: relative;
|
||||
|
||||
.el-icon-connection {
|
||||
font-size: 2.5rem;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.certificate-form {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.form-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
:deep(.block-input) {
|
||||
.el-input__inner {
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 0.75rem;
|
||||
padding-left: 2.5rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #409EFF;
|
||||
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__prefix {
|
||||
left: 12px;
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
.block-textarea {
|
||||
:deep(.el-textarea__inner) {
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-radius: 0.75rem;
|
||||
min-height: 100px;
|
||||
resize: vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 2rem;
|
||||
text-align: center;
|
||||
|
||||
.submit-btn {
|
||||
padding: 12px 30px;
|
||||
font-size: 1rem;
|
||||
background: linear-gradient(135deg, #409EFF, #1a237e);
|
||||
border: none;
|
||||
border-radius: 0.75rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
padding: 12px 30px;
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-color: #e0e0e0;
|
||||
border-radius: 0.75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blockchain-features {
|
||||
margin-top: 3rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2rem;
|
||||
|
||||
.feature-item {
|
||||
text-align: center;
|
||||
padding: 1.5rem;
|
||||
background: rgba(245, 247, 250, 0.8);
|
||||
border-radius: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 6px 16px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 2.5rem;
|
||||
color: #409EFF;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #1a237e;
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes chainFlow {
|
||||
from { left: -100%; }
|
||||
to { left: 100%; }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.certificate-container {
|
||||
margin: 1rem;
|
||||
padding: 1.5rem;
|
||||
|
||||
.form-row {
|
||||
grid-template-columns: 1fr !important;
|
||||
}
|
||||
|
||||
.blockchain-features {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
/* 全局弹窗样式 */
|
||||
.chain-confirm-dialog {
|
||||
border-radius: 1rem !important;
|
||||
background: linear-gradient(135deg, #f8f9fa, #ffffff) !important;
|
||||
|
||||
.confirm-box {
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
font-size: 3rem;
|
||||
color: #409EFF;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #1a237e;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
text-align: left;
|
||||
padding-left: 1.5rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chain-success-msg {
|
||||
background: linear-gradient(135deg, #409EFF, #1a237e) !important;
|
||||
color: white !important;
|
||||
border-radius: 0.75rem !important;
|
||||
}
|
||||
|
||||
.form-error-msg {
|
||||
background: #fff5f5 !important;
|
||||
border: 1px solid #ffc4c4 !important;
|
||||
color: #ff4444 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
{
|
||||
|
@ -1,445 +1,66 @@
|
||||
<template>
|
||||
<div class="audit-record-container">
|
||||
<!-- 区块链装饰背景 -->
|
||||
<div class="blockchain-background">
|
||||
<div class="chain-line"></div>
|
||||
<div class="chain-line delay-1"></div>
|
||||
<div class="chain-line delay-2"></div>
|
||||
</div>
|
||||
|
||||
<!-- 审核记录主内容 -->
|
||||
<div class="audit-content">
|
||||
<h2 class="audit-title">
|
||||
<i class="el-icon-notebook-2"></i>
|
||||
证书审核记录
|
||||
<div class="sub-title">查看您的证书审核历史记录</div>
|
||||
</h2>
|
||||
|
||||
<!-- 筛选条件 -->
|
||||
<div class="filter-bar">
|
||||
<el-select
|
||||
v-model="filter.auditStatus"
|
||||
placeholder="按状态筛选"
|
||||
class="auditStatus-filter"
|
||||
clearable
|
||||
<el-table :data="state.tableData" style="width: 100%" align="center">
|
||||
<el-table-column prop="id" label="ID" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="hex" label="身份信息哈希值" width="180" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="name" label="颁发者" show-overflow-tooltip align="center" />
|
||||
<el-table-column prop="issueDate" label="证书生效时间" width="120" align="center" />
|
||||
<el-table-column prop="expireDate" label="证书过期时间" width="120" align="center"/>
|
||||
<el-table-column prop="status" label="证书状态" />
|
||||
<el-table-column label="操作项" min-width="180" align="center">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.prevent="deleteRow(scope.$index)"
|
||||
>
|
||||
<el-option label="待审核" :value="0" />
|
||||
<el-option label="审核通过" :value="1" />
|
||||
<el-option label="审核拒绝" :value="2" />
|
||||
</el-select>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 审核记录列表 -->
|
||||
<div class="record-list">
|
||||
<el-card
|
||||
v-for="record in filteredRecords"
|
||||
:key="record.id"
|
||||
class="record-card"
|
||||
:class="record.auditStatusClass"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="record-auditStatus">
|
||||
<i :class="record.auditStatusIcon"></i>
|
||||
<span>{{ record.auditStatusText }}</span>
|
||||
</div>
|
||||
<div class="record-date">
|
||||
{{ record.createdAt }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div class="record-info">
|
||||
<div class="info-item">
|
||||
<label>证书编号:</label>
|
||||
<span>{{ record.certificateNumber }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>签发日期:</label>
|
||||
<span>{{ record.issueDate }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<label>过期日期:</label>
|
||||
<span>{{ record.expireDate || '--' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="audit-comment" v-if="record.auditComments">
|
||||
<i class="el-icon-chat-line-round"></i>
|
||||
<span>审核意见:{{ record.auditComments }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<el-button type="text" @click="viewDetail(record)" class="detail-btn">
|
||||
<i class="el-icon-view"></i>
|
||||
查看详情
|
||||
生成签名信息
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<div class="empty-state" v-if="filteredRecords.length === 0">
|
||||
<i class="el-icon-document-remove"></i>
|
||||
<p>暂无审核记录</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 查看详情弹窗 -->
|
||||
<el-dialog
|
||||
v-model="detailDialogVisible"
|
||||
title="审核记录详情"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
size="small"
|
||||
@click.prevent="deleteRow(scope.$index)"
|
||||
>
|
||||
<div class="detail-content" v-if="selectedRecord">
|
||||
<div class="detail-item">
|
||||
<label>证书编号:</label>
|
||||
<span>{{ selectedRecord.certificateNumber }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>签发日期:</label>
|
||||
<span>{{ selectedRecord.issueDate }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>过期日期:</label>
|
||||
<span>{{ selectedRecord.expireDate || '--' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>审核状态:</label>
|
||||
<el-tag :type="getAuditTagType(selectedRecord.auditStatus)">
|
||||
{{ getAuditStatusText(selectedRecord.auditStatus) }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="detail-item" v-if="selectedRecord.auditComments">
|
||||
<label>审核意见:</label>
|
||||
<span>{{ selectedRecord.auditComments }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>记录日期:</label>
|
||||
<span>{{ selectedRecord.createdAt }}</span>
|
||||
</div>
|
||||
|
||||
<div class="detail-item">
|
||||
|
||||
|
||||
<el-image :src="selectedRecord.img"></el-image>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="detailDialogVisible = false">关闭</el-button>
|
||||
下载证书
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
// 模拟数据
|
||||
const records = ref([
|
||||
])
|
||||
|
||||
// 筛选条件
|
||||
const filter = ref({
|
||||
auditStatus: null,
|
||||
dateRange: []
|
||||
const state = reactive({
|
||||
tableData:[
|
||||
{
|
||||
id:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
hex:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
name:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
issueDate:"2023-10-25",
|
||||
expireDate:"2025-10-25",
|
||||
status:"已通过",
|
||||
}, {
|
||||
id:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
hex:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
name:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
issueDate:"2023-10-25",
|
||||
expireDate:"2025-10-25",
|
||||
status:"已通过",
|
||||
}, {
|
||||
id:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
hex:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
name:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||
issueDate:"2023-10-25",
|
||||
expireDate:"2025-10-25",
|
||||
status:"已通过",
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// 审核状态配置
|
||||
const auditStatusConfig = {
|
||||
0: { text: '待审核', icon: 'el-icon-time', class: 'pending' },
|
||||
1: { text: '通过', icon: 'el-icon-success', class: 'approved' },
|
||||
2: { text: '拒绝', icon: 'el-icon-error', class: 'rejected' }
|
||||
}
|
||||
|
||||
// 处理后的记录数据
|
||||
const processedRecords = computed(() => {
|
||||
return records.value.map(record => {
|
||||
const auditStatusInfo = auditStatusConfig[record.auditStatus] || {}
|
||||
return {
|
||||
...record,
|
||||
auditStatusText: auditStatusInfo.text,
|
||||
auditStatusIcon: auditStatusInfo.icon,
|
||||
auditStatusClass: auditStatusInfo.class
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// 筛选后的记录
|
||||
const filteredRecords = computed(() => {
|
||||
return processedRecords.value.filter(record => {
|
||||
// 状态筛选
|
||||
if (filter.value.auditStatus !== null && record.auditStatus !== filter.value.auditStatus) {
|
||||
return false
|
||||
}
|
||||
// 日期筛选
|
||||
if (filter.value.dateRange && filter.value.dateRange.length === 2) {
|
||||
const [start, end] = filter.value.dateRange
|
||||
const recordDate = new Date(record.createdAt)
|
||||
if (recordDate < new Date(start) || recordDate > new Date(end)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
})
|
||||
|
||||
// 查看详情弹窗相关
|
||||
const detailDialogVisible = ref(false)
|
||||
const selectedRecord = ref<any>(null)
|
||||
|
||||
const viewDetail = (record: any) => {
|
||||
selectedRecord.value = record
|
||||
detailDialogVisible.value = true
|
||||
}
|
||||
|
||||
// 辅助方法:返回审核状态文字
|
||||
const getAuditStatusText = (status: number) => {
|
||||
const mapping: { [key: number]: string } = {
|
||||
0: '待审核',
|
||||
1: '通过',
|
||||
2: '拒绝'
|
||||
}
|
||||
return mapping[status] || '--'
|
||||
}
|
||||
|
||||
// 辅助方法:返回审核状态对应的标签类型
|
||||
const getAuditTagType = (status: number) => {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return 'warning'
|
||||
case 1:
|
||||
return 'success'
|
||||
case 2:
|
||||
return 'danger'
|
||||
default:
|
||||
return 'info'
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据(模拟接口请求)
|
||||
function init() {
|
||||
|
||||
frontRequest.get("/api/certificate/page", { params: { limit: 999 } }).then(res => {
|
||||
records.value = res.data.list
|
||||
})
|
||||
}
|
||||
init()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.audit-record-container {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
padding: 2rem;
|
||||
background: linear-gradient(135deg, #f8f9fa, #ffffff);
|
||||
overflow: hidden;
|
||||
|
||||
.blockchain-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
.chain-line {
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent, #409EFF 50%, transparent);
|
||||
animation: chainFlow 3s linear infinite;
|
||||
|
||||
&:nth-child(1) { top: 20%; width: 80%; }
|
||||
&:nth-child(2) { top: 50%; width: 60%; }
|
||||
&:nth-child(3) { top: 80%; width: 70%; }
|
||||
|
||||
&.delay-1 { animation-delay: -1s; }
|
||||
&.delay-2 { animation-delay: -2s; }
|
||||
}
|
||||
}
|
||||
|
||||
.audit-content {
|
||||
position: relative;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 1.5rem;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.audit-title {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
color: #1a237e;
|
||||
font-size: 2rem;
|
||||
|
||||
i {
|
||||
font-size: 2.5rem;
|
||||
vertical-align: middle;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
|
||||
.auditStatus-filter,
|
||||
.date-filter {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.record-list {
|
||||
.record-card {
|
||||
margin-bottom: 1.5rem;
|
||||
border-left: 6px solid transparent;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&.pending { border-color: #e6a23c; background: #fffaf0; }
|
||||
&.approved { border-color: #67c23a; background: #f0fff4; }
|
||||
&.rejected { border-color: #f56c6c; background: #fff0f0; }
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
.record-auditStatus {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
i {
|
||||
font-size: 1.2rem;
|
||||
&.el-icon-success { color: #67c23a; }
|
||||
&.el-icon-error { color: #f56c6c; }
|
||||
&.el-icon-time { color: #e6a23c; }
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.record-date {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 1rem 0;
|
||||
|
||||
.record-info {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.info-item {
|
||||
label {
|
||||
color: #666;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.audit-comment {
|
||||
padding: 1rem;
|
||||
background: #f8f9fa;
|
||||
border-radius: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
i {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
text-align: right;
|
||||
|
||||
.detail-btn {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 3rem;
|
||||
color: #666;
|
||||
|
||||
i {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes chainFlow {
|
||||
from { left: -100%; }
|
||||
to { left: 100%; }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.audit-record-container {
|
||||
padding: 1rem;
|
||||
|
||||
.audit-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 弹窗详情样式 */
|
||||
.detail-content {
|
||||
.detail-item {
|
||||
margin-bottom: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
label {
|
||||
width: 120px;
|
||||
font-weight: bold;
|
||||
color: #555;
|
||||
}
|
||||
span {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<route lang="json">
|
||||
|
@ -71,7 +71,7 @@ const onLogin = () => {
|
||||
<style scoped>
|
||||
.module_r {
|
||||
width: 100%;
|
||||
background: url("/ec13203e-20ee-4bb3-ba23-f0b6f93d3760.jpg");
|
||||
background: url("/508d288b-cd6e-4814-a99f-53a3999c4261.jpg");
|
||||
background-size: 100% 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
|
@ -21,21 +21,53 @@
|
||||
<input class="module_input" type="password" placeholder="再次输入密码" v-model="register.confirmPassword" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="forgetpwd" @click="router.push('/login')">有账号?</div>
|
||||
<button class="module_button" @click="onRegister">注册</button>
|
||||
</div>
|
||||
|
||||
<!-- 注册成功弹窗 -->
|
||||
<el-dialog
|
||||
v-model="showKeyDialog"
|
||||
title="注册成功"
|
||||
width="50%"
|
||||
>
|
||||
<el-form label-width="auto" style="max-width: 600px">
|
||||
<el-form-item label="账户地址">
|
||||
<el-input v-model="state.getUserInfo.hex" />
|
||||
</el-form-item>
|
||||
<el-form-item label="公钥">
|
||||
<el-input type="password" show-password v-model="state.getUserInfo.publicKey" />
|
||||
</el-form-item>
|
||||
<el-form-item label="私钥">
|
||||
<el-input v-model="state.getUserInfo.privateKey" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="showKeyDialog = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useRouter } from "vue-router";
|
||||
import { registerFront } from '~/api/user/frontUserApi'
|
||||
const router = useRouter();
|
||||
const register = reactive({
|
||||
username: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
})
|
||||
const showKeyDialog = ref(true)
|
||||
const state = reactive({
|
||||
getUserInfo:{
|
||||
"hex": "1893836584118175698",
|
||||
"nickName": "12345678",
|
||||
"publicKey": "MIIBIjANBgkqhkiG9w0BAQ",
|
||||
"privateKey": "MBAAECggE",
|
||||
"username": "12345678"
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 注册成功
|
||||
@ -45,9 +77,25 @@ const onRegister = () => {
|
||||
ElMessage.warning("不能创建账号Admin")
|
||||
return
|
||||
}
|
||||
registerFront(register).then(() =>{
|
||||
frontRequest.post("/api/user/register", register).then(res =>{
|
||||
ElMessage.success("注册成功~")
|
||||
router.push("/login")
|
||||
state.getUserInfo = res.data
|
||||
showKeyDialog.value = true
|
||||
// router.push("/login")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 复制所有密钥信息
|
||||
*/
|
||||
const copyAllKeys = () => {
|
||||
const text = `账号地址: ${state.getUserInfo.hex}\n公钥: ${state.getUserInfo.publicKey}\n私钥: ${state.getUserInfo.privateKey}`
|
||||
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
ElMessage.success('已复制到剪贴板')
|
||||
}).catch(err => {
|
||||
ElMessage.error('复制失败: ' + err)
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@ -58,7 +106,7 @@ const onRegister = () => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background: url("/ec13203e-20ee-4bb3-ba23-f0b6f93d3760.jpg");
|
||||
background: url("/508d288b-cd6e-4814-a99f-53a3999c4261.jpg");
|
||||
background-size: 100% 100%;
|
||||
.module_mian{
|
||||
width: 26%;
|
||||
|
@ -1,93 +0,0 @@
|
||||
<!--用户详情-->
|
||||
<template>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
style="max-width: 600px"
|
||||
:model="state.userInfo"
|
||||
label-width="auto"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item
|
||||
prop="username"
|
||||
label="用户名"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '用户名不能为空',
|
||||
trigger: 'blur',
|
||||
},
|
||||
|
||||
]"
|
||||
>
|
||||
<el-input v-model="state.userInfo.username" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
prop="nickName"
|
||||
label="用户昵称"
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '用户昵称不能为空',
|
||||
trigger: 'blur',
|
||||
}
|
||||
]"
|
||||
>
|
||||
<el-input v-model="state.userInfo.nickName" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
prop="password"
|
||||
label="密码"
|
||||
|
||||
>
|
||||
<el-input v-model="state.userInfo.password" type="password"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submitForm(formRef)">提交</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { reactive } from 'vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import { userInfoFront, userUpdateFront } from '~/api/user/frontUserApi'
|
||||
const formRef = ref<FormInstance>()
|
||||
const state = reactive({
|
||||
userInfo: {}
|
||||
})
|
||||
function init() {
|
||||
userInfoFront().then(res =>{
|
||||
state.userInfo = res.data
|
||||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 提交
|
||||
* @param formEl
|
||||
*/
|
||||
const submitForm = (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
formEl.validate((valid) => {
|
||||
if (valid) {
|
||||
userUpdateFront(state.userInfo).then(res =>{
|
||||
toast.success("修改成功~")
|
||||
init()
|
||||
}).catch(err=>{
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<route lang="json">
|
||||
{
|
||||
"meta": {
|
||||
"layout": "frontUserInfo"
|
||||
}
|
||||
}
|
||||
</route>
|
@ -8,22 +8,22 @@ export const getAdminList = () => {
|
||||
},
|
||||
{
|
||||
path: "/admin/certificates",
|
||||
name: "证书管理",
|
||||
name: "证书验证",
|
||||
icon: "Postcard",
|
||||
},
|
||||
{
|
||||
path: "/admin/block",
|
||||
name: "上链信息",
|
||||
name: "证书查询",
|
||||
icon: "Postcard",
|
||||
},
|
||||
{
|
||||
path: "/admin/log",
|
||||
name: "申请记录",
|
||||
path: "/admin/user",
|
||||
name: "个人中心",
|
||||
icon: "Postcard",
|
||||
},
|
||||
{
|
||||
path: "/admin/adminuser",
|
||||
name: "用户管理",
|
||||
path: "/admin/about",
|
||||
name: "关于我们",
|
||||
icon: "Notification",
|
||||
}
|
||||
];
|
||||
@ -33,28 +33,28 @@ export const getFrontList = () => {
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "证书信息",
|
||||
icon: "Dashboard",
|
||||
name: "首页",
|
||||
icon: "House",
|
||||
},
|
||||
{
|
||||
path: "/load",
|
||||
name: "证书提交",
|
||||
icon: "Dashboard",
|
||||
name: "证书申请",
|
||||
icon: "Notification",
|
||||
},
|
||||
{
|
||||
path: "/log",
|
||||
name: "审核记录",
|
||||
icon: "ShoppingCart",
|
||||
name: "证书查询",
|
||||
icon: "MessageBox",
|
||||
},
|
||||
{
|
||||
path: "/audit",
|
||||
name: "证书验证",
|
||||
icon: "Warehouse",
|
||||
path: "/user",
|
||||
name: "个人中心",
|
||||
icon: "MapLocation",
|
||||
},
|
||||
{
|
||||
path: "/look",
|
||||
name: "查看证书",
|
||||
icon: "Warehouse",
|
||||
path: "/about",
|
||||
name: "关于我们",
|
||||
icon: "ScaleToOriginal",
|
||||
}
|
||||
]
|
||||
return routes;
|
||||
|
Loading…
Reference in New Issue
Block a user