add
This commit is contained in:
parent
12f367e96e
commit
867e86bd7b
@ -38,10 +38,8 @@ public class Oauth2Realm extends AuthorizingRealm {
|
|||||||
@Override
|
@Override
|
||||||
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
|
||||||
UserDetail user = (UserDetail) principals.getPrimaryPrincipal();
|
UserDetail user = (UserDetail) principals.getPrimaryPrincipal();
|
||||||
|
|
||||||
//用户权限列表
|
//用户权限列表
|
||||||
Set<String> permsSet = shiroService.getUserPermissions(user);
|
Set<String> permsSet = shiroService.getUserPermissions(user);
|
||||||
|
|
||||||
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
|
||||||
info.setStringPermissions(permsSet);
|
info.setStringPermissions(permsSet);
|
||||||
return info;
|
return info;
|
||||||
@ -63,9 +61,6 @@ public class Oauth2Realm extends AuthorizingRealm {
|
|||||||
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
|
SysUserEntity userEntity = shiroService.getUser(tokenEntity.getUserId());
|
||||||
//转换成UserDetail对象
|
//转换成UserDetail对象
|
||||||
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
|
UserDetail userDetail = ConvertUtils.sourceToTarget(userEntity, UserDetail.class);
|
||||||
//获取用户对应的部门数据权限
|
|
||||||
List<Long> deptIdList = shiroService.getDataScopeList(userDetail.getId());
|
|
||||||
userDetail.setDeptIdList(deptIdList);
|
|
||||||
//账号锁定
|
//账号锁定
|
||||||
if (userDetail.getStatus() == 0) {
|
if (userDetail.getStatus() == 0) {
|
||||||
throw new LockedAccountException("账号已被锁定!");
|
throw new LockedAccountException("账号已被锁定!");
|
||||||
|
@ -28,10 +28,5 @@ public interface ShiroService {
|
|||||||
*/
|
*/
|
||||||
SysUserEntity getUser(Long userId);
|
SysUserEntity getUser(Long userId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取用户对应的部门数据权限
|
|
||||||
* @param userId 用户ID
|
|
||||||
* @return 返回部门ID列表
|
|
||||||
*/
|
|
||||||
List<Long> getDataScopeList(Long userId);
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
package io.modules.security.service.impl;
|
package io.modules.security.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
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.entity.SysUserTokenEntity;
|
||||||
import io.modules.security.service.ShiroService;
|
import io.modules.security.service.ShiroService;
|
||||||
import io.modules.security.user.UserDetail;
|
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.dao.SysUserDao;
|
||||||
import io.modules.sys.entity.SysUserEntity;
|
import io.modules.sys.entity.SysUserEntity;
|
||||||
import io.modules.sys.enums.SuperAdminEnum;
|
import io.modules.sys.enums.SuperAdminEnum;
|
||||||
@ -23,30 +19,14 @@ import java.util.Set;
|
|||||||
@Service
|
@Service
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ShiroServiceImpl implements ShiroService {
|
public class ShiroServiceImpl implements ShiroService {
|
||||||
private final SysMenuDao sysMenuDao;
|
|
||||||
private final SysUserDao sysUserDao;
|
private final SysUserDao sysUserDao;
|
||||||
private final SysUserTokenDao sysUserTokenDao;
|
private final SysUserTokenDao sysUserTokenDao;
|
||||||
private final SysRoleDataScopeDao sysRoleDataScopeDao;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getUserPermissions(UserDetail user) {
|
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<>();
|
Set<String> permsSet = new HashSet<>();
|
||||||
for (String permissions : permissionsList) {
|
|
||||||
if (StrUtil.isBlank(permissions)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
permsSet.addAll(Arrays.asList(permissions.trim().split(",")));
|
|
||||||
}
|
|
||||||
|
|
||||||
return permsSet;
|
return permsSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,8 +40,5 @@ public class ShiroServiceImpl implements ShiroService {
|
|||||||
return sysUserDao.selectById(userId);
|
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;
|
private SetRequestService setRequestService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private FrontUserService userService;
|
private FrontUserService userService;
|
||||||
@Value("${upload.url}")
|
|
||||||
private String uploadUrl;
|
|
||||||
|
|
||||||
@GetMapping("page")
|
@GetMapping("page")
|
||||||
@Operation(summary = "分页")
|
@Operation(summary = "分页")
|
||||||
@ -55,8 +54,6 @@ public class CertificatesController {
|
|||||||
public Result<PageData<CertificatesDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params){
|
public Result<PageData<CertificatesDTO>> page(@Parameter(hidden = true) @RequestParam Map<String, Object> params){
|
||||||
PageData<CertificatesDTO> page = certificatesService.page(params);
|
PageData<CertificatesDTO> page = certificatesService.page(params);
|
||||||
List<CertificatesDTO> collect = page.getList().stream().map(e -> {
|
List<CertificatesDTO> collect = page.getList().stream().map(e -> {
|
||||||
// 拼接域名
|
|
||||||
e.setImg(uploadUrl + e.getImg());
|
|
||||||
Long userId = e.getUserId();
|
Long userId = e.getUserId();
|
||||||
UserDTO userDTO = userService.get(userId);
|
UserDTO userDTO = userService.get(userId);
|
||||||
e.setUser(userDTO);
|
e.setUser(userDTO);
|
||||||
@ -71,8 +68,7 @@ public class CertificatesController {
|
|||||||
public Result save(@RequestBody CertificatesDTO dto){
|
public Result save(@RequestBody CertificatesDTO dto){
|
||||||
//效验数据
|
//效验数据
|
||||||
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
|
||||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
|
||||||
certificatesService.save(dto);
|
|
||||||
return new Result();
|
return new Result();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +77,7 @@ public class CertificatesController {
|
|||||||
public Result update(@RequestBody CertificatesDTO dto){
|
public Result update(@RequestBody CertificatesDTO dto){
|
||||||
//效验数据
|
//效验数据
|
||||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
|
||||||
certificatesService.update(dto);
|
certificatesService.update(dto);
|
||||||
return new Result();
|
return new Result();
|
||||||
}
|
}
|
||||||
@ -91,10 +87,9 @@ public class CertificatesController {
|
|||||||
public Result book(@RequestBody CertificatesDTO dto){
|
public Result book(@RequestBody CertificatesDTO dto){
|
||||||
//效验数据
|
//效验数据
|
||||||
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
|
||||||
dto.setImg(dto.getImg().replace(uploadUrl,""));
|
|
||||||
SetResponse setResponse = setRequestService.sendSetRequest(String.valueOf(dto.getId()), dto.toString());
|
SetResponse setResponse = setRequestService.sendSetRequest(String.valueOf(dto.getId()), dto.toString());
|
||||||
dto.setBlockchainTxId(setResponse.getData());
|
dto.setHex(setResponse.getData());
|
||||||
dto.setIsBlock(1);
|
|
||||||
certificatesService.update(dto);
|
certificatesService.update(dto);
|
||||||
return new Result();
|
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> {
|
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;
|
package io.modules.sys.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
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.dto.SysUserDTO;
|
||||||
import io.modules.sys.entity.SysUserEntity;
|
import io.modules.sys.entity.SysUserEntity;
|
||||||
import io.modules.sys.enums.SuperAdminEnum;
|
import io.modules.sys.enums.SuperAdminEnum;
|
||||||
import io.modules.sys.service.SysDeptService;
|
|
||||||
import io.modules.sys.service.SysRoleUserService;
|
import io.modules.sys.service.SysRoleUserService;
|
||||||
import io.modules.sys.service.SysUserService;
|
import io.modules.sys.service.SysUserService;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@ -36,7 +33,6 @@ import java.util.Map;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
|
public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
|
||||||
private final SysRoleUserService sysRoleUserService;
|
private final SysRoleUserService sysRoleUserService;
|
||||||
private final SysDeptService sysDeptService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageData<SysUserDTO> page(Map<String, Object> params) {
|
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);
|
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);
|
List<SysUserEntity> list = baseDao.getList(params);
|
||||||
|
|
||||||
@ -60,12 +50,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntit
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<SysUserDTO> list(Map<String, Object> params) {
|
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);
|
List<SysUserEntity> entityList = baseDao.getList(params);
|
||||||
|
|
||||||
return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
|
return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
|
||||||
|
@ -3,7 +3,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
#MySQL
|
#MySQL
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
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
|
username: root
|
||||||
password: 123456
|
password: 123456
|
||||||
initial-size: 10
|
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 static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private Long id; // 编号
|
private Long id; // 编号
|
||||||
private Integer isBlock;
|
private Long userId;
|
||||||
private Long certificateNumber; // 证书编号
|
private String name;
|
||||||
|
private String company;
|
||||||
private Long userId; // 用户 ID
|
private String department;
|
||||||
|
private Date issueDate;
|
||||||
private Date issueDate; // 签发日期
|
private Date expireDate;
|
||||||
|
private Integer status;
|
||||||
private Date expireDate; // 过期日期
|
|
||||||
|
|
||||||
private String certificateData; // 详情(JSON 字符串)
|
|
||||||
private String img;
|
private String img;
|
||||||
private String blockchainTxId; // 区块链交易 ID
|
private String role;
|
||||||
|
private String certificateData;
|
||||||
private Integer status; // 1: 有效,0: 撤销,2: 过期
|
private String auditStatus;
|
||||||
|
|
||||||
private Date createdAt; // 创建时间
|
|
||||||
|
|
||||||
private Integer auditStatus;
|
|
||||||
private String auditComments;
|
private String auditComments;
|
||||||
|
private String hex;
|
||||||
|
private Date createdAt;
|
||||||
|
|
||||||
private UserDTO user;
|
private UserDTO user;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.modules.item.dto;
|
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.Schema;
|
||||||
import io.swagger.v3.oas.annotations.media.SchemaProperty;
|
import io.swagger.v3.oas.annotations.media.SchemaProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@ -9,32 +10,17 @@ import java.util.Date;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户
|
* 用户
|
||||||
*
|
|
||||||
* @author Mark #
|
|
||||||
* @since 1.0.0 2025-01-14
|
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Schema(name = "用户")
|
@Schema(name = "用户")
|
||||||
public class UserDTO implements Serializable {
|
public class UserDTO implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@SchemaProperty(name = "id")
|
@SchemaProperty(name = "id")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@SchemaProperty(name = "手机号")
|
|
||||||
private String username;
|
|
||||||
|
|
||||||
@SchemaProperty(name = "密码")
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
@SchemaProperty(name = "创建时间")
|
|
||||||
private Date createDate;
|
|
||||||
|
|
||||||
@SchemaProperty(name = "昵称")
|
|
||||||
private String nickName;
|
private String nickName;
|
||||||
|
private String publicKey;
|
||||||
@SchemaProperty(name = "介绍")
|
private String privateKey;
|
||||||
private String introduce;
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private Date createDate;
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,25 @@
|
|||||||
package io.modules.item.entity;
|
package io.modules.item.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主表
|
* 主表
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("tb_certificates")
|
@TableName("tb_certificates")
|
||||||
public class CertificatesEntity {
|
public class CertificatesEntity {
|
||||||
|
private Long id;
|
||||||
private Long id; // 编号
|
private Long userId;
|
||||||
private Integer isBlock;
|
private String name;
|
||||||
|
private String company;
|
||||||
private Integer auditStatus;
|
private String department;
|
||||||
|
private Date issueDate;
|
||||||
private String auditComments;
|
private Date expireDate;
|
||||||
private Long certificateNumber; // 证书编号
|
private Integer status;
|
||||||
|
|
||||||
private Long userId; // 用户 ID
|
|
||||||
|
|
||||||
private Date issueDate; // 签发日期
|
|
||||||
|
|
||||||
private Date expireDate; // 过期日期
|
|
||||||
|
|
||||||
private String certificateData; // 详情(JSON 字符串)
|
|
||||||
private String img;
|
private String img;
|
||||||
private String blockchainTxId; // 区块链交易 ID
|
private String role;
|
||||||
|
private String auditStatus;
|
||||||
private Integer status; // 1: 有效,0: 撤销,2: 过期
|
private String auditComments;
|
||||||
|
private String hex;
|
||||||
private Date createdAt; // 创建时间
|
private Date createdAt;
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package io.modules.item.entity;
|
package io.modules.item.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@ -14,24 +15,12 @@ public class FrontUserEntity {
|
|||||||
* id
|
* id
|
||||||
*/
|
*/
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
|
||||||
* 手机号
|
|
||||||
*/
|
|
||||||
private String username;
|
|
||||||
/**
|
|
||||||
* 密码
|
|
||||||
*/
|
|
||||||
private String password;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private Date createDate;
|
|
||||||
/**
|
|
||||||
* 昵称
|
|
||||||
*/
|
|
||||||
private String nickName;
|
private String nickName;
|
||||||
/**
|
private String publicKey;
|
||||||
* 介绍
|
private String privateKey;
|
||||||
*/
|
private String username;
|
||||||
private String introduce;
|
@JsonIgnore
|
||||||
|
private String password;
|
||||||
|
private Date createDate;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,38 +13,20 @@ import java.util.Date;
|
|||||||
/**
|
/**
|
||||||
* 用户
|
* 用户
|
||||||
*
|
*
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("tb_user")
|
@TableName("tb_user")
|
||||||
public class UserEntity implements Serializable {
|
public class UserEntity implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户ID
|
|
||||||
*/
|
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
|
||||||
* 昵称
|
|
||||||
*/
|
|
||||||
private String nickName;
|
private String nickName;
|
||||||
/**
|
private String publicKey;
|
||||||
* 介绍
|
private String privateKey;
|
||||||
*/
|
|
||||||
private String introduce;
|
|
||||||
/**
|
|
||||||
* 用户名
|
|
||||||
*/
|
|
||||||
private String username;
|
private String username;
|
||||||
/**
|
|
||||||
* 密码
|
|
||||||
*/
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private String password;
|
private String password;
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private Date createDate;
|
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> {
|
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
|
@Service
|
||||||
public class CertificatesServiceImpl extends CrudServiceImpl<CertificatesDao, CertificatesEntity, CertificatesDTO> implements CertificatesService {
|
public class CertificatesServiceImpl extends CrudServiceImpl<CertificatesDao, CertificatesEntity, CertificatesDTO> implements CertificatesService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserDao userService;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryWrapper<CertificatesEntity> getWrapper(Map<String, Object> params){
|
public QueryWrapper<CertificatesEntity> getWrapper(Map<String, Object> params){
|
||||||
String id = (String)params.get("id");
|
String id = (String)params.get("id");
|
||||||
String status = (String)params.get("status");
|
String status = (String)params.get("status");
|
||||||
String isBlock = (String)params.get("isBlock");
|
|
||||||
String auditStatus = (String)params.get("auditStatus");
|
String auditStatus = (String)params.get("auditStatus");
|
||||||
|
|
||||||
QueryWrapper<CertificatesEntity> wrapper = new QueryWrapper<>();
|
QueryWrapper<CertificatesEntity> wrapper = new QueryWrapper<>();
|
||||||
wrapper.eq(StrUtil.isNotBlank(id), "id", id);
|
wrapper.eq(StrUtil.isNotBlank(id), "id", id);
|
||||||
wrapper.eq(StrUtil.isNotBlank(status), "status", status);
|
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);
|
wrapper.eq(StrUtil.isNotBlank(auditStatus) && !auditStatus.equals("all"), "audit_status", auditStatus);
|
||||||
return wrapper;
|
return wrapper;
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,13 @@ import org.springframework.boot.SpringApplication;
|
|||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||||
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* front
|
* front
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@EnableScheduling
|
||||||
public class FrontApplication extends SpringBootServletInitializer {
|
public class FrontApplication extends SpringBootServletInitializer {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(FrontApplication.class, 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 = "信息")
|
@Operation(summary = "信息")
|
||||||
public Result<CertificatesEntity> get(@PathVariable("id") String id){
|
public Result<CertificatesEntity> get(@PathVariable("id") String id){
|
||||||
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
||||||
lwq.eq(CertificatesEntity::getBlockchainTxId,id);
|
lwq.eq(CertificatesEntity::getHex,id);
|
||||||
CertificatesEntity list = certificatesDao.selectOne(lwq);
|
CertificatesEntity list = certificatesDao.selectOne(lwq);
|
||||||
if (list == null){
|
if (list == null){
|
||||||
return new Result<CertificatesEntity>().error("没有查询到");
|
return new Result<CertificatesEntity>().error("没有查询到");
|
||||||
@ -90,7 +90,6 @@ public class CertificatesController {
|
|||||||
@Operation(summary = "保存")
|
@Operation(summary = "保存")
|
||||||
public Result save(@RequestBody CertificatesDTO dto,@Parameter(hidden = true) @RequestAttribute("userId") Long userId){
|
public Result save(@RequestBody CertificatesDTO dto,@Parameter(hidden = true) @RequestAttribute("userId") Long userId){
|
||||||
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<CertificatesEntity> lwq = new LambdaQueryWrapper<>();
|
||||||
lwq.eq(CertificatesEntity::getCertificateNumber,dto.getCertificateNumber());
|
|
||||||
List<CertificatesEntity> list = certificatesDao.selectList(lwq);
|
List<CertificatesEntity> list = certificatesDao.selectList(lwq);
|
||||||
if (!list.isEmpty()){
|
if (!list.isEmpty()){
|
||||||
return new Result().error("证书编号有重复");
|
return new Result().error("证书编号有重复");
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package io.controller;
|
package io.controller;
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.crypto.digest.DigestUtil;
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
import io.annotation.Login;
|
import io.annotation.Login;
|
||||||
import io.annotation.LoginUser;
|
import io.annotation.LoginUser;
|
||||||
|
import io.common.utils.KeyUtil;
|
||||||
import io.common.utils.Result;
|
import io.common.utils.Result;
|
||||||
import io.common.validator.ValidatorUtils;
|
import io.common.validator.ValidatorUtils;
|
||||||
import io.modules.item.dto.LoginDTO;
|
import io.modules.item.dto.LoginDTO;
|
||||||
@ -17,6 +19,9 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.security.KeyPair;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -34,7 +39,7 @@ public class UserController {
|
|||||||
|
|
||||||
@PostMapping("register")
|
@PostMapping("register")
|
||||||
@Operation(summary = "注册")
|
@Operation(summary = "注册")
|
||||||
public Result register(@RequestBody RegisterDTO dto) {
|
public Result register(@RequestBody RegisterDTO dto) throws NoSuchAlgorithmException {
|
||||||
|
|
||||||
if (dto.getUsername().equals("admin")){
|
if (dto.getUsername().equals("admin")){
|
||||||
return new Result().error("admin用户禁止创建~");
|
return new Result().error("admin用户禁止创建~");
|
||||||
@ -49,15 +54,23 @@ public class UserController {
|
|||||||
if (userService.getByUsername(dto.getUsername()) != null) {
|
if (userService.getByUsername(dto.getUsername()) != null) {
|
||||||
return new Result().error("用户名已经存在~");
|
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);
|
ValidatorUtils.validateEntity(dto);
|
||||||
UserEntity user = new UserEntity();
|
UserEntity user = new UserEntity();
|
||||||
user.setUsername(dto.getUsername());
|
user.setUsername(dto.getUsername());
|
||||||
user.setNickName(dto.getUsername());
|
user.setNickName(dto.getUsername());
|
||||||
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
||||||
user.setCreateDate(new Date());
|
user.setPublicKey(publicKey);
|
||||||
|
user.setPrivateKey(privateKey);
|
||||||
userService.insert(user);
|
userService.insert(user);
|
||||||
return new Result();
|
return new Result().ok(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,7 +94,6 @@ public class UserController {
|
|||||||
user.setId(userId);
|
user.setId(userId);
|
||||||
user.setUsername(dto.getUsername());
|
user.setUsername(dto.getUsername());
|
||||||
user.setNickName(dto.getNickName());
|
user.setNickName(dto.getNickName());
|
||||||
user.setIntroduce(dto.getIntroduce());
|
|
||||||
if (StringUtils.isNotEmpty(dto.getPassword())){
|
if (StringUtils.isNotEmpty(dto.getPassword())){
|
||||||
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
user.setPassword(DigestUtil.sha256Hex(dto.getPassword()));
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ spring:
|
|||||||
datasource:
|
datasource:
|
||||||
druid:
|
druid:
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
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
|
username: root
|
||||||
password: 123456
|
password: 123456
|
||||||
initial-size: 10
|
initial-size: 10
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 364 KiB |
@ -1,11 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="head">
|
<div class="head">
|
||||||
<div class="head_l">
|
<div class="head_l">
|
||||||
<!-- <img src="/icoimg.png" alt="收缩" />-->
|
|
||||||
</div>
|
</div>
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<div class="head_r">
|
<div class="head_r">
|
||||||
<!-- <img :src="userStore().adminUserInfo.avatar" alt="头像" class="profile" />-->
|
|
||||||
<div class="head_user">
|
<div class="head_user">
|
||||||
<div class="head_user_name">{{ userStore().adminUserInfo.username }}</div>
|
<div class="head_user_name">{{ userStore().adminUserInfo.username }}</div>
|
||||||
<div class="head_user_desc">管理员</div>
|
<div class="head_user_desc">管理员</div>
|
||||||
@ -13,61 +11,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu slot="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-item @click="logout">退出登录</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
const formRef = ref<FormInstance>()
|
|
||||||
import { updatePasswordAdmin } from '~/api/user/adminUserApi'
|
import { updatePasswordAdmin } from '~/api/user/adminUserApi'
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const drawer = ref(false)
|
|
||||||
const state = reactive(<any>{
|
const state = reactive(<any>{
|
||||||
dynamicValidateForm:{}
|
dynamicValidateForm:{}
|
||||||
})
|
})
|
||||||
|
@ -47,16 +47,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</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>
|
<style scoped>
|
||||||
.main{
|
.main{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -144,21 +156,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</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>
|
<template>
|
||||||
<el-container>
|
<el-container>
|
||||||
<el-header>
|
|
||||||
<heads></heads>
|
|
||||||
</el-header>
|
|
||||||
<el-container>
|
|
||||||
<el-aside width="200px" >
|
<el-aside width="200px" >
|
||||||
<el-menu
|
<el-menu
|
||||||
|
style="height: 100vh"
|
||||||
:default-active="navStore().adminPath"
|
:default-active="navStore().adminPath"
|
||||||
router
|
router
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
|
background-color="#001020"
|
||||||
|
text-color="#fff"
|
||||||
>
|
>
|
||||||
|
<div style="width: 100%;height: 50px"></div>
|
||||||
<el-menu-item
|
<el-menu-item
|
||||||
v-for="r in getAdminList()"
|
v-for="r in getAdminList()"
|
||||||
:key="r.name"
|
:key="r.name"
|
||||||
@ -20,10 +21,15 @@
|
|||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<heads></heads>
|
||||||
|
</el-header>
|
||||||
<el-main class="main">
|
<el-main class="main">
|
||||||
<router-view ></router-view>
|
<router-view ></router-view>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|
||||||
</el-container>
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -47,4 +53,5 @@ const handleSelect = (key: string, keyPath: string[]) => {
|
|||||||
height: 18px;
|
height: 18px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,33 +2,241 @@
|
|||||||
<!--前端模板-->
|
<!--前端模板-->
|
||||||
<template>
|
<template>
|
||||||
<div class="common-layout">
|
<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-container>
|
||||||
<el-header>
|
<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-header>
|
||||||
<el-main class="main">
|
<el-main class="main">
|
||||||
<div class="container">
|
<div class="certificate-container">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
</el-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup lang="ts">
|
<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>
|
</script>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
.main{
|
.main{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: calc(100vh - 60px);
|
height: calc(100vh - 80px);
|
||||||
background-color: #f3f3f4;
|
background-color: #eeeeee;
|
||||||
}
|
}
|
||||||
.container{
|
.icons{
|
||||||
width: 1200px;
|
width: 18px;
|
||||||
margin: 0 auto;
|
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>
|
</style>
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
<template>
|
<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 :data="state.certificateList" v-loading="loading" class="el-table">
|
||||||
<el-table-column prop="id" label="编号" />
|
<el-table-column prop="id" label="编号" />
|
||||||
<el-table-column prop="certificateNumber" label="证书编号" />
|
|
||||||
<el-table-column prop="user.nickName" label="用户" />
|
<el-table-column prop="user.nickName" label="用户" />
|
||||||
<el-table-column prop="issueDate" label="签发日期" />
|
<el-table-column prop="issueDate" label="签发日期" />
|
||||||
<el-table-column prop="expireDate" label="过期日期" />
|
<el-table-column prop="expireDate" label="过期日期" />
|
||||||
|
@ -1,62 +1,91 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="certificate-container">
|
||||||
|
<!-- 查询表单 -->
|
||||||
<el-row>
|
<el-row>
|
||||||
<!-- <el-col :span="12">-->
|
<el-col :span="24">
|
||||||
<!-- <el-button type="primary" @click="openForm(true)">添加证书</el-button>-->
|
<el-form :inline="true" :model="state.query" class="demo-form-inline">
|
||||||
<!-- </el-col>-->
|
<el-form-item label="证书编号">
|
||||||
<el-col :span="12" class="text-right">
|
<el-input v-model="state.query.id" placeholder="请输入证书编号" clearable />
|
||||||
<el-button type="info" @click="openChainInstructions">上链须知</el-button>
|
</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-col>
|
||||||
</el-row>
|
</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 :data="state.certificateList" v-loading="loading" class="el-table">
|
||||||
<el-table-column prop="id" label="编号" />
|
<el-table-column prop="id" label="ID" />
|
||||||
<el-table-column prop="certificateNumber" label="证书编号" />
|
<el-table-column prop="hex" label="身份信息哈希值" width="180" show-overflow-tooltip align="center" />
|
||||||
<el-table-column prop="path" label="证书" align="center">
|
<el-table-column prop="user.password" label="用户公钥" show-overflow-tooltip align="center" />
|
||||||
<template #default="scope">
|
<el-table-column
|
||||||
<el-image
|
prop="issueDate"
|
||||||
style="width: 50px; height: 50px"
|
label="证书生效时间"
|
||||||
:src="scope.row.img"
|
width="180"
|
||||||
:preview-src-list="scope.row.img.toString().split(',')"
|
align="center"
|
||||||
fit="cover"
|
>
|
||||||
:preview-teleported="true"
|
<template #default="{ row }">
|
||||||
/>
|
{{ formatDateSimple(row.issueDate) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="user.nickName" label="用户" />
|
|
||||||
<el-table-column prop="issueDate" label="签发日期" />
|
<el-table-column
|
||||||
<el-table-column prop="expireDate" label="过期日期" />
|
prop="expireDate"
|
||||||
<el-table-column prop="status" label="证书状态" :formatter="statusText" />
|
label="证书过期时间"
|
||||||
<!-- 新增审核状态列 -->
|
width="180"
|
||||||
<el-table-column prop="auditStatus" label="审核状态">
|
align="center"
|
||||||
<template #default="scope">
|
>
|
||||||
<el-tag :type="auditTagType(scope.row.auditStatus)">
|
<template #default="{ row }">
|
||||||
{{ auditStatusText(scope.row.auditStatus) }}
|
{{ 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>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="auditComments" label="审核备注" />
|
<el-table-column label="操作项" align="center" width="230">
|
||||||
<el-table-column prop="createdAt" label="创建时间" />
|
|
||||||
<el-table-column label="操作" fixed="right" align="center">
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button link type="primary" @click="openForm(false, scope.row)">编辑/审核</el-button>
|
<el-button v-if="scope.row.auditStatus ==0" link type="primary" @click="update(scope.row,1)">确认</el-button>
|
||||||
<el-button
|
<el-button v-if="scope.row.auditStatus !=0" link type="primary" @click="showDetail(scope.row)">详情</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>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@ -73,6 +102,7 @@
|
|||||||
@current-change="handlePageChange"
|
@current-change="handlePageChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 添加/编辑弹窗 -->
|
<!-- 添加/编辑弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="state.dialogVisible"
|
v-model="state.dialogVisible"
|
||||||
@ -81,14 +111,11 @@
|
|||||||
:append-to-body="false"
|
:append-to-body="false"
|
||||||
>
|
>
|
||||||
<el-form :model="state.form" :rules="rules" ref="formRef" label-position="top">
|
<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">
|
<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>
|
||||||
<el-form-item label="用户" prop="userId">
|
<el-form-item label="用户" prop="userId">
|
||||||
<el-select v-model="state.form.userId" placeholder="请选择" >
|
<el-select v-model="state.form.userId" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in state.userList"
|
v-for="item in state.userList"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -123,7 +150,6 @@
|
|||||||
<el-option label="过期" :value="2" />
|
<el-option label="过期" :value="2" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- 新增审核相关字段 -->
|
|
||||||
<el-form-item label="审核状态" prop="auditStatus">
|
<el-form-item label="审核状态" prop="auditStatus">
|
||||||
<el-select v-model="state.form.auditStatus">
|
<el-select v-model="state.form.auditStatus">
|
||||||
<el-option label="待审核" :value="0" />
|
<el-option label="待审核" :value="0" />
|
||||||
@ -140,101 +166,89 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 上链须知弹窗 -->
|
<!-- 详情弹窗 -->
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="state.chainDialogVisible"
|
v-model="state.detailDialogVisible"
|
||||||
title="上链须知与注意事项"
|
title="证书详情"
|
||||||
width="500px"
|
width="700px"
|
||||||
:append-to-body="false"
|
:append-to-body="false"
|
||||||
>
|
>
|
||||||
<div class="tip-dialog">
|
<el-descriptions :column="2" border>
|
||||||
<h4>上链须知</h4>
|
<el-descriptions-item label="证书ID">{{ state.currentCertificate.id }}</el-descriptions-item>
|
||||||
<p>1. 一旦证书信息上链后,将不可修改。</p>
|
<el-descriptions-item label="状态">
|
||||||
<p>2. 请务必确保所填写的证书信息准确无误。</p>
|
<el-tag
|
||||||
<p>3. 上链信息具有公正性和透明性,请谨慎操作。</p>
|
:type="{
|
||||||
<p>4. 如果发现错误,请联系管理员进行后续处理。</p>
|
'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>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button type="primary" @click="state.chainDialogVisible = false">我已知晓</el-button>
|
<el-button @click="state.detailDialogVisible = false">关闭</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { FormInstance, ElMessage, TabsPaneContext } from 'element-plus'
|
import { FormInstance, ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
|
|
||||||
const state = reactive(<any>{
|
const state = reactive({
|
||||||
activeTab: 'all', // 当前激活的Tab
|
activeTab: 'all',
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
|
detailDialogVisible: false,
|
||||||
chainDialogVisible: false,
|
chainDialogVisible: false,
|
||||||
dialogTitle: "",
|
dialogTitle: '',
|
||||||
certificateList: [] as any[],
|
certificateList: [] as any[],
|
||||||
form: {
|
currentCertificate: {} as any,
|
||||||
id: null,
|
form: {},
|
||||||
certificateNumber: '',
|
|
||||||
userId: '',
|
|
||||||
issueDate: '',
|
|
||||||
expireDate: '',
|
|
||||||
certificateData: '',
|
|
||||||
blockchainTxId: '',
|
|
||||||
img: '',
|
|
||||||
status: 1,
|
|
||||||
auditStatus: 0, // 新增审核状态
|
|
||||||
auditComments: '' // 新增审核备注
|
|
||||||
},
|
|
||||||
query: {
|
query: {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
total: 1,
|
total: 1,
|
||||||
isBlock: 0,
|
auditStatus: null
|
||||||
auditStatus: null // 新增审核状态查询参数
|
|
||||||
},
|
},
|
||||||
userList: []
|
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 = {
|
const rules = {
|
||||||
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
||||||
userId: [{ required: true, message: '请输入用户ID', trigger: 'blur' }],
|
userId: [{ required: true, message: '请输入用户ID', trigger: 'blur' }],
|
||||||
@ -244,23 +258,33 @@ const rules = {
|
|||||||
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
||||||
auditStatus: [{ required: true, message: '请选择审核状态', trigger: 'change' }]
|
auditStatus: [{ required: true, message: '请选择审核状态', trigger: 'change' }]
|
||||||
}
|
}
|
||||||
const openForm = (isAdd: boolean, data?: any) => {
|
|
||||||
state.dialogVisible = true
|
function update(data: any, status: number) {
|
||||||
state.dialogTitle = isAdd ? '添加证书' : '编辑证书'
|
data.auditStatus = status
|
||||||
nextTick(() => {
|
adminRequest.put("/sys/certificate", data).then(() => {
|
||||||
state.form = isAdd ? {
|
loadCertificates()
|
||||||
...state.form,
|
ElMessage.success("操作完成")
|
||||||
id: null,
|
|
||||||
auditStatus: 0,
|
|
||||||
auditComments: ''
|
|
||||||
} : { ...data }
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) => {
|
const handlePageChange = (page: number) => {
|
||||||
state.query.page = page
|
state.query.page = page
|
||||||
loadCertificates()
|
loadCertificates()
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return
|
||||||
formRef.value.validate(async (valid: boolean) => {
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
@ -273,15 +297,15 @@ const submitForm = () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const del = async (id: number) => {
|
|
||||||
await adminRequest.delete(`/sys/certificate/delete/${id}`)
|
const showDetail = (row: any) => {
|
||||||
ElMessage.success('删除成功')
|
state.currentCertificate = { ...row }
|
||||||
loadCertificates()
|
state.detailDialogVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const statusText = (row: any) => {
|
const viewOnBlockchain = (txHash: string) => {
|
||||||
const map = { 0: '撤销', 1: '有效', 2: '过期' }
|
const explorerUrl = `https://blockchain-explorer.example.com/tx/${txHash}`
|
||||||
return map[row.status] ?? '未知'
|
window.open(explorerUrl, '_blank')
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadCertificates = async () => {
|
const loadCertificates = async () => {
|
||||||
@ -290,7 +314,6 @@ const loadCertificates = async () => {
|
|||||||
const res = await adminRequest.get('/sys/certificate/page', {
|
const res = await adminRequest.get('/sys/certificate/page', {
|
||||||
params: {
|
params: {
|
||||||
...state.query,
|
...state.query,
|
||||||
// 转换审核状态查询参数
|
|
||||||
auditStatus: state.query.auditStatus === null ? undefined : state.query.auditStatus
|
auditStatus: state.query.auditStatus === null ? undefined : state.query.auditStatus
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -303,10 +326,6 @@ const loadCertificates = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const openChainInstructions = () => {
|
|
||||||
state.chainDialogVisible = true
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadCertificates()
|
loadCertificates()
|
||||||
adminRequest.get(`sys/user-front/page`, { params: { limit: 9999 } })
|
adminRequest.get(`sys/user-front/page`, { params: { limit: 9999 } })
|
||||||
@ -317,22 +336,10 @@ onMounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* 新增Tabs样式 */
|
.certificate-container {
|
||||||
.el-tabs {
|
padding: 20px;
|
||||||
margin-top: 20px;
|
|
||||||
background: #fff;
|
|
||||||
padding: 0 20px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 调整审核状态标签样式 */
|
|
||||||
.el-tag {
|
|
||||||
padding: 0 8px;
|
|
||||||
height: 24px;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 其他原有样式保持不变 */
|
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -342,64 +349,26 @@ onMounted(() => {
|
|||||||
.el-table {
|
.el-table {
|
||||||
margin-top: 20px;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 弹出框样式 */
|
.certificate-image-preview {
|
||||||
.el-dialog__header {
|
margin-top: 20px;
|
||||||
background-color: #409EFF;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.el-dialog {
|
|
||||||
border-radius: 8px;
|
.certificate-image-preview h4 {
|
||||||
}
|
margin-bottom: 10px;
|
||||||
.el-dialog__body {
|
color: #606266;
|
||||||
padding: 20px;
|
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 {
|
.tip-dialog h4 {
|
||||||
margin: 0 0 10px 0;
|
margin: 0 0 10px 0;
|
||||||
color: #f0ad4e;
|
color: #f0ad4e;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tip-dialog p {
|
.tip-dialog p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tabs 样式 */
|
|
||||||
.filter-tabs {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,75 +1,313 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-row>
|
<div class="admin-container">
|
||||||
<el-col :span="24">
|
|
||||||
<el-card>
|
<!-- 主要内容区 -->
|
||||||
<template #header>
|
<main class="admin-main">
|
||||||
<div class="card-header">
|
<!-- 统计卡片 -->
|
||||||
<span>平台情况</span>
|
<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>
|
</div>
|
||||||
</template>
|
<div class="stat-content">
|
||||||
<el-row :gutter="20">
|
<h3>{{ stat.title }}</h3>
|
||||||
<el-col v-for="item in state.list" :span="8" :key="item.name">
|
<p class="value">{{ stat.value }}</p>
|
||||||
<div class="list-box">
|
<p class="trend" :class="{up: stat.trend > 0, down: stat.trend < 0}">
|
||||||
<p class="first-p">{{ item.name }}</p>
|
<span>{{ stat.trend > 0 ? '+' : '' }}{{ stat.trend }}%</span>
|
||||||
<p class="second-p">
|
<el-icon>
|
||||||
<span>{{ item.value }}</span>{{ item.tag }}
|
<CaretTop v-if="stat.trend > 0" />
|
||||||
|
<CaretBottom v-else />
|
||||||
|
</el-icon>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</div>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
</el-row>
|
<!-- 最近活动 -->
|
||||||
|
<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>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
const state = reactive(<any>{
|
import {
|
||||||
list: [],
|
User, Notification, List,
|
||||||
row: []
|
CaretTop, CaretBottom,
|
||||||
});
|
Coin
|
||||||
|
} from '@element-plus/icons-vue'
|
||||||
// 获取数据
|
|
||||||
onMounted(() => {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
</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 {
|
const recentActivities = ref([
|
||||||
height: 400px;
|
])
|
||||||
|
|
||||||
|
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%;
|
const statusTagType = (status: string) => {
|
||||||
height: 150px;
|
switch(status) {
|
||||||
border-radius: 10px;
|
case '已通过': return 'success'
|
||||||
background-image: url('/a1.png');
|
case '待验证': return 'warning'
|
||||||
background-size: cover;
|
case '已拒绝': return 'danger'
|
||||||
background-repeat: no-repeat;
|
default: return 'info'
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</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>
|
</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>
|
<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
|
<el-form
|
||||||
|
label-position="right"
|
||||||
:model="form"
|
:model="form"
|
||||||
:rules="rules"
|
:rules="rules"
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
label-position="top"
|
label-width="auto"
|
||||||
class="certificate-form"
|
|
||||||
>
|
>
|
||||||
<!-- 表单内容 -->
|
<!-- 表单内容 -->
|
||||||
<el-form-item label="证书编号" prop="certificateNumber">
|
<div style="width: 60%;margin: 0 auto">
|
||||||
|
<el-form-item label="名称:" prop="name">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="form.certificateNumber"
|
v-model="form.name"
|
||||||
placeholder="请输入证书编号"
|
placeholder="请输入证书名称"
|
||||||
class="block-input"
|
class="block-input"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
@ -32,120 +19,106 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</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">
|
||||||
<el-form-item label="签发日期" prop="issueDate" class="date-picker">
|
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
style="width: 100%"
|
||||||
v-model="form.issueDate"
|
v-model="form.issueDate"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="选择签发日期"
|
format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
/>
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<i class="el-icon-date"></i>
|
|
||||||
</template>
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="过期日期" prop="expireDate" class="date-picker">
|
<el-form-item label="过期时间:" prop="expireDate">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
style="width: 100%"
|
||||||
v-model="form.expireDate"
|
v-model="form.expireDate"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="选择过期日期"
|
format="YYYY-MM-DD"
|
||||||
format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="公钥:" prop="hex">
|
||||||
|
<el-input
|
||||||
|
v-model="form.hex"
|
||||||
|
placeholder="请输入公钥"
|
||||||
|
class="block-input"
|
||||||
>
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<i class="el-icon-time"></i>
|
<i class="el-icon-document"></i>
|
||||||
</template>
|
</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>
|
</el-form-item>
|
||||||
</div>
|
</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>
|
</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>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import type { FormInstance } from 'element-plus'
|
import type { FormInstance } from 'element-plus'
|
||||||
|
|
||||||
const formRef = ref<FormInstance>()
|
const formRef = ref<FormInstance>()
|
||||||
|
const form = reactive(<any>{})
|
||||||
|
|
||||||
const form = reactive({
|
const state = reactive({
|
||||||
certificateNumber: '',
|
path:import.meta.env.VITE_API_FRONT_BASE_URL + "/api/upload",
|
||||||
issueDate: '',
|
|
||||||
expireDate: '',
|
|
||||||
certificateData: '',
|
|
||||||
img: ''
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
certificateNumber: [{ required: true, message: '请输入证书编号', trigger: 'blur' }],
|
||||||
issueDate: [{ required: true, message: '请选择签发日期', trigger: 'change' }],
|
issueDate: [{ required: true, message: '请选择签发日期', trigger: 'change' }],
|
||||||
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
|
expireDate: [{ required: true, message: '请选择过期日期', trigger: 'change' }],
|
||||||
certificateData: [{ required: true, message: '请输入证书详情', trigger: 'blur' }],
|
certificateData: [{ required: true, message: '请输入证书详情', trigger: 'blur' }]
|
||||||
img: [{ required: true, message: '请上传证书图片', trigger: 'change' }]
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleImageUrl(path: string) {
|
|
||||||
form.img = path
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitForm = () => {
|
const submitForm = () => {
|
||||||
@ -158,7 +131,7 @@ const submitForm = () => {
|
|||||||
<h3>请确认证书信息</h3>\
|
<h3>请确认证书信息</h3>\
|
||||||
<p>数据上链后不可修改,请仔细核对以下信息:</p>\
|
<p>数据上链后不可修改,请仔细核对以下信息:</p>\
|
||||||
<ul>\
|
<ul>\
|
||||||
<li>证书编号:'+form.certificateNumber+'</li>\
|
<li>名称:'+form.name+'</li>\
|
||||||
<li>签发日期:'+form.issueDate+'</li>\
|
<li>签发日期:'+form.issueDate+'</li>\
|
||||||
</ul>\
|
</ul>\
|
||||||
</div>',
|
</div>',
|
||||||
@ -196,232 +169,14 @@ const submitForm = () => {
|
|||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
if (formRef.value) {
|
if (formRef.value) {
|
||||||
formRef.value.resetFields()
|
formRef.value.resetFields()
|
||||||
form.img = ''
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<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>
|
||||||
|
|
||||||
<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">
|
<route lang="json">
|
||||||
{
|
{
|
||||||
|
@ -1,445 +1,66 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="audit-record-container">
|
<el-table :data="state.tableData" style="width: 100%" align="center">
|
||||||
<!-- 区块链装饰背景 -->
|
<el-table-column prop="id" label="ID" show-overflow-tooltip align="center" />
|
||||||
<div class="blockchain-background">
|
<el-table-column prop="hex" label="身份信息哈希值" width="180" show-overflow-tooltip align="center" />
|
||||||
<div class="chain-line"></div>
|
<el-table-column prop="name" label="颁发者" show-overflow-tooltip align="center" />
|
||||||
<div class="chain-line delay-1"></div>
|
<el-table-column prop="issueDate" label="证书生效时间" width="120" align="center" />
|
||||||
<div class="chain-line delay-2"></div>
|
<el-table-column prop="expireDate" label="证书过期时间" width="120" align="center"/>
|
||||||
</div>
|
<el-table-column prop="status" label="证书状态" />
|
||||||
|
<el-table-column label="操作项" min-width="180" align="center">
|
||||||
<!-- 审核记录主内容 -->
|
<template #default="scope">
|
||||||
<div class="audit-content">
|
<el-button
|
||||||
<h2 class="audit-title">
|
link
|
||||||
<i class="el-icon-notebook-2"></i>
|
type="primary"
|
||||||
证书审核记录
|
size="small"
|
||||||
<div class="sub-title">查看您的证书审核历史记录</div>
|
@click.prevent="deleteRow(scope.$index)"
|
||||||
</h2>
|
|
||||||
|
|
||||||
<!-- 筛选条件 -->
|
|
||||||
<div class="filter-bar">
|
|
||||||
<el-select
|
|
||||||
v-model="filter.auditStatus"
|
|
||||||
placeholder="按状态筛选"
|
|
||||||
class="auditStatus-filter"
|
|
||||||
clearable
|
|
||||||
>
|
>
|
||||||
<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>
|
</el-button>
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<el-button
|
||||||
<div class="empty-state" v-if="filteredRecords.length === 0">
|
link
|
||||||
<i class="el-icon-document-remove"></i>
|
type="primary"
|
||||||
<p>暂无审核记录</p>
|
size="small"
|
||||||
</div>
|
@click.prevent="deleteRow(scope.$index)"
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 查看详情弹窗 -->
|
|
||||||
<el-dialog
|
|
||||||
v-model="detailDialogVisible"
|
|
||||||
title="审核记录详情"
|
|
||||||
width="600px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
>
|
||||||
<div class="detail-content" v-if="selectedRecord">
|
下载证书
|
||||||
<div class="detail-item">
|
</el-button>
|
||||||
<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>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-table-column>
|
||||||
</div>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue'
|
const state = reactive({
|
||||||
|
tableData:[
|
||||||
// 模拟数据
|
{
|
||||||
const records = ref([
|
id:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||||
])
|
hex:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||||
|
name:"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
|
||||||
// 筛选条件
|
issueDate:"2023-10-25",
|
||||||
const filter = ref({
|
expireDate:"2025-10-25",
|
||||||
auditStatus: null,
|
status:"已通过",
|
||||||
dateRange: []
|
}, {
|
||||||
|
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>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<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>
|
</style>
|
||||||
|
|
||||||
<route lang="json">
|
<route lang="json">
|
||||||
|
@ -71,7 +71,7 @@ const onLogin = () => {
|
|||||||
<style scoped>
|
<style scoped>
|
||||||
.module_r {
|
.module_r {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: url("/ec13203e-20ee-4bb3-ba23-f0b6f93d3760.jpg");
|
background: url("/508d288b-cd6e-4814-a99f-53a3999c4261.jpg");
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -21,21 +21,53 @@
|
|||||||
<input class="module_input" type="password" placeholder="再次输入密码" v-model="register.confirmPassword" />
|
<input class="module_input" type="password" placeholder="再次输入密码" v-model="register.confirmPassword" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="forgetpwd" @click="router.push('/login')">有账号?</div>
|
<div class="forgetpwd" @click="router.push('/login')">有账号?</div>
|
||||||
<button class="module_button" @click="onRegister">注册</button>
|
<button class="module_button" @click="onRegister">注册</button>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { registerFront } from '~/api/user/frontUserApi'
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const register = reactive({
|
const register = reactive({
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
confirmPassword: '',
|
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")
|
ElMessage.warning("不能创建账号Admin")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
registerFront(register).then(() =>{
|
frontRequest.post("/api/user/register", register).then(res =>{
|
||||||
ElMessage.success("注册成功~")
|
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>
|
</script>
|
||||||
@ -58,7 +106,7 @@ const onRegister = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background: url("/ec13203e-20ee-4bb3-ba23-f0b6f93d3760.jpg");
|
background: url("/508d288b-cd6e-4814-a99f-53a3999c4261.jpg");
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
.module_mian{
|
.module_mian{
|
||||||
width: 26%;
|
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",
|
path: "/admin/certificates",
|
||||||
name: "证书管理",
|
name: "证书验证",
|
||||||
icon: "Postcard",
|
icon: "Postcard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/admin/block",
|
path: "/admin/block",
|
||||||
name: "上链信息",
|
name: "证书查询",
|
||||||
icon: "Postcard",
|
icon: "Postcard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/admin/log",
|
path: "/admin/user",
|
||||||
name: "申请记录",
|
name: "个人中心",
|
||||||
icon: "Postcard",
|
icon: "Postcard",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/admin/adminuser",
|
path: "/admin/about",
|
||||||
name: "用户管理",
|
name: "关于我们",
|
||||||
icon: "Notification",
|
icon: "Notification",
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -33,28 +33,28 @@ export const getFrontList = () => {
|
|||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
name: "证书信息",
|
name: "首页",
|
||||||
icon: "Dashboard",
|
icon: "House",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/load",
|
path: "/load",
|
||||||
name: "证书提交",
|
name: "证书申请",
|
||||||
icon: "Dashboard",
|
icon: "Notification",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/log",
|
path: "/log",
|
||||||
name: "审核记录",
|
name: "证书查询",
|
||||||
icon: "ShoppingCart",
|
icon: "MessageBox",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/audit",
|
path: "/user",
|
||||||
name: "证书验证",
|
name: "个人中心",
|
||||||
icon: "Warehouse",
|
icon: "MapLocation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/look",
|
path: "/about",
|
||||||
name: "查看证书",
|
name: "关于我们",
|
||||||
icon: "Warehouse",
|
icon: "ScaleToOriginal",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
return routes;
|
return routes;
|
||||||
|
Loading…
Reference in New Issue
Block a user