market业务模块token相关基础代码初始化
parent
19f81d622c
commit
f7228dccee
|
|
@ -0,0 +1,64 @@
|
||||||
|
package cn.iocoder.yudao.module.market.enums;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Market 错误码枚举类 TODO
|
||||||
|
*
|
||||||
|
* market 系统,使用 1-008-000-000 段
|
||||||
|
*/
|
||||||
|
public interface ErrorCodeConstants {
|
||||||
|
|
||||||
|
// ========== 公众号账号 1008000000============
|
||||||
|
ErrorCode ACCOUNT_NOT_EXISTS = new ErrorCode(1008000000, "公众号账号不存在");
|
||||||
|
ErrorCode ACCOUNT_GENERATE_QR_CODE_FAIL = new ErrorCode(1008000001, "生成公众号二维码失败,原因:{}");
|
||||||
|
ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1008000002, "清空公众号的 API 配额失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号统计 1008001000============
|
||||||
|
ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1008001000, "获取粉丝增减数据失败,原因:{}");
|
||||||
|
ErrorCode STATISTICS_GET_USER_CUMULATE_FAIL = new ErrorCode(1008001001, "获得粉丝累计数据失败,原因:{}");
|
||||||
|
ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1008001002, "获得消息发送概况数据失败,原因:{}");
|
||||||
|
ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1008001003, "获得接口分析数据失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号标签 1008002000============
|
||||||
|
ErrorCode TAG_NOT_EXISTS = new ErrorCode(1008002000, "标签不存在");
|
||||||
|
ErrorCode TAG_CREATE_FAIL = new ErrorCode(1008002001, "创建标签失败,原因:{}");
|
||||||
|
ErrorCode TAG_UPDATE_FAIL = new ErrorCode(1008002002, "更新标签失败,原因:{}");
|
||||||
|
ErrorCode TAG_DELETE_FAIL = new ErrorCode(1008002003, "删除标签失败,原因:{}");
|
||||||
|
ErrorCode TAG_GET_FAIL = new ErrorCode(1008002004, "获得标签失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号粉丝 1008003000============
|
||||||
|
ErrorCode USER_NOT_EXISTS = new ErrorCode(1008003000, "粉丝不存在");
|
||||||
|
ErrorCode USER_UPDATE_TAG_FAIL = new ErrorCode(1008003001, "更新粉丝标签失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号素材 1008004000============
|
||||||
|
ErrorCode MATERIAL_NOT_EXISTS = new ErrorCode(1008004000, "素材不存在");
|
||||||
|
ErrorCode MATERIAL_UPLOAD_FAIL = new ErrorCode(1008004001, "上传素材失败,原因:{}");
|
||||||
|
ErrorCode MATERIAL_IMAGE_UPLOAD_FAIL = new ErrorCode(1008004002, "上传图片失败,原因:{}");
|
||||||
|
ErrorCode MATERIAL_DELETE_FAIL = new ErrorCode(1008004003, "删除素材失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号消息 1008005000============
|
||||||
|
ErrorCode MESSAGE_SEND_FAIL = new ErrorCode(1008005000, "发送消息失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号发布能力 1008006000============
|
||||||
|
ErrorCode FREE_PUBLISH_LIST_FAIL = new ErrorCode(1008006000, "获得已成功发布列表失败,原因:{}");
|
||||||
|
ErrorCode FREE_PUBLISH_SUBMIT_FAIL = new ErrorCode(1008006001, "提交发布失败,原因:{}");
|
||||||
|
ErrorCode FREE_PUBLISH_DELETE_FAIL = new ErrorCode(1008006002, "删除发布失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号草稿 1008007000============
|
||||||
|
ErrorCode DRAFT_LIST_FAIL = new ErrorCode(1008007000, "获得草稿列表失败,原因:{}");
|
||||||
|
ErrorCode DRAFT_CREATE_FAIL = new ErrorCode(1008007001, "创建草稿失败,原因:{}");
|
||||||
|
ErrorCode DRAFT_UPDATE_FAIL = new ErrorCode(1008007002, "更新草稿失败,原因:{}");
|
||||||
|
ErrorCode DRAFT_DELETE_FAIL = new ErrorCode(1008007003, "删除草稿失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号菜单 1008008000============
|
||||||
|
ErrorCode MENU_SAVE_FAIL = new ErrorCode(1008008000, "创建菜单失败,原因:{}");
|
||||||
|
ErrorCode MENU_DELETE_FAIL = new ErrorCode(1008008001, "删除菜单失败,原因:{}");
|
||||||
|
|
||||||
|
// ========== 公众号自动回复 1008009000============
|
||||||
|
ErrorCode AUTO_REPLY_NOT_EXISTS = new ErrorCode(1008009000, "自动回复不存在");
|
||||||
|
ErrorCode AUTO_REPLY_ADD_SUBSCRIBE_FAIL_EXISTS = new ErrorCode(1008009001, "操作失败,原因:已存在关注时的回复");
|
||||||
|
ErrorCode AUTO_REPLY_ADD_MESSAGE_FAIL_EXISTS = new ErrorCode(1008009002, "操作失败,原因:已存在该消息类型的回复");
|
||||||
|
ErrorCode AUTO_REPLY_ADD_KEYWORD_FAIL_EXISTS = new ErrorCode(1008009003, "操作失败,原因:已关在该关键字的回复");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* market 模块,我们放市场数据收集处理业务模块。
|
||||||
|
* 例如说:提供市场数据收集,基础清理,基础计算,基础统计,消息通等功能
|
||||||
|
*
|
||||||
|
* 1. Controller URL:以 /market/ 开头,避免和其它 Module 冲突
|
||||||
|
* 2. DataObject 表名:以 market_ 开头,方便在数据库中区分
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market;
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.market;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目的启动类
|
||||||
|
*
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
* 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MarketServerApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
|
||||||
|
SpringApplication.run(MarketServerApplication.class, args);
|
||||||
|
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
// 如果你碰到启动的问题,请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package cn.iocoder.yudao.module.market.controller.admin.market;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.market.service.info.TokenInfoService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 公众号账号")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mp/account")
|
||||||
|
@Validated
|
||||||
|
public class TokenInfoController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TokenInfoService tokenInfoService;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// @GetMapping("/page")
|
||||||
|
// @Operation(summary = "获得公众号账号分页")
|
||||||
|
// @PreAuthorize("@ss.hasPermission('mp:account:query')")
|
||||||
|
// public CommonResult<PageResult<MpAccountRespVO>> getAccountPage(@Valid MpAccountPageReqVO pageVO) {
|
||||||
|
// PageResult<MpAccountDO> pageResult = tokenInfoService.getAccountPage(pageVO);
|
||||||
|
// return success(MpAccountConvert.INSTANCE.convertPage(pageResult));
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package cn.iocoder.yudao.module.market.controller.admin.market.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号账号 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||||
|
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||||
|
*
|
||||||
|
* @author fengdan
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TokenInfoBaseVO {
|
||||||
|
|
||||||
|
@Schema(description = "公众号名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道源码")
|
||||||
|
@NotEmpty(message = "公众号名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "公众号微信号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudaoyuanma")
|
||||||
|
@NotEmpty(message = "公众号微信号不能为空")
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
@Schema(description = "公众号 appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "wx5b23ba7a5589ecbb")
|
||||||
|
@NotEmpty(message = "公众号 appId 不能为空")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "3a7b3b20c537e52e74afd395eb85f61f")
|
||||||
|
@NotEmpty(message = "公众号密钥不能为空")
|
||||||
|
private String appSecret;
|
||||||
|
|
||||||
|
@Schema(description = "公众号 token", requiredMode = Schema.RequiredMode.REQUIRED, example = "kangdayuzhen")
|
||||||
|
@NotEmpty(message = "公众号 token 不能为空")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Schema(description = "加密密钥", example = "gjN+Ksei")
|
||||||
|
private String aesKey;
|
||||||
|
|
||||||
|
@Schema(description = "备注", example = "请关注芋道源码,学习技术")
|
||||||
|
private String remark;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package cn.iocoder.yudao.module.market.controller.admin.market.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 公众号账号分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class TokenInfoageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(name = "公众号名称", description = "模糊匹配")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(name = "公众号账号", description = "模糊匹配")
|
||||||
|
private String account;
|
||||||
|
|
||||||
|
@Schema(name = "公众号 appid", description = "模糊匹配")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
### 请求 /mp/material/page 接口 => 成功
|
||||||
|
GET {{baseUrl}}/mp/material/page?permanent=true&pageNo=1&pageSize=10
|
||||||
|
Content-Type: application/json
|
||||||
|
Authorization: Bearer {{token}}
|
||||||
|
tenant-id: {{adminTenentId}}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package cn.iocoder.yudao.module.market.controller.admin.material;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.market.service.rank.TokenRankService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 公众号素材")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mp/material")
|
||||||
|
@Validated
|
||||||
|
public class MpMaterialController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TokenRankService tokenRankService;
|
||||||
|
|
||||||
|
// @GetMapping("/page")
|
||||||
|
// @Operation(summary = "获得公众号账号分页")
|
||||||
|
// @PreAuthorize("@ss.hasPermission('mp:account:query')")
|
||||||
|
// public CommonResult<PageResult<MpAccountRespVO>> getAccountPage(@Valid MpAccountPageReqVO pageVO) {
|
||||||
|
// PageResult<MpAccountDO> pageResult = tokenRankService.getAccountPage(pageVO);
|
||||||
|
// return success(MpAccountConvert.INSTANCE.convertPage(pageResult));
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cn.iocoder.yudao.module.market.controller.admin.material.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 公众号素材的分页 Request VO")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class TokenRankPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "公众号账号的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048")
|
||||||
|
@NotNull(message = "公众号账号的编号不能为空")
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
@Schema(description = "是否永久", example = "true")
|
||||||
|
private Boolean permanent;
|
||||||
|
|
||||||
|
@Schema(description = "文件类型 参见 WxConsts.MediaFileType 枚举", example = "image")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* 提供 RESTful API 给前端:
|
||||||
|
* 1. admin 包:提供给管理后台 yudao-ui-admin 前端项目
|
||||||
|
* 2. app 包:提供给用户 APP yudao-ui-app 前端项目,它的 Controller 和 VO 都要添加 App 前缀,用于和管理后台进行区分
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market.controller;
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package cn.iocoder.yudao.module.market.convert.account;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountSimpleRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.account.vo.MpAccountUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MpAccountConvert {
|
||||||
|
|
||||||
|
MpAccountConvert INSTANCE = Mappers.getMapper(MpAccountConvert.class);
|
||||||
|
|
||||||
|
MpAccountDO convert(MpAccountCreateReqVO bean);
|
||||||
|
|
||||||
|
MpAccountDO convert(MpAccountUpdateReqVO bean);
|
||||||
|
|
||||||
|
MpAccountRespVO convert(MpAccountDO bean);
|
||||||
|
|
||||||
|
List<MpAccountRespVO> convertList(List<MpAccountDO> list);
|
||||||
|
|
||||||
|
PageResult<MpAccountRespVO> convertPage(PageResult<MpAccountDO> page);
|
||||||
|
|
||||||
|
List<MpAccountSimpleRespVO> convertList02(List<MpAccountDO> list);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package cn.iocoder.yudao.module.market.convert.material;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.material.vo.MpMaterialRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.material.vo.MpMaterialUploadRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.material.MpMaterialDO;
|
||||||
|
import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface MpMaterialConvert {
|
||||||
|
|
||||||
|
MpMaterialConvert INSTANCE = Mappers.getMapper(MpMaterialConvert.class);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(target = "id", ignore = true),
|
||||||
|
@Mapping(source = "account.id", target = "accountId"),
|
||||||
|
@Mapping(source = "account.appId", target = "appId"),
|
||||||
|
@Mapping(source = "name", target = "name")
|
||||||
|
})
|
||||||
|
MpMaterialDO convert(String mediaId, String type, String url, MpAccountDO account,
|
||||||
|
String name);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(target = "id", ignore = true),
|
||||||
|
@Mapping(source = "account.id", target = "accountId"),
|
||||||
|
@Mapping(source = "account.appId", target = "appId"),
|
||||||
|
@Mapping(source = "name", target = "name")
|
||||||
|
})
|
||||||
|
MpMaterialDO convert(String mediaId, String type, String url, MpAccountDO account,
|
||||||
|
String name, String title, String introduction, String mpUrl);
|
||||||
|
|
||||||
|
MpMaterialUploadRespVO convert(MpMaterialDO bean);
|
||||||
|
|
||||||
|
default WxMpMaterial convert(String name, File file, String title, String introduction) {
|
||||||
|
return new WxMpMaterial(name, file, title, introduction);
|
||||||
|
}
|
||||||
|
|
||||||
|
PageResult<MpMaterialRespVO> convertPage(PageResult<MpMaterialDO> page);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,136 @@
|
||||||
|
package cn.iocoder.yudao.module.market.dal.dataobject.info;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TOKEN基本信息 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("mk_token_info")
|
||||||
|
@KeySequence("mk_token_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TokenInfoDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 交易货币币种
|
||||||
|
*/
|
||||||
|
private String baseCcy;
|
||||||
|
/**
|
||||||
|
* 合约乘数,仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String ctMult;
|
||||||
|
/**
|
||||||
|
* 上线日期
|
||||||
|
*/
|
||||||
|
private LocalDateTime listDate;
|
||||||
|
/**
|
||||||
|
* 合约面值,仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String ctVal;
|
||||||
|
/**
|
||||||
|
* 合约面值计价币种,仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String ctValCcy;
|
||||||
|
/**
|
||||||
|
* 交割/行权日期,仅适用于交割 和 期权
|
||||||
|
*/
|
||||||
|
private LocalDateTime expDate;
|
||||||
|
/**
|
||||||
|
* 交易品种,如 BTC-USD,仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String instFamily;
|
||||||
|
/**
|
||||||
|
* 产品id, 如 BTC-USD-SWAP
|
||||||
|
*/
|
||||||
|
private String instId;
|
||||||
|
/**
|
||||||
|
* 产品类型 币币 SPOT 币币杠杆 MARGIN 永续合约 SWAP 交割合约 FUTURES 期权 OPTION
|
||||||
|
*/
|
||||||
|
private String instType;
|
||||||
|
/**
|
||||||
|
* 该instId支持的最大杠杆倍数,不适用于币币、期权
|
||||||
|
*/
|
||||||
|
private String lever;
|
||||||
|
/**
|
||||||
|
* 下单数量精度,如 BTC-USDT-SWAP:1
|
||||||
|
*/
|
||||||
|
private String lotSz;
|
||||||
|
/**
|
||||||
|
* 合约或现货冰山委托的单笔最大委托数量
|
||||||
|
*/
|
||||||
|
private String maxIcebergSz;
|
||||||
|
/**
|
||||||
|
* 最大限制数量
|
||||||
|
*/
|
||||||
|
private String maxLmtSz;
|
||||||
|
/**
|
||||||
|
* 合约或现货市价单的单笔最大委托数量
|
||||||
|
*/
|
||||||
|
private String maxMktSz;
|
||||||
|
/**
|
||||||
|
* 合约或现货止盈止损委托的单笔最大委托数量
|
||||||
|
*/
|
||||||
|
private String maxStopSz;
|
||||||
|
/**
|
||||||
|
* 合约或现货计划委托委托的单笔最大委托数量
|
||||||
|
*/
|
||||||
|
private String maxTriggerSz;
|
||||||
|
/**
|
||||||
|
* 合约或现货时间加权单的单笔最大委托数量
|
||||||
|
*/
|
||||||
|
private String maxTwapSz;
|
||||||
|
/**
|
||||||
|
* 最小下单数量
|
||||||
|
*/
|
||||||
|
private String minSz;
|
||||||
|
/**
|
||||||
|
* 期权类型,C或P 仅适用于期权
|
||||||
|
*/
|
||||||
|
private String optType;
|
||||||
|
/**
|
||||||
|
* 计价货币币种,如 BTC-USDT 中的USDT ,仅适用于币币/币币杠杆
|
||||||
|
*/
|
||||||
|
private String quoteCcy;
|
||||||
|
/**
|
||||||
|
* 盈亏结算和保证金币种,如 BTC 仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String settleCcy;
|
||||||
|
/**
|
||||||
|
* * 产品状态 * live:交易中 * suspend:暂停中 * preopen:预上线 * test:测试中(测试产品,不可交易) * 当合约预上线时,状态变更为预上线(即新生成一个合约,新合约会处于预上线状态); * 当产品下线的时候(如交割合约被交割的时候,期权合约被行权的时候),查询不到该产品
|
||||||
|
*/
|
||||||
|
private String state;
|
||||||
|
/**
|
||||||
|
* 行权价格,仅适用于期权
|
||||||
|
*/
|
||||||
|
private String stk;
|
||||||
|
/**
|
||||||
|
* 下单价格精度,如 0.0001
|
||||||
|
*/
|
||||||
|
private String tickSz;
|
||||||
|
/**
|
||||||
|
* 标的指数,如 BTC-USD,仅适用于交割/永续/期权
|
||||||
|
*/
|
||||||
|
private String uly;
|
||||||
|
/**
|
||||||
|
* 交易所类型 1 币安交易所 2 欧易交易所 3 芝麻开门交易所
|
||||||
|
*/
|
||||||
|
private Byte exchangeType;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package cn.iocoder.yudao.module.market.dal.dataobject.rank;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TOKEN排名信息 DO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@TableName("mk_token_rank")
|
||||||
|
@KeySequence("mk_token_rank_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TokenRankDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Integer id;
|
||||||
|
/**
|
||||||
|
* 币种基础名称
|
||||||
|
*/
|
||||||
|
private String tokenBaseName;
|
||||||
|
/**
|
||||||
|
* 是否有最新事件触发(0:没有 1:有)
|
||||||
|
*/
|
||||||
|
private Byte event;
|
||||||
|
/**
|
||||||
|
* 是否有近期热点消息(0:没有 1:有)
|
||||||
|
*/
|
||||||
|
private Byte hot;
|
||||||
|
/**
|
||||||
|
* 市值排名
|
||||||
|
*/
|
||||||
|
private Integer capRanking;
|
||||||
|
/**
|
||||||
|
* 近期交易量
|
||||||
|
*/
|
||||||
|
private Object volRanking;
|
||||||
|
/**
|
||||||
|
* 板块概念
|
||||||
|
*/
|
||||||
|
private String concept;
|
||||||
|
/**
|
||||||
|
* 根据币种成交量 热度等生成的排名值 排名值越高币种策略价值越高
|
||||||
|
*/
|
||||||
|
private Byte comprehensiveRanking;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.iocoder.yudao.module.market.dal.mysql.info;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.market.controller.admin.market.vo.TokenInfoageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.market.dal.dataobject.info.TokenInfoDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TokenInfoMapper extends BaseMapperX<TokenInfoDO> {
|
||||||
|
|
||||||
|
default PageResult<TokenInfoDO> selectPage(TokenInfoageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<TokenInfoDO>()
|
||||||
|
.likeIfPresent(TokenInfoDO::getInstId, reqVO.getName())
|
||||||
|
.likeIfPresent(TokenInfoDO::getExchangeType, reqVO.getAccount())
|
||||||
|
.orderByDesc(TokenInfoDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
package cn.iocoder.yudao.module.market.dal.mysql.rank;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.market.controller.admin.material.vo.TokenRankPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.market.dal.dataobject.rank.TokenRankDO;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface TokenRankMapper extends BaseMapperX<TokenRankDO> {
|
||||||
|
|
||||||
|
default PageResult<TokenRankDO> selectPage(TokenRankPageReqVO pageReqVO) {
|
||||||
|
return selectPage(pageReqVO, new LambdaQueryWrapperX<TokenRankDO>()
|
||||||
|
.eq(TokenRankDO::getHot, pageReqVO.getAccountId())
|
||||||
|
.eqIfPresent(TokenRankDO::getTokenBaseName, pageReqVO.getPermanent())
|
||||||
|
.orderByDesc(TokenRankDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.market.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信公众号的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class MarketConfiguration {
|
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||||
|
// public RedisTemplateWxRedisOps redisTemplateWxRedisOps(StringRedisTemplate stringRedisTemplate) {
|
||||||
|
// return new RedisTemplateWxRedisOps(stringRedisTemplate);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Bean
|
||||||
|
// @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
|
||||||
|
// public MpServiceFactory mpServiceFactory(RedisTemplateWxRedisOps redisTemplateWxRedisOps,
|
||||||
|
// WxMpProperties wxMpProperties,
|
||||||
|
// MessageReceiveHandler messageReceiveHandler,
|
||||||
|
// KfSessionHandler kfSessionHandler,
|
||||||
|
// StoreCheckNotifyHandler storeCheckNotifyHandler,
|
||||||
|
// MenuHandler menuHandler,
|
||||||
|
// NullHandler nullHandler,
|
||||||
|
// SubscribeHandler subscribeHandler,
|
||||||
|
// UnsubscribeHandler unsubscribeHandler,
|
||||||
|
// LocationHandler locationHandler,
|
||||||
|
// ScanHandler scanHandler,
|
||||||
|
// MessageAutoReplyHandler messageAutoReplyHandler) {
|
||||||
|
// return new DefaultMpServiceFactory(redisTemplateWxRedisOps, wxMpProperties,
|
||||||
|
// messageReceiveHandler, kfSessionHandler, storeCheckNotifyHandler, menuHandler,
|
||||||
|
// nullHandler, subscribeHandler, unsubscribeHandler, locationHandler, scanHandler, messageAutoReplyHandler);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.market.core;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认的 {@link MarketServiceFactory} 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class DefaultMarketServiceFactory implements MarketServiceFactory {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.market.core;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link WxMpService} 工厂接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface MarketServiceFactory {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2025, zengtao All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
* Author: zengtao (w1999wtw3537@gmail.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cn.iocoder.yudao.module.market.framework.market.core.context;
|
||||||
|
|
||||||
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信上下文 Context
|
||||||
|
*
|
||||||
|
* 目的:解决微信多公众号的问题,在 {@link WxMpMessageHandler} 实现类中,可以通过 {@link #getAppId()} 获取到当前的 appId
|
||||||
|
*
|
||||||
|
* @see MpOpenController#handleMessage(String, String, MpOpenHandleMessageReqVO)
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class MarketContextHolder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信公众号的 appId 上下文
|
||||||
|
*/
|
||||||
|
private static final ThreadLocal<String> APPID = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
|
public static void setAppId(String appId) {
|
||||||
|
APPID.set(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getAppId() {
|
||||||
|
return APPID.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
APPID.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.market.core.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import javax.validation.Validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号工具类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class MarketUtils {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* 属于 mp 模块的 framework 封装
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market.framework;
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.rpc.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
@EnableFeignClients(clients = FileApi.class)
|
||||||
|
public class RpcConfiguration {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market.framework.rpc;
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.security.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
|
||||||
|
import cn.iocoder.yudao.module.system.enums.ApiConstants;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System 模块的 Security 配置
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false, value = "systemSecurityConfiguration")
|
||||||
|
public class SecurityConfiguration {
|
||||||
|
|
||||||
|
@Bean("systemAuthorizeRequestsCustomizer")
|
||||||
|
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
|
||||||
|
return new AuthorizeRequestsCustomizer() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
|
||||||
|
// TODO 芋艿:这个每个项目都需要重复配置,得捉摸有没通用的方案
|
||||||
|
// Swagger 接口文档
|
||||||
|
registry.antMatchers("/v3/api-docs/**").permitAll() // 元数据
|
||||||
|
.antMatchers("/swagger-ui.html").permitAll(); // Swagger UI
|
||||||
|
// Druid 监控
|
||||||
|
registry.antMatchers("/druid/**").anonymous();
|
||||||
|
// Spring Boot Actuator 的安全配置
|
||||||
|
registry.antMatchers("/actuator").anonymous()
|
||||||
|
.antMatchers("/actuator/**").anonymous();
|
||||||
|
// RPC 服务的安全配置
|
||||||
|
registry.antMatchers(ApiConstants.PREFIX + "/**").permitAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* 占位
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market.framework.security.core;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package cn.iocoder.yudao.module.market.framework.web.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration;
|
||||||
|
import org.springdoc.core.GroupedOpenApi;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* market 模块的 web 组件的 Configuration
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
public class MpWebConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mp 模块的 API 分组
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public GroupedOpenApi mpGroupedOpenApi() {
|
||||||
|
return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("market");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/**
|
||||||
|
* mp 模块的 web 配置
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market.framework.web;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/**
|
||||||
|
* mp 模块,我们放微信微信公众号。
|
||||||
|
* 例如说:提供微信公众号的账号、菜单、粉丝、标签、消息、自动回复、素材、模板通知、运营数据等功能
|
||||||
|
*
|
||||||
|
* 1. Controller URL:以 /mp/ 开头,避免和其它 Module 冲突
|
||||||
|
* 2. DataObject 表名:以 mp_ 开头,方便在数据库中区分
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.market;
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cn.iocoder.yudao.module.market.service.info;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号账号 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface TokenInfoService {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package cn.iocoder.yudao.module.market.service.info;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号账号 Service 实现类
|
||||||
|
*
|
||||||
|
* @author fengdan
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class TokenInfoServiceImpl implements TokenInfoService {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cn.iocoder.yudao.module.market.service.rank;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TokenRank Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public interface TokenRankService {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package cn.iocoder.yudao.module.market.service.rank;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号素材 Service 接口
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
@Slf4j
|
||||||
|
public class TokenRankServiceImpl implements TokenRankService {
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue