Commit 42420728 authored by tangtuo's avatar tangtuo

新增后台管理系统nft剧本管理页面的接口

parent 17e1a095
...@@ -47,10 +47,7 @@ ...@@ -47,10 +47,7 @@
<groupId>com.spring4all</groupId> <groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId> <artifactId>swagger-spring-boot-starter</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.fzm.admin.auth;
import cn.dev33.satoken.action.SaTokenActionDefaultImpl;
import com.fzm.common.entity.Admin;
import com.fzm.common.entity.User;
import com.fzm.common.service.AdminService;
import com.fzm.common.service.UserService;
import com.fzm.common.utils.JwtUtil;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* 继承Sa-Token行为Bean默认实现, 重写部分逻辑
*/
@Component
public class MySaTokenAction extends SaTokenActionDefaultImpl {
@Resource
private AdminService adminService;
/**
* 生成自定义token
*
* @param loginId
* @param loginType
* @return
*/
@Override
public String createToken(Object loginId, String loginType) {
Admin loginUser = adminService.getById((Integer) loginId);
return JwtUtil.generateToken(loginUser);
}
}
package com.fzm.admin.auth;
import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import java.util.List;
/**
* Sa-Token 权限验证工具类
*
* @author kong
*/
public class StpAdminUtil {
/**
* 账号类型标识
*/
public static final String TYPE = "admin";
/**
* 底层的 StpLogic 对象
*/
public static StpLogic stpLogic = new StpLogic(TYPE);
/**
* 获取当前 StpLogic 的账号类型
*
* @return See Note
*/
public static String getLoginType() {
return stpLogic.getLoginType();
}
// =================== 获取token 相关 ===================
/**
* 返回token名称
*
* @return 此StpLogic的token名称
*/
public static String getTokenName() {
return stpLogic.getTokenName();
}
/**
* 在当前会话写入当前tokenValue
*
* @param tokenValue token值
* @param cookieTimeout Cookie存活时间(秒)
*/
public static void setTokenValue(String tokenValue, int cookieTimeout) {
stpLogic.setTokenValue(tokenValue, cookieTimeout);
}
/**
* 获取当前tokenValue
*
* @return 当前tokenValue
*/
public static String getTokenValue() {
return stpLogic.getTokenValue();
}
/**
* 获取当前会话的token信息
*
* @return token信息
*/
public static SaTokenInfo getTokenInfo() {
return stpLogic.getTokenInfo();
}
// =================== 登录相关操作 ===================
/**
* 会话登录
*
* @param id 账号id,建议的类型:(long | int | String)
*/
public static void login(Object id) {
stpLogic.login(id);
}
/**
* 会话登录,并指定登录设备
*
* @param id 账号id,建议的类型:(long | int | String)
* @param device 设备标识
*/
public static void login(Object id, String device) {
stpLogic.login(id, device);
}
/**
* 会话登录,并指定是否 [记住我]
*
* @param id 账号id,建议的类型:(long | int | String)
* @param isLastingCookie 是否为持久Cookie
*/
public static void login(Object id, boolean isLastingCookie) {
stpLogic.login(id, isLastingCookie);
}
/**
* 会话登录,并指定所有登录参数Model
*
* @param id 登录id,建议的类型:(long | int | String)
* @param loginModel 此次登录的参数Model
*/
public static void login(Object id, SaLoginModel loginModel) {
stpLogic.login(id, loginModel);
}
/**
* 当前会话注销登录
*/
public static void logout() {
stpLogic.logout();
}
/**
* 指定token的会话注销登录
*
* @param tokenValue 指定token
*/
public static void logoutByTokenValue(String tokenValue) {
stpLogic.logoutByTokenValue(tokenValue);
}
/**
* 指定账号id的会话注销登录(踢人下线)
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
*
* @param loginId 账号id
*/
public static void logoutByLoginId(Object loginId) {
stpLogic.logoutByLoginId(loginId);
}
/**
* 指定账号id指定设备的会话注销登录(踢人下线)
* <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
*
* @param loginId 账号id
* @param device 设备标识
*/
public static void logoutByLoginId(Object loginId, String device) {
stpLogic.logoutByLoginId(loginId, device);
}
/**
* 封禁指定账号
* <p> 此方法不会直接将此账号id踢下线,而是在对方再次登录时抛出`DisableLoginException`异常
*
* @param loginId 指定账号id
* @param disableTime 封禁时间, 单位: 秒 (-1=永久封禁)
*/
public static void disable(Object loginId, long disableTime) {
stpLogic.disable(loginId, disableTime);
}
/**
* 指定账号是否已被封禁 (true=已被封禁, false=未被封禁)
*
* @param loginId 账号id
* @return see note
*/
public static boolean isDisable(Object loginId) {
return stpLogic.isDisable(loginId);
}
/**
* 获取指定账号剩余封禁时间,单位:秒(-1=永久封禁,-2=未被封禁)
*
* @param loginId 账号id
* @return see note
*/
public static long getDisableTime(Object loginId) {
return stpLogic.getDisableTime(loginId);
}
/**
* 解封指定账号
*
* @param loginId 账号id
*/
public static void untieDisable(Object loginId) {
stpLogic.untieDisable(loginId);
}
// 查询相关
/**
* 获取当前会话是否已经登录
*
* @return 是否已登录
*/
public static boolean isLogin() {
return stpLogic.isLogin();
}
/**
* 检验当前会话是否已经登录,如未登录,则抛出异常
*/
public static void checkLogin() {
stpLogic.checkLogin();
}
/**
* 获取当前会话账号id, 如果未登录,则抛出异常
*
* @return 账号id
*/
public static Object getLoginId() {
return stpLogic.getLoginId();
}
/**
* 获取当前会话登录id, 如果未登录,则返回默认值
*
* @param <T> 返回类型
* @param defaultValue 默认值
* @return 登录id
*/
public static <T> T getLoginId(T defaultValue) {
return stpLogic.getLoginId(defaultValue);
}
/**
* 获取当前会话登录id, 如果未登录,则返回null
*
* @return 账号id
*/
public static Object getLoginIdDefaultNull() {
return stpLogic.getLoginIdDefaultNull();
}
/**
* 获取当前会话登录id, 并转换为String
*
* @return 账号id
*/
public static String getLoginIdAsString() {
return stpLogic.getLoginIdAsString();
}
/**
* 获取当前会话登录id, 并转换为int
*
* @return 账号id
*/
public static int getLoginIdAsInt() {
return stpLogic.getLoginIdAsInt();
}
/**
* 获取当前会话登录id, 并转换为long
*
* @return 账号id
*/
public static long getLoginIdAsLong() {
return stpLogic.getLoginIdAsLong();
}
/**
* 获取指定token对应的登录id,如果未登录,则返回 null
*
* @param tokenValue token
* @return 登录id
*/
public static Object getLoginIdByToken(String tokenValue) {
return stpLogic.getLoginIdByToken(tokenValue);
}
// =================== session相关 ===================
/**
* 获取指定loginId的session, 如果session尚未创建,isCreate=是否新建并返回
*
* @param loginId 账号id
* @param isCreate 是否新建
* @return SaSession
*/
public static SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
return stpLogic.getSessionByLoginId(loginId, isCreate);
}
/**
* 获取指定key的session, 如果session尚未创建,则返回null
*
* @param sessionId sessionId
* @return session对象
*/
public static SaSession getSessionBySessionId(String sessionId) {
return stpLogic.getSessionBySessionId(sessionId);
}
/**
* 获取指定loginId的session,如果session尚未创建,则新建并返回
*
* @param loginId 账号id
* @return session会话
*/
public static SaSession getSessionByLoginId(Object loginId) {
return stpLogic.getSessionByLoginId(loginId);
}
/**
* 获取当前会话的session, 如果session尚未创建,isCreate=是否新建并返回
*
* @param isCreate 是否新建
* @return 当前会话的session
*/
public static SaSession getSession(boolean isCreate) {
return stpLogic.getSession(isCreate);
}
/**
* 获取当前会话的session,如果session尚未创建,则新建并返回
*
* @return 当前会话的session
*/
public static SaSession getSession() {
return stpLogic.getSession();
}
// =================== token专属session ===================
/**
* 获取指定token的专属session,如果session尚未创建,则新建并返回
*
* @param tokenValue token值
* @return session会话
*/
public static SaSession getTokenSessionByToken(String tokenValue) {
return stpLogic.getTokenSessionByToken(tokenValue);
}
/**
* 获取当前token的专属-session,如果session尚未创建,则新建并返回
*
* @return session会话
*/
public static SaSession getTokenSession() {
return stpLogic.getTokenSession();
}
// =================== [临时过期] 验证相关 ===================
/**
* 检查当前token 是否已经[临时过期],如果已经过期则抛出异常
*/
public static void checkActivityTimeout() {
stpLogic.checkActivityTimeout();
}
/**
* 续签当前token:(将 [最后操作时间] 更新为当前时间戳)
* <h1>请注意: 即时token已经 [临时过期] 也可续签成功,
* 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否过期即可 </h1>
*/
public static void updateLastActivityToNow() {
stpLogic.updateLastActivityToNow();
}
// =================== 过期时间相关 ===================
/**
* 获取当前登录者的token剩余有效时间 (单位: 秒)
*
* @return token剩余有效时间
*/
public static long getTokenTimeout() {
return stpLogic.getTokenTimeout();
}
/**
* 获取当前登录者的Session剩余有效时间 (单位: 秒)
*
* @return token剩余有效时间
*/
public static long getSessionTimeout() {
return stpLogic.getSessionTimeout();
}
/**
* 获取当前token的专属Session剩余有效时间 (单位: 秒)
*
* @return token剩余有效时间
*/
public static long getTokenSessionTimeout() {
return stpLogic.getTokenSessionTimeout();
}
/**
* 获取当前token[临时过期]剩余有效时间 (单位: 秒)
*
* @return token[临时过期]剩余有效时间
*/
public static long getTokenActivityTimeout() {
return stpLogic.getTokenActivityTimeout();
}
// =================== 角色验证操作 ===================
/**
* 指定账号id是否含有角色标识, 返回true或false
*
* @param loginId 账号id
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public static boolean hasRole(Object loginId, String role) {
return stpLogic.hasRole(loginId, role);
}
/**
* 当前账号是否含有指定角色标识, 返回true或false
*
* @param role 角色标识
* @return 是否含有指定角色标识
*/
public static boolean hasRole(String role) {
return stpLogic.hasRole(role);
}
/**
* 当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
*
* @param role 角色标识
*/
public static void checkRole(String role) {
stpLogic.checkRole(role);
}
/**
* 当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
*
* @param roleArray 角色标识数组
*/
public static void checkRoleAnd(String... roleArray) {
stpLogic.checkRoleAnd(roleArray);
}
/**
* 当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可]
*
* @param roleArray 角色标识数组
*/
public static void checkRoleOr(String... roleArray) {
stpLogic.checkRoleOr(roleArray);
}
// =================== 权限验证操作 ===================
/**
* 指定账号id是否含有指定权限, 返回true或false
*
* @param loginId 账号id
* @param permission 权限码
* @return 是否含有指定权限
*/
public static boolean hasPermission(Object loginId, String permission) {
return stpLogic.hasPermission(loginId, permission);
}
/**
* 当前账号是否含有指定权限, 返回true或false
*
* @param permission 权限码
* @return 是否含有指定权限
*/
public static boolean hasPermission(String permission) {
return stpLogic.hasPermission(permission);
}
/**
* 当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
*
* @param permission 权限码
*/
public static void checkPermission(String permission) {
stpLogic.checkPermission(permission);
}
/**
* 当前账号是否含有指定权限 [指定多个,必须全部验证通过]
*
* @param permissionArray 权限码数组
*/
public static void checkPermissionAnd(String... permissionArray) {
stpLogic.checkPermissionAnd(permissionArray);
}
/**
* 当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
*
* @param permissionArray 权限码数组
*/
public static void checkPermissionOr(String... permissionArray) {
stpLogic.checkPermissionOr(permissionArray);
}
// =================== id 反查token 相关操作 ===================
/**
* 获取指定loginId的tokenValue
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
* 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
*
* @param loginId 账号id
* @return token值
*/
public static String getTokenValueByLoginId(Object loginId) {
return stpLogic.getTokenValueByLoginId(loginId);
}
/**
* 获取指定loginId指定设备端的tokenValue
* <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
* 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
*
* @param loginId 账号id
* @param device 设备标识
* @return token值
*/
public static String getTokenValueByLoginId(Object loginId, String device) {
return stpLogic.getTokenValueByLoginId(loginId, device);
}
/**
* 获取指定loginId的tokenValue集合
*
* @param loginId 账号id
* @return 此loginId的所有相关token
*/
public static List<String> getTokenValueListByLoginId(Object loginId) {
return stpLogic.getTokenValueListByLoginId(loginId);
}
/**
* 获取指定loginId指定设备端的tokenValue集合
*
* @param loginId 账号id
* @param device 设备标识
* @return 此loginId的所有相关token
*/
public static List<String> getTokenValueListByLoginId(Object loginId, String device) {
return stpLogic.getTokenValueListByLoginId(loginId, device);
}
/**
* 返回当前token的登录设备
*
* @return 当前令牌的登录设备
*/
public static String getLoginDevice() {
return stpLogic.getLoginDevice();
}
// =================== 会话管理 ===================
/**
* 根据条件查询token
*
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return token集合
*/
public static List<String> searchTokenValue(String keyword, int start, int size) {
return stpLogic.searchTokenValue(keyword, start, size);
}
/**
* 根据条件查询SessionId
*
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return sessionId集合
*/
public static List<String> searchSessionId(String keyword, int start, int size) {
return stpLogic.searchSessionId(keyword, start, size);
}
/**
* 根据条件查询token专属Session的Id
*
* @param keyword 关键字
* @param start 开始处索引 (-1代表查询所有)
* @param size 获取数量
* @return sessionId集合
*/
public static List<String> searchTokenSessionId(String keyword, int start, int size) {
return stpLogic.searchTokenSessionId(keyword, start, size);
}
// =================== 身份切换 ===================
/**
* 临时切换身份为指定loginId
*
* @param loginId 指定loginId
*/
public static void switchTo(Object loginId) {
stpLogic.switchTo(loginId);
}
/**
* 结束临时切换身份
*/
public static void endSwitch() {
stpLogic.endSwitch();
}
/**
* 当前是否正处于[身份临时切换]中
*
* @return 是否正处于[身份临时切换]中
*/
public static boolean isSwitch() {
return stpLogic.isSwitch();
}
/**
* 在一个代码段里方法内,临时切换身份为指定loginId
*
* @param loginId 指定loginId
* @param function 要执行的方法
*/
public static void switchTo(Object loginId, SaFunction function) {
stpLogic.switchTo(loginId, function);
}
// =================== 历史API,兼容旧版本 ===================
/**
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.getLoginType() ,使用方式保持不变 </h1>
* 获取当前StpLogin的loginKey
*
* @return 当前StpLogin的loginKey
*/
@Deprecated
public static String getLoginKey() {
return stpLogic.getLoginType();
}
/**
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
* 在当前会话上登录id
*
* @param loginId 登录id,建议的类型:(long | int | String)
*/
@Deprecated
public static void setLoginId(Object loginId) {
stpLogic.login(loginId);
}
/**
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定登录设备
*
* @param loginId 登录id,建议的类型:(long | int | String)
* @param device 设备标识
*/
@Deprecated
public static void setLoginId(Object loginId, String device) {
stpLogic.login(loginId, device);
}
/**
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定登录设备
*
* @param loginId 登录id,建议的类型:(long | int | String)
* @param isLastingCookie 是否为持久Cookie
*/
@Deprecated
public static void setLoginId(Object loginId, boolean isLastingCookie) {
stpLogic.login(loginId, isLastingCookie);
}
/**
* <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
* 在当前会话上登录id, 并指定所有登录参数Model
*
* @param loginId 登录id,建议的类型:(long | int | String)
* @param loginModel 此次登录的参数Model
*/
@Deprecated
public static void setLoginId(Object loginId, SaLoginModel loginModel) {
stpLogic.login(loginId, loginModel);
}
}
package com.fzm.admin.auth;
import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author tangtuo
* @date 2021/7/5 15:11
*
* <p>
* 查询当前角色的权限
* </p>
*/
@Component
public class StpServiceImpl implements StpInterface {
@Override
public List<String> getPermissionList(Object loginId, String loginType) {
return null;
}
@Override
public List<String> getRoleList(Object loginId, String loginType) {
return null;
}
}
package com.fzm.admin.controller; package com.fzm.admin.controller;
import cn.dev33.satoken.stp.StpUtil;
import com.fzm.admin.auth.StpAdminUtil;
import com.fzm.admin.params.LoginParam;
import com.fzm.common.constant.TokenConstant;
import com.fzm.common.entity.Admin;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.AdminService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import org.springframework.web.bind.annotation.RequestMapping; import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.RestController; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
/** /**
* @author tangtuo * @author tangtuo
...@@ -12,4 +24,18 @@ import org.springframework.web.bind.annotation.RestController; ...@@ -12,4 +24,18 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/admin") @RequestMapping("/admin")
@Api(tags = "后台用户管理") @Api(tags = "后台用户管理")
public class AdminController { public class AdminController {
@Resource
private AdminService adminService;
@PostMapping("/login")
@ApiOperation(value = "登录")
public ResponseModel<Map<String, Object>> login(@Validated @RequestBody LoginParam loginParam) {
Admin admin = adminService.login(loginParam.getUsername(), loginParam.getPassword());
StpAdminUtil.login(admin.getId());
HashMap<String, Object> result = new HashMap<>();
result.put("user", admin);
result.put(TokenConstant.TOKEN_HEADER, StpAdminUtil.getTokenValue());
return ResponseModel.success(result);
}
} }
package com.fzm.admin.controller;
import com.fzm.common.entity.Category;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.CategoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author tangtuo
* @date 2021/7/1 14:37
*/
@RestController
@RequestMapping(value = "/category")
@Api(tags = "类目管理")
public class CategoryController {
@Resource
private CategoryService categoryService;
@GetMapping("/list")
@ApiOperation(value = "查询所有类目信息")
public ResponseModel<List<Category>> list() {
return ResponseModel.success(categoryService.list());
}
}
package com.fzm.admin.controller;
import com.fzm.common.entity.Nft;
import com.fzm.common.entity.vo.NftListVo;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.NftService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2021/7/5 15:34
*/
@RestController
@RequestMapping("/nft")
@Api(tags = "剧本nft管理")
public class NftController {
@Resource
private NftService nftService;
@GetMapping("/list")
@ApiOperation(value = "查询nft列表")
public ResponseModel<PageInfo<NftListVo>> list(@ApiParam(value = "页码", required = true) @RequestParam Integer pageNum,
@ApiParam(value = "每页记录数", required = true) @RequestParam Integer pageSize,
@ApiParam(value = "类目id") @RequestParam(required = false, defaultValue = "1") Integer categoryId,
@ApiParam(value = "作品名称") @RequestParam(required = false) String name,
@ApiParam(value = "作品标签") @RequestParam(required = false) String theme,
@ApiParam(value = "注册手机号") @RequestParam(required = false) String telephone,
@ApiParam(value = "上架状态 0-未上架 1-已上架") @RequestParam(required = false) Integer status,
@ApiParam(value = "创建开始日期,yyyy-MM-dd格式") @RequestParam(required = false) String start,
@ApiParam(value = "创建截止日期,yyyy-MM-dd格式") @RequestParam(required = false) String end) {
PageInfo<NftListVo> page = nftService.page(pageNum, pageSize, categoryId, name, theme, telephone, status, start, end);
return ResponseModel.success(page);
}
@ApiOperation(value = "置顶")
@PostMapping("/top/{id}")
public ResponseModel<Boolean> top(@ApiParam(value = "nft主键") @PathVariable Integer id) {
return ResponseModel.success(nftService.top(id));
}
@ApiOperation(value = "取消置顶")
@PostMapping("/untop/{id}")
public ResponseModel<Boolean> untop(@ApiParam(value = "nft主键") @PathVariable Integer id) {
return ResponseModel.success(nftService.untop(id));
}
@ApiOperation(value = "上架")
@PostMapping("/onShelf/{id}")
public ResponseModel onShelf(@ApiParam(value = "nft主键") @PathVariable Integer id) {
return ResponseModel.success(nftService.onShelf(id));
}
@ApiOperation(value = "下架")
@PostMapping("/offShelf/{id}")
public ResponseModel offShelf(@ApiParam(value = "nft主键") @PathVariable Integer id) {
return ResponseModel.success(nftService.offShelf(id));
}
@ApiOperation(value = "查看详情")
@PostMapping("/detail/{id}")
public ResponseModel<Nft> getById(@ApiParam(value = "nft主键") @PathVariable Integer id) {
return ResponseModel.success(nftService.getById(id));
}
@ApiOperation(value = "下载文件")
@PostMapping("/download/{id}")
public void download(@ApiParam(value = "nft主键") @PathVariable Integer id) {
nftService.download(id);
}
}
package com.fzm.admin.params;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author tangtuo
* @date 2021/7/5 15:26
*/
@Data
public class LoginParam {
@NotBlank(message = "用户名不能为空")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
}
...@@ -94,3 +94,11 @@ chain: ...@@ -94,3 +94,11 @@ chain:
contract-name: user.evm.0xd996a3a866c577596df260844a045a068ec5accd8d71ccaa3d578c9617ec5490 contract-name: user.evm.0xd996a3a866c577596df260844a045a068ec5accd8d71ccaa3d578c9617ec5490
contract-address: 1iDWTHZQxPES4hLveZRcwJH6AMaMfZfZZ contract-address: 1iDWTHZQxPES4hLveZRcwJH6AMaMfZfZZ
aliyun:
oss:
app-key: LTAI5tHGn7cVJdEtihTFLSeB
app-secret: XYmfBSbLaZoblGXZwIXkbhfBD7a1eg
end-point: oss-cn-hangzhou.aliyuncs.com
simple-bucket: test-nft
encrypt-bucket: test-nft-2
...@@ -79,6 +79,11 @@ ...@@ -79,6 +79,11 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
......
package com.fzm.common.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fzm.common.constant.TokenConstant;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @author tangtuo
* @date 2021/7/5 15:02
*/
@Data
@Accessors(chain = true)
@TableName("tb_admin")
public class Admin extends AbstractUser {
@TableId(type = IdType.AUTO)
private Integer id;
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("昵称")
private String nickname;
@ApiModelProperty("密码")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
@ApiModelProperty("角色id")
private Integer roleId;
@ApiModelProperty("创建时间")
private Date createDate;
@ApiModelProperty("修改时间")
private Date updateDate;
@ApiModelProperty("记录创建的时间戳")
@TableField(fill = FieldFill.INSERT)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Long createTime;
@ApiModelProperty("记录更新的时间戳")
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private Long updateTime;
@Override
public String appId() {
return TokenConstant.TOKEN_APP_ID_ADMIN;
}
@Override
public Integer userId() {
return id;
}
}
package com.fzm.common.entity.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* @author tangtuo
* @date 2021/7/5 15:58
*/
@Data
public class NftListVo {
@ApiModelProperty("作品id")
private Integer id;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("主题,多个用逗号,隔开")
private String theme;
@ApiModelProperty("发行人账号")
private String publisherAccount;
@ApiModelProperty("发行人昵称")
private String publisherNickname;
@ApiModelProperty("nft发行时间")
private Date publishTime;
@ApiModelProperty("是否置顶 0-否 1-是")
private Integer isTop;
@ApiModelProperty("0-下架 1-上架")
private Integer status;
}
...@@ -10,6 +10,7 @@ public enum ResultCode implements IErrorCode { ...@@ -10,6 +10,7 @@ public enum ResultCode implements IErrorCode {
REGISTER_ERROR(410,"您已注册过"), REGISTER_ERROR(410,"您已注册过"),
LOGIN_ERROR(411,"登录失败"), LOGIN_ERROR(411,"登录失败"),
FILE_UPLOAD_ERROR(412,"文件上传失败"), FILE_UPLOAD_ERROR(412,"文件上传失败"),
FILE_DOWNLOAD_ERROR(412,"文件下载失败"),
TOKEN_VALID_ERROR(413,"token校验失败"), TOKEN_VALID_ERROR(413,"token校验失败"),
CODE_ERROR(414,"验证码发送失败"), CODE_ERROR(414,"验证码发送失败"),
; ;
......
package com.fzm.common.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Admin;
import com.fzm.common.entity.Category;
import org.apache.ibatis.annotations.Mapper;
/**
* @author tangtuo
* @date 2021/7/1 14:35
*/
@Mapper
public interface AdminMapper extends BaseMapper<Admin> {
}
package com.fzm.common.mapper; package com.fzm.common.mapper;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.vo.CollectionNftVo; import com.fzm.common.entity.vo.CollectionNftVo;
import com.fzm.common.entity.vo.NftListVo;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -17,6 +19,7 @@ public interface NftMapper extends BaseMapper<Nft> { ...@@ -17,6 +19,7 @@ public interface NftMapper extends BaseMapper<Nft> {
/** /**
* 查询nft列表 * 查询nft列表
*
* @param pageNum * @param pageNum
* @param pageSize * @param pageSize
* @param categoryId * @param categoryId
...@@ -25,4 +28,18 @@ public interface NftMapper extends BaseMapper<Nft> { ...@@ -25,4 +28,18 @@ public interface NftMapper extends BaseMapper<Nft> {
List<Nft> list(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize, @Param("categoryId") Integer categoryId); List<Nft> list(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize, @Param("categoryId") Integer categoryId);
List<CollectionNftVo> getCollectionList(@Param("list") List<Integer> list); List<CollectionNftVo> getCollectionList(@Param("list") List<Integer> list);
/**
* 后天管理系统根据条件检索
*
* @param categoryId
* @param name
* @param telephone
* @param theme
* @param status
* @param startDate
* @param endDate
* @return
*/
List<NftListVo> page(@Param("categoryId") Integer categoryId, @Param("name") String name, @Param("telephone") String telephone, @Param("theme") String theme, @Param("status") Integer status, @Param("startDate") DateTime startDate, @Param("endDate") DateTime endDate);
} }
package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Admin;
/**
* @author tangtuo
* @date 2021/7/5 15:08
*/
public interface AdminService extends IService<Admin> {
Admin login(String username, String password);
}
...@@ -3,6 +3,8 @@ package com.fzm.common.service; ...@@ -3,6 +3,8 @@ package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.vo.CollectionNftVo; import com.fzm.common.entity.vo.CollectionNftVo;
import com.fzm.common.entity.vo.NftListVo;
import com.github.pagehelper.PageInfo;
import java.util.List; import java.util.List;
...@@ -60,4 +62,59 @@ public interface NftService extends IService<Nft> { ...@@ -60,4 +62,59 @@ public interface NftService extends IService<Nft> {
* @return * @return
*/ */
String generateNftId(Integer categoryId); String generateNftId(Integer categoryId);
/**
* 后台管理系统根据条件检索nft列表
*
* @param pageNum
* @param pageSize
* @param categoryId
* @param name
* @param theme
* @param telephone
* @param status
* @param start
* @param end
* @return
*/
PageInfo<NftListVo> page(Integer pageNum, Integer pageSize, Integer categoryId, String name, String theme, String telephone, Integer status, String start, String end);
/**
* 置顶
*
* @param id
* @return
*/
Boolean top(Integer id);
/**
* 取消置顶
*
* @param id
* @return
*/
Boolean untop(Integer id);
/**
* 上架
*
* @param id
* @return
*/
Boolean onShelf(Integer id);
/**
* 下架
*
* @param id
* @return
*/
Boolean offShelf(Integer id);
/**
* 下载附件
*
* @param id
*/
void download(Integer id);
} }
package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Admin;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.mapper.AdminMapper;
import com.fzm.common.service.AdminService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2021/7/5 15:09
*/
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
@Resource
private PasswordEncoder passwordEncoder;
@Override
public Admin login(String username, String password) {
QueryWrapper<Admin> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username", username);
Admin admin = getOne(queryWrapper);
if (admin == null) {
throw GlobalException.newException(ResultCode.UNAUTHORIZED, "您还没有注册");
}
if (!passwordEncoder.matches(password, admin.getPassword())) {
throw GlobalException.newException(ResultCode.UNAUTHORIZED, "密码有误");
}
return admin;
}
}
...@@ -3,15 +3,19 @@ package com.fzm.common.service.impl; ...@@ -3,15 +3,19 @@ package com.fzm.common.service.impl;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.fzm.chain.simplesdk.client.ParaChainClient; import cn.fzm.chain.simplesdk.client.ParaChainClient;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.constant.RedisConstant; import com.fzm.common.constant.RedisConstant;
import com.fzm.common.constant.SystemConstant; import com.fzm.common.constant.SystemConstant;
import com.fzm.common.entity.BaseEntity;
import com.fzm.common.entity.Category; import com.fzm.common.entity.Category;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.User; import com.fzm.common.entity.User;
import com.fzm.common.entity.vo.CollectionNftVo; import com.fzm.common.entity.vo.CollectionNftVo;
import com.fzm.common.entity.vo.NftListVo;
import com.fzm.common.enums.ResultCode; import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException; import com.fzm.common.exception.GlobalException;
import com.fzm.common.mapper.NftMapper; import com.fzm.common.mapper.NftMapper;
...@@ -19,7 +23,10 @@ import com.fzm.common.service.CategoryService; ...@@ -19,7 +23,10 @@ import com.fzm.common.service.CategoryService;
import com.fzm.common.service.NftService; import com.fzm.common.service.NftService;
import com.fzm.common.service.UserService; import com.fzm.common.service.UserService;
import com.fzm.common.utils.JsonUtil; import com.fzm.common.utils.JsonUtil;
import com.fzm.common.utils.OssUtil;
import com.fzm.common.utils.RedisUtil; import com.fzm.common.utils.RedisUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -52,6 +59,9 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -52,6 +59,9 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
@Resource @Resource
private CategoryService categoryService; private CategoryService categoryService;
@Resource
private OssUtil ossUtil;
@Value("${chain.para.contract-name}") @Value("${chain.para.contract-name}")
private String contractName; private String contractName;
...@@ -127,8 +137,63 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe ...@@ -127,8 +137,63 @@ public class NftServiceImpl extends ServiceImpl<NftMapper, Nft> implements NftSe
return String.format("JOYING-%s-%s%s", category.getEnglishName(), System.currentTimeMillis(), code); return String.format("JOYING-%s-%s%s", category.getEnglishName(), System.currentTimeMillis(), code);
} }
public static void main(String[] args) { @Override
int code = RandomUtil.randomInt(1000, 10000); public PageInfo<NftListVo> page(Integer pageNum, Integer pageSize, Integer categoryId, String name, String theme, String telephone, Integer status, String start, String end) {
System.out.println(String.format("JOYING-%s-%s%s", "SCRIPT", System.currentTimeMillis(), code)); PageHelper.startPage(pageNum, pageSize);
DateTime startDate = null;
DateTime endDate = null;
if (StringUtils.isNotBlank(start)) {
startDate = DateUtil.parse(start + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
}
if (StringUtils.isNotBlank(end)) {
endDate = DateUtil.parse(end + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
}
List<NftListVo> list = nftMapper.page(categoryId, name, telephone, theme, status, startDate, endDate);
return new PageInfo<>(list);
}
@Override
public Boolean top(Integer id) {
Nft nft = new Nft();
nft.setIsTop(SystemConstant.BOOLEAN_DATA_TRUE);
nft.setId(id);
return updateById(nft);
}
@Override
public Boolean untop(Integer id) {
Nft nft = new Nft();
nft.setIsTop(SystemConstant.BOOLEAN_DATA_FALSE);
nft.setId(id);
return updateById(nft);
} }
@Override
public Boolean onShelf(Integer id) {
Nft nft = new Nft();
nft.setStatus(SystemConstant.BOOLEAN_DATA_TRUE);
nft.setId(id);
return updateById(nft);
}
@Override
public Boolean offShelf(Integer id) {
Nft nft = new Nft();
nft.setStatus(SystemConstant.BOOLEAN_DATA_FALSE);
nft.setId(id);
return updateById(nft);
}
@Override
public void download(Integer id) {
Nft nft = getById(id);
if (nft == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "没找到此nft详情");
}
if (SystemConstant.BOOLEAN_DATA_FALSE.equals(nft.getIsArchives()) || SystemConstant.BOOLEAN_DATA_TRUE.equals(nft.getIsGrant())) {
throw GlobalException.newException(ResultCode.FILE_DOWNLOAD_ERROR, "当前文件不支持下载");
}
ossUtil.downloadFile(nft.getFileUrl(), nft.getFileName());
}
} }
...@@ -5,7 +5,10 @@ import cn.hutool.core.util.IdUtil; ...@@ -5,7 +5,10 @@ import cn.hutool.core.util.IdUtil;
import com.aliyun.oss.OSS; import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*; import com.aliyun.oss.model.*;
import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException;
import com.fzm.common.properties.OssProperties; import com.fzm.common.properties.OssProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
...@@ -13,12 +16,14 @@ import javax.annotation.Resource; ...@@ -13,12 +16,14 @@ import javax.annotation.Resource;
import javax.servlet.ServletOutputStream; import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.net.URLEncoder;
import java.util.Date; import java.util.Date;
/** /**
* @author tangtuo * @author tangtuo
* @date 2021/6/29 16:07 * @date 2021/6/29 16:07
*/ */
@Slf4j
@Component @Component
public class OssUtil { public class OssUtil {
...@@ -95,22 +100,27 @@ public class OssUtil { ...@@ -95,22 +100,27 @@ public class OssUtil {
/** /**
* 下载文件 * @param fileUrl 文件地址
* * @param fileName 文件名
* @param file
*/ */
public void downloadFile(String file) { public void downloadFile(String fileUrl, String fileName) {
String endpoint = ossProperties.getEndPoint(); String endpoint = ossProperties.getEndPoint();
// 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。 // 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录RAM控制台创建RAM账号。
String accessKeyId = ossProperties.getAppKey(); String accessKeyId = ossProperties.getAppKey();
String accessKeySecret = ossProperties.getAppSecret(); String accessKeySecret = ossProperties.getAppSecret();
String bucketName = ossProperties.getEncryptBucket(); String bucketName = ossProperties.getEncryptBucket();
try {
// 文件名以附件的形式下载
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
} catch (UnsupportedEncodingException e) {
log.error(e.getMessage(), e);
throw GlobalException.newException(ResultCode.FILE_DOWNLOAD_ERROR, e.getMessage());
}
// 创建OSSClient实例。 // 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。 // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
file = file.replace(String.format("https://%s.%s/", bucketName, endpoint), ""); fileUrl = fileUrl.replace(String.format("https://%s.%s/", bucketName, endpoint), "");
OSSObject ossObject = ossClient.getObject(bucketName, file); OSSObject ossObject = ossClient.getObject(bucketName, fileUrl);
try { try {
// 读取文件内容。 // 读取文件内容。
InputStream inputStream = ossObject.getObjectContent(); InputStream inputStream = ossObject.getObjectContent();
...@@ -129,9 +139,9 @@ public class OssUtil { ...@@ -129,9 +139,9 @@ public class OssUtil {
if (in != null) { if (in != null) {
in.close(); in.close();
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error(e.getMessage(), e);
throw GlobalException.newException(ResultCode.FILE_DOWNLOAD_ERROR, e.getMessage());
} }
} }
......
...@@ -26,4 +26,49 @@ ...@@ -26,4 +26,49 @@
) )
</select> </select>
<select id="page" resultType="com.fzm.common.entity.vo.NftListVo">
SELECT
n.id,
n.`name`,
n.theme,
n.`status`,
n.is_top,
n.publish_time,
u.nickname AS publisherNickname,
u.telephone AS publisherAccount
FROM
tb_nft n
LEFT JOIN tb_user u ON n.user_id = u.id
WHERE
1 = 1
<if test="name != null and name != ''">
and n.name like concat ('%',#{name},'%')
</if>
<if test="categoryId != null">
and n.category_id = #{categoryId}
</if>
<if test="theme != null and theme != ''">
and FIND_IN_SET(#{theme},n.theme)
</if>
<if test="categoryId != null">
and n.category_id = #{categoryId}
</if>
<if test="status != null">
and n.status = #{status}
</if>
<if test="telephone != null and telephone != ''">
and u.telephone = #{telephone}
</if>
<if test="startDate != null">
and n.create_date >= #{startDate}
</if>
<if test="endDate != null">
and n.create_date &lt;= #{endDate}
</if>
ORDER BY
is_top DESC,
`status` DESC,
publish_time DESC
</select>
</mapper> </mapper>
\ No newline at end of file
...@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckLogin; ...@@ -4,7 +4,6 @@ import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.SecureUtil;
import com.fzm.common.constant.SystemConstant; import com.fzm.common.constant.SystemConstant;
import com.fzm.common.entity.Category;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.User; import com.fzm.common.entity.User;
import com.fzm.common.entity.vo.CollectionNftVo; import com.fzm.common.entity.vo.CollectionNftVo;
...@@ -70,6 +69,10 @@ public class NftController { ...@@ -70,6 +69,10 @@ public class NftController {
if (file == null || isGrant == null) { if (file == null || isGrant == null) {
throw GlobalException.newException(ResultCode.VALIDATE_FAILED, "当选择加密存档的时候,文件和授权阅读不能为空"); throw GlobalException.newException(ResultCode.VALIDATE_FAILED, "当选择加密存档的时候,文件和授权阅读不能为空");
} }
// 判断文件的hash是否被篡改过
if (!SecureUtil.md5(file.getInputStream()).equals(fileHash)) {
throw GlobalException.newException(ResultCode.VALIDATE_FAILED, "文件hash和文件内容不匹配");
}
String fileUrl = ossUtil.putEncryptObject(file); String fileUrl = ossUtil.putEncryptObject(file);
nft.setFileUrl(fileUrl).setIsGrant(isGrant).setFileName(file.getOriginalFilename()); nft.setFileUrl(fileUrl).setIsGrant(isGrant).setFileName(file.getOriginalFilename());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment