feat:会员代码生成

This commit is contained in:
dzc committed 2025-11-10 09:39:28 +08:00
1 parent 29e3b787b0
commit 142f9486fb
13 files changed
+603 -4

No files matched your search

+48 -1
View File
@@ -163,4 +163,51 @@ CREATE TABLE `member_location`
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户位置记录';
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户位置记录';
-- ----------------------------
-- Table structure for member_open_type
-- ----------------------------
DROP TABLE IF EXISTS `member_open_type`;
CREATE TABLE `member_open_type`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '会员开通类型',
`title` varchar(128) NOT NULL COMMENT '会员开通分类标题',
`icon` varchar(256) DEFAULT NULL COMMENT '图标',
`preferential_price` int NOT NULL COMMENT '价格(优惠价)',
`original_price` int NOT NULL COMMENT '价格(原价)',
`duration` int NOT NULL COMMENT '时长(天)',
`status` char(32) NOT NULL COMMENT '状态',
`is_hot` char(32) NOT NULL COMMENT '是否热门',
`sort` int DEFAULT 0 NOT NULL COMMENT '排序',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '会员开通类型';
-- ----------------------------
-- Table structure for member_open_type_user
-- ----------------------------
DROP TABLE IF EXISTS `member_open_type_user`;
CREATE TABLE `member_open_type_user`
(
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '会员开通类型与用户关联表',
`open_type_id` bigint NOT NULL COMMENT '会员开通类型编号',
`member_id` bigint NOT NULL COMMENT '用户编号',
`pay_price` int NOT NULL COMMENT '购买价格',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime NOT NULL COMMENT '结束时间',
`status` char(32) NOT NULL COMMENT '状态',
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '会员开通类型与用户关联表';
@@ -72,4 +72,7 @@ public interface MemberErrorCode {
//========== 用户位置管理 1-004-015-000 ==========
ErrorCode LOCATION_NOT_EXISTS = new ErrorCode(1_004_015_000, "用户位置不存在");
//========== 会员开通类型 1-004-016-000 ==========
ErrorCode OPEN_TYPE_NOT_EXISTS = new ErrorCode(1_004_016_000, "开通类型不存在");
}
@@ -0,0 +1,97 @@
package cn.iocoder.yudao.module.member.controller.admin.opentype;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.member.controller.admin.opentype.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeDO;
import cn.iocoder.yudao.module.member.service.opentype.OpenTypeService;
@Tag(name = "管理后台 - 会员类型")
@RestController
@RequestMapping("/member/open-type")
@Validated
public class OpenTypeController {
@Resource
private OpenTypeService openTypeService;
@PostMapping("/create")
@Operation(summary = "创建会员类型")
@PreAuthorize("@ss.hasPermission('member:open-type:create')")
public CommonResult<Long> createOpenType(@Valid @RequestBody OpenTypeSaveReqVO createReqVO) {
return success(openTypeService.createOpenType(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新会员类型")
@PreAuthorize("@ss.hasPermission('member:open-type:update')")
public CommonResult<Boolean> updateOpenType(@Valid @RequestBody OpenTypeSaveReqVO updateReqVO) {
openTypeService.updateOpenType(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除会员类型")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:open-type:delete')")
public CommonResult<Boolean> deleteOpenType(@RequestParam("id") Long id) {
openTypeService.deleteOpenType(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得会员类型")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:open-type:query')")
public CommonResult<OpenTypeRespVO> getOpenType(@RequestParam("id") Long id) {
OpenTypeDO openType = openTypeService.getOpenType(id);
return success(BeanUtils.toBean(openType, OpenTypeRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得会员类型分页")
@PreAuthorize("@ss.hasPermission('member:open-type:query')")
public CommonResult<PageResult<OpenTypeRespVO>> getOpenTypePage(@Valid OpenTypePageReqVO pageReqVO) {
PageResult<OpenTypeDO> pageResult = openTypeService.getOpenTypePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, OpenTypeRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出会员类型 Excel")
@PreAuthorize("@ss.hasPermission('member:open-type:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportOpenTypeExcel(@Valid OpenTypePageReqVO pageReqVO, HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<OpenTypeDO> list = openTypeService.getOpenTypePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "会员类型.xls", "数据", OpenTypeRespVO.class, BeanUtils.toBean(list, OpenTypeRespVO.class));
}
}
@@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.member.controller.admin.opentype.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 会员类型分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OpenTypePageReqVO extends PageParam {
@Schema(description = "会员开通分类标题")
private String title;
@Schema(description = "图标")
private String icon;
@Schema(description = "价格(优惠价)", example = "19296")
private Integer preferentialPrice;
@Schema(description = "价格(原价)", example = "30096")
private Integer originalPrice;
@Schema(description = "时长(天)")
private Integer duration;
@Schema(description = "状态", example = "2")
private String status;
@Schema(description = "是否热门")
private String isHot;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}
@@ -0,0 +1,55 @@
package cn.iocoder.yudao.module.member.controller.admin.opentype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 会员类型 Response VO")
@Data
@ExcelIgnoreUnannotated
public class OpenTypeRespVO {
@Schema(description = "会员开通类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "13402")
@ExcelProperty("会员开通类型")
private Long id;
@Schema(description = "会员开通分类标题", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("会员开通分类标题")
private String title;
@Schema(description = "图标")
@ExcelProperty("图标")
private String icon;
@Schema(description = "价格(优惠价)", requiredMode = Schema.RequiredMode.REQUIRED, example = "19296")
@ExcelProperty("价格(优惠价)")
private Integer preferentialPrice;
@Schema(description = "价格(原价)", requiredMode = Schema.RequiredMode.REQUIRED, example = "30096")
@ExcelProperty("价格(原价)")
private Integer originalPrice;
@Schema(description = "时长(天)", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("时长(天)")
private Integer duration;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@ExcelProperty("状态")
private String status;
@Schema(description = "是否热门", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("是否热门")
private String isHot;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("排序")
private Integer sort;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}
@@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.member.controller.admin.opentype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 会员类型新增/修改 Request VO")
@Data
public class OpenTypeSaveReqVO {
@Schema(description = "会员开通类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "13402")
private Long id;
@Schema(description = "会员开通分类标题", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "会员开通分类标题不能为空")
private String title;
@Schema(description = "图标")
private String icon;
@Schema(description = "价格(优惠价)", requiredMode = Schema.RequiredMode.REQUIRED, example = "19296")
@NotNull(message = "价格(优惠价)不能为空")
private Integer preferentialPrice;
@Schema(description = "价格(原价)", requiredMode = Schema.RequiredMode.REQUIRED, example = "30096")
@NotNull(message = "价格(原价)不能为空")
private Integer originalPrice;
@Schema(description = "时长(天)", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "时长(天)不能为空")
private Integer duration;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@NotEmpty(message = "状态不能为空")
private String status;
@Schema(description = "是否热门", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "是否热门不能为空")
private String isHot;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "排序不能为空")
private Integer sort;
}
@@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.member.dal.dataobject.opentype;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 会员类型 DO
*
* @author 聊天交友
*/
@TableName("member_open_type")
@KeySequence("member_open_type_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OpenTypeDO extends BaseDO {
/**
* 会员开通类型
*/
@TableId
private Long id;
/**
* 会员开通分类标题
*/
private String title;
/**
* 图标
*/
private String icon;
/**
* 价格(优惠价)
*/
private Integer preferentialPrice;
/**
* 价格(原价)
*/
private Integer originalPrice;
/**
* 时长(天)
*/
private Integer duration;
/**
* 状态
*/
private String status;
/**
* 是否热门
*/
private String isHot;
/**
* 排序
*/
private Integer sort;
}
@@ -0,0 +1,57 @@
package cn.iocoder.yudao.module.member.dal.dataobject.opentype;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 会员开通类型与用户关联 DO
*
* @author 聊天交友
*/
@TableName("member_open_type_user")
@KeySequence("member_open_type_user_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OpenTypeUserDO extends BaseDO {
/**
* 会员开通类型与用户关联表
*/
@TableId
private Long id;
/**
* 会员开通类型编号
*/
private Long openTypeId;
/**
* 用户编号
*/
private Long memberId;
/**
* 购买价格
*/
private Integer payPrice;
/**
* 开始时间
*/
private LocalDateTime startTime;
/**
* 结束时间
*/
private LocalDateTime endTime;
/**
* 状态
*/
private String status;
}
@@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.member.dal.mysql.opentype;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.opentype.vo.*;
/**
* 会员类型 Mapper
*
* @author 聊天交友
*/
@Mapper
public interface OpenTypeMapper extends BaseMapperX<OpenTypeDO> {
default PageResult<OpenTypeDO> selectPage(OpenTypePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<OpenTypeDO>()
.eqIfPresent(OpenTypeDO::getTitle, reqVO.getTitle())
.eqIfPresent(OpenTypeDO::getIcon, reqVO.getIcon())
.eqIfPresent(OpenTypeDO::getPreferentialPrice, reqVO.getPreferentialPrice())
.eqIfPresent(OpenTypeDO::getOriginalPrice, reqVO.getOriginalPrice())
.eqIfPresent(OpenTypeDO::getDuration, reqVO.getDuration())
.eqIfPresent(OpenTypeDO::getStatus, reqVO.getStatus())
.eqIfPresent(OpenTypeDO::getIsHot, reqVO.getIsHot())
.eqIfPresent(OpenTypeDO::getSort, reqVO.getSort())
.betweenIfPresent(OpenTypeDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(OpenTypeDO::getId));
}
}
@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.member.dal.mysql.opentype;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeUserDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 会员开通类型与用户关联 Mapper
*
* @author 聊天交友
*/
@Mapper
public interface OpenTypeUserMapper extends BaseMapperX<OpenTypeUserDO> {
}
@@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.member.service.opentype;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.opentype.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 会员类型 Service 接口
*/
public interface OpenTypeService {
/**
* 创建会员类型
*/
Long createOpenType(@Valid OpenTypeSaveReqVO createReqVO);
/**
* 更新会员类型
*/
void updateOpenType(@Valid OpenTypeSaveReqVO updateReqVO);
/**
* 删除会员类型
*/
void deleteOpenType(Long id);
/**
* 获得会员类型
*/
OpenTypeDO getOpenType(Long id);
/**
* 获得会员类型分页
*/
PageResult<OpenTypeDO> getOpenTypePage(OpenTypePageReqVO pageReqVO);
}
@@ -0,0 +1,87 @@
package cn.iocoder.yudao.module.member.service.opentype;
import cn.iocoder.yudao.module.member.enums.MemberErrorCode;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.module.member.controller.admin.opentype.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.opentype.OpenTypeDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.member.dal.mysql.opentype.OpenTypeMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 会员类型 Service 实现类
*/
@Service
@Validated
public class OpenTypeServiceImpl implements OpenTypeService {
@Resource
private OpenTypeMapper openTypeMapper;
/**
* 创建会员类型
*/
@Override
public Long createOpenType(OpenTypeSaveReqVO createReqVO) {
// 插入
OpenTypeDO openType = BeanUtils.toBean(createReqVO, OpenTypeDO.class);
openTypeMapper.insert(openType);
// 返回
return openType.getId();
}
/**
* 删除会员类型
*/
@Override
public void updateOpenType(OpenTypeSaveReqVO updateReqVO) {
// 校验存在
validateOpenTypeExists(updateReqVO.getId());
// 更新
OpenTypeDO updateObj = BeanUtils.toBean(updateReqVO, OpenTypeDO.class);
openTypeMapper.updateById(updateObj);
}
/**
* 获得会员类型
*/
@Override
public void deleteOpenType(Long id) {
// 校验存在
validateOpenTypeExists(id);
// 删除
openTypeMapper.deleteById(id);
}
/**
* 获得会员类型
*/
@Override
public OpenTypeDO getOpenType(Long id) {
return openTypeMapper.selectById(id);
}
/**
* 获得会员类型分页
*/
@Override
public PageResult<OpenTypeDO> getOpenTypePage(OpenTypePageReqVO pageReqVO) {
return openTypeMapper.selectPage(pageReqVO);
}
private void validateOpenTypeExists(Long id) {
if (openTypeMapper.selectById(id) == null) {
throw exception(MemberErrorCode.OPEN_TYPE_NOT_EXISTS);
}
}
}
@@ -1,14 +1,11 @@
package cn.iocoder.yudao.module.member.service.thirdauth;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.member.api.thirdauth.ThirdAuthVo;
import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyData;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyDataResult;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;