From f3dbebb04e2c7ce2d0ebaa89496956e4c8c96284 Mon Sep 17 00:00:00 2001 From: khy <2908249413@qq.com> Date: Thu, 24 Apr 2025 17:55:31 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=8F=91=E7=A5=A8=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=92=8C=E5=8F=91=E7=A5=A8=E6=8A=AC=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/api/mall/trade/invoice/index.ts | 56 ++++ .../src/api/mall/trade/invoiceheader/index.ts | 48 ++++ .../views/mall/trade/invoice/InvoiceForm.vue | 258 ++++++++++++++++++ .../src/views/mall/trade/invoice/index.vue | 233 ++++++++++++++++ .../trade/invoiceheader/InvoiceHeaderForm.vue | 141 ++++++++++ .../views/mall/trade/invoiceheader/index.vue | 247 +++++++++++++++++ .../admin/invoice/InvoiceController.java | 148 ++++++++++ .../admin/invoice/vo/InvoicePageReqVO.java | 56 ++++ .../admin/invoice/vo/InvoiceRespVO.java | 93 +++++++ .../admin/invoice/vo/InvoiceSaveReqVO.java | 56 ++++ .../InvoiceHeaderController.java | 94 +++++++ .../vo/InvoiceHeaderPageReqVO.java | 55 ++++ .../invoiceheader/vo/InvoiceHeaderRespVO.java | 63 +++++ .../vo/InvoiceHeaderSaveReqVO.java | 50 ++++ .../app/invoice/AppInvoiceController.java | 117 ++++++++ .../app/invoice/vo/AppInvoicePageReqVO.java | 52 ++++ .../app/invoice/vo/AppInvoiceRespVO.java | 72 +++++ .../AppInvoiceHeaderController.java | 72 +++++ .../trade/convert/invoice/InvoiceConvert.java | 50 ++++ .../dal/dataobject/invoice/InvoiceDO.java | 78 ++++++ .../invoiceheader/InvoiceHeaderDO.java | 71 +++++ .../dal/mysql/invoice/InvoiceMapper.java | 31 +++ .../invoiceheader/InvoiceHeaderMapper.java | 33 +++ .../trade/service/invoice/InvoiceService.java | 65 +++++ .../service/invoice/InvoiceServiceImpl.java | 165 +++++++++++ .../invoiceheader/InvoiceHeaderService.java | 63 +++++ .../InvoiceHeaderServiceImpl.java | 129 +++++++++ 27 files changed, 2596 insertions(+) create mode 100644 yudao-admin-vue3/src/api/mall/trade/invoice/index.ts create mode 100644 yudao-admin-vue3/src/api/mall/trade/invoiceheader/index.ts create mode 100644 yudao-admin-vue3/src/views/mall/trade/invoice/InvoiceForm.vue create mode 100644 yudao-admin-vue3/src/views/mall/trade/invoice/index.vue create mode 100644 yudao-admin-vue3/src/views/mall/trade/invoiceheader/InvoiceHeaderForm.vue create mode 100644 yudao-admin-vue3/src/views/mall/trade/invoiceheader/index.vue create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/InvoiceController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoicePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceSaveReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/InvoiceHeaderController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderSaveReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/AppInvoiceController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoicePageReqVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoiceRespVO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoiceheader/AppInvoiceHeaderController.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/invoice/InvoiceConvert.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoice/InvoiceDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoiceheader/InvoiceHeaderDO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoice/InvoiceMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoiceheader/InvoiceHeaderMapper.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderService.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderServiceImpl.java diff --git a/yudao-admin-vue3/src/api/mall/trade/invoice/index.ts b/yudao-admin-vue3/src/api/mall/trade/invoice/index.ts new file mode 100644 index 0000000..6e3e9ba --- /dev/null +++ b/yudao-admin-vue3/src/api/mall/trade/invoice/index.ts @@ -0,0 +1,56 @@ +import request from '@/config/axios' + +// 发票管理 VO +export interface InvoiceVO { + id: number // id + userId: number // 用户编号 + bizId: string // 业务编号 + bizType: number // 业务类型:1-订单,2-提现 + type: number // 发票类型 + price: number // 金额 + headerType: number // 发票抬头类型 + status: number // 状态:0-未开票,1-已开票 + name: string //发票名称 + no: string //订单流水号 + orderTime: Date// 订单时间 + tradeOrderStatus: number // 订单状态 + taxNumber: string // 税号 + + headerId: number // 发票抬头编号 + + headerName: string // 发票抬头名称 + +} + +// 发票管理 API +export const InvoiceApi = { + // 查询发票管理分页 + getInvoicePage: async (params: any) => { + return await request.get({ url: `/trade/invoice/page`, params }) + }, + + // 查询发票管理详情 + getInvoice: async (id: number) => { + return await request.get({ url: `/trade/invoice/get?id=` + id }) + }, + + // 新增发票管理 + createInvoice: async (data: InvoiceVO) => { + return await request.post({ url: `/trade/invoice/create`, data }) + }, + + // 修改发票管理 + updateInvoice: async (data: InvoiceVO) => { + return await request.put({ url: `/trade/invoice/update`, data }) + }, + + // 删除发票管理 + deleteInvoice: async (id: number) => { + return await request.delete({ url: `/trade/invoice/delete?id=` + id }) + }, + + // 导出发票管理 Excel + exportInvoice: async (params) => { + return await request.download({ url: `/trade/invoice/export-excel`, params }) + }, +} diff --git a/yudao-admin-vue3/src/api/mall/trade/invoiceheader/index.ts b/yudao-admin-vue3/src/api/mall/trade/invoiceheader/index.ts new file mode 100644 index 0000000..960188c --- /dev/null +++ b/yudao-admin-vue3/src/api/mall/trade/invoiceheader/index.ts @@ -0,0 +1,48 @@ +import request from '@/config/axios' + +// 发票抬头 VO +export interface InvoiceHeaderVO { + id: number // id + userId: number // 用户编号 + name: string // 购方名称 + taxNumber: string // 纳税人识别号 + companyAddress: string // 公司地址 + companyTel: string // 公司电话 + bankName: string // 开户银行 + bankAccount: string // 发票 + isDefault: boolean // 是否默认 + type: boolean // 抬头类型 +} + +// 发票抬头 API +export const InvoiceHeaderApi = { + // 查询发票抬头分页 + getInvoiceHeaderPage: async (params: any) => { + return await request.get({ url: `/trade/invoice-header/page`, params }) + }, + + // 查询发票抬头详情 + getInvoiceHeader: async (id: number) => { + return await request.get({ url: `/trade/invoice-header/get?id=` + id }) + }, + + // 新增发票抬头 + createInvoiceHeader: async (data: InvoiceHeaderVO) => { + return await request.post({ url: `/trade/invoice-header/create`, data }) + }, + + // 修改发票抬头 + updateInvoiceHeader: async (data: InvoiceHeaderVO) => { + return await request.put({ url: `/trade/invoice-header/update`, data }) + }, + + // 删除发票抬头 + deleteInvoiceHeader: async (id: number) => { + return await request.delete({ url: `/trade/invoice-header/delete?id=` + id }) + }, + + // 导出发票抬头 Excel + exportInvoiceHeader: async (params) => { + return await request.download({ url: `/trade/invoice-header/export-excel`, params }) + }, +} \ No newline at end of file diff --git a/yudao-admin-vue3/src/views/mall/trade/invoice/InvoiceForm.vue b/yudao-admin-vue3/src/views/mall/trade/invoice/InvoiceForm.vue new file mode 100644 index 0000000..f26ad3b --- /dev/null +++ b/yudao-admin-vue3/src/views/mall/trade/invoice/InvoiceForm.vue @@ -0,0 +1,258 @@ + + + + diff --git a/yudao-admin-vue3/src/views/mall/trade/invoice/index.vue b/yudao-admin-vue3/src/views/mall/trade/invoice/index.vue new file mode 100644 index 0000000..b543e89 --- /dev/null +++ b/yudao-admin-vue3/src/views/mall/trade/invoice/index.vue @@ -0,0 +1,233 @@ + + + diff --git a/yudao-admin-vue3/src/views/mall/trade/invoiceheader/InvoiceHeaderForm.vue b/yudao-admin-vue3/src/views/mall/trade/invoiceheader/InvoiceHeaderForm.vue new file mode 100644 index 0000000..2df89f0 --- /dev/null +++ b/yudao-admin-vue3/src/views/mall/trade/invoiceheader/InvoiceHeaderForm.vue @@ -0,0 +1,141 @@ + + diff --git a/yudao-admin-vue3/src/views/mall/trade/invoiceheader/index.vue b/yudao-admin-vue3/src/views/mall/trade/invoiceheader/index.vue new file mode 100644 index 0000000..a30611d --- /dev/null +++ b/yudao-admin-vue3/src/views/mall/trade/invoiceheader/index.vue @@ -0,0 +1,247 @@ + + + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/InvoiceController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/InvoiceController.java new file mode 100644 index 0000000..6eaf667 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/InvoiceController.java @@ -0,0 +1,148 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoice; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoicePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceSaveReqVO; +import cn.iocoder.yudao.module.trade.convert.invoice.InvoiceConvert; +import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO; +import cn.iocoder.yudao.module.trade.service.invoice.InvoiceService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderLogService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +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.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +@Tag(name = "管理后台 - 发票管理") +@RestController +@RequestMapping("/trade/invoice") +@Validated +public class InvoiceController { + + @Resource + private InvoiceService invoiceService; + @Resource + private TradeOrderQueryService tradeOrderQueryService; + + @Resource + private MemberUserApi memberUserApi; + + @Resource + private TradeOrderLogService tradeOrderLogService; + + @PostMapping("/create") + @Operation(summary = "创建发票管理") + @PreAuthorize("@ss.hasPermission('trade:invoice:create')") + public CommonResult createInvoice(@Valid @RequestBody InvoiceSaveReqVO createReqVO) { + return success(invoiceService.createInvoice(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新发票管理") + @PreAuthorize("@ss.hasPermission('trade:invoice:update')") + public CommonResult updateInvoice(@Valid @RequestBody InvoiceSaveReqVO updateReqVO) { + invoiceService.updateInvoice(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除发票管理") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('trade:invoice:delete')") + public CommonResult deleteInvoice(@RequestParam("id") Integer id) { + invoiceService.deleteInvoice(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得发票管理") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('trade:invoice:query')") + public CommonResult getInvoice(@RequestParam("id") Integer id) { + InvoiceDO invoice = invoiceService.getInvoice(id); + // 查询订单 + TradeOrderDO order = tradeOrderQueryService.getOrder(Long.valueOf(invoice.getBizId())); + if (order == null) { + return success(BeanUtils.toBean(invoice, InvoiceRespVO.class)); + } + InvoiceRespVO respVO = BeanUtils.toBean(invoice, InvoiceRespVO.class); + // 查询订单项 + List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(Long.valueOf(invoice.getBizId())); + + // 拼接数据 + MemberUserRespDTO user = memberUserApi.getUser(order.getUserId()); + MemberUserRespDTO brokerageUser = order.getBrokerageUserId() != null ? + memberUserApi.getUser(order.getBrokerageUserId()) : null; + List orderLogs = tradeOrderLogService.getOrderLogListByOrderId(Long.valueOf(invoice.getBizId())); + respVO.setTradeOrder(TradeOrderConvert.INSTANCE.convert(order, orderItems, orderLogs, user, brokerageUser)); + return success(respVO); + } + + @GetMapping("/page") + @Operation(summary = "获得发票管理分页") + @PreAuthorize("@ss.hasPermission('trade:invoice:query')") + public CommonResult> getInvoicePage(@Valid InvoicePageReqVO pageReqVO) { + PageResult pageResult = invoiceService.getInvoicePage(pageReqVO); + + //拼接订单信息 + Set bizIds = convertSet(pageResult.getList(), InvoiceDO::getBizId); + Map map = invoiceService.getInvoiceRespMap(bizIds); + + //拼接抬头信息 + Set headerIds = convertSet(pageResult.getList(), InvoiceDO::getHeaderId); + Map headerMap = invoiceService.getHeaderMap(headerIds); + + return success(InvoiceConvert.INSTANCE.convertPage(pageResult, map,headerMap)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出发票管理 Excel") + @PreAuthorize("@ss.hasPermission('trade:invoice:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportInvoiceExcel(@Valid InvoicePageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + PageResult pageResult = invoiceService.getInvoicePage(pageReqVO); + + //拼接订单信息 + Set bizIds = convertSet(pageResult.getList(), InvoiceDO::getBizId); + Map map = invoiceService.getInvoiceRespMap(bizIds); + + //拼接抬头信息 + Set headerIds = convertSet(pageResult.getList(), InvoiceDO::getHeaderId); + Map headerMap = invoiceService.getHeaderMap(headerIds); + + PageResult page = InvoiceConvert.INSTANCE.convertPage(pageResult, map,headerMap); + // 导出 Excel + ExcelUtils.write(response, "发票管理.xls", "数据", InvoiceRespVO.class, + page.getList()); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoicePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoicePageReqVO.java new file mode 100644 index 0000000..ce2eb4a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoicePageReqVO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoice.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import 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 InvoicePageReqVO extends PageParam { + + @Schema(description = "用户编号", example = "22458") + private Long userId; + + @Schema(description = "业务编号", example = "31817") + private String bizId; + + @Schema(description = "业务类型:1-订单,2-提现", example = "2") + private Integer bizType; + + @Schema(description = "发票类型", example = "2") + private Integer type; + + @Schema(description = "金额", example = "22110") + private Integer price; + + + @Schema(description = "状态:0-未开票,1-已开票", example = "2") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "发票名称", example = "2") + private String name; + + @Schema(description = "发票附件", example = "2") + private String invoice; + + + @Schema(description = "邮箱", example = "2") + private String email; + + @Schema(description = "发票抬头id", example = "2") + private Long headerId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceRespVO.java new file mode 100644 index 0000000..d1d5893 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceRespVO.java @@ -0,0 +1,93 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoice.vo; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDetailRespVO; +import cn.iocoder.yudao.module.trade.enums.DictTypeConstants; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 发票管理 Response VO") +@Data +@ExcelIgnoreUnannotated +public class InvoiceRespVO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15728") + @ExcelProperty("id") + private Integer id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22458") + private Long userId; + + @Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31817") + private String bizId; + + @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + private Integer bizType; + + @Schema(description = "发票类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty(value = "发票类型", converter = DictConvert.class) + @DictFormat(DictTypeConstants.INVOICE_TYPE) + private Integer type; + + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "22110") + @ExcelProperty(value = "订单金额",converter = MoneyConvert.class) + private Integer price; + + + @Schema(description = "状态:0-未开票,1-已开票", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty(value = "状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.INVOICE_STATUS) + private Integer status; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "发票名称", example = "2") + @ExcelProperty("发票名称") + private String name; + + @Schema(description = "发票附件", example = "2") + @ExcelProperty("发票附件") + private String invoice; + + + @Schema(description = "邮箱", example = "2") + private String email; + + @Schema(description = "订单号", example = "2") + private String no; + + @Schema(description = "下单时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("下单时间") + private LocalDateTime orderTime; + + @Schema(description = "交易订单状态", requiredMode = Schema.RequiredMode.REQUIRED) + private Integer tradeOrderStatus; + + @Schema(description = "交易订单详情", requiredMode = Schema.RequiredMode.REQUIRED) + private TradeOrderDetailRespVO tradeOrder; + + @Schema(description = "发票抬头id", example = "2") + private Long headerId; + + @Schema(description = "发票抬头", example = "2") + @ExcelProperty("发票抬头") + private String headerName; + + @Schema(description = "发票抬头类型", example = "2") + @ExcelProperty(value = "发票抬头类型", converter = DictConvert.class) + @DictFormat(DictTypeConstants.INVOICE_TITLE_TYPE) + private Boolean headerType; + + + @Schema(description = "纳税人识别号", example = "2") + @ExcelProperty("纳税人识别号") + private String taxNumber; +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceSaveReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceSaveReqVO.java new file mode 100644 index 0000000..690f424 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoice/vo/InvoiceSaveReqVO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoice.vo; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; + +@Schema(description = "管理后台 - 发票管理新增/修改 Request VO") +@Data +public class InvoiceSaveReqVO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15728") + private Integer id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22458") +// @NotNull(message = "用户编号不能为空") + private Long userId; + + @Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31817") + @NotEmpty(message = "业务编号不能为空") + private String bizId; + + @Schema(description = "业务类型:1-订单,2-提现", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") +// @NotNull(message = "业务类型:1-订单,2-提现不能为空") + private Integer bizType; + + @Schema(description = "发票类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") +// @NotNull(message = "发票类型不能为空") + private Integer type; + + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "22110") +// @NotNull(message = "金额不能为空") + private Integer price; + + @Schema(description = "状态:0-未开票,1-已开票", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") +// @NotNull(message = "状态:0-未开票,1-已开票不能为空") + private Integer status; + + @Schema(description = "发票名称", example = "2") +// @NotNull(message = "发票名称不能为空") + private String name; + + @Schema(description = "发票附件", example = "2") +// @NotNull(message = "发票附件不能为空") + private String invoice; + + + @Schema(description = "邮箱", example = "2") +// @NotNull(message = "邮箱不能为空") + private String email; + + @Schema(description = "发票抬头id", example = "2") + private Long headerId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/InvoiceHeaderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/InvoiceHeaderController.java new file mode 100644 index 0000000..8548fb4 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/InvoiceHeaderController.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoiceheader; + +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderSaveReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import cn.iocoder.yudao.module.trade.service.invoiceheader.InvoiceHeaderService; +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.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.List; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 发票抬头") +@RestController +@RequestMapping("/trade/invoice-header") +@Validated +public class InvoiceHeaderController { + + @Resource + private InvoiceHeaderService invoiceHeaderService; + + @PostMapping("/create") + @Operation(summary = "创建发票抬头") + @PreAuthorize("@ss.hasPermission('trade:invoice-header:create')") + public CommonResult createInvoiceHeader(@Valid @RequestBody InvoiceHeaderSaveReqVO createReqVO) { + return success(invoiceHeaderService.createInvoiceHeader(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新发票抬头") + @PreAuthorize("@ss.hasPermission('trade:invoice-header:update')") + public CommonResult updateInvoiceHeader(@Valid @RequestBody InvoiceHeaderSaveReqVO updateReqVO) { + invoiceHeaderService.updateInvoiceHeader(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除发票抬头") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('trade:invoice-header:delete')") + public CommonResult deleteInvoiceHeader(@RequestParam("id") Long id) { + invoiceHeaderService.deleteInvoiceHeader(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得发票抬头") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('trade:invoice-header:query')") + public CommonResult getInvoiceHeader(@RequestParam("id") Long id) { + InvoiceHeaderDO invoiceHeader = invoiceHeaderService.getInvoiceHeader(id); + return success(BeanUtils.toBean(invoiceHeader, InvoiceHeaderRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得发票抬头分页") + @PreAuthorize("@ss.hasPermission('trade:invoice-header:query')") + public CommonResult> getInvoiceHeaderPage(@Valid InvoiceHeaderPageReqVO pageReqVO) { + PageResult pageResult = invoiceHeaderService.getInvoiceHeaderPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, InvoiceHeaderRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出发票抬头 Excel") + @PreAuthorize("@ss.hasPermission('trade:invoice-header:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportInvoiceHeaderExcel(@Valid InvoiceHeaderPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = invoiceHeaderService.getInvoiceHeaderPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "发票抬头.xls", "数据", InvoiceHeaderRespVO.class, + BeanUtils.toBean(list, InvoiceHeaderRespVO.class)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderPageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderPageReqVO.java new file mode 100644 index 0000000..819a37c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderPageReqVO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import 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 InvoiceHeaderPageReqVO extends PageParam { + + @Schema(description = "用户编号", example = "4889") + private Long userId; + + @Schema(description = "购方名称", example = "李四") + private String name; + + @Schema(description = "纳税人识别号") + private String taxNumber; + + @Schema(description = "公司地址") + private String companyAddress; + + @Schema(description = "公司电话") + private String companyTel; + + @Schema(description = "开户银行", example = "赵六") + private String bankName; + + @Schema(description = "发票", example = "27501") + private String bankAccount; + + @Schema(description = "是否默认") + private Boolean isDefault; + + @Schema(description = "抬头类型", example = "1") + private Boolean type; + + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private String email; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderRespVO.java new file mode 100644 index 0000000..303685d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 发票抬头 Response VO") +@Data +@ExcelIgnoreUnannotated +public class InvoiceHeaderRespVO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "29034") + @ExcelProperty("id") + private Long id; + + @Schema(description = "用户编号", example = "4889") + @ExcelProperty("用户编号") + private Long userId; + + @Schema(description = "购方名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @ExcelProperty("购方名称") + private String name; + + @Schema(description = "纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("纳税人识别号") + private String taxNumber; + + @Schema(description = "公司地址", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("公司地址") + private String companyAddress; + + @Schema(description = "公司电话") + @ExcelProperty("公司电话") + private String companyTel; + + @Schema(description = "开户银行", example = "赵六") + @ExcelProperty("开户银行") + private String bankName; + + @Schema(description = "发票", example = "27501") + @ExcelProperty("发票") + private String bankAccount; + + @Schema(description = "是否默认") + @ExcelProperty("是否默认") + private Boolean isDefault; + + @Schema(description = "抬头类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("抬头类型") + private Boolean type; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @ExcelProperty("邮箱") + private String email; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderSaveReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderSaveReqVO.java new file mode 100644 index 0000000..75d3b30 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/invoiceheader/vo/InvoiceHeaderSaveReqVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 发票抬头新增/修改 Request VO") +@Data +public class InvoiceHeaderSaveReqVO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "29034") + private Long id; + + @Schema(description = "用户编号", example = "4889") + private Long userId; + + @Schema(description = "购方名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @NotEmpty(message = "购方名称不能为空") + private String name; + + @Schema(description = "纳税人识别号", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotEmpty(message = "纳税人识别号不能为空") + private String taxNumber; + + @Schema(description = "公司地址", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotEmpty(message = "公司地址不能为空") + private String companyAddress; + + @Schema(description = "公司电话") + private String companyTel; + + @Schema(description = "开户银行", example = "赵六") + private String bankName; + + @Schema(description = "发票", example = "27501") + private String bankAccount; + + @Schema(description = "是否默认") + private Boolean isDefault; + + @Schema(description = "抬头类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "抬头类型不能为空") + private Boolean type; + + @Schema(description = "邮箱", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private String email; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/AppInvoiceController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/AppInvoiceController.java new file mode 100644 index 0000000..28a68e0 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/AppInvoiceController.java @@ -0,0 +1,117 @@ +package cn.iocoder.yudao.module.trade.controller.app.invoice; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoicePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceSaveReqVO; +import cn.iocoder.yudao.module.trade.controller.app.invoice.vo.AppInvoicePageReqVO; +import cn.iocoder.yudao.module.trade.controller.app.invoice.vo.AppInvoiceRespVO; +import cn.iocoder.yudao.module.trade.convert.invoice.InvoiceConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.service.invoice.InvoiceService; +import cn.iocoder.yudao.module.trade.service.invoiceheader.InvoiceHeaderService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; +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.*; + +import javax.annotation.Resource; +import javax.validation.Valid; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +@Tag(name = "用户 App - 发票管理") +@RestController +@RequestMapping("/trade/invoice") +@Validated +public class AppInvoiceController { + + @Resource + private InvoiceService invoiceService; + + @Resource + private InvoiceHeaderService invoiceHeaderService; + + @Resource + private TradeOrderQueryService tradeOrderQueryService; + + @Resource + private TradeOrderUpdateService tradeOrderUpdateService; + + @PostMapping("/create") + @Operation(summary = "创建发票管理") + public CommonResult createInvoice(@Valid @RequestBody InvoiceSaveReqVO createReqVO) { + if(createReqVO.getUserId() == null){ + createReqVO.setUserId(getLoginUserId()); + } + if(createReqVO.getHeaderId() == null){ + InvoiceHeaderDO invoiceHeaderDO = invoiceHeaderService.getDefaultInvoiceHeader(getLoginUserId()); + if (invoiceHeaderDO != null){ + createReqVO.setHeaderId(invoiceHeaderDO.getId()); + } + else { + return error(400, "请先设置默认发票抬头"); + } + } + //查询订单,修改订单状态为已开票 + TradeOrderDO tradeOrderDO = tradeOrderQueryService.getOrder(Long.valueOf(createReqVO.getBizId())); + if(tradeOrderDO != null){ + tradeOrderDO.setInvoiceStatus(1); + tradeOrderUpdateService.updateTradeOrder(tradeOrderDO); + if(createReqVO.getPrice() == null){ + createReqVO.setPrice(tradeOrderDO.getPayPrice()); + } + } + return success(invoiceService.createInvoice(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新发票管理") + public CommonResult updateInvoice(@Valid @RequestBody InvoiceSaveReqVO updateReqVO) { + if(updateReqVO.getUserId() == null){ + updateReqVO.setUserId(getLoginUserId()); + } + invoiceService.updateInvoice(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除发票管理") + @Parameter(name = "id", description = "编号", required = true) + public CommonResult deleteInvoice(@RequestParam("id") Integer id) { + invoiceService.deleteInvoice(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得发票管理") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getInvoice(@RequestParam("id") Integer id) { + InvoiceDO invoice = invoiceService.getInvoice(id); + return success(BeanUtils.toBean(invoice, AppInvoiceRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得发票管理分页") + public CommonResult> getInvoicePage(@Valid AppInvoicePageReqVO pageReqVO) { + pageReqVO.setUserId(getLoginUserId()); + PageResult pageResult = invoiceService.getInvoicePage(BeanUtils.toBean(pageReqVO, InvoicePageReqVO.class)); + //拼接订单信息 + Set bizIds = convertSet(pageResult.getList(), InvoiceDO::getBizId); + Map map = invoiceService.getAppInvoiceRespMap(bizIds); + return success(InvoiceConvert.INSTANCE.convertPage01(pageResult, map)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoicePageReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoicePageReqVO.java new file mode 100644 index 0000000..3588569 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoicePageReqVO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.trade.controller.app.invoice.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +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 +public class AppInvoicePageReqVO extends PageParam { + + @Schema(description = "用户编号", example = "22458") + private Long userId; + + @Schema(description = "业务编号", example = "31817") + private String bizId; + + @Schema(description = "业务类型:1-订单,2-提现", example = "2") + private Integer bizType; + + @Schema(description = "发票类型", example = "2") + private Integer type; + + @Schema(description = "金额", example = "22110") + private Integer price; + + @Schema(description = "状态:0-未开票,1-已开票", example = "2") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "发票名称", example = "2") + private String name; + + + @Schema(description = "发票附件", example = "2") + private String invoice; + + + @Schema(description = "邮箱", example = "2") + private String email; + + @Schema(description = "抬头id", example = "2") + private Long headerId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoiceRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoiceRespVO.java new file mode 100644 index 0000000..cdccd9d --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoice/vo/AppInvoiceRespVO.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.trade.controller.app.invoice.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 发票管理 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AppInvoiceRespVO { + + @Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "15728") + @ExcelProperty("id") + private Integer id; + + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22458") + @ExcelProperty("用户编号") + private Long userId; + + @Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31817") + @ExcelProperty("业务编号") + private String bizId; + + @Schema(description = "业务类型:1-订单,2-提现", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty("业务类型:1-订单,2-提现") + private Integer bizType; + + @Schema(description = "发票类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty("发票类型") + private Integer type; + + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "22110") + @ExcelProperty("金额") + private Integer price; + + @Schema(description = "状态:0-未开票,1-已开票", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") + @ExcelProperty("状态:0-未开票,1-已开票") + private Integer status; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "发票名称", example = "2") + @ExcelProperty("发票名称") + private String name; + + @Schema(description = "发票附件", example = "2") + @ExcelProperty("发票附件") + private String invoice; + + + @Schema(description = "邮箱", example = "2") + @ExcelProperty("邮箱") + private String email; + + @Schema(description = "抬头id", example = "2") + @ExcelProperty("抬头id") + private String headerId; + + @Schema(description = "商品图片", example = "2") + @ExcelProperty("商品图片") + private String picUrl; + + @Schema(description = "商品名称", example = "2") + @ExcelProperty("商品名称") + private String spuName; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoiceheader/AppInvoiceHeaderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoiceheader/AppInvoiceHeaderController.java new file mode 100644 index 0000000..d18df78 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/invoiceheader/AppInvoiceHeaderController.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.trade.controller.app.invoiceheader; + + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderSaveReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import cn.iocoder.yudao.module.trade.service.invoiceheader.InvoiceHeaderService; +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.*; + +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("/trade/invoice-header") +@Validated +public class AppInvoiceHeaderController { + + + @Resource + private InvoiceHeaderService invoiceHeaderService; + + @PostMapping("/create") + @Operation(summary = "创建发票抬头") + public CommonResult createInvoiceHeader(@Valid @RequestBody InvoiceHeaderSaveReqVO createReqVO) { + createReqVO.setUserId(getLoginUserId()); + return success(invoiceHeaderService.createInvoiceHeader(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新发票抬头") + public CommonResult updateInvoiceHeader(@Valid @RequestBody InvoiceHeaderSaveReqVO updateReqVO) { + updateReqVO.setUserId(getLoginUserId()); + invoiceHeaderService.updateInvoiceHeader(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除发票抬头") + @Parameter(name = "id", description = "编号", required = true) + public CommonResult deleteInvoiceHeader(@RequestParam("id") Long id) { + invoiceHeaderService.deleteInvoiceHeader(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得发票抬头") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult getInvoiceHeader(@RequestParam("id") Long id) { + InvoiceHeaderDO invoiceHeader = invoiceHeaderService.getInvoiceHeader(id); + return success(BeanUtils.toBean(invoiceHeader, InvoiceHeaderRespVO.class)); + } + + @GetMapping("/list") + @Operation(summary = "获得发票抬头列表") + public CommonResult> getInvoiceHeaderList() { + List list = invoiceHeaderService.selectOneByUserId(getLoginUserId()); + return success(BeanUtils.toBean(list, InvoiceHeaderRespVO.class)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/invoice/InvoiceConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/invoice/InvoiceConvert.java new file mode 100644 index 0000000..07e64ed --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/invoice/InvoiceConvert.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.trade.convert.invoice; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceRespVO; +import cn.iocoder.yudao.module.trade.controller.app.invoice.vo.AppInvoiceRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.Map; +import java.util.Optional; + +@Mapper +public interface InvoiceConvert { + + InvoiceConvert INSTANCE = Mappers.getMapper(InvoiceConvert.class); + + PageResult convertPage(PageResult pageResult); + + default PageResult convertPage(PageResult pageResult, Map map, + Map headerMap) { + PageResult result = convertPage(pageResult); + for (InvoiceRespVO respVO : result.getList()){ + Optional.ofNullable(map.get(respVO.getBizId())).ifPresent(item -> + respVO.setBizType(item.getBizType()) + .setNo(item.getNo()) + .setOrderTime(item.getOrderTime()) + .setTradeOrderStatus(item.getTradeOrderStatus())); + Optional.ofNullable(headerMap.get(respVO.getHeaderId())).ifPresent(item -> + respVO.setTaxNumber(item.getTaxNumber()) + .setHeaderType(item.getHeaderType()) + .setHeaderName(item.getHeaderName())); + } + + return result; + } + PageResult convertPage01(PageResult pageResult); + + //小程序拼接 + default PageResult convertPage01(PageResult pageResult, Map map) { + PageResult result = convertPage01(pageResult); + for (AppInvoiceRespVO respVO : result.getList()){ + Optional.ofNullable(map.get(respVO.getBizId())).ifPresent(item -> + respVO.setSpuName(item.getSpuName()) + .setPicUrl(item.getPicUrl())); + } + return result; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoice/InvoiceDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoice/InvoiceDO.java new file mode 100644 index 0000000..97ba85e --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoice/InvoiceDO.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.invoice; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 发票管理 DO + * + * @author 东方好果 + */ +@TableName("trade_invoice") +@KeySequence("trade_invoice_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceDO extends BaseDO { + + /** + * id + */ + @TableId + private Integer id; + /** + * 用户编号 + */ + private Long userId; + /** + * 业务编号 + */ + private String bizId; + /** + * 业务类型:1-订单,2-提现 + */ + private Integer bizType; + /** + * 发票类型 + */ + private Integer type; + /** + * 金额 + */ + private Integer price; + + /** + * 状态:0-未开票,1-已开票 + */ + private Integer status; + + /* + * 发票名称 + * */ + private String name; + + + /* + * 发票附件 + * */ + private String invoice; + + + /* + * 邮箱 + * */ + private String email; + + /* + * + * 发票抬头id + * */ + private Long headerId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoiceheader/InvoiceHeaderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoiceheader/InvoiceHeaderDO.java new file mode 100644 index 0000000..f74e67c --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/invoiceheader/InvoiceHeaderDO.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 发票抬头 DO + * + * @author 东方好果 + */ +@TableName("trade_invoice_header") +@KeySequence("trade_invoice_header_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class InvoiceHeaderDO extends BaseDO { + + /** + * id + */ + @TableId + private Long id; + /** + * 用户编号 + */ + private Long userId; + /** + * 购方名称 + */ + private String name; + /** + * 纳税人识别号 + */ + private String taxNumber; + /** + * 公司地址 + */ + private String companyAddress; + /** + * 公司电话 + */ + private String companyTel; + /** + * 开户银行 + */ + private String bankName; + /** + * 发票 + */ + private String bankAccount; + /** + * 是否默认 + */ + private Boolean isDefault; + /** + * 抬头类型 + */ + private Boolean type; + + /* + * 邮箱 + * */ + private String email; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoice/InvoiceMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoice/InvoiceMapper.java new file mode 100644 index 0000000..b329d10 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoice/InvoiceMapper.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.invoice; + +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.trade.controller.admin.invoice.vo.*; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 发票管理 Mapper + * + * @author 东方好果 + */ +@Mapper +public interface InvoiceMapper extends BaseMapperX { + + default PageResult selectPage(InvoicePageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(InvoiceDO::getUserId, reqVO.getUserId()) + .eqIfPresent(InvoiceDO::getBizId, reqVO.getBizId()) + .eqIfPresent(InvoiceDO::getBizType, reqVO.getBizType()) + .eqIfPresent(InvoiceDO::getType, reqVO.getType()) + .eqIfPresent(InvoiceDO::getPrice, reqVO.getPrice()) + .eqIfPresent(InvoiceDO::getStatus, reqVO.getStatus()) + .likeIfPresent(InvoiceDO::getName, reqVO.getName()) + .betweenIfPresent(InvoiceDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(InvoiceDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoiceheader/InvoiceHeaderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoiceheader/InvoiceHeaderMapper.java new file mode 100644 index 0000000..87dffee --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/invoiceheader/InvoiceHeaderMapper.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.trade.dal.mysql.invoiceheader; + +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.trade.controller.admin.invoiceheader.vo.*; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 发票抬头 Mapper + * + * @author 东方好果 + */ +@Mapper +public interface InvoiceHeaderMapper extends BaseMapperX { + + default PageResult selectPage(InvoiceHeaderPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(InvoiceHeaderDO::getUserId, reqVO.getUserId()) + .likeIfPresent(InvoiceHeaderDO::getName, reqVO.getName()) + .eqIfPresent(InvoiceHeaderDO::getTaxNumber, reqVO.getTaxNumber()) + .eqIfPresent(InvoiceHeaderDO::getCompanyAddress, reqVO.getCompanyAddress()) + .eqIfPresent(InvoiceHeaderDO::getCompanyTel, reqVO.getCompanyTel()) + .likeIfPresent(InvoiceHeaderDO::getBankName, reqVO.getBankName()) + .eqIfPresent(InvoiceHeaderDO::getBankAccount, reqVO.getBankAccount()) + .eqIfPresent(InvoiceHeaderDO::getIsDefault, reqVO.getIsDefault()) + .eqIfPresent(InvoiceHeaderDO::getType, reqVO.getType()) + .betweenIfPresent(InvoiceHeaderDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(InvoiceHeaderDO::getId)); + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceService.java new file mode 100644 index 0000000..d5d2f88 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceService.java @@ -0,0 +1,65 @@ +package cn.iocoder.yudao.module.trade.service.invoice; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoicePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceSaveReqVO; +import cn.iocoder.yudao.module.trade.controller.app.invoice.vo.AppInvoiceRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; + + +import javax.validation.Valid; +import java.util.Map; +import java.util.Set; + +/** + * 发票管理 Service 接口 + * + * @author 东方好果 + */ +public interface InvoiceService { + + /** + * 创建发票管理 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Integer createInvoice(@Valid InvoiceSaveReqVO createReqVO); + + /** + * 更新发票管理 + * + * @param updateReqVO 更新信息 + */ + void updateInvoice(@Valid InvoiceSaveReqVO updateReqVO); + + /** + * 删除发票管理 + * + * @param id 编号 + */ + void deleteInvoice(Integer id); + + /** + * 获得发票管理 + * + * @param id 编号 + * @return 发票管理 + */ + InvoiceDO getInvoice(Integer id); + + /** + * 获得发票管理分页 + * + * @param pageReqVO 分页查询 + * @return 发票管理分页 + */ + PageResult getInvoicePage(InvoicePageReqVO pageReqVO); + + Map getInvoiceRespMap(Set bizIds); + + Map getHeaderMap(Set headerIds); + + Map getAppInvoiceRespMap(Set bizIds); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceServiceImpl.java new file mode 100644 index 0000000..d58d59f --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoice/InvoiceServiceImpl.java @@ -0,0 +1,165 @@ +package cn.iocoder.yudao.module.trade.service.invoice; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoicePageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceRespVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoice.vo.InvoiceSaveReqVO; +import cn.iocoder.yudao.module.trade.controller.app.invoice.vo.AppInvoiceRespVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoice.InvoiceDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; +import cn.iocoder.yudao.module.trade.dal.mysql.invoice.InvoiceMapper; +import cn.iocoder.yudao.module.trade.service.invoiceheader.InvoiceHeaderService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.*; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.INVOICE_NOT_EXISTS; + +/** + * 发票管理 Service 实现类 + * + * @author 东方好果 + */ +@Service +@Validated +public class InvoiceServiceImpl implements InvoiceService { + + @Resource + private InvoiceMapper invoiceMapper; + + @Resource + private TradeOrderQueryService tradeOrderQueryService; + + @Resource + private InvoiceHeaderService invoiceHeaderService; + + @Resource + private TradeOrderUpdateService tradeOrderUpdateService; + + + @Override + public Integer createInvoice(InvoiceSaveReqVO createReqVO) { + // 插入 + InvoiceDO invoice = BeanUtils.toBean(createReqVO, InvoiceDO.class); + invoiceMapper.insert(invoice); + // 返回 + return invoice.getId(); + } + + @Override + public void updateInvoice(InvoiceSaveReqVO updateReqVO) { + // 校验存在 + validateInvoiceExists(updateReqVO.getId()); + // 更新 + InvoiceDO updateObj = BeanUtils.toBean(updateReqVO, InvoiceDO.class); + if(updateObj.getStatus() == 1){ + TradeOrderDO tradeOrderDO = tradeOrderQueryService.getOrder(Long.valueOf(updateObj.getBizId())); + if(tradeOrderDO != null){ + tradeOrderDO.setInvoiceStatus(2); + tradeOrderUpdateService.updateTradeOrder(tradeOrderDO); + } + } + invoiceMapper.updateById(updateObj); + } + + @Override + public void deleteInvoice(Integer id) { + // 校验存在 + validateInvoiceExists(id); + // 删除 + invoiceMapper.deleteById(id); + } + + private void validateInvoiceExists(Integer id) { + if (invoiceMapper.selectById(id) == null) { + throw exception(INVOICE_NOT_EXISTS); + } + } + + @Override + public InvoiceDO getInvoice(Integer id) { + return invoiceMapper.selectById(id); + } + + @Override + public PageResult getInvoicePage(InvoicePageReqVO pageReqVO) { + return invoiceMapper.selectPage(pageReqVO); + } + + @Override + public Map getInvoiceRespMap(Set bizIds) { + if (bizIds.isEmpty()) { + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + bizIds.forEach(bizId -> { + Long id = Long.valueOf(bizId); + TradeOrderDO order = tradeOrderQueryService.getOrder(id); + if(order != null){ + InvoiceRespVO invoiceRespVO = new InvoiceRespVO(); + invoiceRespVO.setBizId(bizId); + invoiceRespVO.setBizType(order.getType()); + invoiceRespVO.setNo(order.getNo()); + invoiceRespVO.setOrderTime(order.getCreateTime()); + invoiceRespVO.setTradeOrderStatus(order.getStatus()); + + map.put(bizId, invoiceRespVO); + } + }); + return map; + } + + @Override + public Map getHeaderMap(Set headerIds) { + if (headerIds.isEmpty()) { + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + headerIds.forEach(headerId -> { + InvoiceHeaderDO invoice = invoiceHeaderService.getInvoiceHeader(headerId); + if (invoice != null) { + InvoiceRespVO invoiceRespVO = new InvoiceRespVO(); + invoiceRespVO.setHeaderId(headerId); + invoiceRespVO.setHeaderType(invoice.getType()); + invoiceRespVO.setHeaderName(invoice.getName()); + invoiceRespVO.setTaxNumber(invoice.getTaxNumber()); + map.put(headerId, invoiceRespVO); + } + }); + return map; + } + + @Override + public Map getAppInvoiceRespMap(Set bizIds) { + if (bizIds.isEmpty()) { + return Collections.emptyMap(); + } + Map map = new HashMap<>(); + bizIds.forEach(bizId -> { + Long id = Long.valueOf(bizId); + TradeOrderDO order = tradeOrderQueryService.getOrder(id); + if(order != null){ + AppInvoiceRespVO appInvoiceRespVO = new AppInvoiceRespVO(); + appInvoiceRespVO.setBizId(bizId); + appInvoiceRespVO.setBizType(order.getType()); + List list = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); + if(list.size() != 0){ + appInvoiceRespVO.setSpuName(list.get(0).getSpuName()); + appInvoiceRespVO.setPicUrl(list.get(0).getPicUrl()); + map.put(bizId, appInvoiceRespVO); + } + + } + }); + return map; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderService.java new file mode 100644 index 0000000..7937afc --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderService.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.trade.service.invoiceheader; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderSaveReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; + + +import javax.validation.Valid; +import java.util.List; + +/** + * 发票抬头 Service 接口 + * + * @author 东方好果 + */ +public interface InvoiceHeaderService { + + /** + * 创建发票抬头 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createInvoiceHeader(@Valid InvoiceHeaderSaveReqVO createReqVO); + + /** + * 更新发票抬头 + * + * @param updateReqVO 更新信息 + */ + void updateInvoiceHeader(@Valid InvoiceHeaderSaveReqVO updateReqVO); + + /** + * 删除发票抬头 + * + * @param id 编号 + */ + void deleteInvoiceHeader(Long id); + + /** + * 获得发票抬头 + * + * @param id 编号 + * @return 发票抬头 + */ + InvoiceHeaderDO getInvoiceHeader(Long id); + + /** + * 获得发票抬头分页 + * + * @param pageReqVO 分页查询 + * @return 发票抬头分页 + */ + PageResult getInvoiceHeaderPage(InvoiceHeaderPageReqVO pageReqVO); + +// 查询当前默认抬头列表 + List selectOneByUserIdAndIsDefault(Long loginUserId); + + List selectOneByUserId(Long loginUserId); + + InvoiceHeaderDO getDefaultInvoiceHeader(Long userId); +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderServiceImpl.java new file mode 100644 index 0000000..7e1ba20 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/invoiceheader/InvoiceHeaderServiceImpl.java @@ -0,0 +1,129 @@ +package cn.iocoder.yudao.module.trade.service.invoiceheader; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.invoiceheader.vo.InvoiceHeaderSaveReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.invoiceheader.InvoiceHeaderDO; +import cn.iocoder.yudao.module.trade.dal.mysql.invoiceheader.InvoiceHeaderMapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; + +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.trade.enums.ErrorCodeConstants.INVOICE_HEADER_NOT_EXISTS; + +/** + * 发票抬头 Service 实现类 + * + * @author 东方好果 + */ +@Service +@Validated +public class InvoiceHeaderServiceImpl implements InvoiceHeaderService { + + @Resource + private InvoiceHeaderMapper invoiceHeaderMapper; + + @Override + public Long createInvoiceHeader(InvoiceHeaderSaveReqVO createReqVO) { + // 插入 + InvoiceHeaderDO invoiceHeader = BeanUtils.toBean(createReqVO, InvoiceHeaderDO.class); + if(createReqVO.getIsDefault().equals(true)) { + List invoiceHeaderDOS = invoiceHeaderMapper.selectList(new LambdaQueryWrapper() + .eq(InvoiceHeaderDO::getUserId, createReqVO.getUserId()) + .eq(InvoiceHeaderDO::getIsDefault, true) + .eq(InvoiceHeaderDO::getDeleted, false)); + if (invoiceHeaderDOS.size() != 0) { + invoiceHeaderDOS.forEach(invoiceHeaderDO -> { + invoiceHeaderDO.setIsDefault(false); + invoiceHeaderMapper.updateById(invoiceHeaderDO); + }); + } + } + invoiceHeaderMapper.insert(invoiceHeader); + // 返回 + return invoiceHeader.getId(); + } + + @Override + public void updateInvoiceHeader(InvoiceHeaderSaveReqVO updateReqVO) { + // 校验存在 + validateInvoiceHeaderExists(updateReqVO.getId()); + if(updateReqVO.getIsDefault().equals(true)){ + List invoiceHeaderDOS = invoiceHeaderMapper.selectList(new LambdaQueryWrapper() + .eq(InvoiceHeaderDO::getUserId,updateReqVO.getUserId()) + .eq(InvoiceHeaderDO::getIsDefault, true) + .eq(InvoiceHeaderDO::getDeleted, false)); + if(invoiceHeaderDOS.size() != 0){ + invoiceHeaderDOS.forEach(invoiceHeaderDO -> { + invoiceHeaderDO.setIsDefault(false); + invoiceHeaderMapper.updateById(invoiceHeaderDO); + }); + } + } + // 更新 + InvoiceHeaderDO updateObj = BeanUtils.toBean(updateReqVO, InvoiceHeaderDO.class); + invoiceHeaderMapper.updateById(updateObj); + } + + @Override + public void deleteInvoiceHeader(Long id) { + // 校验存在 + validateInvoiceHeaderExists(id); + // 删除 + invoiceHeaderMapper.deleteById(id); + } + + private void validateInvoiceHeaderExists(Long id) { + if (invoiceHeaderMapper.selectById(id) == null) { + throw exception(INVOICE_HEADER_NOT_EXISTS); + } + } + + @Override + public InvoiceHeaderDO getInvoiceHeader(Long id) { + return invoiceHeaderMapper.selectById(id); + } + + @Override + public PageResult getInvoiceHeaderPage(InvoiceHeaderPageReqVO pageReqVO) { + return invoiceHeaderMapper.selectPage(pageReqVO); + } + + @Override + public List selectOneByUserIdAndIsDefault(Long loginUserId) { + if (loginUserId != null) { + return invoiceHeaderMapper.selectList(new LambdaUpdateWrapper() + .eq(InvoiceHeaderDO::getUserId, loginUserId) + .eq(InvoiceHeaderDO::getIsDefault, true) + .eq(InvoiceHeaderDO::getDeleted, false)); + } + return null; + } + + @Override + public List selectOneByUserId(Long loginUserId) { + if (loginUserId != null) { + return invoiceHeaderMapper.selectList(new LambdaUpdateWrapper() + .eq(InvoiceHeaderDO::getUserId, loginUserId) + .eq(InvoiceHeaderDO::getDeleted, false)); + } + return null; + } + + @Override + public InvoiceHeaderDO getDefaultInvoiceHeader(Long userId) { + InvoiceHeaderDO invoiceHeaderDO = invoiceHeaderMapper.selectOne(new LambdaUpdateWrapper() + .eq(InvoiceHeaderDO::getUserId, userId) + .eq(InvoiceHeaderDO::getIsDefault, true) + .eq(InvoiceHeaderDO::getDeleted, false)); + return invoiceHeaderDO; + } + +} -- 2.47.2 From 88bcf054fadd46a6728084366261c3c526bcfd02 Mon Sep 17 00:00:00 2001 From: khy <2908249413@qq.com> Date: Fri, 25 Apr 2025 18:02:43 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=A7=BB=E6=A4=8D=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E5=95=86=EF=BC=8C=E7=AD=89=E7=BA=A7=EF=BC=8C=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E7=BB=93=E7=AE=97=EF=BC=8C=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yudao-admin-vue3/src/api/agent/info/index.ts | 92 +++ yudao-admin-vue3/src/api/agent/level/index.ts | 41 ++ yudao-admin-vue3/src/api/agent/order/index.ts | 54 ++ yudao-admin-vue3/src/api/member/user/index.ts | 15 + yudao-admin-vue3/src/utils/dict.ts | 36 +- .../closingrecord/ClosingRecordAgreeForm.vue | 76 +++ .../agent/closingrecord/ClosingRecordForm.vue | 180 ++++++ .../src/views/agent/closingrecord/index.vue | 318 ++++++++++ .../src/views/agent/info/InfoDetail.vue | 221 +++++++ .../src/views/agent/info/InfoForm.vue | 435 ++++++++++++++ .../info/detail/AgentInfoLowerDialog.vue | 137 +++++ .../agent/info/detail/AgentInfoUpdateForm.vue | 179 ++++++ .../agent/info/detail/UserAccountInfo.vue | 73 +++ .../views/agent/info/detail/UserBasicInfo.vue | 124 ++++ .../agent/info/detail/UserBrokerageList.vue | 125 ++++ .../src/views/agent/info/detail/index.vue | 124 ++++ .../src/views/agent/info/index.vue | 560 ++++++++++++++++++ .../src/views/agent/level/LevelForm.vue | 115 ++++ .../src/views/agent/level/index.vue | 196 ++++++ .../src/views/agent/order/BonusForm.vue | 118 ++++ .../src/views/agent/order/index.vue | 344 +++++++++++ .../src/views/member/config/index.vue | 6 +- .../common/util/object/BeanUtils.java | 9 +- .../framework/ip/core/utils/AreaUtils.java | 48 ++ .../yudao-module-trade-api/pom.xml | 22 + .../api/brokerage/BrokerageRecordApi.java | 14 + .../trade/api/brokerage/BrokerageUserApi.java | 14 + .../api/brokerage/BrokerageWithDrawApi.java | 9 + .../dto/BrokerageRecordPageReqDTO.java | 40 ++ .../brokerage/dto/BrokerageRecordRespDTO.java | 186 ++++++ .../brokerage/dto/BrokerageUserRespDTO.java | 49 ++ .../module/trade/enums/DictTypeConstants.java | 31 + .../trade/enums/ErrorCodeConstants.java | 5 + .../brokerage/BrokerageWithdrawTypeEnum.java | 11 + .../yudao-module-trade-biz/pom.xml | 6 + .../api/brokerage/BrokerageRecordApiImpl.java | 44 ++ .../api/brokerage/BrokerageUserApiImpl.java | 45 ++ .../brokerage/BrokerageWithDrawApiImpl.java | 37 ++ .../BrokerageWithdrawController.java | 16 + .../vo/user/BrokerageUserCreateReqVO.java | 20 + .../vo/withdraw/BrokerageWithdrawBaseVO.java | 16 + .../brokerage/BrokerageRecordConvert.java | 3 + .../brokerage/BrokerageUserConvert.java | 3 + .../brokerage/BrokerageWithdrawDO.java | 28 + .../dal/dataobject/order/TradeOrderDO.java | 16 + .../order/config/TradeOrderProperties.java | 6 + .../brokerage/BrokerageRecordService.java | 3 + .../brokerage/BrokerageRecordServiceImpl.java | 14 + .../brokerage/BrokerageUserService.java | 14 + .../brokerage/BrokerageUserServiceImpl.java | 35 ++ .../brokerage/BrokerageWithdrawService.java | 1 + .../BrokerageWithdrawServiceImpl.java | 97 ++- .../service/order/TradeOrderQueryService.java | 8 +- .../order/TradeOrderQueryServiceImpl.java | 63 ++ .../order/TradeOrderUpdateService.java | 1 + .../order/TradeOrderUpdateServiceImpl.java | 8 + yudao-module-member/pom.xml | 2 + .../yudao-module-agent-api/pom.xml | 33 ++ .../agent/enums/ErrorCodeConstants.java | 64 ++ .../enums/api/agentinfo/AgentInfoApi.java | 35 ++ .../api/agentinfo/dto/AgentInfoRespDTO.java | 120 ++++ .../yudao-module-agent-biz/pom.xml | 103 ++++ .../agent/api/agentinfo/AgentInfoApiImpl.java | 81 +++ .../admin/info/AgentInfoController.java | 246 ++++++++ .../admin/info/vo/AgentInfoPageReqVO.java | 49 ++ .../admin/info/vo/AgentInfoRespVO.java | 130 ++++ .../admin/info/vo/AgentInfoSaveReqVO.java | 114 ++++ .../admin/level/AgentLevelController.java | 103 ++++ .../admin/level/vo/AgentLevelPageReqVO.java | 30 + .../admin/level/vo/AgentLevelRespVO.java | 39 ++ .../admin/level/vo/AgentLevelSaveReqVO.java | 26 + .../admin/order/agentOrderController.java | 137 +++++ .../agent/convert/AgentInfoConvert.java | 39 ++ .../dal/dataobject/info/AgentInfoDO.java | 149 +++++ .../dal/dataobject/level/AgentLevelDO.java | 40 ++ .../agent/dal/mysql/info/AgentInfoMapper.java | 53 ++ .../dal/mysql/level/AgentLevelMapper.java | 26 + .../agent/service/info/AgentInfoService.java | 96 +++ .../service/info/AgentInfoServiceImpl.java | 263 ++++++++ .../service/level/AgentLevelService.java | 57 ++ .../service/level/AgentLevelServiceImpl.java | 88 +++ .../resources/mapper/info/AgentInfoMapper.xml | 12 + .../mapper/level/AgentLevelMapper.xml | 12 + .../admin/config/vo/MemberConfigBaseVO.java | 3 + .../admin/user/MemberUserController.java | 16 + .../dal/dataobject/config/MemberConfigDO.java | 7 + .../service/user/MemberUserService.java | 5 + .../service/user/MemberUserServiceImpl.java | 33 +- yudao-module-pay/yudao-module-pay-api/pom.xml | 5 + .../pay/api/transfer/PayTransferApi.java | 9 + .../transfer/dto/PayTransferCreateReqDTO.java | 3 + .../api/transfer/dto/PayTransferRespDTO.java | 31 + .../module/pay/api/wallet/PayWalletApi.java | 4 + .../wallet/dto/PayWalletAddBalanceReqDTO.java | 50 ++ .../enums/wallet/PayWalletBizTypeEnum.java | 8 +- .../pay/api/transfer/PayTransferApiImpl.java | 9 + .../pay/api/wallet/PayWalletApiImpl.java | 14 + .../pay/dal/mysql/wallet/PayWalletMapper.java | 13 + .../framework/pay/config/PayProperties.java | 10 + .../transfer/PayTransferServiceImpl.java | 15 + .../service/wallet/PayWalletServiceImpl.java | 4 + .../yudao-spring-boot-starter-biz-pay/pom.xml | 5 + .../dto/transfer/PayTransferRespDTO.java | 14 +- .../transfer/PayTransferUnifiedReqDTO.java | 9 + .../impl/alipay/AbstractAlipayPayClient.java | 4 +- .../impl/weixin/AbstractWxPayClient.java | 62 +- .../bean/transfer/TransferBatchesRequest.java | 118 ++++ .../module/system/api/user/AdminUserApi.java | 15 + .../system/api/user/dto/AdminUserRespDTO.java | 10 + .../system/api/user/AdminUserApiImpl.java | 54 +- .../admin/user/vo/user/UserPageReqVO.java | 9 + .../dal/mysql/permission/RoleMapper.java | 10 + .../dal/mysql/permission/UserRoleMapper.java | 5 + .../dal/mysql/user/AdminUserMapper.java | 53 ++ .../service/permission/PermissionService.java | 3 + .../permission/PermissionServiceImpl.java | 5 + .../service/permission/RoleService.java | 4 + .../service/permission/RoleServiceImpl.java | 10 + .../system/service/user/AdminUserService.java | 31 + .../service/user/AdminUserServiceImpl.java | 163 ++++- yudao-server/pom.xml | 6 + 121 files changed, 7435 insertions(+), 32 deletions(-) create mode 100644 yudao-admin-vue3/src/api/agent/info/index.ts create mode 100644 yudao-admin-vue3/src/api/agent/level/index.ts create mode 100644 yudao-admin-vue3/src/api/agent/order/index.ts create mode 100644 yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordAgreeForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/closingrecord/index.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/InfoDetail.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/InfoForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/AgentInfoLowerDialog.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/AgentInfoUpdateForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/UserAccountInfo.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/UserBasicInfo.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/UserBrokerageList.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/detail/index.vue create mode 100644 yudao-admin-vue3/src/views/agent/info/index.vue create mode 100644 yudao-admin-vue3/src/views/agent/level/LevelForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/level/index.vue create mode 100644 yudao-admin-vue3/src/views/agent/order/BonusForm.vue create mode 100644 yudao-admin-vue3/src/views/agent/order/index.vue create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApi.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApi.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApi.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordPageReqDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserRespDTO.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApiImpl.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/user/BrokerageUserCreateReqVO.java create mode 100644 yudao-module-member/yudao-module-agent-api/pom.xml create mode 100644 yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/ErrorCodeConstants.java create mode 100644 yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/AgentInfoApi.java create mode 100644 yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/dto/AgentInfoRespDTO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/pom.xml create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/api/agentinfo/AgentInfoApiImpl.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/AgentInfoController.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoPageReqVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoRespVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoSaveReqVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/AgentLevelController.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelPageReqVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelRespVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelSaveReqVO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/order/agentOrderController.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/convert/AgentInfoConvert.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/info/AgentInfoDO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/level/AgentLevelDO.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/info/AgentInfoMapper.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/level/AgentLevelMapper.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoService.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoServiceImpl.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelService.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelServiceImpl.java create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/info/AgentInfoMapper.xml create mode 100644 yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/level/AgentLevelMapper.xml create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java create mode 100644 yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletAddBalanceReqDTO.java create mode 100644 yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java diff --git a/yudao-admin-vue3/src/api/agent/info/index.ts b/yudao-admin-vue3/src/api/agent/info/index.ts new file mode 100644 index 0000000..38cc702 --- /dev/null +++ b/yudao-admin-vue3/src/api/agent/info/index.ts @@ -0,0 +1,92 @@ +import request from '@/config/axios' + +// 代理商信息 VO +export interface InfoVO { + id: number // 代理商ID + agentName: string // 代理商名称 + region: string // 所属区域 + agentLevelId: string // 代理商等级id + address: string // 地址 + wxAvatar: string // 微信头像 + phone: string // 手机号 + performance: number // 业绩 + depositAmount: number // 保证金额 + teamSize: number // 团队成员数 + profitRatio: number // 分润结算比 + bankName: string // 开户行 + bankCardNo: string // 银行卡号 + cardholder: string // 持卡人 + idCardNo: string // 身份证号码 + userId: number // 用户id + areaId: number // 区域编码 + endTime: string//到期时间 + contractStatus: number // 合同状态 +} + +// 代理商信息 API +export const InfoApi = { + // 查询代理商信息分页 + getInfoPage: async (params: any) => { + return await request.get({ url: `/agent/info/page`, params }) + }, + // 查询组织信息分页 + getOrgInfoPage: async (params: any) => { + return await request.get({ url: `/agent/info/org-page`, params }) + }, + // 查询代理商信息详情 + getInfo: async (id: number) => { + return await request.get({ url: `/agent/info/get?id=` + id }) + }, + + // 新增代理商信息 + createInfo: async (data: InfoVO) => { + return await request.post({ url: `/agent/info/create`, data }) + }, + + // 修改代理商信息 + updateInfo: async (data: InfoVO) => { + return await request.put({ url: `/agent/info/update`, data }) + }, + + // 删除代理商信息 + deleteInfo: async (id: number) => { + return await request.delete({ url: `/agent/info/delete?id=` + id }) + }, + + // 导出代理商信息 Excel + exportInfo: async (params) => { + return await request.download({ url: `/agent/info/export-excel`, params }) + }, + + // 导出事业部信息 Excel + exportInfoOrg: async (params) => { + return await request.download({ url: `/agent/info/export-org-excel`, params }) + }, + + // 查询代理商用户id列表 + getAgentList: async () => { + return await request.get({ url: `/agent/info/get-agent-list` }) + }, + + // 查询代理商等级列表 + getAgentLevelList: async () => { + return await request.get({ url: `/agent/level/get-agent-level-list` }) + }, + + // 取消代理商 + cancelAgent: async (data: InfoVO) => { + return await request.put({ url: `/agent/info/cancel`, data}) + }, + + getBoundUserList: async () => { + return await request.get({ url: `/agent/info/get-bound-userid-list` }) + }, + + getCascaderOptions: async () => { + return await request.get({ url: `/agent/info/cascader-options` }) + }, + + getAreaList : async () => { + return await request.get({ url: `/agent/info/getAreaList` }) + }, +} diff --git a/yudao-admin-vue3/src/api/agent/level/index.ts b/yudao-admin-vue3/src/api/agent/level/index.ts new file mode 100644 index 0000000..9c7fea5 --- /dev/null +++ b/yudao-admin-vue3/src/api/agent/level/index.ts @@ -0,0 +1,41 @@ +import request from '@/config/axios' + +// 代理商等级 VO +export interface LevelVO { + id: number // 代理商等级ID + levelName: string // 等级名称 + status: number // 状态 +} + +// 代理商等级 API +export const LevelApi = { + // 查询代理商等级分页 + getLevelPage: async (params: any) => { + return await request.get({ url: `/agent/level/page`, params }) + }, + + // 查询代理商等级详情 + getLevel: async (id: number) => { + return await request.get({ url: `/agent/level/get?id=` + id }) + }, + + // 新增代理商等级 + createLevel: async (data: LevelVO) => { + return await request.post({ url: `/agent/level/create`, data }) + }, + + // 修改代理商等级 + updateLevel: async (data: LevelVO) => { + return await request.put({ url: `/agent/level/update`, data }) + }, + + // 删除代理商等级 + deleteLevel: async (id: number) => { + return await request.delete({ url: `/agent/level/delete?id=` + id }) + }, + + // 导出代理商等级 Excel + exportLevel: async (params) => { + return await request.download({ url: `/agent/level/export-excel`, params }) + }, +} \ No newline at end of file diff --git a/yudao-admin-vue3/src/api/agent/order/index.ts b/yudao-admin-vue3/src/api/agent/order/index.ts new file mode 100644 index 0000000..8a77b2f --- /dev/null +++ b/yudao-admin-vue3/src/api/agent/order/index.ts @@ -0,0 +1,54 @@ +import request from '@/config/axios' + +// 代理商分红明细 VO +export interface AgentOrderVO { + id: number // id + price: number // 订单支付金额,单位:分 + bonus: number // 分红金额,单位: 分 + agentId: number // 代理商id + status: number // 支付状态 + bizId: string // 业务id + bizType: number //业务类型 + title: string //标题 + // description: string //描述 + + agentLevel: number //等级id + + agentName: string //代理商名称 + + productCount: number //商品数量 + + terminal: number //终端类型 + + userId: number //用户id + + orderTime: Date // 创建时间 + + spuId: number //商品id + + spuName: string //商品名称 + + picUrl: string //商品图片 + + productPrice: number //商品价格 + + payPrice: number //支付金额 + + payStatus: boolean //支付状态 + + tradeOrderStatus: number //交易订单状态 +} + +// 代理商分红明细 API +export const AgentOrderApi = { + // 查询代理商分红明细分页 + getAgenPage: async (params: any) => { + return await request.get({url: `/agent/order/page`, params}) + }, + + // 导出佣金提现 Excel + exportAgentOrder: async (params: any) => { + return await request.download({ url: `/agent/order/export-excel`, params }) + } +} + diff --git a/yudao-admin-vue3/src/api/member/user/index.ts b/yudao-admin-vue3/src/api/member/user/index.ts index b8b5304..c80edfa 100644 --- a/yudao-admin-vue3/src/api/member/user/index.ts +++ b/yudao-admin-vue3/src/api/member/user/index.ts @@ -57,3 +57,18 @@ export const updateUserBalance = async (data: any) => { export const getUserInfo = async (id: number) => { return await request.get({ url: `/member/user/getUserInfo?id=` + id }) } + +// 查询当前代理商户可绑用户列表 +export const getUserListForAgent = async () => { + return await request.get({ url: `/member/user/get-agent-list`}) +} + +// 查询当前代理商户可绑用户列表 +export const getBrokerListForAgent = async () => { + return await request.get({ url: `/member/user/get-broker-list`}) +} + +// 导出支付订单 +export const exportUser = async (params) => { + return await request.download({ url: '/member/user/export-excel', params }) +} diff --git a/yudao-admin-vue3/src/utils/dict.ts b/yudao-admin-vue3/src/utils/dict.ts index 8efdd00..3b17798 100644 --- a/yudao-admin-vue3/src/utils/dict.ts +++ b/yudao-admin-vue3/src/utils/dict.ts @@ -123,19 +123,19 @@ export enum DICT_TYPE { TYPES = 'types', TECHNICIAN_STATUS = 'technician_status', SEX = 'sex', - + //客服配置类型 KEFU_CONFIGURATION_TYPE = 'kefu_configuration_type', - + INFRA_FILE_TYPE = 'infra_file_type', - + PAY_WALLET_RECHARGE_PAY_STATUS = 'pay_wallet_recharge_pay_status', - + //预约:项目 SUBSCRIBE_PROJECT_STATUS = 'subscribe_project_status', - + SUBSCRIBE_RESERVATION_STATUS = 'subscribe_reservation_status', - + //预约:配置 SUBSCRIBE_CONFIGURATION_STATUS = 'subscribe_configuration_status', @@ -152,17 +152,17 @@ export enum DICT_TYPE { //预约:机构管理 ORGANIZATION_STATUS = 'organization_status', - + //客服:自动回复 KEFU_AUTO_RESPONSE_TYPE = 'kefu_auto_response_type', KEFU_AUTO_RESPONSE_STATUS = 'kefu_auto_response_status', - + //客服:留言 KEFU_LEAVE_WORD_STATUS = 'kefu_leave_word_status', - + //客服:话术 KEFU_VERBAL_TRICK_TYPE = 'kefu_verbal_trick_type', - + //客服人员管理 KEFU_SUPPORT_STAFF_STATUS = 'kefu_support_staff_status', KEFU_SUPPORT_STAFF_ORDER_MANAGE = 'kefu_support_staff_order_manage', @@ -295,5 +295,19 @@ export enum DICT_TYPE { // ========== 通用模块 ========== ZERO_OR_ONE = 'zero_or_one', IS_ACTIVATE = 'is_activate', - CARD_STATUS = 'card_status' + CARD_STATUS = 'card_status', + + // ========== AGENT - 代理商模块 ========== + AGENT_CONTRACT_STATUS = 'agent_contract_status', // 代理商合同状态 + + // ========== INVOICE - 发票模块 ========== + + INVOICE_TYPE = 'invoice_type', //发票类型 + + INVOICE_TITLE_TYPE = 'invoice_title_type', //发票抬头 + + INVOICE_STATUS = 'invoice_status', //发票状态 + + INVOICE_HEADER_DEFAULT = 'invoice_header_default', //抬头默认 + } diff --git a/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordAgreeForm.vue b/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordAgreeForm.vue new file mode 100644 index 0000000..80b4567 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordAgreeForm.vue @@ -0,0 +1,76 @@ + + diff --git a/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordForm.vue b/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordForm.vue new file mode 100644 index 0000000..47730ab --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/closingrecord/ClosingRecordForm.vue @@ -0,0 +1,180 @@ + + diff --git a/yudao-admin-vue3/src/views/agent/closingrecord/index.vue b/yudao-admin-vue3/src/views/agent/closingrecord/index.vue new file mode 100644 index 0000000..e93e8d8 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/closingrecord/index.vue @@ -0,0 +1,318 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/InfoDetail.vue b/yudao-admin-vue3/src/views/agent/info/InfoDetail.vue new file mode 100644 index 0000000..73112c6 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/InfoDetail.vue @@ -0,0 +1,221 @@ + + diff --git a/yudao-admin-vue3/src/views/agent/info/InfoForm.vue b/yudao-admin-vue3/src/views/agent/info/InfoForm.vue new file mode 100644 index 0000000..96cb54e --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/InfoForm.vue @@ -0,0 +1,435 @@ + + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoLowerDialog.vue b/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoLowerDialog.vue new file mode 100644 index 0000000..14e40a9 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoLowerDialog.vue @@ -0,0 +1,137 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoUpdateForm.vue b/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoUpdateForm.vue new file mode 100644 index 0000000..7ea8157 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/AgentInfoUpdateForm.vue @@ -0,0 +1,179 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/UserAccountInfo.vue b/yudao-admin-vue3/src/views/agent/info/detail/UserAccountInfo.vue new file mode 100644 index 0000000..4b25adc --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/UserAccountInfo.vue @@ -0,0 +1,73 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/UserBasicInfo.vue b/yudao-admin-vue3/src/views/agent/info/detail/UserBasicInfo.vue new file mode 100644 index 0000000..8fe9b7c --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/UserBasicInfo.vue @@ -0,0 +1,124 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/UserBrokerageList.vue b/yudao-admin-vue3/src/views/agent/info/detail/UserBrokerageList.vue new file mode 100644 index 0000000..832ebad --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/UserBrokerageList.vue @@ -0,0 +1,125 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/detail/index.vue b/yudao-admin-vue3/src/views/agent/info/detail/index.vue new file mode 100644 index 0000000..e2da95b --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/detail/index.vue @@ -0,0 +1,124 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/info/index.vue b/yudao-admin-vue3/src/views/agent/info/index.vue new file mode 100644 index 0000000..f231716 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/info/index.vue @@ -0,0 +1,560 @@ + + + + diff --git a/yudao-admin-vue3/src/views/agent/level/LevelForm.vue b/yudao-admin-vue3/src/views/agent/level/LevelForm.vue new file mode 100644 index 0000000..ca7f4ac --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/level/LevelForm.vue @@ -0,0 +1,115 @@ + + diff --git a/yudao-admin-vue3/src/views/agent/level/index.vue b/yudao-admin-vue3/src/views/agent/level/index.vue new file mode 100644 index 0000000..537f8a6 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/level/index.vue @@ -0,0 +1,196 @@ + + + diff --git a/yudao-admin-vue3/src/views/agent/order/BonusForm.vue b/yudao-admin-vue3/src/views/agent/order/BonusForm.vue new file mode 100644 index 0000000..3141828 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/order/BonusForm.vue @@ -0,0 +1,118 @@ + + \ No newline at end of file diff --git a/yudao-admin-vue3/src/views/agent/order/index.vue b/yudao-admin-vue3/src/views/agent/order/index.vue new file mode 100644 index 0000000..c11f0a9 --- /dev/null +++ b/yudao-admin-vue3/src/views/agent/order/index.vue @@ -0,0 +1,344 @@ + + + + diff --git a/yudao-admin-vue3/src/views/member/config/index.vue b/yudao-admin-vue3/src/views/member/config/index.vue index 2593509..90afdbb 100644 --- a/yudao-admin-vue3/src/views/member/config/index.vue +++ b/yudao-admin-vue3/src/views/member/config/index.vue @@ -47,6 +47,9 @@ 下单支付金额按比例赠送积分(实际支付 1 元赠送多少积分) + + + @@ -71,7 +74,8 @@ const formData = ref({ pointTradeDeductEnable: true, pointTradeDeductUnitPrice: 0, pointTradeDeductMaxPrice: 0, - pointTradeGivePoint: 0 + pointTradeGivePoint: 0, + content: '' }) // 创建一个计算属性,用于将 pointTradeDeductUnitPrice 显示为带两位小数的形式 diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java index 720b565..cbfc572 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/object/BeanUtils.java @@ -59,4 +59,11 @@ public class BeanUtils { return new PageResult<>(list, source.getTotal()); } -} \ No newline at end of file + public static void copyProperties(Object source, Object target) { + if (source == null || target == null) { + return; + } + BeanUtil.copyProperties(source, target, false); + } + +} diff --git a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java index 8e27a31..89ce1f0 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java @@ -211,4 +211,52 @@ public class AreaUtils { return null; } + public static List> convertToCascaderOptions() { + List> options = new ArrayList<>(); + for (Area area : areas.values()) { + // 找到所有顶级节点 + /* if (area.getParent() == null || area.getParent().getId() == Area.ID_GLOBAL) { + options.add(convertAreaToCascaderOption(area)); + }*/ + if (area.getId() == Area.ID_CHINA) { + options.add(convertAreaToCascaderOption(area)); + } + } + return options; + } + + private static Map convertAreaToCascaderOption(Area area) { + Map map = new HashMap<>(); + map.put("value", area.getId()); // value 为 ID + map.put("label", area.getName()); // label 为 名称 + + // 如果有子区域,递归转换 + if (!area.getChildren().isEmpty()) { + List> children = new ArrayList<>(); + for (Area child : area.getChildren()) { + children.add(convertAreaToCascaderOption(child)); + } + map.put("children", children); + } + + return map; + } + + public static String getAreaFullPath(Integer areaId) { + Area area = areas.get(areaId); + if (area == null) { + return null; + } + + StringBuilder fullPath = new StringBuilder(); + while (area != null) { + fullPath.insert(0, area.getName()); // 将当前区域的名称插入到路径的前面 + area = area.getParent(); // 查找父节点 + if (area != null) { + fullPath.insert(0, "/"); // 添加分隔符 + } + } + return fullPath.toString(); + } + } diff --git a/yudao-module-mall/yudao-module-trade-api/pom.xml b/yudao-module-mall/yudao-module-trade-api/pom.xml index 6dd926b..925391c 100644 --- a/yudao-module-mall/yudao-module-trade-api/pom.xml +++ b/yudao-module-mall/yudao-module-trade-api/pom.xml @@ -28,6 +28,28 @@ spring-boot-starter-validation true + + io.swagger.core.v3 + swagger-annotations + 2.2.9 + compile + + + com.alibaba + easyexcel-core + 3.3.4 + compile + + + com.baomidou + mybatis-plus-annotation + 3.5.7 + compile + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApi.java new file mode 100644 index 0000000..5cf13df --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApi.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordRespDTO; + +import java.util.List; + +public interface BrokerageRecordApi { + + List getBrokerageRecordPage(BrokerageRecordPageReqDTO pageReqVO); + + void createBrokerUser(Long userId,Long subId); + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApi.java new file mode 100644 index 0000000..cfd3a44 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApi.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserRespDTO; + +import java.util.List; + +public interface BrokerageUserApi { + + BrokerageUserRespDTO getBrokerageUser(Long bindUserId); + + List getBrokerageUserIds(); + + List getChildUserIdsByBinduserId(Long bindUserId,Integer level); +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApi.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApi.java new file mode 100644 index 0000000..f828d8b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApi.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + +public interface BrokerageWithDrawApi { + + + + int updateBrokeageWithDrawById(Long id,String transferBillNo,String transferStatus,String pkInfo,Integer status); + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordPageReqDTO.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordPageReqDTO.java new file mode 100644 index 0000000..5eea066 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordPageReqDTO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.trade.api.brokerage.dto; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +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 DTO") +@Data +public class BrokerageRecordPageReqDTO extends PageParam { + + @Schema(description = "用户编号", example = "25973") + private Long userId; + + @Schema(description = "业务类型", example = "1") + private Integer bizType; + + @Schema(description = "状态", example = "1") + private Integer status; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + @Schema(description = "用户类型", example = "1") + private Integer sourceUserLevel; + + @Schema(description = "代理商id", example = "1") + private Long agentId; + + @Schema(description = "代理商等级", example = "1") + private Long agentLevel; + + @Schema(description = "状态", example = "1") + private Integer tradeOrderStatus; +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordRespDTO.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordRespDTO.java new file mode 100644 index 0000000..3a4fd1a --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageRecordRespDTO.java @@ -0,0 +1,186 @@ +package cn.iocoder.yudao.module.trade.api.brokerage.dto; + +import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat; +import cn.iocoder.yudao.framework.excel.core.convert.DictConvert; +import cn.iocoder.yudao.framework.excel.core.convert.MoneyConvert; +import cn.iocoder.yudao.module.trade.enums.DictTypeConstants; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@ExcelIgnoreUnannotated +public class BrokerageRecordRespDTO { + /** + * 编号 + */ + @TableId + private Integer id; + /** + * 用户编号 + *

+ * 关联 MemberUserDO.id + */ + private Long userId; + /** + * 业务编号 + */ + private String bizId; + /** + * 业务类型 + *

+ * 枚举 {@link BrokerageRecordBizTypeEnum} + */ + @ExcelProperty(value = "业务类型",converter = DictConvert.class) + @DictFormat(DictTypeConstants.BROKERAGE_RECORD_BIZ_TYPE) + private Integer bizType; + + /** + * 标题 + */ + private String title; + /** + * 说明 + */ + private String description; + + /** + * 金额 + */ + @ExcelProperty(value = "分红金额", converter = MoneyConvert.class) + private Integer price; + /** + * 当前总佣金 + */ + private Integer totalPrice; + + /** + * 状态 + *

+ * 枚举 {@link BrokerageRecordStatusEnum} + */ + private Integer status; + + /** + * 冻结时间(天) + */ + private Integer frozenDays; + /** + * 解冻时间 + */ + private LocalDateTime unfreezeTime; + + /** + * 来源用户等级 + *

+ * 被推广用户和 {@link #userId} 的推广层级关系 + */ + private Integer sourceUserLevel; + /** + * 来源用户编号 + *

+ * 关联 MemberUserDO.id 字段,被推广用户的编号 + */ + private Long sourceUserId; + + /* + * 流水订单号 + * */ + @ExcelProperty("订单编号") + private String no; + + /* + * 购买的商品数量 + * */ + private Integer productCount; + + /* + * 订单详情id + * */ + private Long tradeOrderItemId; + + /* + * 商品id + * */ + private Long spuId; + + /* + 商品名称 + */ + private String spuName; + + /* + 商品图片 + */ + @ExcelProperty("商品图片") + private String picUrl; + + /* + * 下单时间 + * */ + @ExcelProperty("下单时间") + private LocalDateTime orderTime; + + /* + * 商品价格 + * */ + private Integer productPrice; + + /* + * 代理商id + * */ + private Long agentId; + + + /* + * 代理商等级id + * */ + private Long agentLevel; + + + /* + * 代理商名称 + * */ + private String agentName; + + /* + * 地区编码 + * */ + private Integer areaId; + + /* + * 应付金额 + * */ + @ExcelProperty(value = "付款金额", converter = MoneyConvert.class) + private Integer payPrice; + + /** + * 是否已支付 + * + * true - 已经支付过 + * false - 没有支付过 + */ + private Boolean payStatus; + + /** + * 订单状态 + * + * 枚举 {@link TradeOrderStatusEnum} + */ + @ExcelProperty(value = "订单状态", converter = DictConvert.class) + @DictFormat(DictTypeConstants.TRADE_ORDER_STATUS) + private Integer tradeOrderStatus; + + @ExcelProperty("商品信息") + private String productInfo; + + @ExcelProperty("归属") + private String belong; + +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserRespDTO.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserRespDTO.java new file mode 100644 index 0000000..9bd485b --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserRespDTO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.trade.api.brokerage.dto; + +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class BrokerageUserRespDTO { + /** + * 用户编号 + *

+ * 对应 MemberUserDO 的 id 字段 + */ + private Long id; + + /** + * 推广员编号 + *

+ * 关联 MemberUserDO 的 id 字段 + */ + private Long bindUserId; + /** + * 推广员绑定时间 + */ + private LocalDateTime bindUserTime; + + /** + * 是否有分销资格 + */ + private Boolean brokerageEnabled; + /** + * 成为分销员时间 + */ + private LocalDateTime brokerageTime; + + /** + * 可用佣金 + */ + private Integer brokeragePrice; + /** + * 冻结佣金 + */ + private Integer frozenPrice; + + /* + * 推广用户数量 + * */ + private Integer brokerageUserCount; +} diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java index ff09e59..e878324 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/DictTypeConstants.java @@ -9,4 +9,35 @@ public interface DictTypeConstants { String BROKERAGE_WITHDRAW_STATUS = "brokerage_withdraw_status"; // 佣金提现状态 + String BROKEERAGE_WITHDRAW_TYPE = "brokerage_withdraw_type"; // 佣金提现类型 + + String BROKERAGE_RECORD_STATUS = "brokerage_record_status"; // 佣金记录状态 + + String BROKERAGE_RECORD_BIZ_TYPE = "brokerage_record_biz_type"; // 佣金记录业务类型 + + //发票字典 + String INVOICE_TYPE = "invoice_type"; //发票类型 + + String INVOICE_STATUS = "invoice_status"; //开票状态 + + String INVOICE_TITLE_TYPE = "invoice_title_type"; //发票抬头类型 + + //交易订单字典 + String TRADE_ORDER_STATUS = "trade_order_status"; + + String INFRA_BOOLEAN_STRING = "infra_boolean_string"; + + String TERMINAL = "terminal"; + + String TRADE_ORDER_TYPE = "trade_order_type"; + + + // pay模块字典 + String PAY_CHANNEL_CODE = "pay_channel_code"; + + String TRADE_ORDER_ITEM_AFTER_SALE_STATUS = "trade_order_item_after_sale_status"; + + //物流模块 + String TRADE_DELIVERY_TYPE = "trade_deliver_type"; + } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java index aad6fb4..b0b3b13 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java @@ -91,10 +91,15 @@ public interface ErrorCodeConstants { ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级"); ErrorCode BROKERAGE_USER_LEVEL_NOT_SUPPORT = new ErrorCode(1_011_007_008, "目前只支持 level 小于等于 2"); + ErrorCode BROKERAGE_CREATE_USER_EXISTS = new ErrorCode(1_011_007_009, "分销用户已存在"); // ========== 分销提现 模块 1-011-008-000 ========== ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1_011_008_000, "佣金提现记录不存在"); ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1_011_008_001, "佣金提现记录状态不是审核中"); ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元"); ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元"); + // ========== 发票管理 模块 1-011-009-000 ========== + ErrorCode INVOICE_NOT_EXISTS = new ErrorCode(1_011_009_000, "发票管理不存在"); + + ErrorCode INVOICE_HEADER_NOT_EXISTS = new ErrorCode(1_011_009_001, "发票抬头不存在"); } diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java index 46edf01..254eb20 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java @@ -19,6 +19,7 @@ public enum BrokerageWithdrawTypeEnum implements IntArrayValuable { BANK(2, "银行卡"), WECHAT(3, "微信"), ALIPAY(4, "支付宝"), + WECHAT_API(5, "微信零钱"), // 自动打款,通过微信转账 API ; public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawTypeEnum::getType).toArray(); @@ -37,4 +38,14 @@ public enum BrokerageWithdrawTypeEnum implements IntArrayValuable { return ARRAYS; } + /** + * 是否通过支付平台的 API 打款 + * + * @param type 类型 + * @return 是否 + */ + public static boolean isApi(Integer type) { + return WECHAT_API.getType().equals(type); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml index 41bf7cb..46d3643 100644 --- a/yudao-module-mall/yudao-module-trade-biz/pom.xml +++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml @@ -97,6 +97,12 @@ yudao-module-promotion-biz ${revision} + + cn.iocoder.boot + yudao-module-agent-api + 2.1.0-jdk8-snapshot + compile + diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApiImpl.java new file mode 100644 index 0000000..c9604bb --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageRecordApiImpl.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + + +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserCreateReqVO; +import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; +import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +@Service +@Validated +public class BrokerageRecordApiImpl implements BrokerageRecordApi{ + + @Resource + private BrokerageRecordService brokerageRecordService; + + @Resource + private TradeOrderQueryService tradeOrderQueryService; + @Resource + private BrokerageUserService brokerageUserService; + + @Override + public List getBrokerageRecordPage(BrokerageRecordPageReqDTO pageReqVO) { + List list = brokerageRecordService.getBrokerageRecordList(BrokerageRecordConvert.INSTANCE.convert(pageReqVO)); + List respDTOS = tradeOrderQueryService.getTradeOrderList(list,pageReqVO); + return respDTOS; + } + + @Override + public void createBrokerUser(Long userId,Long subId) { + BrokerageUserCreateReqVO vo = new BrokerageUserCreateReqVO(); + vo.setUserId(userId); + vo.setBindUserId(subId); + brokerageUserService.createBrokerageUser(vo); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApiImpl.java new file mode 100644 index 0000000..3f4e433 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageUserApiImpl.java @@ -0,0 +1,45 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + + +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserRespDTO; +import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageUserConvert; +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService; + +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +@Service +@Validated +public class BrokerageUserApiImpl implements BrokerageUserApi{ + + @Resource + private BrokerageUserService brokerageUserService; + + + @Override + public BrokerageUserRespDTO getBrokerageUser(Long bindUserId) { + BrokerageUserRespDTO brokerageUserRespDTO = BrokerageUserConvert.INSTANCE.convert01 + (brokerageUserService.getBrokerageUser(bindUserId)); + if (brokerageUserRespDTO != null) { + Long count = brokerageUserService.getBrokerageUserCountByBindUserId(bindUserId,null); + brokerageUserRespDTO.setBrokerageUserCount(Math.toIntExact(count)); + return brokerageUserRespDTO; + } + return null; + } + + @Override + public List getBrokerageUserIds() { + List brokerageUserList = brokerageUserService.getBrokerageUserIds(); + return brokerageUserList; + } + + @Override + public List getChildUserIdsByBinduserId(Long bindUserId, Integer level){ + List childUserIds = brokerageUserService.getChildUserIdsByBinduserId(bindUserId, level); + return childUserIds; + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApiImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApiImpl.java new file mode 100644 index 0000000..77ebf34 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageWithDrawApiImpl.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.trade.api.brokerage; + + +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper; + +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +@Service +@Validated +public class BrokerageWithDrawApiImpl implements BrokerageWithDrawApi{ + @Resource + private BrokerageWithdrawMapper withdrawMapper; + + + @Override + public int updateBrokeageWithDrawById(Long id, String transferBillNo,String transferStatus, String pkInfo,Integer status) { + BrokerageWithdrawDO withdrawDO = new BrokerageWithdrawDO(); + withdrawDO.setId(id); + if (transferStatus != null) { + withdrawDO.setTransferStatus(transferStatus); + } + if (transferBillNo != null) { + withdrawDO.setTransferBillNo(transferBillNo); + } + if (pkInfo != null) { + withdrawDO.setPackageInfo(pkInfo); + } + if (status != null) { + withdrawDO.setStatus(status); + } + return withdrawMapper.updateById(withdrawDO); + } +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java index 609cfa4..5df19cc 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/BrokerageWithdrawController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO; @@ -14,11 +15,13 @@ import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService; 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.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.annotation.security.PermitAll; import javax.validation.Valid; import java.util.Map; @@ -29,6 +32,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @RestController @RequestMapping("/trade/brokerage-withdraw") @Validated +@Slf4j public class BrokerageWithdrawController { @Resource @@ -75,4 +79,16 @@ public class BrokerageWithdrawController { return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap)); } + // TODO @luchi:update-transferred,url 改成这个。和 update-paid 、update-refunded 保持一致 + @PostMapping("/update-transfer") + @Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob + @PermitAll // 无需登录,安全由 PayDemoOrderService 内部校验实现 + public CommonResult updateBrokerageWithdrawTransferred(@RequestBody PayTransferNotifyReqDTO notifyReqDTO) { + log.info("[updateAfterRefund][notifyReqDTO({})]", notifyReqDTO); + brokerageWithdrawService.updateBrokerageWithdrawTransferred( + Long.parseLong(notifyReqDTO.getMerchantTransferId()), notifyReqDTO.getPayTransferId()); + return success(true); + } + + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/user/BrokerageUserCreateReqVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/user/BrokerageUserCreateReqVO.java new file mode 100644 index 0000000..1a88809 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/user/BrokerageUserCreateReqVO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Data; + +import javax.validation.constraints.NotNull; + +@Schema(description = "管理后台 - 分销用户创建 Request VO") +@Data +public class BrokerageUserCreateReqVO { + + @Schema(description = "分销用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + @NotNull(message = "分销用户编号不能为空") + private Long userId; + + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587") + private Long bindUserId; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java index 8aca8a2..e84569e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/vo/withdraw/BrokerageWithdrawBaseVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -65,4 +66,19 @@ public class BrokerageWithdrawBaseVO { @Schema(description = "备注", example = "随便") private String remark; + /* @Schema(description = "代理商id", example = "1") + private Long agentId; + + @Schema(description = "代理商名称", example = "谁便") + @ExcelProperty("代理商名称") + private String agentName; + + @Schema(description = "凭证", example = "谁便") + @ExcelProperty("凭证") + private String voucher;*/ + + @Schema(description = "转账单据状态", example = "1") + @ExcelProperty(value = "转账单据状态") + private String transferStatus; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java index 0f1fe61..01c0d93 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; @@ -78,4 +79,6 @@ public interface BrokerageRecordConvert { } void copyTo(MemberUserRespDTO from, @MappingTarget AppBrokerageUserRankByPriceRespVO to); + + BrokerageRecordDO convert(BrokerageRecordPageReqDTO reqVO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java index aa4ba34..998800a 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java @@ -4,6 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserMySummaryRespVO; @@ -31,6 +32,8 @@ public interface BrokerageUserConvert { BrokerageUserRespVO convert(BrokerageUserDO bean); + BrokerageUserRespDTO convert01(BrokerageUserDO bean); + List convertList(List list); PageResult convertPage(PageResult page, Map userMap, Map brokerageUserCountMap, Map userOrderSummaryMap); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java index f31c238..6c552a2 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java @@ -95,4 +95,32 @@ public class BrokerageWithdrawDO extends BaseDO { */ private String remark; +// /* +// * 代理商id +// * */ +// private Long agentId; +// +// /* +// * 代理商名称 +// * */ +// private String agentName; +// +// /** +// * 凭证 +// * */ +// private String voucher; + + /** + * 用户提现信息 + */ + private String packageInfo; + /** + * 转账单号 + */ + private String transferBillNo; + /** + * 转账单据状态 + */ + private String transferStatus; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java index 4c06c80..cd58be1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java @@ -360,4 +360,20 @@ public class TradeOrderDO extends BaseDO { */ private Long pointActivityId; + /* + * 代理商户id + * */ + private Long agentId; + + /* + * 是否开发票 + * */ + private Integer invoiceStatus; + + + /** + * 核销人员 + */ + private Long auditUserId; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java index 786c000..dc9e7be 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/config/TradeOrderProperties.java @@ -4,6 +4,7 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.validation.annotation.Validated; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.time.Duration; @@ -18,6 +19,8 @@ import java.time.Duration; @Validated public class TradeOrderProperties { + private static final String PAY_APP_KEY_DEFAULT = "mall"; + /** * 应用编号 */ @@ -42,4 +45,7 @@ public class TradeOrderProperties { @NotNull(message = "评论超时时间不能为空") private Duration commentExpireTime; + @NotEmpty(message = "Pay 应用标识不能为空") + private String payAppKey = PAY_APP_KEY_DEFAULT; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java index 1cf1e24..178a647 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java @@ -156,4 +156,7 @@ public interface BrokerageRecordService { */ AppBrokerageProductPriceRespVO calculateProductBrokeragePrice(Long userId, Long spuId); + + List getBrokerageRecordList(BrokerageRecordDO BrokerageRecordDO); + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java index 8b60c4f..e8a835e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java @@ -6,6 +6,7 @@ import cn.hutool.core.util.*; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; @@ -365,4 +366,17 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { return SpringUtil.getBean(getClass()); } + /* + * 查询类列表 + * */ + @Override + public List getBrokerageRecordList(BrokerageRecordDO brokerageRecordDO) { + + return brokerageRecordMapper.selectList(new LambdaQueryWrapperX() + .eqIfPresent(BrokerageRecordDO::getUserId, brokerageRecordDO.getUserId()) + .eqIfPresent(BrokerageRecordDO::getBizType, brokerageRecordDO.getBizType()) + .eqIfPresent(BrokerageRecordDO::getStatus, brokerageRecordDO.getStatus()) + .eqIfPresent(BrokerageRecordDO::getSourceUserId, brokerageRecordDO.getSourceUserId()) + .orderByDesc(BrokerageRecordDO::getId)); + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java index 5811752..f0bfe59 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserCreateReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO; @@ -8,6 +9,7 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; +import javax.validation.Valid; import javax.validation.constraints.NotNull; import java.util.Collection; import java.util.List; @@ -148,4 +150,16 @@ public interface BrokerageUserService { void updateBrokerageByUserId(Long id, Long bindUserId); void updateBrokerageBySecondUserId(Long id, Long secondBindUserId); + + List getBrokerageUserIds(); + + List getChildUserIdsByBinduserId(Long bindUserId, Integer level); + + /** + * 【管理员】创建分销用户 + * + * @param createReqVO 请求 + * @return 编号 + */ + Long createBrokerageUser(@Valid BrokerageUserCreateReqVO createReqVO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java index 7e90dad..8f44f8d 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java @@ -8,9 +8,11 @@ import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserCreateReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO; @@ -28,15 +30,18 @@ import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMapByFilter; import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_CREATE_USER_EXISTS; /** * 分销用户 Service 实现类 @@ -405,4 +410,34 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT); } + @Override + public List getBrokerageUserIds() { + List list = brokerageUserMapper.selectList().stream().map(BrokerageUserDO::getId).collect(Collectors.toList()); + return list; + } + + @Override + public List getChildUserIdsByBinduserId(Long bindUserId, Integer level) { + return getChildUserIdsByLevel(bindUserId, level); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long createBrokerageUser(BrokerageUserCreateReqVO createReqVO) { + // 1.1 校验分销用户是否已存在 + BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(createReqVO.getUserId()); + if (brokerageUser != null) { + throw exception(BROKERAGE_CREATE_USER_EXISTS); + } + // 1.2 校验是否能绑定用户 + brokerageUser = BeanUtils.toBean(createReqVO, BrokerageUserDO.class).setId(createReqVO.getUserId()) + .setBrokerageTime(LocalDateTime.now()); + validateCanBindUser(brokerageUser, createReqVO.getBindUserId()); + + // 2. 创建分销人 + brokerageUserMapper.insert(brokerageUser); + return brokerageUser.getId(); + } + + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java index 04ea9c4..602d0f4 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java @@ -77,4 +77,5 @@ public interface BrokerageWithdrawService { return convertMap(getWithdrawSummaryListByUserId(userIds, status), BrokerageWithdrawSummaryRespBO::getUserId); } + void updateBrokerageWithdrawTransferred(Long id, Long payTransferId); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java index b6b4034..cee578b 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java @@ -4,10 +4,22 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; +import cn.iocoder.yudao.module.pay.api.transfer.PayTransferApi; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferTypeEnum; +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; +import cn.iocoder.yudao.module.system.api.social.SocialUserApi; +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert; @@ -18,8 +30,10 @@ import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; +import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -33,6 +47,7 @@ import java.util.List; import java.util.Map; 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.trade.enums.ErrorCodeConstants.*; /** @@ -42,6 +57,7 @@ import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; */ @Service @Validated +@Slf4j public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource @@ -58,6 +74,18 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @Resource private Validator validator; + @Resource + private PayWalletApi payWalletApi; + + @Resource + private SocialUserApi socialUserApi; + + @Resource + private TradeOrderProperties tradeOrderProperties; + + @Resource + private PayTransferApi payTransferApi; + @Override @Transactional(rollbackFor = Exception.class) public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) { @@ -78,6 +106,7 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { String templateCode; if (BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.equals(status)) { templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE; + auditBrokerageWithdrawSuccess(withdraw); // 3.1 通过时佣金转余额 if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { // todo 疯狂: @@ -92,14 +121,55 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { throw new IllegalArgumentException("不支持的提现状态:" + status); } - // 4. 通知用户 + /* // 4. 通知用户 Map templateParams = MapUtil.builder() .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime())) .put("price", MoneyUtils.fenToYuanStr(withdraw.getPrice())) .put("reason", withdraw.getAuditReason()) .build(); notifyMessageSendApi.sendSingleMessageToMember(new NotifySendSingleToUserReqDTO() - .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams)); + .setUserId(withdraw.getUserId()).setTemplateCode(templateCode).setTemplateParams(templateParams));*/ + } + + private void auditBrokerageWithdrawSuccess(BrokerageWithdrawDO withdraw) { + // 1.1 钱包 + if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) { + payWalletApi.addWalletBalance(new PayWalletAddBalanceReqDTO() + .setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue()) + .setBizType(PayWalletBizTypeEnum.BROKERAGE_WITHDRAW.getType()).setBizId(withdraw.getId().toString()) + .setPrice(withdraw.getPrice())); + // 1.2 微信 API + } else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) { + // TODO @luchi:这里,要加个转账单号的记录;另外,调用 API 转账,是立马成功,还是有延迟的哈? + Long payTransferId = createPayTransfer(withdraw); + // 1.3 剩余类型,都是手动打款,所以不处理 + } else { + // TODO 可优化:未来可以考虑,接入支付宝、银联等 API 转账,实现自动打款 + log.info("[auditBrokerageWithdrawSuccess][withdraw({}) 类型({}) 手动打款,无需处理]", withdraw.getId(), withdraw.getType()); + } + + // 2. 非支付 API,则直接体现成功 + if (!BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) { + brokerageWithdrawMapper.updateByIdAndStatus(Math.toIntExact(withdraw.getId()), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(), + new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus())); + } + } + + private Long createPayTransfer(BrokerageWithdrawDO withdraw) { + // 1.1 获取微信 openid + SocialUserRespDTO socialUser = socialUserApi.getSocialUserByUserId( + UserTypeEnum.MEMBER.getValue(), withdraw.getUserId(), SocialTypeEnum.WECHAT_MINI_APP.getType()); + // TODO @luchi:这里,需要校验非空。如果空的话,要有业务异常哈; + // 1.2 构建请求 + PayTransferCreateReqDTO payTransferCreateReqDTO = new PayTransferCreateReqDTO() + .setAppKey(tradeOrderProperties.getPayAppKey()) + .setChannelCode("wx_lite").setType(PayTransferTypeEnum.WX_BALANCE.getType()) + .setMerchantTransferId(withdraw.getId().toString()) + .setPrice(withdraw.getPrice()) + .setSubject("佣金提现") + .setOpenid(socialUser.getOpenid()).setUserIp(getClientIP()); + // 2. 发起请求 + return payTransferApi.createTransfer(payTransferCreateReqDTO); } private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) { @@ -150,6 +220,27 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { return brokerageWithdrawMapper.selectCountAndSumPriceByUserIdAndStatus(userIds, status.getStatus()); } + @Override + @Transactional(rollbackFor = Exception.class) + public void updateBrokerageWithdrawTransferred(Long id, Long payTransferId) { + BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(Math.toIntExact(id)); + PayTransferRespDTO transfer = payTransferApi.getTransfer(payTransferId); + // TODO @luchi:建议参考支付那,即使成功的情况下,也要各种校验;金额是否匹配、转账单号是否匹配、是否重复调用; + if (PayTransferStatusEnum.isSuccess(transfer.getStatus())) { + withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()); + // TODO @luchi:发送站内信 + } else if (PayTransferStatusEnum.isPendingStatus(transfer.getStatus())) { + // TODO @luchi:这里,是不是不用更新哈? + withdraw.setStatus(BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()); + } else { + withdraw.setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_FAIL.getStatus()); + // 3.2 驳回时需要退还用户佣金 + brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT, + String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle()); + } + brokerageWithdrawMapper.updateById(withdraw); + } + /** * 计算提现手续费 * @@ -178,4 +269,6 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { } return tradeConfig; } + + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java index 3e8afb5..34a447f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppPointOrderVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; @@ -168,5 +171,8 @@ public interface TradeOrderQueryService { List getPointOrder(Long userId); - + /* + * api获取订单列表 + * */ + List getTradeOrderList(List list, BrokerageRecordPageReqDTO pageReqVO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java index ce5413d..2f8fb61 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java @@ -6,13 +6,18 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.AgentInfoApi; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppPointOrderVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.aftersale.AfterSaleDO; +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -62,6 +67,8 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { @Resource private AfterSaleMapper afterSaleMapper; + @Resource + private AgentInfoApi agentInfoApi; // =================== Order =================== @Override @@ -306,7 +313,63 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { } + @Override + public List getTradeOrderList(List list, BrokerageRecordPageReqDTO pageReqVO) { + if(CollUtil.isEmpty(list)){ + return Collections.emptyList(); + } + List respDTOS = new ArrayList<>(); + list.forEach(item->{ + TradeOrderDO tradeOrder = tradeOrderMapper.selectById(item.getBizId()); + if(tradeOrder != null){ + BrokerageRecordRespDTO brokerageRecordRespDTO = new BrokerageRecordRespDTO(); + brokerageRecordRespDTO.setId(item.getId()); + brokerageRecordRespDTO.setBizId(item.getBizId()); + brokerageRecordRespDTO.setBizType(item.getBizType()); + brokerageRecordRespDTO.setPrice(item.getPrice()); + brokerageRecordRespDTO.setStatus(item.getStatus()); + brokerageRecordRespDTO.setUserId(item.getUserId()); + brokerageRecordRespDTO.setNo(tradeOrder.getNo()); + brokerageRecordRespDTO.setProductCount(tradeOrder.getProductCount()); + brokerageRecordRespDTO.setOrderTime(tradeOrder.getCreateTime()); +// brokerageRecordRespDTO.setAgentId(tradeOrder.getAgentId()); + brokerageRecordRespDTO.setPayPrice(tradeOrder.getPayPrice()); + brokerageRecordRespDTO.setPayStatus(tradeOrder.getPayStatus()); + brokerageRecordRespDTO.setTradeOrderStatus(tradeOrder.getStatus()); + List orderItems = tradeOrderItemMapper.selectListByOrderId(tradeOrder.getId()); + if (CollUtil.isNotEmpty(orderItems)){ + brokerageRecordRespDTO.setSpuId(orderItems.get(0).getSpuId()); + brokerageRecordRespDTO.setSpuName(orderItems.get(0).getSpuName()); + brokerageRecordRespDTO.setPicUrl(orderItems.get(0).getPicUrl()); + brokerageRecordRespDTO.setTradeOrderItemId(orderItems.get(0).getId()); + brokerageRecordRespDTO.setProductPrice(orderItems.get(0).getPrice()); + AgentInfoRespDTO agentInfoRespDTO = agentInfoApi.getInfoByUserId(item.getUserId()); + if(agentInfoRespDTO != null) { + brokerageRecordRespDTO.setAgentId(agentInfoRespDTO.getId()); + brokerageRecordRespDTO.setAgentName(agentInfoRespDTO.getAgentName()); + brokerageRecordRespDTO.setAgentLevel(Long.valueOf(agentInfoRespDTO.getAgentLevelId())); + brokerageRecordRespDTO.setAreaId(agentInfoRespDTO.getAreaId()); + } + //过滤查询条件 + if ( + // agentId 条件:传入值非空时需匹配,否则忽略 + (pageReqVO.getAgentId() == null || pageReqVO.getAgentId().equals(brokerageRecordRespDTO.getAgentId())) && + // agentLevel 条件:同上 + (pageReqVO.getAgentLevel() == null || pageReqVO.getAgentLevel().equals(brokerageRecordRespDTO.getAgentLevel())) && + // status 条件:同上 + (pageReqVO.getTradeOrderStatus() == null || pageReqVO.getTradeOrderStatus().equals(brokerageRecordRespDTO.getTradeOrderStatus())) + ) { + respDTOS.add(brokerageRecordRespDTO); + } + } + } + }); + if (CollUtil.isEmpty(respDTOS)){ + return Collections.emptyList(); + } + return respDTOS; + } } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java index 370a8fd..1bfb795 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateService.java @@ -206,4 +206,5 @@ public interface TradeOrderUpdateService { */ void cancelPaidOrder(Long userId, Long orderId); + void updateTradeOrder(TradeOrderDO tradeOrderDO); } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index fdf60d7..a465e70 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -1110,4 +1110,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { return SpringUtil.getBean(getClass()); } + /* + * 更新交易订单 + * */ + @Override + public void updateTradeOrder(TradeOrderDO tradeOrderDO) { + tradeOrderMapper.updateById(tradeOrderDO); + } + } diff --git a/yudao-module-member/pom.xml b/yudao-module-member/pom.xml index ea65199..a6eb1f8 100644 --- a/yudao-module-member/pom.xml +++ b/yudao-module-member/pom.xml @@ -11,6 +11,8 @@ yudao-module-member-api yudao-module-member-biz + yudao-module-agent-api + yudao-module-agent-biz yudao-module-member pom diff --git a/yudao-module-member/yudao-module-agent-api/pom.xml b/yudao-module-member/yudao-module-agent-api/pom.xml new file mode 100644 index 0000000..a8caf26 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-api/pom.xml @@ -0,0 +1,33 @@ + + + + cn.iocoder.boot + yudao-module-member + ${revision} + + 4.0.0 + yudao-module-agent-api + jar + + ${project.artifactId} + + member 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + + diff --git a/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/ErrorCodeConstants.java new file mode 100644 index 0000000..f8b82de --- /dev/null +++ b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/ErrorCodeConstants.java @@ -0,0 +1,64 @@ +package cn.iocoder.yudao.module.agent.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * Member 错误码枚举类 + *

+ * member 系统,使用 1-004-000-000 段 + */ +public interface ErrorCodeConstants { + + // ========== 用户相关 1-004-001-000 ============ + ErrorCode USER_NOT_EXISTS = new ErrorCode(1_004_001_000, "用户不存在"); + ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1_004_001_001, "手机号未注册用户"); + ErrorCode USER_MOBILE_USED = new ErrorCode(1_004_001_002, "修改手机失败,该手机号({})已经被使用"); + ErrorCode USER_POINT_NOT_ENOUGH = new ErrorCode(1_004_001_003, "用户积分余额不足"); + + // ========== AUTH 模块 1-004-003-000 ========== + ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,账号密码不正确"); + ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_004_003_001, "登录失败,账号被禁用"); + ErrorCode AUTH_SOCIAL_USER_NOT_FOUND = new ErrorCode(1_004_003_005, "登录失败,解析不到三方登录信息"); + ErrorCode AUTH_MOBILE_USED = new ErrorCode(1_004_003_007, "手机号已经被使用"); + + // ========== 用户收件地址 1-004-004-000 ========== + ErrorCode ADDRESS_NOT_EXISTS = new ErrorCode(1_004_004_000, "用户收件地址不存在"); + + //========== 用户标签 1-004-006-000 ========== + ErrorCode TAG_NOT_EXISTS = new ErrorCode(1_004_006_000, "用户标签不存在"); + ErrorCode TAG_NAME_EXISTS = new ErrorCode(1_004_006_001, "用户标签已经存在"); + ErrorCode TAG_HAS_USER = new ErrorCode(1_004_006_002, "用户标签下存在用户,无法删除"); + + //========== 积分配置 1-004-007-000 ========== + + //========== 积分记录 1-004-008-000 ========== + ErrorCode POINT_RECORD_BIZ_NOT_SUPPORT = new ErrorCode(1_004_008_000, "用户积分记录业务类型不支持"); + + //========== 签到配置 1-004-009-000 ========== + ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在"); + ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在"); + + //========== 签到配置 1-004-010-000 ========== + ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000, "今日已签到,请勿重复签到"); + + //========== 用户等级 1-004-011-000 ========== + ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1_004_011_000, "用户等级不存在"); + ErrorCode LEVEL_NAME_EXISTS = new ErrorCode(1_004_011_001, "用户等级名称[{}]已被使用"); + ErrorCode LEVEL_VALUE_EXISTS = new ErrorCode(1_004_011_002, "用户等级值[{}]已被[{}]使用"); + ErrorCode LEVEL_EXPERIENCE_MIN = new ErrorCode(1_004_011_003, "升级经验必须大于上一个等级[{}]设置的升级经验[{}]"); + ErrorCode LEVEL_EXPERIENCE_MAX = new ErrorCode(1_004_011_004, "升级经验必须小于下一个等级[{}]设置的升级经验[{}]"); + ErrorCode LEVEL_HAS_USER = new ErrorCode(1_004_011_005, "用户等级下存在用户,无法删除"); + + ErrorCode EXPERIENCE_BIZ_NOT_SUPPORT = new ErrorCode(1_004_011_201, "用户经验业务类型不支持"); + + //========== 用户分组 1-004-012-000 ========== + ErrorCode GROUP_NOT_EXISTS = new ErrorCode(1_004_012_000, "用户分组不存在"); + ErrorCode GROUP_HAS_USER = new ErrorCode(1_004_012_001, "用户分组下存在用户,无法删除"); + + ErrorCode INFO_NOT_EXISTS = new ErrorCode(1111111, "代理商信息不存在"); + ErrorCode AGENT_LEVEL_NOT_EXISTS = new ErrorCode(2222222, "代理商等级不存在"); + + //========== 代理商 1-004-013-000 ========== + ErrorCode BONUS_NOT_EXISTS = new ErrorCode(1_004_013_000, "代理商分红明细不存在"); + +} diff --git a/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/AgentInfoApi.java b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/AgentInfoApi.java new file mode 100644 index 0000000..4f81c14 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/AgentInfoApi.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.agent.enums.api.agentinfo; + +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; + +/** + * 代理商 API 接口 + * + * @author owen + */ +public interface AgentInfoApi { + + /** + * 获得代理等级 + * + * @param id 代理商等级编号 + * @return 会员等级 + */ + AgentInfoRespDTO getAgentByUserId(Long id); + AgentInfoRespDTO getAgentByLevelId(Long id); + + Long createAgentInfo(AgentInfoRespDTO agentInfoRespDTO); + + AgentInfoRespDTO getInfo(Long id); + + AgentInfoRespDTO getInfoByUserId(Long userId); + + /** + * 禁用代理商等级 + * @param userId + */ + void disableAgentInfo(Long userId,Integer status); + + AgentInfoRespDTO getInfoBySysUserId(Long sysUserId); + +} diff --git a/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/dto/AgentInfoRespDTO.java b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/dto/AgentInfoRespDTO.java new file mode 100644 index 0000000..84c7675 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-api/src/main/java/cn/iocoder/yudao/module/agent/enums/api/agentinfo/dto/AgentInfoRespDTO.java @@ -0,0 +1,120 @@ +package cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 会员等级 Resp DTO + * + * @author 芋道源码 + */ +@Data +public class AgentInfoRespDTO { + + /** + * 代理商ID + */ + private Long id; + /** + * 代理商名称 + */ + private String agentName; + /** + * 所属区域 + */ + private String region; + /** + * 代理商等级id + */ + private String agentLevelId; + private String agentLevelName; + /** + * 地址 + */ + private String address; + /** + * 微信头像 + */ + private String wxAvatar; + /** + * 手机号 + */ + private String phone; + /** + * 业绩 + */ + private BigDecimal performance; + /** + * 保证金额 + */ + private BigDecimal depositAmount; + /** + * 团队成员数 + */ + private Integer teamSize; + /** + * 分润结算比 + */ + private BigDecimal profitRatio; + /** + * 开户行 + */ + private String bankName; + /** + * 银行卡号 + */ + private String bankCardNo; + /** + * 持卡人 + */ + private String cardholder; + /** + * 身份证号码 + */ + private String idCardNo; + /** + * 用户id + */ + private Long userId; + + private Integer status; + + private Integer areaId; + + /* + * 到期时间 + * */ + private String endTime; + + /* + * 签约状态 + * */ + private Integer contractStatus; + + /* + * 微信收款二维码 + * */ + private String wechatAccountQrCodeUrl; + + /* + * 支付宝收款二维码 + * */ + private String alipayAccountQrCodeUrl; + + /* + * 关联后台用户id + * */ + private Long sysUserId; + + /* + * 微信账号 + * */ + private String wechatAccount; + + /* + * 支付宝收款二维码 + * */ + private String alipayAccount; +} diff --git a/yudao-module-member/yudao-module-agent-biz/pom.xml b/yudao-module-member/yudao-module-agent-biz/pom.xml new file mode 100644 index 0000000..cd68810 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/pom.xml @@ -0,0 +1,103 @@ + + + + cn.iocoder.boot + yudao-module-member + ${revision} + + 4.0.0 + yudao-module-agent-biz + jar + + ${project.artifactId} + + agent 模块,我们放代理商业务。 + 例如说:代理商中心等等 + + + + + cn.iocoder.boot + yudao-module-agent-api + ${revision} + + + cn.iocoder.boot + yudao-module-system-api + ${revision} + + + cn.iocoder.boot + yudao-module-infra-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-tenant + + + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + org.springframework.boot + spring-boot-starter-validation + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + cn.iocoder.boot + yudao-spring-boot-starter-redis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mq + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-ip + + + cn.iocoder.boot + yudao-module-trade-api + 2.1.0-jdk8-snapshot + compile + + + cn.iocoder.boot + yudao-module-member-api + 2.1.0-jdk8-snapshot + compile + + + + + diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/api/agentinfo/AgentInfoApiImpl.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/api/agentinfo/AgentInfoApiImpl.java new file mode 100644 index 0000000..7f5ad1a --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/api/agentinfo/AgentInfoApiImpl.java @@ -0,0 +1,81 @@ +package cn.iocoder.yudao.module.agent.api.agentinfo; + +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.AgentInfoSaveReqVO; +import cn.iocoder.yudao.module.agent.convert.AgentInfoConvert; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; +import cn.iocoder.yudao.module.agent.dal.dataobject.level.AgentLevelDO; +import cn.iocoder.yudao.module.agent.dal.mysql.info.AgentInfoMapper; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.AgentInfoApi; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; +import cn.iocoder.yudao.module.agent.service.info.AgentInfoService; +import cn.iocoder.yudao.module.agent.service.level.AgentLevelService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 代理商 API 实现类 + * + * @author owen + */ +@Slf4j +@Service +@Validated +public class AgentInfoApiImpl implements AgentInfoApi { + + @Resource + private AgentInfoService agentInfoService; + @Resource + private AgentLevelService agentLevelService; + + @Override + public AgentInfoRespDTO getAgentByUserId(Long id) { + AgentInfoRespDTO res = AgentInfoConvert.INSTANCE.convert02(agentInfoService.getAgentByUserId(id)); + if(res!=null){ + AgentLevelDO agentLevelDO = agentLevelService.getLevel(Long.valueOf(res.getAgentLevelId())); + res.setAgentLevelName(agentLevelDO.getLevelName()); + } + + return res; + } + + @Override + public AgentInfoRespDTO getAgentByLevelId(Long id) { + AgentInfoRespDTO res = AgentInfoConvert.INSTANCE.convert02(agentInfoService.getAgentByLevelId(id)); + return res; + } + + @Override + public Long createAgentInfo(AgentInfoRespDTO agentInfoRespDTO) { + return agentInfoService.createAgentInfo(agentInfoRespDTO); + } + + @Override + public AgentInfoRespDTO getInfo(Long id) { + AgentInfoRespDTO res = AgentInfoConvert.INSTANCE.convert02(agentInfoService.getInfo(id)); + if(res!=null){ + AgentLevelDO agentLevelDO = agentLevelService.getLevel(Long.valueOf(res.getAgentLevelId())); + res.setAgentLevelName(agentLevelDO.getLevelName()); + } + return res; + } + + @Override + public AgentInfoRespDTO getInfoByUserId(Long userId) { + + return AgentInfoConvert.INSTANCE.convert02(agentInfoService.getAgentByUserId(userId)); + } + + @Override + public void disableAgentInfo(Long userId,Integer status) { + agentInfoService.disableAgentInfo(userId,status); + } + + @Override + public AgentInfoRespDTO getInfoBySysUserId(Long sysUserId) { + return AgentInfoConvert.INSTANCE.convert02(agentInfoService.getAgentBySysUserId(sysUserId)); + } + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/AgentInfoController.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/AgentInfoController.java new file mode 100644 index 0000000..4ffce3b --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/AgentInfoController.java @@ -0,0 +1,246 @@ +package cn.iocoder.yudao.module.agent.controller.admin.info; + +import cn.iocoder.yudao.framework.ip.core.Area; +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import cn.iocoder.yudao.module.agent.convert.AgentInfoConvert; +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageRecordApi; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageUserApi; +import org.springframework.web.bind.annotation.*; +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 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.error; +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 static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; +import cn.iocoder.yudao.module.agent.service.info.AgentInfoService; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +@Tag(name = "管理后台 - 代理商信息") +@RestController +@RequestMapping("/agent/info") +@Validated +public class AgentInfoController { + + @Resource + private AgentInfoService infoService; + + @Resource + private AdminUserApi adminUserApi; + @Resource + private BrokerageRecordApi brokerageRecordApi; + @Resource + private MemberUserApi memberUserApi; + @Resource + private BrokerageUserApi brokerageUserApi; + + @PostMapping("/create") + @Operation(summary = "创建代理商信息") + @PreAuthorize("@ss.hasPermission('agent:info:create')") + public CommonResult createInfo(@Valid @RequestBody AgentInfoSaveReqVO createReqVO) { + MemberUserRespDTO memberUserRespDTO = memberUserApi.getUser(createReqVO.getUserId()); + if (memberUserRespDTO != null) { + createReqVO.setWxAvatar(memberUserRespDTO.getAvatar()); + } + /* if (createReqVO.getSysUserId() != null){ + List bindedSysUserIds = infoService.getBoundUserIdList(); + if (bindedSysUserIds.contains(createReqVO.getSysUserId())) { + return error(400, "该后台用户已绑定代理商"); + } + }*/ + + + Long id = infoService.createInfo(createReqVO); + Long bindUser =null; +// if (createReqVO.getAgentLevelId().equals("3")) {//如果是合伙人 +// AgentInfoDO groupUser = infoService.getAgentByLevelId(4L); +// bindUser = groupUser.getUserId(); +// brokerageRecordApi.createBrokerUser(createReqVO.getUserId(),bindUser); +// } + return success(id); + } + + @PutMapping("/update") + @Operation(summary = "更新代理商信息") + @PreAuthorize("@ss.hasPermission('agent:info:update')") + public CommonResult updateInfo(@Valid @RequestBody AgentInfoSaveReqVO updateReqVO) { + /* if (updateReqVO.getSysUserId() != null){ + List bindedSysUserIds = infoService.getBoundUserIdList(); + if (bindedSysUserIds.contains(updateReqVO.getSysUserId())) { + AgentInfoDO agentInfoDO = infoService.getInfo(updateReqVO.getId()); + if(agentInfoDO.getSysUserId() == null || !agentInfoDO.getSysUserId().equals(updateReqVO.getSysUserId())){ + return error(400, "该后台用户已绑定代理商"); + } + } + }*/ + infoService.updateInfo(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除代理商信息") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('agent:info:delete')") + public CommonResult deleteInfo(@RequestParam("id") Long id) { + infoService.deleteInfo(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得代理商信息") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('agent:info:query')") + public CommonResult getInfo(@RequestParam("id") Long id) { + AgentInfoDO info = infoService.getInfo(id); + return success(BeanUtils.toBean(info, AgentInfoRespVO.class)); + } + + + + @GetMapping("/page") + @Operation(summary = "获得代理商信息分页") + @PreAuthorize("@ss.hasPermission('agent:info:query')") + public CommonResult> getInfoPage(@Valid AgentInfoPageReqVO pageReqVO) { + + /* List list = adminUserApi.getAdminUserByCode("super_admin"); + List userList = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + if(!list.get(0).getId().equals(userId) && !userList.get(0).getId().equals(userId)){ + pageReqVO.setSysUserId(userId); + AgentInfoDO agentInfoDO = infoService.getAgentBySysUserId(userId); + if(agentInfoDO.getUserId() != null){ + List childUserIds = brokerageUserApi.getChildUserIdsByBinduserId(agentInfoDO.getUserId(),null); + pageReqVO.setUserIds(childUserIds != null ? childUserIds : null); + } + }*/ + PageResult pageResult = infoService.getInfoPage(pageReqVO); + Set userIds = convertSet(pageResult.getList(), AgentInfoDO::getUserId); + Map brokerageMap = infoService.getAgentInfoRespMap(userIds); + return success(AgentInfoConvert.INSTANCE.convertPage(pageResult, brokerageMap)); + } + + @GetMapping("/org-page") + @Operation(summary = "获得组织信息分页") + @PreAuthorize("@ss.hasPermission('agent:info:query')") + public CommonResult> getOrgInfoPage(@Valid AgentInfoPageReqVO pageReqVO) { + /*List list = adminUserApi.getAdminUserByCode("super_admin"); + List userList = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + if(!list.get(0).getId().equals(userId) && !userList.get(0).getId().equals(userId)){ + pageReqVO.setSysUserId(userId); + }*/ + PageResult pageResult = infoService.getOrgInfoPage(pageReqVO); + Set userIds = convertSet(pageResult.getList(), AgentInfoDO::getUserId); + Map brokerageMap = infoService.getAgentInfoRespMap(userIds); + return success(AgentInfoConvert.INSTANCE.convertPage(pageResult, brokerageMap)); + } + + @GetMapping("/export-org-excel") + @Operation(summary = "导出事业部信息 Excel") + @PreAuthorize("@ss.hasPermission('agent:info:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportOrgInfoExcel(@Valid AgentInfoPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + + /* List list = adminUserApi.getAdminUserByCode("super_admin"); + List userList = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + if(!list.get(0).getId().equals(userId) && !userList.get(0).getId().equals(userId)){ + pageReqVO.setSysUserId(userId); + }*/ + PageResult pageResult = infoService.getOrgInfoPage(pageReqVO); + Set userIds = convertSet(pageResult.getList(), AgentInfoDO::getUserId); + Map brokerageMap = infoService.getAgentInfoRespMap(userIds); + PageResult page = AgentInfoConvert.INSTANCE.convertPage(pageResult, brokerageMap); + + // 导出 Excel + ExcelUtils.write(response, "事业部信息.xls", "数据", AgentInfoRespVO.class, + page.getList()); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出代理商信息 Excel") + @PreAuthorize("@ss.hasPermission('agent:info:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportInfoExcel(@Valid AgentInfoPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + + /* List list = adminUserApi.getAdminUserByCode("super_admin"); + List userList = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + if(!list.get(0).getId().equals(userId) && !userList.get(0).getId().equals(userId)){ + pageReqVO.setSysUserId(userId); + AgentInfoDO agentInfoDO = infoService.getAgentBySysUserId(userId); + if(agentInfoDO.getUserId() != null){ + List childUserIds = brokerageUserApi.getChildUserIdsByBinduserId(agentInfoDO.getUserId(),null); + pageReqVO.setUserIds(childUserIds != null ? childUserIds : null); + } + }*/ + PageResult pageResult = infoService.getInfoPage(pageReqVO); + Set userIds = convertSet(pageResult.getList(), AgentInfoDO::getUserId); + Map brokerageMap = infoService.getAgentInfoRespMap(userIds); + PageResult page = AgentInfoConvert.INSTANCE.convertPage(pageResult, brokerageMap); + + // 导出 Excel + ExcelUtils.write(response, "代理商信息.xls", "数据", AgentInfoRespVO.class, + page.getList()); + } + + @GetMapping("/get-agent-list") + @PreAuthorize("@ss.hasPermission('agent:info:query')") + public CommonResult>> getAgentList() { + return success(adminUserApi.getUserListByRoleCode("agent")); + } + + @PutMapping("/cancel") + @PreAuthorize("@ss.hasPermission('agent:info:update')") + public CommonResult cancel(@RequestBody AgentInfoSaveReqVO updateReqVO) { + infoService.cancelAgent(updateReqVO); + return success(true); + } + + @GetMapping("/get-bound-userid-list") + @PreAuthorize("@ss.hasPermission('agent:info:query')") + public CommonResult> getBoundUserIdList() { + return success(infoService.getBoundUserIdList()); + } + + + @GetMapping("/cascader-options") + public CommonResult>> getCascaderOptions() { + return success(AreaUtils.convertToCascaderOptions()); + } + + @GetMapping("/getAreaList") + public CommonResult>> getAreaList() { + return success(infoService.getAreaList()); + } +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoPageReqVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoPageReqVO.java new file mode 100644 index 0000000..811eb01 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoPageReqVO.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.agent.controller.admin.info.vo; + +import lombok.*; +import java.util.*; +import io.swagger.v3.oas.annotations.media.Schema; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import java.math.BigDecimal; +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 AgentInfoPageReqVO extends PageParam { + + @Schema(description = "用户id") + private Long userId; + + @Schema(description = "代理商名称") + private String agentName; + + @Schema(description = "代理商等级id") + private String agentLevelId; + + @Schema(description = "手机号") + private String phone; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + private Long areaId; + + @Schema(description = "到期时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] endTime; + + @Schema(description = "合同状态", example = "0:未签1:已签") + private Integer contractStatus; + + @Schema(description = "用户id") + private Long sysUserId; + + @Schema(description = "用户id列表") + private List userIds; + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoRespVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoRespVO.java new file mode 100644 index 0000000..009bff4 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoRespVO.java @@ -0,0 +1,130 @@ +package cn.iocoder.yudao.module.agent.controller.admin.info.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import org.springframework.format.annotation.DateTimeFormat; +import java.time.LocalDateTime; +import com.alibaba.excel.annotation.*; + +@Schema(description = "管理后台 - 代理商信息 Response VO") +@Data +@ExcelIgnoreUnannotated +public class AgentInfoRespVO { + + @Schema(description = "代理商ID", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("代理商ID") + private Long id; + + @Schema(description = "代理商名称", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("代理商名称") + private String agentName; + + @Schema(description = "所属区域", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("所属区域") + private String region; + + @Schema(description = "代理商等级id", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("代理商等级id") + private String agentLevelId; + + @Schema(description = "地址") + @ExcelProperty("地址") + private String address; + + @Schema(description = "微信头像") + @ExcelProperty("微信头像") + private String wxAvatar; + + @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("手机号") + private String phone; + + @Schema(description = "业绩", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("业绩") + private BigDecimal performance; + + @Schema(description = "保证金额", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("保证金额") + private BigDecimal depositAmount; + + @Schema(description = "团队成员数") + @ExcelProperty("团队成员数") + private Integer teamSize; + + @Schema(description = "分润结算比", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("分润结算比") + private BigDecimal profitRatio; + + @Schema(description = "开户行") + @ExcelProperty("开户行") + private String bankName; + + @Schema(description = "银行卡号") + @ExcelProperty("银行卡号") + private String bankCardNo; + + @Schema(description = "持卡人") + @ExcelProperty("持卡人") + private String cardholder; + + @Schema(description = "身份证号码") + @ExcelProperty("身份证号码") + private String idCardNo; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("用户id") + private Long userId; + + private Integer status; + private Long areaId; + + @Schema(description = "到期时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("到期时间") + private String endTime; + + @Schema(description = "合同状态", example = "0:未签1:已签") + @ExcelProperty("合同状态") + private Integer contractStatus; + + @Schema(description = "结算类型:", example = "1-钱包;2-银行卡;3-微信;4-支付宝") + @ExcelProperty("结算类型") + private Integer closingType; + + + @Schema(description = "微信收款二维码", example = "") + @ExcelProperty("微信收款二维码") + private String wechatAccountQrCodeUrl; + + + @Schema(description = "支付宝收款二维码", example = "") + @ExcelProperty("支付宝收款二维码") + private String alipayAccountQrCodeUrl; + + @Schema(description = "后台用户id", example = "") + @ExcelProperty("后台用户id") + private Long sysUserId; + + @Schema(description = "微信账号", example = "") + @ExcelProperty("微信账号") + private String wechatAccount; + + + @Schema(description = "支付宝账号", example = "") + @ExcelProperty("支付宝账号") + private String alipayAccount; + + + @Schema(description = "登录账号", example = "") + private String account; + + + @Schema(description = "登录密码", example = "") + private String password; + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoSaveReqVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoSaveReqVO.java new file mode 100644 index 0000000..776d9fc --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/info/vo/AgentInfoSaveReqVO.java @@ -0,0 +1,114 @@ +package cn.iocoder.yudao.module.agent.controller.admin.info.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.*; +import org.springframework.format.annotation.DateTimeFormat; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 代理商信息新增/修改 Request VO") +@Data +public class AgentInfoSaveReqVO { + + @Schema(description = "代理商ID", requiredMode = Schema.RequiredMode.REQUIRED) + private Long id; + + @Schema(description = "代理商名称", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "代理商名称不能为空") + private String agentName; + + @Schema(description = "所属区域", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotEmpty(message = "所属区域不能为空") + private String region; + + @Schema(description = "代理商等级id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "代理商等级id不能为空") + private String agentLevelId; + + @Schema(description = "地址") + private String address; + + @Schema(description = "微信头像") + private String wxAvatar; + + @Schema(description = "手机号", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "手机号不能为空") + private String phone; + + @Schema(description = "业绩", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotNull(message = "业绩不能为空") + private BigDecimal performance; + + @Schema(description = "保证金额", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotNull(message = "保证金额不能为空") + private BigDecimal depositAmount; + + @Schema(description = "团队成员数") + private Integer teamSize; + + @Schema(description = "分润结算比", requiredMode = Schema.RequiredMode.REQUIRED) +// @NotNull(message = "分润结算比不能为空") + private BigDecimal profitRatio; + + @Schema(description = "开户行") + private String bankName; + + @Schema(description = "银行卡号") + private String bankCardNo; + + @Schema(description = "持卡人") + private String cardholder; + + @Schema(description = "身份证号码") + private String idCardNo; + + @Schema(description = "用户id", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "用户id不能为空") + private Long userId; + + private Integer status; + + private Long areaId; + + @Schema(description = "到期时间", requiredMode = Schema.RequiredMode.REQUIRED) + private String endTime; + + @Schema(description = "合同状态", example = "0:未签1:已签") + @NotNull(message = "合同状态不能为空") + private Integer contractStatus; + + @Schema(description = "结算类型:", example = "1-钱包;2-银行卡;3-微信;4-支付宝") + private Integer closingType; + + + @Schema(description = "微信收款二维码", example = "") + private String wechatAccountQrCodeUrl; + + + @Schema(description = "支付宝收款二维码", example = "") + private String alipayAccountQrCodeUrl; + + @Schema(description = "后台用户id", example = "") + private Long sysUserId; + + @Schema(description = "微信账号", example = "") + private String wechatAccount; + + + @Schema(description = "支付宝账号", example = "") + private String alipayAccount; + + @Schema(description = "登录账号", example = "") + private String account; + + @Schema(description = "登录密码", example = "") + private String password; + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/AgentLevelController.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/AgentLevelController.java new file mode 100644 index 0000000..c4f5c43 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/AgentLevelController.java @@ -0,0 +1,103 @@ +package cn.iocoder.yudao.module.agent.controller.admin.level; + +import org.springframework.web.bind.annotation.*; + +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 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.agent.controller.admin.level.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.level.AgentLevelDO; +import cn.iocoder.yudao.module.agent.service.level.AgentLevelService; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; + +@Tag(name = "管理后台 - 代理商等级") +@RestController +@RequestMapping("/agent/level") +@Validated +public class AgentLevelController { + + @Resource + private AgentLevelService levelService; + + @PostMapping("/create") + @Operation(summary = "创建代理商等级") + @PreAuthorize("@ss.hasPermission('agent:level:create')") + public CommonResult createLevel(@Valid @RequestBody AgentLevelSaveReqVO createReqVO) { + return success(levelService.createLevel(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新代理商等级") + @PreAuthorize("@ss.hasPermission('agent:level:update')") + public CommonResult updateLevel(@Valid @RequestBody AgentLevelSaveReqVO updateReqVO) { + levelService.updateLevel(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除代理商等级") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('agent:level:delete')") + public CommonResult deleteLevel(@RequestParam("id") Long id) { + levelService.deleteLevel(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得代理商等级") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('agent:level:query')") + public CommonResult getLevel(@RequestParam("id") Long id) { + AgentLevelDO level = levelService.getLevel(id); + return success(BeanUtils.toBean(level, AgentLevelRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得代理商等级分页") + @PreAuthorize("@ss.hasPermission('agent:level:query')") + public CommonResult> getLevelPage(@Valid AgentLevelPageReqVO pageReqVO) { + PageResult pageResult = levelService.getLevelPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, AgentLevelRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出代理商等级 Excel") + @PreAuthorize("@ss.hasPermission('agent:level:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportLevelExcel(@Valid AgentLevelPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = levelService.getLevelPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "代理商等级.xls", "数据", AgentLevelRespVO.class, + BeanUtils.toBean(list, AgentLevelRespVO.class)); + } + + @GetMapping("/get-agent-level-list") + @Operation(summary = "获得代理商等级列表") + @PreAuthorize("@ss.hasPermission('agent:level:query')") + public CommonResult>> getAgentLevelList() { + return success( levelService.getAgentLevelList()); + } +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelPageReqVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelPageReqVO.java new file mode 100644 index 0000000..5e661a1 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.agent.controller.admin.level.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 AgentLevelPageReqVO extends PageParam { + + @Schema(description = "等级名称") + private String levelName; + + @Schema(description = "状态") + private Integer status; + + @Schema(description = "分润比") + private String profitRatio; + + @Schema(description = "备注") + private String remark; + +} \ No newline at end of file diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelRespVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelRespVO.java new file mode 100644 index 0000000..28c8018 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.agent.controller.admin.level.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 AgentLevelRespVO { + + @Schema(description = "代理商等级ID", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("代理商等级ID") + private Long id; + + @Schema(description = "等级名称") + @ExcelProperty("等级名称") + private String levelName; + + @Schema(description = "状态") + @ExcelProperty("状态") + private Integer status; + + @Schema(description = "分润比") + @ExcelProperty("分润比") + private String profitRatio; + + @Schema(description = "备注") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelSaveReqVO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelSaveReqVO.java new file mode 100644 index 0000000..f9e8e98 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/level/vo/AgentLevelSaveReqVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.agent.controller.admin.level.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; + +@Schema(description = "管理后台 - 代理商等级新增/修改 Request VO") +@Data +public class AgentLevelSaveReqVO { + + @Schema(description = "代理商等级ID", requiredMode = Schema.RequiredMode.REQUIRED) + private Long id; + + @Schema(description = "等级名称") + private String levelName; + + @Schema(description = "状态") + private Integer status; + + @Schema(description = "分润比") + private String profitRatio; + + @Schema(description = "备注") + private String remark; + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/order/agentOrderController.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/order/agentOrderController.java new file mode 100644 index 0000000..8494e56 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/controller/admin/order/agentOrderController.java @@ -0,0 +1,137 @@ +package cn.iocoder.yudao.module.agent.controller.admin.order; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.AgentInfoPageReqVO; +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.AgentInfoRespVO; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; +import cn.iocoder.yudao.module.agent.dal.dataobject.level.AgentLevelDO; +import cn.iocoder.yudao.module.agent.service.info.AgentInfoService; +import cn.iocoder.yudao.module.agent.service.level.AgentLevelService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageRecordApi; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordPageReqDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageRecordRespDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + + +@Tag(name = "管理后台 - 代理商订单") +@RestController +@RequestMapping("/agent/order") +@Validated +public class agentOrderController { + + @Resource + private BrokerageRecordApi brokerageRecordApi; + + @Resource + private AdminUserApi adminUserApi; + + @Resource + private AgentInfoService agentInfoService; + + @Resource + private AgentLevelService agentLevelService; + + @GetMapping("/page") + @Operation(summary = "获得代理商交易订单分页") + @PreAuthorize("@ss.hasPermission('agent:order:query')") + public CommonResult> getOrderPage(BrokerageRecordPageReqDTO reqVO) { + List userList = adminUserApi.getAdminUserByCode("super_admin"); + List users = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + if(!userList.get(0).getId().equals(userId) && !users.get(0).getId().equals(userId)){ + AgentInfoDO agentInfoDO = agentInfoService.getAgentBySysUserId(userId); + if(agentInfoDO != null){ + reqVO.setAgentId(agentInfoDO.getId()); + } + else{ + return success(PageResult.empty()); + } + } + // 查询订单 + List list = brokerageRecordApi.getBrokerageRecordPage(reqVO); + PageResult pageResult = new PageResult(list, Long.valueOf(list.size())); + if(CollUtil.isEmpty(list)){ + return success(PageResult.empty()); + } + return success(pageResult); + } + @GetMapping("/getTongji") + @Operation(summary = "统计代理商订单") + public CommonResult> getOrderPage() { + BrokerageRecordPageReqDTO recordPageReqDTO = new BrokerageRecordPageReqDTO(); + // 查询订单 + List list = brokerageRecordApi.getBrokerageRecordPage(null); + PageResult pageResult = new PageResult(list, Long.valueOf(list.size())); + if(CollUtil.isEmpty(list)){ + return success(PageResult.empty()); + } + return success(pageResult); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出分销订单 Excel") + @PreAuthorize("@ss.hasPermission('agent:order:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportInfoExcel(@Valid BrokerageRecordPageReqDTO reqVO, + HttpServletResponse response) throws IOException { + reqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List userList = adminUserApi.getAdminUserByCode("super_admin"); + List users = adminUserApi.getAdminUserByCode("dfhg"); + Long userId = getLoginUserId(); + AgentInfoDO agentInfoDO = new AgentInfoDO(); + if(!userList.get(0).getId().equals(userId) && !users.get(0).getId().equals(userId)){ + agentInfoDO = agentInfoService.getAgentBySysUserId(userId); + if(agentInfoDO != null){ + reqVO.setAgentId(agentInfoDO.getId()); + } + } + // 查询订单 + List list = brokerageRecordApi.getBrokerageRecordPage(reqVO); + String productInfo = ""; + String belong = ""; + for (BrokerageRecordRespDTO brokerageRecordRespDTO : list){ + AgentLevelDO agentLevelDO = agentLevelService.getLevel(brokerageRecordRespDTO.getAgentLevel()); + if(agentLevelDO != null){ + productInfo = brokerageRecordRespDTO.getSpuName() + "\n" +"x" + brokerageRecordRespDTO.getProductCount(); + belong = "分销用户id:" + brokerageRecordRespDTO.getUserId() + "\n" + +"代理商名称:" + brokerageRecordRespDTO.getAgentName() + "\n" + +"代理商等级:" + agentLevelDO.getLevelName(); + } + brokerageRecordRespDTO.setProductInfo(productInfo); + brokerageRecordRespDTO.setBelong(belong); + } + if(!userList.get(0).getId().equals(userId) && !users.get(0).getId().equals(userId) && agentInfoDO == null){ + list = new ArrayList<>(); + } + // 导出 Excel + ExcelUtils.write(response, "分销订单.xls", "数据", BrokerageRecordRespDTO.class + ,list); + } + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/convert/AgentInfoConvert.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/convert/AgentInfoConvert.java new file mode 100644 index 0000000..ab0d229 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/convert/AgentInfoConvert.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.agent.convert; + + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.AgentInfoRespVO; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; + +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.Map; +import java.util.Optional; + +/** + * 会员等级 Convert + * + * @author owen + */ +@Mapper +public interface AgentInfoConvert { + + AgentInfoConvert INSTANCE = Mappers.getMapper(AgentInfoConvert.class); + + AgentInfoRespDTO convert02(AgentInfoDO bean); + + PageResult convertPage(PageResult pageResult); + default PageResult convertPage(PageResult pageResult, Map map) { + PageResult result = convertPage(pageResult); + for (AgentInfoRespVO item : result.getList()){ + Optional.ofNullable(map.get(item.getUserId())).ifPresent(agentInfoRespVO -> { + item.setTeamSize(agentInfoRespVO.getTeamSize()); + item.setPerformance(agentInfoRespVO.getPerformance()); + }); + } + return result; + } + +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/info/AgentInfoDO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/info/AgentInfoDO.java new file mode 100644 index 0000000..bd28931 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/info/AgentInfoDO.java @@ -0,0 +1,149 @@ +package cn.iocoder.yudao.module.agent.dal.dataobject.info; + +import lombok.*; +import java.util.*; +import java.math.BigDecimal; +import java.math.BigDecimal; +import java.math.BigDecimal; +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("agent_info") +@KeySequence("agent_info_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AgentInfoDO extends BaseDO { + + /** + * 代理商ID + */ + @TableId + private Long id; + /** + * 代理商名称 + */ + private String agentName; + /** + * 所属区域 + */ + private String region; + /** + * 代理商等级id + */ + private String agentLevelId; + /** + * 地址 + */ + private String address; + /** + * 微信头像 + */ + private String wxAvatar; + /** + * 手机号 + */ + private String phone; + /** + * 业绩 + */ + private BigDecimal performance; + /** + * 保证金额 + */ + private BigDecimal depositAmount; + /** + * 团队成员数 + */ + private Integer teamSize; + /** + * 分润结算比 + */ + private BigDecimal profitRatio; + /** + * 开户行 + */ + private String bankName; + /** + * 银行卡号 + */ + private String bankCardNo; + /** + * 持卡人 + */ + private String cardholder; + /** + * 身份证号码 + */ + private String idCardNo; + /** + * 用户id + */ + private Long userId; + + private Integer status; + + private Integer areaId; + + /* + * 到期时间 + * */ + private String endTime; + + /* + * 签约状态 + * */ + private Integer contractStatus; + + /* + * 结算类型:1-钱包;2-银行卡;3-微信;4-支付宝 + * */ + private Integer closingType; + + /* + * 微信收款二维码 + * */ + private String wechatAccountQrCodeUrl; + + /* + * 支付宝收款二维码 + * */ + private String alipayAccountQrCodeUrl; + + /** + * 后台用户id + */ + @TableField(updateStrategy = FieldStrategy.IGNORED) + private Long sysUserId; + + /* + * 微信账号 + * */ + private String wechatAccount; + + /* + * 支付宝收款二维码 + * */ + private String alipayAccount; + + /* + * 登录账号 + * */ + private String account; + + /* + * 登录密码 + * */ + private String password; +} + diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/level/AgentLevelDO.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/level/AgentLevelDO.java new file mode 100644 index 0000000..67fd4c1 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/dataobject/level/AgentLevelDO.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.agent.dal.dataobject.level; + +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("agent_level") +@KeySequence("agent_level_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class AgentLevelDO extends BaseDO { + + /** + * 代理商等级ID + */ + @TableId + private Long id; + /** + * 等级名称 + */ + private String levelName; + /** + * 状态 + */ + private Integer status; + private String profitRatio; + private String remark; +} \ No newline at end of file diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/info/AgentInfoMapper.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/info/AgentInfoMapper.java new file mode 100644 index 0000000..daca911 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/info/AgentInfoMapper.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.agent.dal.mysql.info; + +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.agent.dal.dataobject.info.AgentInfoDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.*; + +/** + * 代理商信息 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface AgentInfoMapper extends BaseMapperX { + + default PageResult selectPage(AgentInfoPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(AgentInfoDO::getAgentName, reqVO.getAgentName()) + .eqIfPresent(AgentInfoDO::getAgentLevelId, reqVO.getAgentLevelId()) + .eqIfPresent(AgentInfoDO::getPhone, reqVO.getPhone()) + .eqIfPresent(AgentInfoDO::getContractStatus, reqVO.getContractStatus()) + .inIfPresent(AgentInfoDO::getUserId, reqVO.getUserIds()) +// .eqIfPresent(AgentInfoDO::getSysUserId,reqVO.getSysUserId()) + .betweenIfPresent(AgentInfoDO::getCreateTime, reqVO.getCreateTime()) + .betweenIfPresent(AgentInfoDO::getEndTime, reqVO.getEndTime()) + .orderByDesc(AgentInfoDO::getId)); + } + default AgentInfoDO selectByLevel(Long levelId) { + return selectOne(AgentInfoDO::getAgentLevelId, levelId); + } + + default AgentInfoDO selectByUserId(Long userId) { + return selectOne(new LambdaQueryWrapperX().eq(AgentInfoDO::getUserId, userId)); + } + + default PageResult selectOrgPage(AgentInfoPageReqVO reqVO){ + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(AgentInfoDO::getAgentName, reqVO.getAgentName()) + .eqIfPresent(AgentInfoDO::getAgentLevelId, reqVO.getAgentLevelId()) + .eqIfPresent(AgentInfoDO::getPhone, reqVO.getPhone()) + .eqIfPresent(AgentInfoDO::getContractStatus, reqVO.getContractStatus()) + .eqIfPresent(AgentInfoDO::getUserId, reqVO.getUserId()) + .eqIfPresent(AgentInfoDO::getSysUserId, reqVO.getSysUserId()) + .betweenIfPresent(AgentInfoDO::getCreateTime, reqVO.getCreateTime()) + .betweenIfPresent(AgentInfoDO::getEndTime, reqVO.getEndTime()) + .ne(AgentInfoDO::getAgentLevelId, 1) + .orderByDesc(AgentInfoDO::getId)); + } +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/level/AgentLevelMapper.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/level/AgentLevelMapper.java new file mode 100644 index 0000000..a58c732 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/dal/mysql/level/AgentLevelMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.agent.dal.mysql.level; + +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.agent.dal.dataobject.level.AgentLevelDO; +import org.apache.ibatis.annotations.Mapper; +import cn.iocoder.yudao.module.agent.controller.admin.level.vo.*; + +/** + * 代理商等级 Mapper + * + * @author 芋道源码 + */ +@Mapper +public interface AgentLevelMapper extends BaseMapperX { + + default PageResult selectPage(AgentLevelPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(AgentLevelDO::getLevelName, reqVO.getLevelName()) + .eqIfPresent(AgentLevelDO::getStatus, reqVO.getStatus()) + .orderByDesc(AgentLevelDO::getId)); + } +} \ No newline at end of file diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoService.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoService.java new file mode 100644 index 0000000..934a6e2 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoService.java @@ -0,0 +1,96 @@ +package cn.iocoder.yudao.module.agent.service.info; + +import java.util.*; + +import cn.iocoder.yudao.framework.ip.core.Area; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; + +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +import javax.validation.Valid; + +/** + * 代理商信息 Service 接口 + * + * @author 芋道源码 + */ +public interface AgentInfoService { + + /** + * 创建代理商信息 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createInfo(@Valid AgentInfoSaveReqVO createReqVO); + + /** + * 写入代理商信息 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createAgentInfo(@Valid AgentInfoRespDTO createReqVO); + + /** + * 更新代理商信息 + * + * @param updateReqVO 更新信息 + */ + void updateInfo(@Valid AgentInfoSaveReqVO updateReqVO); + /** + * 禁用代理商等级 + * + * @param id 更新信息 + */ + void disableAgentInfo(Long id,Integer status); + + /** + * 删除代理商信息 + * + * @param id 编号 + */ + void deleteInfo(Long id); + + /** + * 获得代理商信息 + * + * @param id 编号 + * @return 代理商信息 + */ + AgentInfoDO getInfo(Long id); + + /** + * 获得代理商信息分页 + * + * @param pageReqVO 分页查询 + * @return 代理商信息分页 + */ + PageResult getInfoPage(AgentInfoPageReqVO pageReqVO); + + void cancelAgent(AgentInfoSaveReqVO updateReqVO); + + List getBoundUserIdList(); + + List> getAreaList(); + + Map getBonusMap(Collection agentIds); + AgentInfoDO getAgentByUserId(Long userId); + AgentInfoDO getAgentByLevelId(Long levelId); + + PageResult getOrgInfoPage(AgentInfoPageReqVO pageReqVO); + + /* + * 拼接团员人数及业绩 + * */ + Map getAgentInfoRespMap(Collection userIds); + + /* + * + * 根据后台关联用户id查询代理商信息 + * */ + AgentInfoDO getAgentBySysUserId(Long userId); +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoServiceImpl.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoServiceImpl.java new file mode 100644 index 0000000..4c6d1ec --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/info/AgentInfoServiceImpl.java @@ -0,0 +1,263 @@ +package cn.iocoder.yudao.module.agent.service.info; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; +import cn.iocoder.yudao.module.agent.convert.AgentInfoConvert; +import cn.iocoder.yudao.module.agent.enums.api.agentinfo.dto.AgentInfoRespDTO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageRecordApi; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageUserApi; +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserRespDTO; +import cn.iocoder.yudao.module.trade.api.order.TradeOrderApi; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; +import java.util.*; + +import cn.iocoder.yudao.module.agent.controller.admin.info.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.info.AgentInfoDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.agent.dal.mysql.info.AgentInfoMapper; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.agent.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS; + +/** + * 代理商信息 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class AgentInfoServiceImpl implements AgentInfoService { + + @Resource + private AgentInfoMapper infoMapper; + + @Resource + private BrokerageUserApi brokerageUserApi; + + @Resource + private AdminUserApi adminUserApi; + + @Override + public Long createInfo(AgentInfoSaveReqVO createReqVO) { + // 插入 + AgentInfoDO info = BeanUtils.toBean(createReqVO, AgentInfoDO.class); + + if(createReqVO.getAccount() != null && createReqVO.getPassword() != null){ + List users = adminUserApi.getListNoArgs(); + if(ObjectUtil.isNotEmpty(users)){ + users.forEach(user -> { + if (user.getUsername().equals(createReqVO.getAccount())){ + throw exception(USER_USERNAME_EXISTS); + } + }); + } + //新增后台用户 + AdminUserRespDTO adminUserRespDTO = new AdminUserRespDTO(); + adminUserRespDTO.setUsername(createReqVO.getAccount()); + adminUserRespDTO.setPassword(createReqVO.getPassword()); + adminUserRespDTO.setNickname(info.getAgentName()); + adminUserRespDTO.setMobile(info.getPhone()); + adminUserRespDTO.setId(adminUserApi.createUserByAgent(adminUserRespDTO)); + //设置后台用户id + info.setSysUserId(adminUserRespDTO.getId()); + } + infoMapper.insert(info); + // 返回 + return info.getId(); + } + + @Override + public Long createAgentInfo(AgentInfoRespDTO createRespDTO) { + AgentInfoDO agentInfoDO = BeanUtils.toBean(createRespDTO, AgentInfoDO.class); + infoMapper.insert(agentInfoDO); + return agentInfoDO.getId(); + } + + @Override + public void updateInfo(AgentInfoSaveReqVO updateReqVO) { + // 校验存在 + validateInfoExists(updateReqVO.getId()); + // 更新 + AgentInfoDO updateObj = BeanUtils.toBean(updateReqVO, AgentInfoDO.class); + + if(updateObj.getAccount() != null && updateObj.getPassword() != null){ + AgentInfoDO agentInfoDO = infoMapper.selectById(updateReqVO.getId()); + //新增后台用户 + AdminUserRespDTO adminUser = new AdminUserRespDTO(); + adminUser.setUsername(updateReqVO.getAccount()); + adminUser.setPassword(updateReqVO.getPassword()); + adminUser.setNickname(updateReqVO.getAgentName()); + adminUser.setMobile(updateReqVO.getPhone()); + + AdminUserRespDTO adminUserRespDTO = adminUserApi.getUserByUserName(agentInfoDO.getAccount()); + if(adminUserRespDTO == null){ +// 新建一个后台账户 + adminUser.setId(adminUserApi.createUserByAgent(adminUser)); + updateObj.setSysUserId(adminUser.getId()); + } + else { + adminUserRespDTO.setUsername(adminUser.getUsername()); + adminUserRespDTO.setPassword(adminUser.getPassword()); + adminUserApi.updateUserBySupportStaff(adminUserRespDTO); + updateObj.setSysUserId(adminUserRespDTO.getId()); + } + } + infoMapper.updateById(updateObj); + } + + @Override + public void disableAgentInfo(Long userId,Integer status) { + status = ObjectUtil.defaultIfNull(status, 0); + AgentInfoDO agentInfoDO = infoMapper.selectByUserId(userId); + agentInfoDO.setStatus(status); + infoMapper.updateById(agentInfoDO); + + } + + @Override + public void deleteInfo(Long id) { + // 校验存在 + validateInfoExists(id); + // 删除 + infoMapper.deleteById(id); + } + + private void validateInfoExists(Long id) { + if (infoMapper.selectById(id) == null) { + throw exception(INFO_NOT_EXISTS); + } + } + + @Override + public AgentInfoDO getInfo(Long id) { + return infoMapper.selectById(id); + } + + @Override + public PageResult getInfoPage(AgentInfoPageReqVO pageReqVO) { + return infoMapper.selectPage(pageReqVO); + } + + @Override + public void cancelAgent(AgentInfoSaveReqVO updateReqVO) { + updateInfo(updateReqVO); + } + + @Override + public List getBoundUserIdList() { + List agentInfoDOS = infoMapper.selectList(); + List boundUserIdList = new ArrayList<>(); + for (AgentInfoDO agentInfoDO : agentInfoDOS) { + boundUserIdList.add(agentInfoDO.getSysUserId()); + } + return boundUserIdList; + } + + @Override + public List> getAreaList() { + List areaIdlist = new ArrayList<>(); + for (AgentInfoDO agentInfoDO : infoMapper.selectList()) { + areaIdlist.add(agentInfoDO.getAreaId()); + } + List> areaList = new ArrayList<>(); + for (Integer areaId : areaIdlist) { + Map map = new HashMap<>(); + String areaFullPath = AreaUtils.getAreaFullPath(areaId); + // 只保留中国/后面的 + if (areaFullPath != null) { + areaFullPath = areaFullPath.substring(areaFullPath.indexOf("全球/中国/") + 6); + String[] split = areaFullPath.split("/"); + StringBuilder stringBuilder = new StringBuilder(); + for (String s : split) { + stringBuilder.append(s); + } + areaFullPath = stringBuilder.toString(); + map.put("id", areaId); + map.put("name", areaFullPath); + areaList.add(map); + } + } + System.out.println("areaList:::" + areaList); + return areaList; + } + + /* + * 根据代理id集合获取代理信息 + * */ + @Override + public Map getBonusMap(Collection agentIds) { + if (CollUtil.isEmpty(agentIds)){ + return MapUtil.empty(); + } + List list = infoMapper.selectBatchIds(agentIds); + return convertMap(list,AgentInfoDO::getId); + } + + @Override + public PageResult getOrgInfoPage(AgentInfoPageReqVO pageReqVO) { + return infoMapper.selectOrgPage(pageReqVO); + } + + /* + * 拼接团员人数及业绩 + * */ + @Override + public Map getAgentInfoRespMap(Collection userIds) { + if (CollUtil.isEmpty(userIds)){ + return MapUtil.empty(); + } + Map agentInfoRespMap = new HashMap<>(); + for (Long userId : userIds){ + BrokerageUserRespDTO brokerageUserRespDTO = brokerageUserApi.getBrokerageUser(userId); + AgentInfoRespVO agentInfoRespVO = new AgentInfoRespVO(); + agentInfoRespVO.setUserId(userId); + if(brokerageUserRespDTO != null){ + agentInfoRespVO.setPerformance(BigDecimal.valueOf(brokerageUserRespDTO.getFrozenPrice())); + agentInfoRespVO.setTeamSize(brokerageUserRespDTO.getBrokerageUserCount()); + } + agentInfoRespMap.put(userId,agentInfoRespVO); + } + return agentInfoRespMap; + } + + /* + * + * 根据后台关联用户id查询代理商信息 + * */ + @Override + public AgentInfoDO getAgentBySysUserId(Long userId) { + if (userId != null){ + return infoMapper.selectOne(new LambdaQueryWrapper() + .eq(AgentInfoDO::getSysUserId,userId)); + } + return null; + } + + @Override + public AgentInfoDO getAgentByUserId(Long mobile) { + return infoMapper.selectByUserId(mobile); + } + + @Override + public AgentInfoDO getAgentByLevelId(Long levelId) { + return infoMapper.selectByLevel(levelId); + } +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelService.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelService.java new file mode 100644 index 0000000..4128c27 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelService.java @@ -0,0 +1,57 @@ +package cn.iocoder.yudao.module.agent.service.level; + +import java.util.*; +import cn.iocoder.yudao.module.agent.controller.admin.level.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.level.AgentLevelDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +import javax.validation.Valid; + +/** + * 代理商等级 Service 接口 + * + * @author 芋道源码 + */ +public interface AgentLevelService { + + /** + * 创建代理商等级 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createLevel(@Valid AgentLevelSaveReqVO createReqVO); + + /** + * 更新代理商等级 + * + * @param updateReqVO 更新信息 + */ + void updateLevel(@Valid AgentLevelSaveReqVO updateReqVO); + + /** + * 删除代理商等级 + * + * @param id 编号 + */ + void deleteLevel(Long id); + + /** + * 获得代理商等级 + * + * @param id 编号 + * @return 代理商等级 + */ + AgentLevelDO getLevel(Long id); + + /** + * 获得代理商等级分页 + * + * @param pageReqVO 分页查询 + * @return 代理商等级分页 + */ + PageResult getLevelPage(AgentLevelPageReqVO pageReqVO); + + List> getAgentLevelList(); +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelServiceImpl.java b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelServiceImpl.java new file mode 100644 index 0000000..0460ca1 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/java/cn/iocoder/yudao/module/agent/service/level/AgentLevelServiceImpl.java @@ -0,0 +1,88 @@ +package cn.iocoder.yudao.module.agent.service.level; + +import org.springframework.stereotype.Service; + +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import cn.iocoder.yudao.module.agent.controller.admin.level.vo.*; +import cn.iocoder.yudao.module.agent.dal.dataobject.level.AgentLevelDO; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; + +import cn.iocoder.yudao.module.agent.dal.mysql.level.AgentLevelMapper; + +import javax.annotation.Resource; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.agent.enums.ErrorCodeConstants.*; + +/** + * 代理商等级 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class AgentLevelServiceImpl implements AgentLevelService { + + @Resource + private AgentLevelMapper levelMapper; + + @Override + public Long createLevel(AgentLevelSaveReqVO createReqVO) { + // 插入 + AgentLevelDO level = BeanUtils.toBean(createReqVO, AgentLevelDO.class); + levelMapper.insert(level); + // 返回 + return level.getId(); + } + + @Override + public void updateLevel(AgentLevelSaveReqVO updateReqVO) { + // 校验存在 + validateLevelExists(updateReqVO.getId()); + // 更新 + AgentLevelDO updateObj = BeanUtils.toBean(updateReqVO, AgentLevelDO.class); + levelMapper.updateById(updateObj); + } + + @Override + public void deleteLevel(Long id) { + // 校验存在 + validateLevelExists(id); + // 删除 + levelMapper.deleteById(id); + } + + private void validateLevelExists(Long id) { + if (levelMapper.selectById(id) == null) { + throw exception(LEVEL_NOT_EXISTS); + } + } + + @Override + public AgentLevelDO getLevel(Long id) { + return levelMapper.selectById(id); + } + + @Override + public PageResult getLevelPage(AgentLevelPageReqVO pageReqVO) { + return levelMapper.selectPage(pageReqVO); + } + + @Override + public List> getAgentLevelList() { + List agentLevelDOS = levelMapper.selectList(); + List> list = new ArrayList<>(); + for (AgentLevelDO agentLevelDO : agentLevelDOS) { + Map agentLevelMap = new HashMap<>(); + agentLevelMap.put("id", agentLevelDO.getId()); + agentLevelMap.put("name", agentLevelDO.getLevelName()); + list.add(agentLevelMap); + } + return list; + } +} diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/info/AgentInfoMapper.xml b/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/info/AgentInfoMapper.xml new file mode 100644 index 0000000..5630435 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/info/AgentInfoMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/level/AgentLevelMapper.xml b/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/level/AgentLevelMapper.xml new file mode 100644 index 0000000..e2c5073 --- /dev/null +++ b/yudao-module-member/yudao-module-agent-biz/src/main/resources/mapper/level/AgentLevelMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java index a9a6b31..6e584b9 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/config/vo/MemberConfigBaseVO.java @@ -28,4 +28,7 @@ public class MemberConfigBaseVO { @NotNull(message = "1 元赠送积分不能为空") private Integer pointTradeGivePoint; + @Schema(description = "积分协议内容", example = "100") + private String content; + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java index 5aa4f2f..434ea9f 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/admin/user/MemberUserController.java @@ -29,6 +29,7 @@ import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; import cn.iocoder.yudao.module.member.service.tag.MemberTagService; import cn.iocoder.yudao.module.member.service.user.MemberUserService; import cn.iocoder.yudao.module.pay.api.wallet.PayWalletApi; +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageUserApi; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -80,6 +81,8 @@ public class MemberUserController { private ClubCardService cardService; @Resource private MemberCodeMapper memberCodeMapper; + @Resource + private BrokerageUserApi brokerageUserApi; @PutMapping("/update") @Operation(summary = "更新会员用户") @PreAuthorize("@ss.hasPermission('member:user:update')") @@ -200,4 +203,17 @@ public class MemberUserController { return success(user); } + @GetMapping("/get-agent-list") + @Operation(summary = "获得当前商户可绑会员用户列表") + public CommonResult>> getUserListForAgent() { + return success(memberUserService.getUserListForAgent()); + } + + @GetMapping("/get-broker-list") + @Operation(summary = "获得上级代理商列表") + public CommonResult>> getBrokerListForAgent() { + List ids = brokerageUserApi.getBrokerageUserIds(); + return success(memberUserService.getBrokerListForAgent(ids)); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java index 6efb4a1..6515d2e 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/config/MemberConfigDO.java @@ -45,4 +45,11 @@ public class MemberConfigDO extends BaseDO { */ private Integer pointTradeGivePoint; + /** + * 积分协议内容 + */ + private String content; + + + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java index dee546e..33c6185 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; import javax.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; /** * 会员用户 Service 接口 @@ -191,4 +192,8 @@ public interface MemberUserService { void updateActivate(String cardName,Long userId); + List> getUserListForAgent(); + + List> getBrokerListForAgent(List ids); + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java index 5d0d65d..6ff096b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java @@ -33,8 +33,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager import javax.annotation.Resource; import javax.validation.Valid; import java.time.LocalDateTime; -import java.util.Collection; -import java.util.List; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP; @@ -340,4 +339,34 @@ public class MemberUserServiceImpl implements MemberUserService { memberUserMapper.updateById(memberUserDO); } + @Override + public List> getUserListForAgent() { + List> list = new ArrayList<>(); + List memberUserDOList = memberUserMapper.selectList(); + memberUserDOList.forEach(memberUserDO -> { + Map map = new HashMap<>(); + map.put("id", memberUserDO.getId()); + map.put("name", memberUserDO.getNickname()); + map.put("avatar", memberUserDO.getAvatar()); + list.add(map); + }); + return list; + } + + @Override + public List> getBrokerListForAgent(List ids) { + List> list = new ArrayList<>(); + ids.forEach(id -> { + MemberUserDO memberUserDO = memberUserMapper.selectById(id); + if(memberUserDO != null){ + Map map = new HashMap<>(); + map.put("id", memberUserDO.getId()); + map.put("name", memberUserDO.getNickname()); + map.put("avatar", memberUserDO.getAvatar()); + list.add(map); + } + }); + return list; + } + } diff --git a/yudao-module-pay/yudao-module-pay-api/pom.xml b/yudao-module-pay/yudao-module-pay-api/pom.xml index 0903abe..30f4762 100644 --- a/yudao-module-pay/yudao-module-pay-api/pom.xml +++ b/yudao-module-pay/yudao-module-pay-api/pom.xml @@ -28,6 +28,11 @@ spring-boot-starter-validation true + + jakarta.validation + jakarta.validation-api + 2.0.2 + diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java index 7899068..29ab90a 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.pay.api.transfer; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; import javax.validation.Valid; @@ -19,4 +20,12 @@ public interface PayTransferApi { */ Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + /** + * 获得转账单 + * + * @param id 转账单编号 + * @return 转账单 + */ + PayTransferRespDTO getTransfer(Long id); + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index d7bb660..a2e2839 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java @@ -21,6 +21,9 @@ public class PayTransferCreateReqDTO { /** * 应用编号 */ + @NotNull(message = "应用标识不能为空") + private String appKey; + @NotNull(message = "应用编号不能为空") private Long appId; diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java new file mode 100644 index 0000000..d287dcc --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferRespDTO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.pay.api.transfer.dto; + +import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; +import lombok.Data; + +@Data +public class PayTransferRespDTO { + + /** + * 编号 + */ + private Long id; + + /** + * 转账单号 + */ + private String no; + + /** + * 转账金额,单位:分 + */ + private Integer price; + + /** + * 转账状态 + * + * 枚举 {@link PayTransferStatusEnum} + */ + private Integer status; + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java index 27a21b6..9d73e3f 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApi.java @@ -1,5 +1,9 @@ package cn.iocoder.yudao.module.pay.api.wallet; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; + public interface PayWalletApi { Integer getUserBalance (Long id); + + void addWalletBalance(PayWalletAddBalanceReqDTO reqDTO); } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletAddBalanceReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletAddBalanceReqDTO.java new file mode 100644 index 0000000..927e13f --- /dev/null +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/dto/PayWalletAddBalanceReqDTO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.pay.api.wallet.dto; + +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * 钱包余额增加 Request DTO + * + * @author 芋道源码 + */ +@Data +public class PayWalletAddBalanceReqDTO { + + /** + * 用户编号 + * + * 关联 MemberUserDO 的 id 属性,或者 AdminUserDO 的 id 属性 + */ + @NotNull(message = "用户编号不能为空") + private Long userId; + /** + * 用户类型 + * + * 关联 {@link UserTypeEnum} + */ + @NotNull(message = "用户类型不能为空") + private Integer userType; + + /** + * 关联业务分类 + */ + @NotNull(message = "关联业务分类不能为空") + private Integer bizType; + /** + * 关联业务编号 + */ + @NotNull(message = "关联业务编号不能为空") + private String bizId; + + /** + * 交易金额,单位分 + * + * 正值表示余额增加,负值表示余额减少 + */ + @NotNull(message = "交易金额不能为空") + private Integer price; + +} diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java index 61e7f8d..ece1115 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/wallet/PayWalletBizTypeEnum.java @@ -20,9 +20,11 @@ public enum PayWalletBizTypeEnum implements IntArrayValuable { PAYMENT(3, "支付"), PAYMENT_REFUND(4, "支付退款"), // ADMIN_MODIFY(5, "管理员修改"); - UPDATE_BALANCE(5, "更新余额"); + UPDATE_BALANCE(5, "更新余额"), + BROKERAGE_WITHDRAW(6, "分佣提现"); // TODO 后续增加 + /** * 业务分类 */ @@ -38,4 +40,8 @@ public enum PayWalletBizTypeEnum implements IntArrayValuable { public int[] array() { return ARRAYS; } + + public static PayWalletBizTypeEnum valueOf(Integer type) { + return Arrays.stream(values()).filter(item -> item.getType().equals(type)).findFirst().orElse(null); + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java index 786cf70..e6f2ac3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.pay.api.transfer; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO; +import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferRespDTO; +import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO; import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -24,4 +27,10 @@ public class PayTransferApiImpl implements PayTransferApi { return payTransferService.createTransfer(reqDTO); } + @Override + public PayTransferRespDTO getTransfer(Long id) { + PayTransferDO transfer = payTransferService.getTransfer(id); + return BeanUtils.toBean(transfer, PayTransferRespDTO.class); + } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java index fe41283..270f980 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/wallet/PayWalletApiImpl.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.pay.api.wallet; +import cn.hutool.core.lang.Assert; +import cn.iocoder.yudao.module.pay.api.wallet.dto.PayWalletAddBalanceReqDTO; import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; +import cn.iocoder.yudao.module.pay.enums.wallet.PayWalletBizTypeEnum; import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -19,4 +22,15 @@ public class PayWalletApiImpl implements PayWalletApi{ PayWalletDO walletDO = payWalletService.getOrCreateWallet(id, MEMBER.getValue()); return walletDO.getBalance(); } + + @Override + public void addWalletBalance(PayWalletAddBalanceReqDTO reqDTO) { + // 创建或获取钱包 + PayWalletDO wallet = payWalletService.getOrCreateWallet(reqDTO.getUserId(), reqDTO.getUserType()); + Assert.notNull(wallet, "钱包({}/{})不存在", reqDTO.getUserId(), reqDTO.getUserType()); + + // 增加余额 + PayWalletBizTypeEnum bizType = PayWalletBizTypeEnum.valueOf(reqDTO.getBizType()); + payWalletService.addWalletBalance(wallet.getId(), reqDTO.getBizId(), bizType, reqDTO.getPrice()); + } } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index 4bbaff8..b80d854 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java @@ -68,6 +68,19 @@ public interface PayWalletMapper extends BaseMapperX { return update(null, lambdaUpdateWrapper); } + /** + * 增加余额的时候,更新钱包 + * + * @param id 钱包 id + * @param price 钱包金额 + */ + default void updateWhenAdd(Long id, Integer price) { + LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() + .setSql(" balance = balance + " + price) + .eq(PayWalletDO::getId, id); + update(null, lambdaUpdateWrapper); + } + /** * 冻结钱包部分余额 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java index d422b35..6123934 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/config/PayProperties.java @@ -49,4 +49,14 @@ public class PayProperties { @NotEmpty(message = "退款订单 no 的前缀不能为空") private String refundNoPrefix = REFUND_NO_PREFIX; + /** + * 转账回调地址 + * + * 实际上,对应的 PayNotifyController 的 notifyTransfer 方法的 URL + * + * 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 transferNotifyUrl 地址 => 业务的 PayAppDO.transferNotifyUrl 地址 + */ + private String transferNotifyUrl; + + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 73b726d..be6e040 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java @@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.pay.dal.mysql.transfer.PayTransferMapper; import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum; import cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum; +import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties; import cn.iocoder.yudao.module.pay.service.app.PayAppService; import cn.iocoder.yudao.module.pay.service.channel.PayChannelService; import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService; @@ -50,6 +51,8 @@ public class PayTransferServiceImpl implements PayTransferService { private static final String TRANSFER_NO_PREFIX = "T"; + @Resource + private PayProperties payProperties; @Resource private PayTransferMapper transferMapper; @Resource @@ -103,7 +106,9 @@ public class PayTransferServiceImpl implements PayTransferService { // 3. 调用三方渠道发起转账 PayTransferUnifiedReqDTO transferUnifiedReq = INSTANCE.convert2(transfer) .setOutTransferNo(transfer.getNo()); + transferUnifiedReq.setNotifyUrl(genChannelTransferNotifyUrl(channel)); PayTransferRespDTO unifiedTransferResp = client.unifiedTransfer(transferUnifiedReq); + // 4. 通知转账结果 getSelf().notifyTransfer(channel, unifiedTransferResp); } catch (Throwable e) { @@ -116,6 +121,16 @@ public class PayTransferServiceImpl implements PayTransferService { return transfer.getId(); } + /** + * 根据支付渠道的编码,生成支付渠道的回调地址 + * + * @param channel 支付渠道 + * @return 支付渠道的回调地址 配置地址 + "/" + channel id + */ + private String genChannelTransferNotifyUrl(PayChannelDO channel) { + return payProperties.getTransferNotifyUrl() + "/" + channel.getId(); + } + private PayTransferDO validateTransferCanCreate(PayTransferCreateReqDTO dto) { PayTransferDO transfer = transferMapper.selectByAppIdAndMerchantTransferId(dto.getAppId(), dto.getMerchantTransferId()); if (transfer != null) { diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index 87ed511..4b551ce 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java @@ -228,6 +228,9 @@ public class PayWalletServiceImpl implements PayWalletService { walletMapper.updateWhenRecharge(payWallet.getId(), price); break; } + case BROKERAGE_WITHDRAW: // 分佣提现 + walletMapper.updateWhenAdd(payWallet.getId(), price); + break; case UPDATE_BALANCE: // 更新余额 walletMapper.updateWhenRecharge(payWallet.getId(), price); break; @@ -262,6 +265,7 @@ public class PayWalletServiceImpl implements PayWalletService { } + // @Override // public void updateWallet(PayWalletUserBalanceVo reqVo) { // // 如果 diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml index 93193d0..3aee771 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/pom.xml @@ -71,6 +71,11 @@ yudao-spring-boot-starter-test test + + com.github.binarywang + weixin-java-pay + 4.7.4.B + diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java index 0f9b482..d9b9943 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferRespDTO.java @@ -50,6 +50,15 @@ public class PayTransferRespDTO { */ private String channelErrorMsg; + /** + * 转账单号 + */ + private String transferBillNo; + /** + * 转账单据状态 + */ + private String transferStatus; + /** * 创建【WAITING】状态的转账返回 */ @@ -67,15 +76,18 @@ public class PayTransferRespDTO { * 创建【IN_PROGRESS】状态的转账返回 */ public static PayTransferRespDTO dealingOf(String channelTransferNo, - String outTransferNo, Object rawData) { + String outTransferNo, Object rawData,String transStatus,String transBillNO) { PayTransferRespDTO respDTO = new PayTransferRespDTO(); respDTO.status = PayTransferStatusRespEnum.IN_PROGRESS.getStatus(); respDTO.channelTransferNo = channelTransferNo; respDTO.outTransferNo = outTransferNo; respDTO.rawData = rawData; + respDTO.transferBillNo = transBillNO; + respDTO.transferStatus = transStatus; return respDTO; } + /** * 创建【CLOSED】状态的转账返回 */ diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index 9a13dda..b61fcec 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum; import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; import lombok.Data; import org.hibernate.validator.constraints.Length; +import org.hibernate.validator.constraints.URL; import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; @@ -75,4 +76,12 @@ public class PayTransferUnifiedReqDTO { * 支付渠道的额外参数 */ private Map channelExtras; + + /** + * 转账结果的 notify 回调地址 + */ + @NotEmpty(message = "转账结果的回调地址不能为空") + @URL(message = "转账结果的 notify 回调地址必须是 URL 格式") + private String notifyUrl; + } diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java index 4dcf236..38d0980 100644 --- a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java @@ -277,7 +277,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient transferDetailList = Collections.singletonList( + TransferBatchesRequest.TransferDetail.newBuilder() + .outDetailNo(reqDTO.getOutTransferNo()) + .transferAmount(reqDTO.getPrice()) + .transferRemark(reqDTO.getSubject()) + .openid(reqDTO.getOpenid()) + .build()); + // TODO @luchi:能不能我们搞个 TransferBatchesRequestX extends TransferBatchesRequest,这样更简洁一点。 + TransferBatchesRequest transferBatches = TransferBatchesRequest.newBuilder() + .appid(this.config.getAppId()) + .outBatchNo(reqDTO.getOutTransferNo()) + .batchName(reqDTO.getSubject()) + .batchRemark(reqDTO.getSubject()) + .totalAmount(reqDTO.getPrice()) + .totalNum(transferDetailList.size()) + .transferDetailList(transferDetailList).build() + .setNotifyUrl(reqDTO.getNotifyUrl()); + // 2.1 执行请求 +// TransferBatchesResult transferBatchesResult = client.getTransferService().transferBatches(transferBatches); + +// return PayTransferRespDTO.dealingOf(transferBatchesResult.getBatchId(), reqDTO.getOutTransferNo(), transferBatchesResult); + + + //新版商家转账到零钱 + List infos = new ArrayList<>(); + TransferBillsRequest.TransferSceneReportInfo info = new TransferBillsRequest.TransferSceneReportInfo(); + info.setInfoType("岗位类型"); + info.setInfoContent("会员"); + + TransferBillsRequest.TransferSceneReportInfo info2 = new TransferBillsRequest.TransferSceneReportInfo(); + info2.setInfoType("报酬说明"); + info2.setInfoContent("推广佣金"); + + infos.add(info); + infos.add(info2); + + TransferBillsRequest request2 = TransferBillsRequest.newBuilder() + .appid(this.config.getAppId()) + .outBillNo(reqDTO.getOutTransferNo()) + .transferSceneId("1005") + .transferAmount(reqDTO.getPrice()) + .openid(reqDTO.getOpenid()) + .transferRemark("商家转账") + .notifyUrl("https://xcx.dfhg888.cn/admin-api/pay/notify/transfer") +// .userName("林奋达") + .transferSceneReportInfos(infos).build(); + + TransferBillsResult result2 = client.getTransferService().transferBills(request2); + // 2.2 创建返回结果 + System.out.println("零钱提现同步返回" + result2); + return PayTransferRespDTO.dealingOf(result2.getTransferBillNo(), reqDTO.getOutTransferNo(), result2.getPackageInfo(),result2.getState(),result2.getTransferBillNo()); } @Override diff --git a/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java new file mode 100644 index 0000000..72296da --- /dev/null +++ b/yudao-module-pay/yudao-spring-boot-starter-biz-pay/src/main/java/com/github/binarywang/wxpay/bean/transfer/TransferBatchesRequest.java @@ -0,0 +1,118 @@ +package com.github.binarywang.wxpay.bean.transfer; + +import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 发起商家转账API参数 + * + * @author zhongjun + * created on 2022/6/17 + **/ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class TransferBatchesRequest implements Serializable { + private static final long serialVersionUID = -2175582517588397426L; + + /** + * 直连商户的appid + */ + @SerializedName("appid") + private String appid; + + /** + * 商家批次单号 + */ + @SerializedName("out_batch_no") + private String outBatchNo; + + /** + * 批次名称 + */ + @SerializedName("batch_name") + private String batchName; + + /** + * 批次备注 + */ + @SerializedName("batch_remark") + private String batchRemark; + + /** + * 转账总金额 + */ + @SerializedName("total_amount") + private Integer totalAmount; + + /** + * 转账总笔数 + */ + @SerializedName("total_num") + private Integer totalNum; + + /** + * 转账明细列表 + */ + @SpecEncrypt + @SerializedName("transfer_detail_list") + private List transferDetailList; + + /** + * 转账场景ID + */ + @SerializedName("transfer_scene_id") + private String transferSceneId; + + /** + * 通知地址 说明:异步接收微信支付结果通知的回调地址,通知url必须为公网可访问的url,必须为https,不能携带参数。 + */ + @SerializedName("notify_url") + private String notifyUrl; + + @Data + @Builder(builderMethodName = "newBuilder") + @AllArgsConstructor + @NoArgsConstructor + public static class TransferDetail { + + /** + * 商家明细单号 + */ + @SerializedName("out_detail_no") + private String outDetailNo; + + /** + * 转账金额 + */ + @SerializedName("transfer_amount") + private Integer transferAmount; + + /** + * 转账备注 + */ + @SerializedName("transfer_remark") + private String transferRemark; + + /** + * 用户在直连商户应用下的用户标示 + */ + @SerializedName("openid") + private String openid; + + /** + * 收款用户姓名 + */ + @SpecEncrypt + @SerializedName("user_name") + private String userName; + } +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java index 507fb4b..97b04e7 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApi.java @@ -86,4 +86,19 @@ public interface AdminUserApi { */ void validateUserList(Collection ids); + List> getUserListByRoleCode(String roleCode); + + List getAdminUserByCode(String roleCode); + + Long createUserBySupportStaff(AdminUserRespDTO user); + + Long createUserByAgent(AdminUserRespDTO user); + + List getListNoArgs(); + + AdminUserRespDTO getUserByUserName(String account); + + // 更新后台登录账号或密码 + void updateUserBySupportStaff(AdminUserRespDTO user); + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java index d86f3e5..f22f924 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/user/dto/AdminUserRespDTO.java @@ -45,4 +45,14 @@ public class AdminUserRespDTO { */ private String avatar; + /** + * 用户账号 + */ + private String username; + + /* + * 密码 + * */ + private String password; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java index 373e088..674fa83 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/user/AdminUserApiImpl.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjUtil; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.service.dept.DeptService; @@ -11,10 +12,7 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import java.util.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -88,4 +86,52 @@ public class AdminUserApiImpl implements AdminUserApi { userService.validateUserList(ids); } + @Override + public List> getUserListByRoleCode(String roleCode) { + return userService.getUserListByRole(roleCode); + } + + @Override + public List getAdminUserByCode(String roleCode) { + List users = userService.getAdminUserByCode(roleCode); + return BeanUtils.toBean(users, AdminUserRespDTO.class); + } + + @Override + public Long createUserBySupportStaff(AdminUserRespDTO user) { + UserSaveReqVO reqVO = new UserSaveReqVO(); + BeanUtils.copyProperties(user, reqVO); + return userService.createUserBySupportStaff(reqVO); + } + + @Override + public Long createUserByAgent(AdminUserRespDTO user) { + UserSaveReqVO reqVO = new UserSaveReqVO(); + BeanUtils.copyProperties(user, reqVO); + return userService.createUserByAgent(reqVO); + } + + @Override + public List getListNoArgs() { + List users = userService.getList(); + return BeanUtils.toBean(users, AdminUserRespDTO.class); + } + + @Override + public AdminUserRespDTO getUserByUserName(String account) { + AdminUserDO user = userService.getUserByUsername(account); + return BeanUtils.toBean(user, AdminUserRespDTO.class); + } + + /** + * 修改后台用户账号或密码 + * + * @param user 用户信息 + */ + @Override + public void updateUserBySupportStaff(AdminUserRespDTO user) { + UserSaveReqVO reqVO = new UserSaveReqVO(); + BeanUtils.copyProperties(user, reqVO); + userService.updateUserBySupportStaff(reqVO); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java index 525cb11..66eae79 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/vo/user/UserPageReqVO.java @@ -35,4 +35,13 @@ public class UserPageReqVO extends PageParam { @Schema(description = "部门编号,同时筛选子部门", example = "1024") private Long deptId; + @Schema(description = "角色编号", example = "1024") + private Long roleId; + + @Schema(description = "创建人", example = "zuihou") + private String creator; + + @Schema(description = "登录用户id", example = "zuihou") + private Long userId; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java index 2e4da2b..4801272 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/RoleMapper.java @@ -36,4 +36,14 @@ public interface RoleMapper extends BaseMapperX { return selectList(RoleDO::getStatus, statuses); } + default PageResult selectPageNotSuperAdmin(RolePageReqVO reqVO){ + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(RoleDO::getName, reqVO.getName()) + .likeIfPresent(RoleDO::getCode, reqVO.getCode()) + .eqIfPresent(RoleDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(BaseDO::getCreateTime, reqVO.getCreateTime()) + .ne(RoleDO::getId,1L) + .orderByAsc(RoleDO::getSort)); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java index 12ff88a..553db59 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/permission/UserRoleMapper.java @@ -33,4 +33,9 @@ public interface UserRoleMapper extends BaseMapperX { return selectList(UserRoleDO::getRoleId, roleIds); } + default List selectUserIdListByRoleId(Long roleId) { + return selectList(new LambdaQueryWrapper() + .eq(UserRoleDO::getRoleId, roleId)); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java index 75bf3fa..dc41d66 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; @@ -47,4 +48,56 @@ public interface AdminUserMapper extends BaseMapperX { return selectList(AdminUserDO::getDeptId, deptIds); } + default PageResult selectPageByCreator(UserPageReqVO reqVO, Collection deptIds, Collection userIds) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .and(wq -> { + // 添加所有可能为空的 AND 子条件 + boolean hasCondition = false; // 标记是否有有效条件 + // 使用原生方法 + 手动空值判断 + if (StringUtils.isNotBlank(reqVO.getUsername())) { + wq.like(AdminUserDO::getUsername, reqVO.getUsername()); + hasCondition = true; + } + if (StringUtils.isNotBlank(reqVO.getMobile())) { + wq.like(AdminUserDO::getMobile, reqVO.getMobile()); + hasCondition = true; + } + if (reqVO.getStatus() != null) { + wq.eq(AdminUserDO::getStatus, reqVO.getStatus()); + hasCondition = true; + } + if (reqVO.getCreateTime() != null && reqVO.getCreateTime().length == 2) { + wq.between(AdminUserDO::getCreateTime, reqVO.getCreateTime()[0], reqVO.getCreateTime()[1]); + hasCondition = true; + } + if(reqVO.getCreator() != null && !reqVO.getCreator().isEmpty()){ + wq.eq(AdminUserDO::getCreator, reqVO.getCreator()); + hasCondition = true; + } + if (deptIds != null && !deptIds.isEmpty()) { + wq.in(AdminUserDO::getDeptId, deptIds); + hasCondition = true; + } + if (!hasCondition){ + wq.apply("1=1"); + } + }) + .or(wq -> { + boolean hasCondition = false; // 标记是否有有效条件 + if (userIds != null && !userIds.isEmpty()) { + wq.in(AdminUserDO::getId, userIds); + hasCondition = true; + } + if (reqVO.getUserId() != null){ + wq.eq(AdminUserDO::getId, reqVO.getUserId()); + hasCondition = true; + } + if (!hasCondition){ + wq.apply("1=0"); + } + }) + .orderByDesc(AdminUserDO::getId) + ); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java index efc4714..3e3e58b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionService.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespDTO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; import java.util.Collection; +import java.util.List; import java.util.Set; import static java.util.Collections.singleton; @@ -143,4 +145,5 @@ public interface PermissionService { */ DeptDataPermissionRespDTO getDeptDataPermission(Long userId); + List selectUserIdListByRoleId(Long roleId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index dba2831..015dac4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -334,4 +334,9 @@ public class PermissionServiceImpl implements PermissionService { return SpringUtil.getBean(getClass()); } + @Override + public List selectUserIdListByRoleId(Long roleId) { + return userRoleMapper.selectUserIdListByRoleId(roleId); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java index 44ec110..e5e43f1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java @@ -121,4 +121,8 @@ public interface RoleService { */ void validateRoleList(Collection ids); + RoleDO getRoleByCode(String code); + + PageResult getRolePageNotSuperAdmin(RolePageReqVO pageReqVO); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index 389f28b..51043f6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -258,4 +258,14 @@ public class RoleServiceImpl implements RoleService { return SpringUtil.getBean(getClass()); } + @Override + public RoleDO getRoleByCode(String code) { + return roleMapper.selectByCode(code); + } + + @Override + public PageResult getRolePageNotSuperAdmin(RolePageReqVO reqVO) { + return roleMapper.selectPageNotSuperAdmin(reqVO); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index e715a69..68e34a9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java @@ -201,4 +201,35 @@ public interface AdminUserService { */ boolean isPasswordMatch(String rawPassword, String encodedPassword); + List> getUserListByRole(String roleCode); + + List getAdminUserByCode(String code); + + /* + * 获得所有用户 + * */ + List getList(); + + /** + * 修改后台用户账号或密码 + * + * @param updateReqVO 用户信息 + */ + void updateUserBySupportStaff(@Valid UserSaveReqVO updateReqVO); + + /* + * 新建后台用户并关联客服角色 + * */ + Long createUserBySupportStaff(@Valid UserSaveReqVO createReqVO); + + /* + * 新建后台用户并关联代理商角色 + * */ + Long createUserByAgent(UserSaveReqVO createReqVO); + + /* + * 查询除超级管理员外的用户分页列表 + * */ + PageResult getUserPageByCreator(UserPageReqVO pageReqVO); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 9d3720f..dd8a96f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java @@ -20,12 +20,15 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqV import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper; import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.dept.PostService; import cn.iocoder.yudao.module.system.service.permission.PermissionService; +import cn.iocoder.yudao.module.system.service.permission.RoleService; import cn.iocoder.yudao.module.system.service.tenant.TenantService; import com.google.common.annotations.VisibleForTesting; import com.mzt.logapi.context.LogRecordContext; @@ -43,8 +46,7 @@ import java.time.LocalDateTime; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.system.enums.LogRecordConstants.*; @@ -82,6 +84,9 @@ public class AdminUserServiceImpl implements AdminUserService { @Resource private ConfigApi configApi; + @Resource + private RoleService roleService; + @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_CREATE_SUB_TYPE, bizNo = "{{#user.id}}", @@ -492,4 +497,158 @@ public class AdminUserServiceImpl implements AdminUserService { return passwordEncoder.encode(password); } + @Override + public List> getUserListByRole(String roleCode) { + RoleDO roleByCode = roleService.getRoleByCode(roleCode); + List userRoleDOS = permissionService.selectUserIdListByRoleId(roleByCode.getId()); + List> userList = new ArrayList<>(); + userRoleDOS.forEach(userRoleDO -> { + AdminUserDO adminUserDO = userMapper.selectById(userRoleDO.getUserId()); + Map userMap = new HashMap<>(); + userMap.put("id", adminUserDO.getId()); + userMap.put("name", adminUserDO.getUsername()); + userList.add(userMap); + }); + + return userList; + } + + /* + * 获取角色下的用户 + * */ + @Override + public List getAdminUserByCode(String code) { + RoleDO roleByCode = roleService.getRoleByCode(code); + List userRoleDOS = permissionService.selectUserIdListByRoleId(roleByCode.getId()); + List userList = new ArrayList<>(); + userRoleDOS.forEach(userRoleDO -> { + AdminUserDO adminUserDO = userMapper.selectById(userRoleDO.getUserId()); + userList.add(adminUserDO); + }); + return userList; + } + + @Override + public List getList() { + List list = userMapper.selectList(); + return list; + } + + /* + * 修改后台用户账号或密码 + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", + success = SYSTEM_USER_UPDATE_SUCCESS) + public void updateUserBySupportStaff(UserSaveReqVO updateReqVO) { + + // 1. 校验正确性 + AdminUserDO oldUser = validateUserForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getUsername(), + updateReqVO.getMobile(), updateReqVO.getEmail(), updateReqVO.getDeptId(), updateReqVO.getPostIds()); + + // 2.1 更新用户 + AdminUserDO updateObj = BeanUtils.toBean(updateReqVO, AdminUserDO.class); +// 2.1.1加密密码 + updateObj.setPassword(encodePassword(updateReqVO.getPassword())); + userMapper.updateById(updateObj); + // 2.2 更新岗位 + updateUserPost(updateReqVO, updateObj); + + // 3. 记录操作日志上下文 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldUser, UserSaveReqVO.class)); + LogRecordContext.putVariable("user", oldUser); + LogRecordContext.putVariable("newPassword", updateObj.getPassword()); + } + + /* + * 新建后台用户并关联客服角色 + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_CREATE_SUB_TYPE, bizNo = "{{#user.id}}", + success = SYSTEM_USER_CREATE_SUCCESS) + public Long createUserBySupportStaff(UserSaveReqVO createReqVO) { + // 1.1 校验账户配合 + tenantService.handleTenantInfo(tenant -> { + long count = userMapper.selectCount(); + if (count >= tenant.getAccountCount()) { + throw exception(USER_COUNT_MAX, tenant.getAccountCount()); + } + }); + // 1.2 校验正确性 + validateUserForCreateOrUpdate(null, createReqVO.getUsername(), + createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds()); + // 2.1 插入用户 + AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class); + user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 + user.setPassword(encodePassword(createReqVO.getPassword())); // 加密密码 + userMapper.insert(user); + // 2.2 插入关联岗位 + if (CollectionUtil.isNotEmpty(user.getPostIds())) { + userPostMapper.insertBatch(convertList(user.getPostIds(), + postId -> new UserPostDO().setUserId(user.getId()).setPostId(postId))); + } + RoleDO role = roleService.getRoleByCode("support_staff"); + if (role != null){ + //给后台用户关联客服角色 + permissionService.assignUserRole(user.getId(), Collections.singleton(role.getId())); + } + // 3. 记录操作日志上下文 + LogRecordContext.putVariable("user", user); + return user.getId(); + } + + /* + * 新建后台用户并关联代理商角色 + * */ + @Override + @Transactional(rollbackFor = Exception.class) + @LogRecord(type = SYSTEM_USER_TYPE, subType = SYSTEM_USER_CREATE_SUB_TYPE, bizNo = "{{#user.id}}", + success = SYSTEM_USER_CREATE_SUCCESS) + public Long createUserByAgent(UserSaveReqVO createReqVO) { + // 1.1 校验账户配合 + tenantService.handleTenantInfo(tenant -> { + long count = userMapper.selectCount(); + if (count >= tenant.getAccountCount()) { + throw exception(USER_COUNT_MAX, tenant.getAccountCount()); + } + }); + // 1.2 校验正确性 + validateUserForCreateOrUpdate(null, createReqVO.getUsername(), + createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptId(), createReqVO.getPostIds()); + // 2.1 插入用户 + AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class); + user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 + user.setPassword(encodePassword(createReqVO.getPassword())); // 加密密码 + userMapper.insert(user); + // 2.2 插入关联岗位 + if (CollectionUtil.isNotEmpty(user.getPostIds())) { + userPostMapper.insertBatch(convertList(user.getPostIds(), + postId -> new UserPostDO().setUserId(user.getId()).setPostId(postId))); + } + RoleDO role = roleService.getRoleByCode("agent"); + if (role != null){ + //给后台用户关联客服角色 + permissionService.assignUserRole(user.getId(), Collections.singleton((role.getId()))); + } + // 3. 记录操作日志上下文 + LogRecordContext.putVariable("user", user); + return user.getId(); + } + + /* + * 查询除超级管理员用户用户列表 + * + * */ + @Override + public PageResult getUserPageByCreator(UserPageReqVO reqVO) { + // 如果有角色编号,查询角色对应的用户编号 + Set userIds = reqVO.getRoleId() != null ? + permissionService.getUserRoleIdListByRoleId(singleton(reqVO.getRoleId())) : null; + + // 分页查询 + return userMapper.selectPageByCreator(reqVO, getDeptCondition(reqVO.getDeptId()), userIds); + } + } diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index 0627011..7c7b7fa 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -32,6 +32,12 @@ ${revision} + + cn.iocoder.boot + yudao-module-agent-biz + ${revision} + + cn.iocoder.boot -- 2.47.2