商户管理

pull/2/head
perry 2023-05-16 18:17:54 +08:00
parent 9b9af448fc
commit 72645b9dfc
61 changed files with 2108 additions and 112 deletions

View File

@ -33,11 +33,19 @@ public class AreaUtils {
*/
private static Map<Integer, Area> areas;
/**
* Area 访
*/
private static Map<String, Area> areaNames;
private AreaUtils() {
long now = System.currentTimeMillis();
areas = new HashMap<>();
areaNames = new HashMap<>();
areas.put(Area.ID_GLOBAL, new Area(Area.ID_GLOBAL, "全球", 0,
null, new ArrayList<>()));
areaNames.put("全球", new Area(Area.ID_GLOBAL, "全球", 0,
null, new ArrayList<>()));
// 从 csv 中加载数据
List<CsvRow> rows = CsvUtil.getReader().read(ResourceUtil.getUtf8Reader("area.csv")).getRows();
rows.remove(0); // 删除 header
@ -47,6 +55,7 @@ public class AreaUtils {
null, new ArrayList<>());
// 添加到 areas 中
areas.put(area.getId(), area);
areaNames.put(area.getName(),area);
}
// 构建父子关系:因为 Area 中没有 parentId 字段,所以需要重复读取
@ -69,6 +78,15 @@ public class AreaUtils {
public static Area getArea(Integer id) {
return areas.get(id);
}
/**
*
*
* @param name
* @return
*/
public static Area getAreaName(String name) {
return areaNames.get(name);
}
public static void getAreaId(List<Integer> ids, AreaTypeEnum areaTypeEnum, List<Area> areaList) {
areaList.forEach(areas -> {
if(areaTypeEnum.getType().equals(areas.getType())){

View File

@ -0,0 +1,80 @@
package cn.iocoder.yudao.module.infra.controller.app.file;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.infra.controller.app.file.vo.file.FileUploadReqVO;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "用户app - 文件存储")
@RestController
@RequestMapping("/infra/file")
@Validated
@Slf4j
public class AppFileController {
@Resource
private FileService fileService;
@PostMapping("/upload")
@Operation(summary = "上传文件")
@OperateLog(logArgs = false) // 上传文件,没有记录操作日志的必要
public CommonResult<String> uploadFile(FileUploadReqVO uploadReqVO) throws Exception {
MultipartFile file = uploadReqVO.getFile();
String path = uploadReqVO.getPath();
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
}
@DeleteMapping("/delete")
@Operation(summary = "删除文件")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
public CommonResult<Boolean> deleteFile(@RequestParam("id") Long id) throws Exception {
fileService.deleteFile(id);
return success(true);
}
@GetMapping("/{configId}/get/**")
@PermitAll
@Operation(summary = "下载文件")
@Parameter(name = "configId", description = "配置编号", required = true)
public void getFileContent(HttpServletRequest request,
HttpServletResponse response,
@PathVariable("configId") Long configId) throws Exception {
// 获取请求的路径
String path = StrUtil.subAfter(request.getRequestURI(), "/get/", false);
if (StrUtil.isEmpty(path)) {
throw new IllegalArgumentException("结尾的 path 路径必须传递");
}
// 读取内容
byte[] content = fileService.getFileContent(configId, path);
if (content == null) {
log.warn("[getFileContent][configId({}) path({}) 文件不存在]", configId, path);
response.setStatus(HttpStatus.NOT_FOUND.value());
return;
}
ServletUtils.writeAttachment(response, path, content);
}
}

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.infra.controller.app.file.vo.file;
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 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 FilePageReqVO extends PageParam {
@Schema(description = "文件路径,模糊匹配", example = "yudao")
private String path;
@Schema(description = "文件类型,模糊匹配", example = "application/octet-stream")
private String type;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.infra.controller.app.file.vo.file;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 文件 Response VO,不返回 content 字段,太大")
@Data
public class FileRespVO {
@Schema(description = "文件编号", required = true, example = "1024")
private Long id;
@Schema(description = "配置编号", required = true, example = "11")
private Long configId;
@Schema(description = "文件路径", required = true, example = "yudao.jpg")
private String path;
@Schema(description = "原文件名", required = true, example = "yudao.jpg")
private String name;
@Schema(description = "文件 URL", required = true, example = "https://www.iocoder.cn/yudao.jpg")
private String url;
@Schema(description = "文件MIME类型", example = "application/octet-stream")
private String type;
@Schema(description = "文件大小", example = "2048", required = true)
private Integer size;
@Schema(description = "创建时间", required = true)
private LocalDateTime createTime;
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.infra.controller.app.file.vo.file;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 上传文件 Request VO")
@Data
public class FileUploadReqVO {
@Schema(description = "文件附件", required = true)
@NotNull(message = "文件附件不能为空")
private MultipartFile file;
@Schema(description = "文件附件", example = "yudaoyuanma.png")
private String path;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.promotion.dal.dataobject.banner;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
@ -16,7 +17,7 @@ import lombok.*;
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BannerDO extends BaseDO {
public class BannerDO extends TenantBaseDO {
/**
*

View File

@ -45,6 +45,12 @@ public interface ErrorCodeConstants {
ErrorCode SKU_STOCK_NOT_ENOUGH = new ErrorCode(1008006004, "商品 SKU 库存不足");
// ========== Banner 相关 1003002000 ============
ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在");
ErrorCode BANNER_NUM_FIVE = new ErrorCode(1003002001, "Banner 只能添加5个");
// ========== 商品 SKU 1008007000 ==========
ErrorCode GOODS_NUM_ERROR = new ErrorCode(1008007000, "商品数量不合法");

View File

@ -0,0 +1,77 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerRespVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerUpdateReqVO;
import cn.iocoder.yudao.module.shop.convert.banner.BannerConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.banner.BannerDO;
import cn.iocoder.yudao.module.shop.service.banner.BannerService;
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 static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 商户Banner 管理")
@RestController
@RequestMapping("/market/banner")
@Validated
public class BannerController {
@Resource
private BannerService bannerService;
@PostMapping("/create")
@Operation(summary = "创建 Banner")
@PreAuthorize("@ss.hasPermission('market:banner:create')")
public CommonResult<Long> createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) {
createReqVO.setSort(0);
createReqVO.setStatus(0);
return success(bannerService.createBanner(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新 Banner")
@PreAuthorize("@ss.hasPermission('market:banner:update')")
public CommonResult<Boolean> updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) {
bannerService.updateBanner(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除 Banner")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('market:banner:delete')")
public CommonResult<Boolean> deleteBanner(@RequestParam("id") Long id) {
bannerService.deleteBanner(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得 Banner")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('market:banner:query')")
public CommonResult<BannerRespVO> getBanner(@RequestParam("id") Long id) {
BannerDO banner = bannerService.getBanner(id);
return success(BannerConvert.INSTANCE.convert(banner));
}
@GetMapping("/page")
@Operation(summary = "获得 Banner 分页")
@PreAuthorize("@ss.hasPermission('market:banner:query')")
public CommonResult<PageResult<BannerRespVO>> getBannerPage(@Valid BannerPageReqVO pageVO) {
PageResult<BannerDO> pageResult = bannerService.getBannerPage(pageVO);
return success(BannerConvert.INSTANCE.convertPage(pageResult));
}
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* Banner Base VO VO 使
* VO Swagger
* @author xia
*/
@Data
public class BannerBaseVO {
/**
*
*/
@Schema(description = "多租户编号", required = true)
@NotNull(message = "多租户编号不能为空")
private Long tenantId;
@Schema(description = "标题", required = true)
@NotEmpty(message = "标题不能为空")
private String title;
@Schema(description = "跳转链接", required = true)
@NotEmpty(message = "跳转链接不能为空")
private String url;
@Schema(description = "图片地址", required = true)
@NotEmpty(message = "图片地址不能为空")
private String picUrl;
@Schema(description = "排序", required = true)
private Integer sort;
@Schema(description = "状态", required = true)
private Integer status;
@Schema(description = "备注")
private String memo;
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner 创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerCreateReqVO extends BannerBaseVO {
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
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;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner 分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerPageReqVO extends PageParam {
@Schema(description = "标题")
private String title;
@Schema(description = "状态")
@InEnum(CommonStatusEnum.class)
private Integer status;
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@Schema(description = "创建时间")
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner Response VO")
@Data
@ToString(callSuper = true)
public class BannerRespVO extends BannerBaseVO {
@Schema(description = "banner编号", required = true)
@NotNull(message = "banner编号不能为空")
private Long id;
@Schema(description = "创建时间", required = true)
private LocalDateTime createTime;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.shop.controller.admin.banner.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
/**
* @author xia
*/
@Schema(description = "管理后台 - Banner更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BannerUpdateReqVO extends BannerBaseVO {
@Schema(description = "banner 编号", required = true)
@NotNull(message = "banner 编号不能为空")
private Long id;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.shop.convert.banner;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerRespVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerUpdateReqVO;
import cn.iocoder.yudao.module.shop.dal.dataobject.banner.BannerDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface BannerConvert {
BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class);
List<BannerRespVO> convertList(List<BannerDO> list);
PageResult<BannerRespVO> convertPage(PageResult<BannerDO> pageResult);
BannerRespVO convert(BannerDO banner);
BannerDO convert(BannerCreateReqVO createReqVO);
BannerDO convert(BannerUpdateReqVO updateReqVO);
}

View File

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.shop.dal.dataobject.banner;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* banner DO
*
* @author xia
*/
@TableName("market_banner")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BannerDO extends TenantBaseDO {
/**
*
*/
private Long id;
/**
*
*/
private String title;
/**
*
*/
private String url;
/**
*
*/
private String picUrl;
/**
*
*/
private Integer sort;
/**
* {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
*/
private Integer status;
/**
*
*/
private String memo;
// TODO 芋艿 点击次数。&& 其他数据相关
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.shop.dal.mysql.banner;
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.shop.controller.admin.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.shop.dal.dataobject.banner.BannerDO;
import org.apache.ibatis.annotations.Mapper;
/**
* Banner Mapper
*
* @author xia
*/
@Mapper
public interface BannerMapper extends BaseMapperX<BannerDO> {
default PageResult<BannerDO> selectPage(BannerPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<BannerDO>()
.likeIfPresent(BannerDO::getTitle, reqVO.getTitle())
.eqIfPresent(BannerDO::getStatus, reqVO.getStatus())
.betweenIfPresent(BannerDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(BannerDO::getSort));
}
}

View File

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.shop.service.banner;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerUpdateReqVO;
import cn.iocoder.yudao.module.shop.dal.dataobject.banner.BannerDO;
import javax.validation.Valid;
import java.util.List;
/**
* Banner Service
*
* @author xia
*/
public interface BannerService {
/**
* Banner
*
* @param createReqVO
* @return
*/
Long createBanner(@Valid BannerCreateReqVO createReqVO);
/**
* Banner
*
* @param updateReqVO
*/
void updateBanner(@Valid BannerUpdateReqVO updateReqVO);
/**
* Banner
*
* @param id
*/
void deleteBanner(Long id);
/**
* Banner
*
* @param id
* @return Banner
*/
BannerDO getBanner(Long id);
/**
* Banner
* @return Banner
*/
List<BannerDO> getBannerList();
/**
* Banner
*
* @param pageReqVO
* @return Banner
*/
PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO);
}

View File

@ -0,0 +1,88 @@
package cn.iocoder.yudao.module.shop.service.banner;
import cn.iocoder.yudao.framework.common.enums.Constants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerCreateReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerPageReqVO;
import cn.iocoder.yudao.module.shop.controller.admin.banner.vo.BannerUpdateReqVO;
import cn.iocoder.yudao.module.shop.convert.banner.BannerConvert;
import cn.iocoder.yudao.module.shop.dal.dataobject.banner.BannerDO;
import cn.iocoder.yudao.module.shop.dal.mysql.banner.BannerMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.BANNER_NOT_EXISTS;
import static cn.iocoder.yudao.module.shop.enums.ErrorCodeConstants.BANNER_NUM_FIVE;
/**
* banner
*
* @author xia
*/
@Service
@Validated
public class BannerServiceImpl implements BannerService {
@Resource
private BannerMapper bannerMapper;
@Override
public Long createBanner(BannerCreateReqVO createReqVO) {
//判断只能新增5个
Long count =bannerMapper.selectCount(Wrappers.lambdaQuery(BannerDO.class).eq(BannerDO::getTenantId,createReqVO.getTenantId()));
if(count>= Constants.NUM_FIVE){
throw exception(BANNER_NUM_FIVE);
}
// 插入
BannerDO banner = BannerConvert.INSTANCE.convert(createReqVO);
bannerMapper.insert(banner);
// 返回
return banner.getId();
}
@Override
public void updateBanner(BannerUpdateReqVO updateReqVO) {
// 校验存在
this.validateBannerExists(updateReqVO.getId());
// 更新
BannerDO updateObj = BannerConvert.INSTANCE.convert(updateReqVO);
bannerMapper.updateById(updateObj);
}
@Override
public void deleteBanner(Long id) {
// 校验存在
this.validateBannerExists(id);
// 删除
bannerMapper.deleteById(id);
}
private void validateBannerExists(Long id) {
if (bannerMapper.selectById(id) == null) {
throw exception(BANNER_NOT_EXISTS);
}
}
@Override
public BannerDO getBanner(Long id) {
return bannerMapper.selectById(id);
}
@Override
public List<BannerDO> getBannerList() {
return bannerMapper.selectList();
}
@Override
public PageResult<BannerDO> getBannerPage(BannerPageReqVO pageReqVO) {
return bannerMapper.selectPage(pageReqVO);
}
}

View File

@ -36,21 +36,7 @@ public class CrmebUtil {
/**
*
*/
public static String decryptPassowrd(String pwd, String key)
throws Exception {
Security.addProvider(new com.sun.crypto.provider.SunJCE());
Key aKey = getDESSercretKey(key);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, aKey);
byte[] data = new sun.misc.BASE64Decoder().decodeBuffer(pwd);
byte[] result = cipher.doFinal(data);
return new String(result, StandardCharsets.UTF_8);
}
/**
* map

View File

@ -12,7 +12,7 @@ public interface ErrorCodeConstants {
// ========== 用户相关 1004001000============
ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1004001001, "密码校验失败");
ErrorCode PROMOTER_NOT_EXISTS = new ErrorCode(1004001002, "推广员不存在");
// ========== AUTH 模块 1004003000 ==========
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1004003001, "登录失败,账号被禁用");
@ -23,4 +23,6 @@ public interface ErrorCodeConstants {
// ========== 用户收件地址 1004004000 ==========
ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1004004000, "用户收件地址不存在");
}

View File

@ -43,6 +43,10 @@
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
@ -82,7 +86,15 @@
<artifactId>yudao-spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
<!-- 工具类相关 -->
</dependencies>

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter;
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.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.promoter.PromoterDO;
import cn.iocoder.yudao.module.member.convert.promoter.PromoterConvert;
import cn.iocoder.yudao.module.member.service.promoter.PromoterService;
@Tag(name = "管理后台 - 推广员")
@RestController
@RequestMapping("/member/promoter")
@Validated
public class PromoterController {
@Resource
private PromoterService promoterService;
@PostMapping("/create")
@Operation(summary = "创建推广员")
@PreAuthorize("@ss.hasPermission('member:promoter:create')")
public CommonResult<Long> createPromoter(@Valid @RequestBody PromoterCreateReqVO createReqVO) {
return success(promoterService.createPromoter(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新推广员")
@PreAuthorize("@ss.hasPermission('member:promoter:update')")
public CommonResult<Boolean> updatePromoter(@Valid @RequestBody PromoterUpdateReqVO updateReqVO) {
promoterService.updatePromoter(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除推广员")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('member:promoter:delete')")
public CommonResult<Boolean> deletePromoter(@RequestParam("id") Long id) {
promoterService.deletePromoter(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得推广员")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('member:promoter:query')")
public CommonResult<PromoterRespVO> getPromoter(@RequestParam("id") Long id) {
PromoterDO promoter = promoterService.getPromoter(id);
return success(PromoterConvert.INSTANCE.convert(promoter));
}
@GetMapping("/list")
@Operation(summary = "获得推广员列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('member:promoter:query')")
public CommonResult<List<PromoterRespVO>> getPromoterList(@RequestParam("ids") Collection<Long> ids) {
List<PromoterDO> list = promoterService.getPromoterList(ids);
return success(PromoterConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得推广员分页")
@PreAuthorize("@ss.hasPermission('member:promoter:query')")
public CommonResult<PageResult<PromoterRespVO>> getPromoterPage(@Valid PromoterPageReqVO pageVO) {
PageResult<PromoterDO> pageResult = promoterService.getPromoterPage(pageVO);
return success(PromoterConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出推广员 Excel")
@PreAuthorize("@ss.hasPermission('member:promoter:export')")
@OperateLog(type = EXPORT)
public void exportPromoterExcel(@Valid PromoterExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<PromoterDO> list = promoterService.getPromoterList(exportReqVO);
// 导出 Excel
List<PromoterExcelVO> datas = PromoterConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "推广员.xls", "数据", PromoterExcelVO.class, datas);
}
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.Mobile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
/**
* 广 Base VO VO 使
* VO Swagger
*/
@Data
public class PromoterBaseVO {
@Schema(description = "组织id", required = true, example = "18443")
@NotNull(message = "组织id不能为空")
private String orgId;
@Schema(description = "推广员名称", required = true, example = "5841")
@NotEmpty(message = "推广员名称不能为空")
@Size(max = 10,message = "推广员名称最长不能超过{max}")
private String nickName;
@Schema(description = "推广员手机号", example = "15601691300")
@Mobile
@NotEmpty(message = "推广员手机号不能为空")
private String mobile;
/**
*
* <p>
* {@link CommonStatusEnum}
*/
@Schema(description = "帐号状态")
@NotNull
private Integer status;
}

View File

@ -0,0 +1,14 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 推广员创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PromoterCreateReqVO extends PromoterBaseVO {
}

View File

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import com.alibaba.excel.annotation.ExcelProperty;
/**
* 广 Excel VO
*
* @author
*/
@Data
public class PromoterExcelVO {
@ExcelProperty("编号")
private Long id;
@ExcelProperty("组织id")
private String orgId;
@ExcelProperty("会员id")
private Long userId;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - 推广员 Excel 导出 Request VO参数和 PromoterPageReqVO 是一致的")
@Data
public class PromoterExportReqVO {
@Schema(description = "组织id", example = "18443")
private String orgId;
@Schema(description = "会员id", example = "5841")
private Long userId;
}

View File

@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - 推广员分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PromoterPageReqVO extends PageParam {
@Schema(description = "组织id", example = "18443")
private String orgId;
@Schema(description = "会员id", example = "5841")
private Long userId;
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 推广员 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PromoterRespVO extends PromoterBaseVO {
@Schema(description = "编号", required = true, example = "3051")
private Long id;
}

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.member.controller.admin.promoter.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 推广员更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class PromoterUpdateReqVO extends PromoterBaseVO {
@Schema(description = "编号", required = true, example = "3051")
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -1,75 +0,0 @@
package cn.iocoder.yudao.module.member.controller.app.address;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressRespVO;
import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
import cn.iocoder.yudao.module.member.dal.dataobject.address.AddressDO;
import cn.iocoder.yudao.module.member.service.address.AddressService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
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;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "用户 APP - 用户收件地址")
@RestController
@RequestMapping("/member/address")
@Validated
public class AppAddressController {
@Resource
private AddressService addressService;
@PostMapping("/create")
@Operation(summary = "创建用户收件地址")
public CommonResult<Long> createAddress(@Valid @RequestBody AppAddressCreateReqVO createReqVO) {
return success(addressService.createAddress(getLoginUserId(), createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新用户收件地址")
public CommonResult<Boolean> updateAddress(@Valid @RequestBody AppAddressUpdateReqVO updateReqVO) {
addressService.updateAddress(getLoginUserId(), updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除用户收件地址")
@Parameter(name = "id", description = "编号", required = true)
public CommonResult<Boolean> deleteAddress(@RequestParam("id") Long id) {
addressService.deleteAddress(getLoginUserId(), id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得用户收件地址")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<AppAddressRespVO> getAddress(@RequestParam("id") Long id) {
AddressDO address = addressService.getAddress(getLoginUserId(), id);
return success(AddressConvert.INSTANCE.convert(address));
}
@GetMapping("/get-default")
@Operation(summary = "获得默认的用户收件地址")
public CommonResult<AppAddressRespVO> getDefaultUserAddress() {
AddressDO address = addressService.getDefaultUserAddress(getLoginUserId());
return success(AddressConvert.INSTANCE.convert(address));
}
@GetMapping("/list")
@Operation(summary = "获得用户收件地址列表")
public CommonResult<List<AppAddressRespVO>> getAddressList() {
List<AddressDO> list = addressService.getAddressList(getLoginUserId());
return success(AddressConvert.INSTANCE.convertList(list));
}
}

View File

@ -0,0 +1,108 @@
package cn.iocoder.yudao.module.member.controller.app.address;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.member.controller.app.address.vo.UserAddressDelRequest;
import cn.iocoder.yudao.module.member.controller.app.address.vo.UserAddressReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.address.UserAddress;
import cn.iocoder.yudao.module.member.service.address.UserAddressService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Slf4j
@RestController
@RequestMapping("address")
@Tag(name = "用户 -- 地址")
public class UserAddressController {
@Autowired
private UserAddressService userAddressService;
/**
*
*/
@Operation(summary = "列表")
@RequestMapping(value = "/list", method = RequestMethod.GET)
public CommonResult<PageInfo<UserAddress>> getList(PageParam pageParamRequest) {
return CommonResult.success(userAddressService.getList(pageParamRequest));
}
/**
*
* @param request
*/
@Operation(summary = "保存")
@RequestMapping(value = "/edit", method = RequestMethod.POST)
public CommonResult<UserAddress> save(@RequestBody @Validated UserAddressReqVO request) {
return CommonResult.success(userAddressService.create(request));
}
/**
*
* @param request UserAddressDelRequest
*/
@Operation(summary = "删除")
@RequestMapping(value = "/del", method = RequestMethod.POST)
public CommonResult<Boolean> delete(@RequestBody UserAddressDelRequest request) {
if (userAddressService.delete(request.getId())) {
return CommonResult.success(true);
} else {
return CommonResult.error(GlobalErrorCodeConstants.ERROR);
}
}
/**
*
*/
@Operation(summary = "地址详情")
@RequestMapping(value = "/detail/{id}", method = RequestMethod.GET)
public CommonResult<UserAddress> info(@PathVariable("id") Long id) {
return CommonResult.success(userAddressService.getDetail(id));
}
/**
*
*/
@Operation(summary = "获取默认地址")
@RequestMapping(value = "/default", method = RequestMethod.GET)
public CommonResult<UserAddress> getDefault() {
return CommonResult.success(userAddressService.getDefault());
}
/**
*
* @param request UserAddressDelRequest
*/
@Operation(summary= "设置默认地址")
@RequestMapping(value = "/default/set", method = RequestMethod.POST)
public CommonResult<Boolean> def(@RequestBody UserAddressDelRequest request) {
if (userAddressService.def(request.getId())) {
return CommonResult.success(true);
} else {
return CommonResult.error(GlobalErrorCodeConstants.ERROR);
}
}
}

View File

@ -0,0 +1,46 @@
package cn.iocoder.yudao.module.member.controller.app.address.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema( description="用户地址详细对象")
public class UserAddressCityVO implements Serializable {
private static final long serialVersionUID=1L;
@Schema( description = "收货人所在省", required = true)
@NotBlank(message = "收货人所在省不能为空")
private String province;
@Schema( description = "收货人所在市", required = true)
@NotBlank(message = "收货人所在市不能为空")
private String city;
@Schema( description = "城市id")
private Integer cityId = 0;
@Schema( description = "收货人所在区", required = true)
@NotBlank(message = "收货人所在区不能为空")
private String district;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.member.controller.app.address.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import java.io.Serializable;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema( description="用户地址")
public class UserAddressDelRequest implements Serializable {
private static final long serialVersionUID=1L;
@Schema(description = "用户地址id")
@Min(value = 1, message = "请选择用户地址")
private Long id;
}

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.member.controller.app.address.vo;
import cn.iocoder.yudao.framework.common.validation.Mobile;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@Schema( description="新增用户地址对象")
public class UserAddressReqVO implements Serializable {
private static final long serialVersionUID=1L;
@Schema( description = "用户地址id")
private Long id;
@Schema( description = "收货人姓名", required = true)
@NotBlank(message = "收货人姓名不能为空")
@Length(max = 32, message = "收货人姓名不能超过32个字符")
private String realName;
@Schema( description = "收货人电话", required = true)
@NotBlank(message = "收货人电话不能为空")
@Mobile( message = "请填写正确的收货人电话")
private String phone;
@Schema( description = "收货人详细地址", required = true)
@NotBlank(message = "收货人详细地址不能为空")
@Length(max = 256, message = "收货人详细地址不能超过32个字符")
private String detail;
@Schema( description= "是否默认", example = "false", required = true)
private Boolean isDefault;
@Valid
@Schema( description = "城市信息", required = true)
private UserAddressCityVO address;
}

View File

@ -48,6 +48,7 @@ public class AppAuthController {
@PostMapping("/logout")
@PermitAll
@Operation(summary = "登出系统")
@TenantIgnore
public CommonResult<Boolean> logout(HttpServletRequest request) {
String token = SecurityFrameworkUtils.obtainAuthorization(request, securityProperties.getTokenHeader());
if (StrUtil.isNotBlank(token)) {
@ -59,6 +60,7 @@ public class AppAuthController {
@PostMapping("/refresh-token")
@Operation(summary = "刷新令牌")
@Parameter(name = "refreshToken", description = "刷新令牌", required = true)
@TenantIgnore
@OperateLog(enable = false) // 避免 Post 请求被记录操作日志
public CommonResult<AppAuthLoginRespVO> refreshToken(@RequestParam("refreshToken") String refreshToken) {
return success(authService.refreshToken(refreshToken));
@ -88,7 +90,7 @@ public class AppAuthController {
@PostMapping("/reset-password")
@Operation(summary = "重置密码", description = "用户忘记密码时使用")
@PreAuthenticated
@TenantIgnore
public CommonResult<Boolean> resetPassword(@RequestBody @Valid AppAuthResetPasswordReqVO reqVO) {
authService.resetPassword(reqVO);
return success(true);
@ -97,6 +99,7 @@ public class AppAuthController {
@PostMapping("/update-password")
@Operation(summary = "修改用户密码", description = "用户修改密码时使用")
@PreAuthenticated
@TenantIgnore
public CommonResult<Boolean> updatePassword(@RequestBody @Valid AppAuthUpdatePasswordReqVO reqVO) {
authService.updatePassword(getLoginUserId(), reqVO);
return success(true);

View File

@ -1,7 +1,10 @@
package cn.iocoder.yudao.module.member.controller.app.user;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoReqVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserInfoRespVO;
import cn.iocoder.yudao.module.member.controller.app.user.vo.AppUserUpdateMobileReqVO;
import cn.iocoder.yudao.module.member.convert.user.UserConvert;
@ -66,6 +69,18 @@ public class AppUserController {
userService.updateUserMobile(getLoginUserId(), reqVO);
return success(true);
}
@PostMapping("/update-user")
@Operation(summary = "修改用户信息")
@PreAuthenticated
public CommonResult<Boolean> updateMobile(@RequestBody @Validated AppUserInfoReqVO req) {
req.setId(getLoginUserId());
MemberUserDO userDO = new MemberUserDO();
userDO.setId(req.getId());
userDO.setNickname(req.getNickname());
userDO.setAvatar(req.getAvatar());
userService.updateById(userDO);
return success(true);
}
}

View File

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.member.controller.app.user.vo;
import cn.hutool.core.date.DatePattern;
import cn.iocoder.yudao.module.system.enums.common.SexEnum;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import java.util.Date;
@Schema(description = "用户 APP - 用户个人信息 Response VO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppUserInfoReqVO {
/**
* ID
*/
private Long id;
@Schema(description = "用户昵称", required = true, example = "芋艿")
@NotEmpty(message = "用户昵称不能为空")
private String nickname;
@Schema(description = "用户头像", required = true, example = "/infra/file/get/35a12e57-4297-4faa-bf7d-7ed2f211c952")
private String avatar;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.member.convert.promoter;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.promoter.PromoterDO;
/**
* 广 Convert
*
* @author
*/
@Mapper
public interface PromoterConvert {
PromoterConvert INSTANCE = Mappers.getMapper(PromoterConvert.class);
PromoterDO convert(PromoterCreateReqVO bean);
PromoterDO convert(PromoterUpdateReqVO bean);
PromoterRespVO convert(PromoterDO bean);
List<PromoterRespVO> convertList(List<PromoterDO> list);
PageResult<PromoterRespVO> convertPage(PageResult<PromoterDO> page);
List<PromoterExcelVO> convertList02(List<PromoterDO> list);
}

View File

@ -0,0 +1,76 @@
package cn.iocoder.yudao.module.member.dal.dataobject.address;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
*
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("eb_user_address")
@Schema(name="用户地址表", description="用户地址表")
public class UserAddress extends BaseDO {
private static final long serialVersionUID=1L;
@Schema(description = "用户地址id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "收货人姓名")
private String realName;
@Schema(description = "收货人电话")
private String phone;
@Schema(description = "收货人所在省")
private String province;
@Schema(description = "收货人所在市")
private String city;
@Schema(description = "城市id")
private Integer cityId;
@Schema(description = "收货人所在区")
private String district;
@Schema(description = "收货人详细地址")
private String detail;
@Schema(description = "邮编")
private Integer postCode;
@Schema(description = "经度")
private String longitude;
@Schema(description = "纬度")
private String latitude;
@Schema(description = "是否默认")
private Boolean isDefault;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.member.dal.dataobject.promoter;
import lombok.*;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.*;
/**
* 广 DO
*
* @author
*/
@TableName("member_promoter")
@KeySequence("member_promoter_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PromoterDO implements Serializable {
/**
*
*/
@TableId
private Long id;
/**
*
*/
private Long tenantId;
/**
* id
*/
private String orgId;
/**
* id
*/
private Long userId;
}

View File

@ -68,6 +68,10 @@ public class MemberUserDO extends TenantBaseDO {
*
*/
private LocalDateTime loginDate;
/**
* 广id
*/
private Long promoterId;
// TODO 芋艿name 真实名字;
// TODO 芋艿email 邮箱;

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.member.dal.mysql.address;
import cn.iocoder.yudao.module.member.dal.dataobject.address.UserAddress;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Mapper
public interface UserAddressMapper extends BaseMapper<UserAddress> {
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.member.dal.mysql.promoter;
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.promoter.PromoterDO;
import org.apache.ibatis.annotations.Mapper;
import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*;
/**
* 广 Mapper
*
* @author
*/
@Mapper
public interface PromoterMapper extends BaseMapperX<PromoterDO> {
default PageResult<PromoterDO> selectPage(PromoterPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PromoterDO>()
.eqIfPresent(PromoterDO::getOrgId, reqVO.getOrgId())
.eqIfPresent(PromoterDO::getUserId, reqVO.getUserId())
.orderByDesc(PromoterDO::getId));
}
default List<PromoterDO> selectList(PromoterExportReqVO reqVO) {
return selectList(new LambdaQueryWrapperX<PromoterDO>()
.eqIfPresent(PromoterDO::getOrgId, reqVO.getOrgId())
.eqIfPresent(PromoterDO::getUserId, reqVO.getUserId())
.orderByDesc(PromoterDO::getId));
}
}

View File

@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.member.service.address;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.member.controller.app.address.vo.UserAddressReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.address.UserAddress;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
* UserAddressService
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
public interface UserAddressService extends IService<UserAddress> {
/**
*
* @param pageParamRequest
* @return List<UserAddress>
*/
PageInfo<UserAddress> getList(PageParam pageParamRequest);
/**
*
* @param request
* @return UserAddress
*/
UserAddress create(UserAddressReqVO request);
/**
*
* @param id id
* @return Boolean
*/
Boolean def(Long id);
/**
*
* @param id id
* @return Boolean
*/
Boolean delete(Long id);
UserAddress getDefault();
UserAddress getById(Long addressId);
/**
*
* @param id id
* @return UserAddress
*/
UserAddress getDetail(Long id);
/**
*
* @return UserAddress
*/
UserAddress getDefaultByUid(Long uid);
}

View File

@ -0,0 +1,208 @@
package cn.iocoder.yudao.module.member.service.address;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.app.address.vo.UserAddressReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.address.UserAddress;
import cn.iocoder.yudao.module.member.dal.mysql.address.UserAddressMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* UserAddressServiceImpl
* +----------------------------------------------------------------------
* | CRMEB [ CRMEB ]
* +----------------------------------------------------------------------
* | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
* +----------------------------------------------------------------------
* | Licensed CRMEBCRMEB
* +----------------------------------------------------------------------
* | Author: CRMEB Team <admin@crmeb.com>
* +----------------------------------------------------------------------
*/
@Service
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress> implements UserAddressService {
@Resource
private UserAddressMapper userAddressMapper;
/**
*
* @return List<UserAddress>
*/
@Override
public PageInfo<UserAddress> getList(PageParam pageParamRequest) {
Long UserId = SecurityFrameworkUtils.getLoginUserId();
PageHelper.startPage(pageParamRequest.getPageNo(), pageParamRequest.getPageSize());
LambdaQueryWrapper<UserAddress> lqw = Wrappers.lambdaQuery();
lqw.select(UserAddress::getId, UserAddress::getRealName, UserAddress::getPhone, UserAddress::getProvince,
UserAddress::getCity, UserAddress::getDistrict, UserAddress::getDetail, UserAddress::getIsDefault);
lqw.eq(UserAddress::getUserId, UserId);
lqw.orderByDesc(UserAddress::getIsDefault);
lqw.orderByDesc(UserAddress::getId);
return new PageInfo<>(userAddressMapper.selectList(lqw));
}
/**
*
* @param request UserAddressRequest
* @return List<UserAddress>
*/
@Override
public UserAddress create(UserAddressReqVO request) {
UserAddress userAddress = new UserAddress();
BeanUtils.copyProperties(request, userAddress);
userAddress.setCity(request.getAddress().getCity());
userAddress.setCityId(request.getAddress().getCityId());
userAddress.setDistrict(request.getAddress().getDistrict());
userAddress.setProvince(request.getAddress().getProvince());
// 添加地址时cityId和城市名称不能同时为空如果id为空必须用城市名称自查后set CityId
if (request.getAddress().getCityId() == 0 && StringUtils.isBlank(request.getAddress().getCity())) {
throw new ServiceException("请选择正确城市数据");
}
if (StringUtils.isNotBlank(request.getAddress().getCity()) && request.getAddress().getCityId() == 0) {
Area area =AreaUtils.getAreaName(request.getAddress().getCity());
if (ObjectUtil.isNull(area)) {
throw new ServiceException("当前城市未找到!");
}
userAddress.setCityId(area.getId());
}
if (request.getAddress().getCityId() > 0 && StringUtils.isNotBlank(request.getAddress().getCity())) {
checkCity(userAddress.getCityId());
}
userAddress.setUserId(SecurityFrameworkUtils.getLoginUserId());
if (userAddress.getIsDefault()) {
//把当前用户其他默认地址取消
cancelDefault(userAddress.getUserId());
}
saveOrUpdate(userAddress);
return userAddress;
}
/**
*
* @param id Integer id
* @return UserAddress
*/
@Override
public Boolean def(Long id) {
//把当前用户其他默认地址取消
cancelDefault(SecurityFrameworkUtils.getLoginUserId());
UserAddress userAddress = new UserAddress();
userAddress.setId(id);
userAddress.setUserId(SecurityFrameworkUtils.getLoginUserId());
userAddress.setIsDefault(true);
return updateById(userAddress);
}
/**
*
* @param id Integer id
* @return UserAddress
*/
@Override
public Boolean delete(Long id) {
//把当前用户其他默认地址取消
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserAddress::getId, id);
lambdaQueryWrapper.eq(UserAddress::getUserId, SecurityFrameworkUtils.getLoginUserId());
userAddressMapper.delete(lambdaQueryWrapper);
return true;
}
/**
*
* @return UserAddress
*/
@Override
public UserAddress getDefault() {
//把当前用户其他默认地址取消
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserAddress::getIsDefault, true);
lambdaQueryWrapper.eq(UserAddress::getUserId, SecurityFrameworkUtils.getLoginUser());
return userAddressMapper.selectOne(lambdaQueryWrapper);
}
@Override
public UserAddress getById(Long addressId) {
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserAddress::getId, addressId);
return userAddressMapper.selectOne(lambdaQueryWrapper);
}
/**
*
* @param id id
* @return UserAddress
*/
@Override
public UserAddress getDetail(Long id) {
Long userId = SecurityFrameworkUtils.getLoginUserId();
LambdaQueryWrapper<UserAddress> lqw = Wrappers.lambdaQuery();
lqw.select(UserAddress::getId, UserAddress::getRealName, UserAddress::getPhone, UserAddress::getProvince,
UserAddress::getCity, UserAddress::getDistrict, UserAddress::getDetail, UserAddress::getIsDefault);
lqw.eq(UserAddress::getId, id);
lqw.eq(UserAddress::getUserId, userId);
return userAddressMapper.selectOne(lqw);
}
/**
*
* @return UserAddress
*/
@Override
public UserAddress getDefaultByUid(Long uid) {
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(UserAddress::getIsDefault, true);
lambdaQueryWrapper.eq(UserAddress::getUserId, uid);
return userAddressMapper.selectOne(lambdaQueryWrapper);
}
/**
* id
* @param cityId Integer id
*/
private void checkCity(Integer cityId) {
//检测城市Id是否存在
Area area =AreaUtils.getArea(cityId);
if (ObjectUtil.isNull(area)) {
throw new ServiceException("当前城市未找到!");
}
if (ObjectUtil.isNull(area)) {
throw new ServiceException("请选择正确的城市");
}
}
/**
*
* @param userId Integer id
*/
private void cancelDefault(Long userId) {
//检测城市Id是否存在
UserAddress userAddress = new UserAddress();
userAddress.setIsDefault(false);
LambdaQueryWrapper<UserAddress> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(UserAddress::getUserId, userId);
update(userAddress, lambdaQueryWrapper);
}
}

View File

@ -92,8 +92,17 @@ public class MemberAuthServiceImpl implements MemberAuthService {
smsCodeApi.useSmsCode(AuthConvert.INSTANCE.convert(reqVO, SmsSceneEnum.MEMBER_LOGIN.getScene(), userIp));
// 获得获得注册用户
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(),reqVO.getRealName(), userIp);
Assert.notNull(user, "获取用户失败,结果为空");
// 校验账号是否存在
MemberUserDO user = userService.getUserByMobile(reqVO.getMobile());
if (user == null) {
createLoginLog(null, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.BAD_CREDENTIALS);
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
}
// 校验是否禁用
if (ObjectUtil.notEqual(user.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
createLoginLog(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.USER_DISABLED);
throw exception(AUTH_LOGIN_USER_DISABLED);
}
// 如果 socialType 非空,说明需要绑定社交用户
if (reqVO.getSocialType() != null) {

View File

@ -0,0 +1,70 @@
package cn.iocoder.yudao.module.member.service.promoter;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.promoter.PromoterDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 广 Service
*
* @author
*/
public interface PromoterService {
/**
* 广
*
* @param createReqVO
* @return
*/
Long createPromoter(@Valid PromoterCreateReqVO createReqVO);
/**
* 广
*
* @param updateReqVO
*/
void updatePromoter(@Valid PromoterUpdateReqVO updateReqVO);
/**
* 广
*
* @param id
*/
void deletePromoter(Long id);
/**
* 广
*
* @param id
* @return 广
*/
PromoterDO getPromoter(Long id);
/**
* 广
*
* @param ids
* @return 广
*/
List<PromoterDO> getPromoterList(Collection<Long> ids);
/**
* 广
*
* @param pageReqVO
* @return 广
*/
PageResult<PromoterDO> getPromoterPage(PromoterPageReqVO pageReqVO);
/**
* 广, Excel
*
* @param exportReqVO
* @return 广
*/
List<PromoterDO> getPromoterList(PromoterExportReqVO exportReqVO);
}

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.member.service.promoter;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.service.user.MemberUserService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.module.member.controller.admin.promoter.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.promoter.PromoterDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.convert.promoter.PromoterConvert;
import cn.iocoder.yudao.module.member.dal.mysql.promoter.PromoterMapper;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
/**
* 广 Service
*
* @author
*/
@Service
@Validated
public class PromoterServiceImpl implements PromoterService {
@Resource
private PromoterMapper promoterMapper;
@Resource
private MemberUserService memberUserService;
@Override
public Long createPromoter(PromoterCreateReqVO createReqVO) {
//判断手机号是否注册
MemberUserDO memberUserDO = memberUserService.getUserByMobile(createReqVO.getMobile());
if(memberUserDO==null){
//创建用户
memberUserDO = new MemberUserDO();
memberUserDO.setNickname(createReqVO.getNickName());
memberUserDO.setMobile(createReqVO.getMobile());
memberUserDO.setStatus(createReqVO.getStatus());
memberUserService.createUserIfAbsent(createReqVO.getMobile(),createReqVO.getNickName(),getClientIP());
}
// 插入
PromoterDO promoter = PromoterConvert.INSTANCE.convert(createReqVO);
promoter.setTenantId(SecurityFrameworkUtils.getLoginUser().getTenantId());
promoter.setUserId(memberUserDO.getId());
promoterMapper.insert(promoter);
// 返回
return promoter.getId();
}
@Override
public void updatePromoter(PromoterUpdateReqVO updateReqVO) {
// 校验存在
validatePromoterExists(updateReqVO.getId());
// 更新
PromoterDO updateObj = PromoterConvert.INSTANCE.convert(updateReqVO);
promoterMapper.updateById(updateObj);
}
@Override
public void deletePromoter(Long id) {
// 校验存在
validatePromoterExists(id);
// 删除
promoterMapper.deleteById(id);
}
private void validatePromoterExists(Long id) {
if (promoterMapper.selectById(id) == null) {
throw exception(PROMOTER_NOT_EXISTS);
}
}
@Override
public PromoterDO getPromoter(Long id) {
return promoterMapper.selectById(id);
}
@Override
public List<PromoterDO> getPromoterList(Collection<Long> ids) {
return promoterMapper.selectBatchIds(ids);
}
@Override
public PageResult<PromoterDO> getPromoterPage(PromoterPageReqVO pageReqVO) {
return promoterMapper.selectPage(pageReqVO);
}
@Override
public List<PromoterDO> getPromoterList(PromoterExportReqVO exportReqVO) {
return promoterMapper.selectList(exportReqVO);
}
}

View File

@ -116,4 +116,6 @@ public interface MemberUserService {
*/
int updateById(MemberUserDO member);
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.member.dal.mysql.promoter.PromoterMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>

View File

@ -52,6 +52,8 @@ public class TenantController {
createReqVO.setAccountCount(99999);
createReqVO.setExpireTime(LocalDateTimeUtil.offset(LocalDateTime.now(),99, ChronoUnit.YEARS));
createReqVO.setPackageId(1L);
createReqVO.setUsername(createReqVO.getContactMobile());
createReqVO.setPassword(createReqVO.getContactMobile().substring(createReqVO.getContactMobile().length()-6,createReqVO.getContactMobile().length()));
return success(tenantService.createTenant(createReqVO));
}
@ -62,7 +64,13 @@ public class TenantController {
tenantService.updateTenant(updateReqVO);
return success(true);
}
@PutMapping("/update-commission")
@Operation(summary = "更新租户提成")
@PreAuthorize("@ss.hasPermission('system:tenant:update')")
public CommonResult<Boolean> updateTenantCommission(@Valid @RequestBody TenantCommissionUpdateReqVO updateReqVO) {
tenantService.updateTenantCommission(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除租户")
@Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@ -95,4 +95,12 @@ public class TenantBaseVO {
@Length( max =1000, message = "通知公告长度为 {max}位")
private String notice;
/**
* logo
*/
@Schema(description = "logo", example = "https://www.iocoder.cn")
@Length( max =200, message = "logo长度为 {max}位")
private String logo;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Schema(description = "管理后台 - 租户更新 Request VO")
@Data
@ToString(callSuper = true)
public class TenantCommissionUpdateReqVO {
@Schema(description = "租户编号", required = true, example = "1024")
@NotNull(message = "租户编号不能为空")
private Long id;
/**
*
*/
@NotNull(message = "商品提成不能为空")
@Size(min = 0,max = 100,message ="商品提成{min}{max}之间" )
private Integer goodsCommission;
/**
*
*/
@NotNull(message = "会员充值提成不能为空")
@Size(min = 0,max = 100,message ="会员充值提成{min}{max}之间" )
private Integer memberCommission;
}

View File

@ -16,14 +16,9 @@ import javax.validation.constraints.Size;
public class TenantCreateReqVO extends TenantBaseVO {
@Schema(description = "用户账号", required = true, example = "yudao")
@NotBlank(message = "用户账号不能为空")
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
private String username;
@Schema(description = "密码", required = true, example = "123456")
@NotEmpty(message = "密码不能为空")
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.system.controller.app.ip;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.ip.core.Area;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.framework.ip.core.utils.IPUtils;
import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO;
import cn.iocoder.yudao.module.system.convert.ip.AreaConvert;
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.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "用户 - 地区")
@RestController
@RequestMapping("/area")
@Validated
public class AppAreaController {
@GetMapping("/tree")
@Operation(summary = "获得地区树")
public CommonResult<List<AreaNodeRespVO>> getAreaTree() {
Area area = AreaUtils.getArea(Area.ID_CHINA);
Assert.notNull(area, "获取不到中国");
return success(AreaConvert.INSTANCE.convertList(area.getChildren()));
}
@GetMapping("/get-by-ip")
@Operation(summary = "获得 IP 对应的地区名")
@Parameter(name = "ip", description = "IP", required = true)
public CommonResult<String> getAreaByIp(@RequestParam("ip") String ip) {
// 获得城市
Area area = IPUtils.getArea(ip);
if (area == null) {
return success("未知");
}
// 格式化返回
return success(AreaUtils.format(area.getId()));
}
}

View File

@ -61,4 +61,14 @@ public class DeptDO extends TenantBaseDO {
*/
private Integer status;
/**
*
*/
private String parentOrganizationIds;
/**
*
*/
private String parentOrganizationName;
}

View File

@ -112,7 +112,17 @@ public class TenantDO extends BaseDO {
*
*/
private String notice;
/**
*
*/
private Integer goodsCommission;
/**
*
*/
private Integer memberCommission;
/**
* logo
*/
private String logo;
}

View File

@ -12,6 +12,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.enums.dept.DeptIdEnum;
import cn.iocoder.yudao.module.system.mq.producer.dept.DeptProducer;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
@ -94,6 +95,16 @@ public class DeptServiceImpl implements DeptService {
validateForCreateOrUpdate(null, reqVO.getParentId(), reqVO.getName());
// 插入部门
DeptDO dept = DeptConvert.INSTANCE.convert(reqVO);
dept.setId(IdWorker.getId());
if(DeptIdEnum.ROOT.getId().equals(dept.getParentId())){
dept.setParentOrganizationIds(dept.getId()+"");
dept.setParentOrganizationName(dept.getName());
}else{
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
dept.setParentOrganizationIds(parent.getParentOrganizationIds()+","+dept.getId());
dept.setParentOrganizationName(parent.getParentOrganizationName()+">"+dept.getName());
}
deptMapper.insert(dept);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();
@ -109,6 +120,14 @@ public class DeptServiceImpl implements DeptService {
validateForCreateOrUpdate(reqVO.getId(), reqVO.getParentId(), reqVO.getName());
// 更新部门
DeptDO updateObj = DeptConvert.INSTANCE.convert(reqVO);
if(DeptIdEnum.ROOT.getId().equals(updateObj.getParentId())){
updateObj.setParentOrganizationIds(updateObj.getId()+"");
updateObj.setParentOrganizationName(updateObj.getName());
}else{
DeptDO parent = deptMapper.selectById(reqVO.getParentId());
updateObj.setParentOrganizationIds(parent.getParentOrganizationIds()+","+updateObj.getId());
updateObj.setParentOrganizationName(parent.getParentOrganizationName()+">"+updateObj.getName());
}
deptMapper.updateById(updateObj);
// 发送刷新消息
deptProducer.sendDeptRefreshMessage();

View File

@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.system.service.tenant;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.*;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantInfoHandler;
import cn.iocoder.yudao.module.system.service.tenant.handler.TenantMenuHandler;
@ -35,7 +32,17 @@ public interface TenantService {
* @param updateReqVO
*/
void updateTenant(@Valid TenantUpdateReqVO updateReqVO);
/**
* <pre>
* <b>updateTenantCommission</b>
* <b>Description:</b>
* <b>@author:</b> zenghuapei
* <b>@date:</b> 2023/5/16 13:24
* @param tenantCommission:
* @return
* </pre>
*/
void updateTenantCommission(@Valid TenantCommissionUpdateReqVO tenantCommission);
/**
*
*

View File

@ -12,10 +12,7 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantCreateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantExportReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.TenantUpdateReqVO;
import cn.iocoder.yudao.module.system.controller.admin.tenant.vo.tenant.*;
import cn.iocoder.yudao.module.system.convert.tenant.TenantConvert;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
@ -173,6 +170,26 @@ public class TenantServiceImpl implements TenantService {
}
}
/**
* <pre>
* <b>updateTenantCommission</b>
* <b>Description:</b>
* <b>@author:</b> zenghuapei
* <b>@date:</b> 2023/5/16 13:24
* @param tenantCommission :
* @return
* </pre>
*/
@Override
public void updateTenantCommission(TenantCommissionUpdateReqVO tenantCommission) {
// 校验存在
TenantDO tenant = validateUpdateTenant(tenantCommission.getId());
// 更新租户
tenant.setGoodsCommission(tenantCommission.getGoodsCommission());
tenant.setMemberCommission(tenantCommission.getMemberCommission());
tenantMapper.updateById(tenant);
}
private void validTenantNameDuplicate(String name, Long id) {
TenantDO tenant = tenantMapper.selectByName(name);
if (tenant == null) {

View File

@ -159,6 +159,10 @@ yudao:
- system_sms_log
- system_sensitive_word
- system_oauth2_client
- system_oauth2_code
- system_oauth2_access_token
- system_oauth2_approve
- system_oauth2_refresh_token
- system_mail_account
- system_mail_template
- system_mail_log
@ -210,6 +214,7 @@ yudao:
- cy_phone_record
- cy_recharge_order_info
- cy_refund_fee_record
- market_banner
sms-code: # 短信验证码相关的配置项
expire-times: 10m
send-frequency: 1m