Merge branch 'dev' of https://git.yfgame.vip/r/hangtag into dev

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
This commit is contained in:
YuanFeng 2024-10-06 08:44:33 +08:00
commit a12b47aeac
126 changed files with 4559 additions and 5817 deletions

View File

@ -1,2 +0,0 @@
cn.hangtag.framework.datapermission.config.HangtagDataPermissionAutoConfiguration
cn.hangtag.framework.datapermission.config.HangtagDeptDataPermissionAutoConfiguration

View File

@ -1,30 +0,0 @@
{
"groups": [
{
"name": "hangtag.tenant",
"type": "cn.hangtag.framework.tenant.config.TenantProperties",
"sourceType": "cn.hangtag.framework.tenant.config.TenantProperties"
}
],
"properties": [
{
"name": "hangtag.tenant.enable",
"type": "java.lang.Boolean",
"description": "是否开启",
"sourceType": "cn.hangtag.framework.tenant.config.TenantProperties"
},
{
"name": "hangtag.tenant.ignore-tables",
"type": "java.util.Set<java.lang.String>",
"description": "需要忽略多租户的表 即默认所有表都开启多租户的功能,所以记得添加对应的 tenant_id 字段哟",
"sourceType": "cn.hangtag.framework.tenant.config.TenantProperties"
},
{
"name": "hangtag.tenant.ignore-urls",
"type": "java.util.Set<java.lang.String>",
"description": "需要忽略多租户的请求 默认情况下,每个请求需要带上 tenant-id 的请求头。但是,部分请求是无需带上的,例如说短信回调、支付回调等 Open API",
"sourceType": "cn.hangtag.framework.tenant.config.TenantProperties"
}
],
"hints": []
}

View File

@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
cn.hangtag.framework.tenant.core.mq.kafka.TenantKafkaEnvironmentPostProcessor

View File

@ -1,2 +0,0 @@
cn.hangtag.framework.quartz.config.HangtagQuartzAutoConfiguration
cn.hangtag.framework.quartz.config.HangtagAsyncAutoConfiguration

View File

@ -1,11 +0,0 @@
{
"groups": [
{
"name": "hangtag.tracer",
"type": "cn.hangtag.framework.tracer.config.TracerProperties",
"sourceType": "cn.hangtag.framework.tracer.config.TracerProperties"
}
],
"properties": [],
"hints": []
}

View File

@ -1,2 +0,0 @@
cn.hangtag.framework.tracer.config.HangtagTracerAutoConfiguration
cn.hangtag.framework.tracer.config.HangtagMetricsAutoConfiguration

View File

@ -1,3 +0,0 @@
cn.hangtag.framework.mq.redis.config.HangtagRedisMQProducerAutoConfiguration
cn.hangtag.framework.mq.redis.config.HangtagRedisMQConsumerAutoConfiguration
cn.hangtag.framework.mq.rabbitmq.config.HangtagRabbitMQAutoConfiguration

View File

@ -1,2 +0,0 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
cn.hangtag.framework.mybatis.config.IdTypeEnvironmentPostProcessor

View File

@ -1,3 +0,0 @@
cn.hangtag.framework.datasource.config.HangtagDataSourceAutoConfiguration
cn.hangtag.framework.mybatis.config.HangtagMybatisAutoConfiguration
cn.hangtag.framework.translate.config.HangtagTranslateAutoConfiguration

View File

@ -1,4 +0,0 @@
cn.hangtag.framework.idempotent.config.HangtagIdempotentConfiguration
cn.hangtag.framework.lock4j.config.HangtagLock4jConfiguration
cn.hangtag.framework.ratelimiter.config.HangtagRateLimiterConfiguration
cn.hangtag.framework.signature.config.HangtagApiSignatureAutoConfiguration

View File

@ -1,18 +0,0 @@
{
"groups": [
{
"name": "hangtag.cache",
"type": "cn.hangtag.framework.redis.config.HangtagCacheProperties",
"sourceType": "cn.hangtag.framework.redis.config.HangtagCacheProperties"
}
],
"properties": [
{
"name": "hangtag.cache.redis-scan-batch-size",
"type": "java.lang.Integer",
"description": "redis scan 一次返回数量",
"sourceType": "cn.hangtag.framework.redis.config.HangtagCacheProperties"
}
],
"hints": []
}

View File

@ -1,2 +0,0 @@
cn.hangtag.framework.redis.config.HangtagRedisAutoConfiguration
cn.hangtag.framework.redis.config.HangtagCacheAutoConfiguration

View File

@ -1,48 +0,0 @@
{
"groups": [
{
"name": "hangtag.security",
"type": "cn.hangtag.framework.security.config.SecurityProperties",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
}
],
"properties": [
{
"name": "hangtag.security.mock-enable",
"type": "java.lang.Boolean",
"description": "mock 模式的开关",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
},
{
"name": "hangtag.security.mock-secret",
"type": "java.lang.String",
"description": "mock 模式的密钥 一定要配置密钥,保证安全性",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
},
{
"name": "hangtag.security.password-encoder-length",
"type": "java.lang.Integer",
"description": "PasswordEncoder 加密复杂度,越高开销越大",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
},
{
"name": "hangtag.security.permit-all-urls",
"type": "java.util.List<java.lang.String>",
"description": "免登录的 URL 列表",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
},
{
"name": "hangtag.security.token-header",
"type": "java.lang.String",
"description": "HTTP 请求时,访问令牌的请求 Header",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
},
{
"name": "hangtag.security.token-parameter",
"type": "java.lang.String",
"description": "HTTP 请求时,访问令牌的请求参数 初始目的:解决 WebSocket 无法通过 header 传参,只能通过 token 参数拼接",
"sourceType": "cn.hangtag.framework.security.config.SecurityProperties"
}
],
"hints": []
}

View File

@ -1,3 +0,0 @@
cn.hangtag.framework.security.config.HangtagSecurityAutoConfiguration
cn.hangtag.framework.security.config.HangtagWebSecurityConfigurerAdapter
cn.hangtag.framework.operatelog.config.HangtagOperateLogConfiguration

View File

@ -1,127 +0,0 @@
{
"groups": [
{
"name": "hangtag.swagger",
"type": "cn.hangtag.framework.swagger.config.SwaggerProperties",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.web",
"type": "cn.hangtag.framework.web.config.WebProperties",
"sourceType": "cn.hangtag.framework.web.config.WebProperties"
},
{
"name": "hangtag.web.admin-api",
"type": "cn.hangtag.framework.web.config.WebProperties$Api",
"sourceType": "cn.hangtag.framework.web.config.WebProperties"
},
{
"name": "hangtag.web.admin-ui",
"type": "cn.hangtag.framework.web.config.WebProperties$Ui",
"sourceType": "cn.hangtag.framework.web.config.WebProperties"
},
{
"name": "hangtag.web.app-api",
"type": "cn.hangtag.framework.web.config.WebProperties$Api",
"sourceType": "cn.hangtag.framework.web.config.WebProperties"
},
{
"name": "hangtag.xss",
"type": "cn.hangtag.framework.xss.config.XssProperties",
"sourceType": "cn.hangtag.framework.xss.config.XssProperties"
}
],
"properties": [
{
"name": "hangtag.swagger.author",
"type": "java.lang.String",
"description": "作者",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.description",
"type": "java.lang.String",
"description": "描述",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.email",
"type": "java.lang.String",
"description": "email",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.license",
"type": "java.lang.String",
"description": "license",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.license-url",
"type": "java.lang.String",
"description": "license-url",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.title",
"type": "java.lang.String",
"description": "标题",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.url",
"type": "java.lang.String",
"description": "url",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.swagger.version",
"type": "java.lang.String",
"description": "版本",
"sourceType": "cn.hangtag.framework.swagger.config.SwaggerProperties"
},
{
"name": "hangtag.web.admin-api.controller",
"type": "java.lang.String",
"description": "Controller 所在包的 Ant 路径规则 主要目的是,给该 Controller 设置指定的 {@link #prefix}",
"sourceType": "cn.hangtag.framework.web.config.WebProperties$Api"
},
{
"name": "hangtag.web.admin-api.prefix",
"type": "java.lang.String",
"description": "API 前缀,实现所有 Controller 提供的 RESTFul API 的统一前缀 意义:通过该前缀,避免 Swagger、Actuator 意外通过 Nginx 暴露出来给外部,带来安全性问题 这样Nginx 只需要配置转发到 \/api\/* 的所有接口即可。 @see HangtagWebAutoConfiguration#configurePathMatch(PathMatchConfigurer)",
"sourceType": "cn.hangtag.framework.web.config.WebProperties$Api"
},
{
"name": "hangtag.web.admin-ui.url",
"type": "java.lang.String",
"description": "访问地址",
"sourceType": "cn.hangtag.framework.web.config.WebProperties$Ui"
},
{
"name": "hangtag.web.app-api.controller",
"type": "java.lang.String",
"description": "Controller 所在包的 Ant 路径规则 主要目的是,给该 Controller 设置指定的 {@link #prefix}",
"sourceType": "cn.hangtag.framework.web.config.WebProperties$Api"
},
{
"name": "hangtag.web.app-api.prefix",
"type": "java.lang.String",
"description": "API 前缀,实现所有 Controller 提供的 RESTFul API 的统一前缀 意义:通过该前缀,避免 Swagger、Actuator 意外通过 Nginx 暴露出来给外部,带来安全性问题 这样Nginx 只需要配置转发到 \/api\/* 的所有接口即可。 @see HangtagWebAutoConfiguration#configurePathMatch(PathMatchConfigurer)",
"sourceType": "cn.hangtag.framework.web.config.WebProperties$Api"
},
{
"name": "hangtag.xss.enable",
"type": "java.lang.Boolean",
"description": "是否开启,默认为 true",
"sourceType": "cn.hangtag.framework.xss.config.XssProperties"
},
{
"name": "hangtag.xss.exclude-urls",
"type": "java.util.List<java.lang.String>",
"description": "需要排除的 URL默认为空",
"sourceType": "cn.hangtag.framework.xss.config.XssProperties"
}
],
"hints": []
}

View File

@ -1,6 +0,0 @@
cn.hangtag.framework.apilog.config.HangtagApiLogAutoConfiguration
cn.hangtag.framework.jackson.config.HangtagJacksonAutoConfiguration
cn.hangtag.framework.swagger.config.HangtagSwaggerAutoConfiguration
cn.hangtag.framework.web.config.HangtagWebAutoConfiguration
cn.hangtag.framework.xss.config.HangtagXssAutoConfiguration
cn.hangtag.framework.banner.config.HangtagBannerAutoConfiguration

View File

@ -1,16 +0,0 @@
Application Version: ${hangtag.info.version}
Spring Boot Version: ${spring-boot.version}
.__ __. ______ .______ __ __ _______
| \ | | / __ \ | _ \ | | | | / _____|
| \| | | | | | | |_) | | | | | | | __
| . ` | | | | | | _ < | | | | | | |_ |
| |\ | | `--' | | |_) | | `--' | | |__| |
|__| \__| \______/ |______/ \______/ \______|
███╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ██████╗
████╗ ██║██╔═══██╗ ██╔══██╗██║ ██║██╔════╝
██╔██╗ ██║██║ ██║ ██████╔╝██║ ██║██║ ███╗
██║╚██╗██║██║ ██║ ██╔══██╗██║ ██║██║ ██║
██║ ╚████║╚██████╔╝ ██████╔╝╚██████╔╝╚██████╔╝
╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝

View File

@ -1,24 +0,0 @@
{
"groups": [
{
"name": "hangtag.websocket",
"type": "cn.hangtag.framework.websocket.config.WebSocketProperties",
"sourceType": "cn.hangtag.framework.websocket.config.WebSocketProperties"
}
],
"properties": [
{
"name": "hangtag.websocket.path",
"type": "java.lang.String",
"description": "WebSocket 的连接路径",
"sourceType": "cn.hangtag.framework.websocket.config.WebSocketProperties"
},
{
"name": "hangtag.websocket.sender-type",
"type": "java.lang.String",
"description": "消息发送器的类型 可选值local、redis、rocketmq、kafka、rabbitmq",
"sourceType": "cn.hangtag.framework.websocket.config.WebSocketProperties"
}
],
"hints": []
}

View File

@ -10,7 +10,7 @@ public interface ErrorCodeConstants extends cn.hangtag.module.system.enums.Erro
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(3300, "客户不存在");
ErrorCode SHAPE_TEMPLATE_NOT_EXISTS = new ErrorCode(3400, "图形模板管理 不存在");
ErrorCode DRAFT_DESIGN_DATA_NOT_EXISTS = new ErrorCode(3500, "稿件模板数据 不存在");
ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(3600, "OMS销售订单主表不存在");
ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(3600, "OMS销售订单不存在");
ErrorCode SALE_ORDER_ENTRY_NOT_EXISTS = new ErrorCode(3700, "OMS销售订单明细不存在");
ErrorCode SALE_ORDER_ENTRY_PRICE_NOT_NULL= new ErrorCode(3701, "单价不允许为空");
ErrorCode CUSTOMER_BRAND_NOT_EXISTS = new ErrorCode(3800, "客户和品牌关联不存在");

View File

@ -0,0 +1,48 @@
package cn.hangtag.module.oms.enums;
import cn.hangtag.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 时间范围类型的枚举
*
* @author owen
*/
@AllArgsConstructor
@Getter
public enum TimeRangeTypeEnum implements IntArrayValuable {
/**
*
*/
DAY(1),
/**
*
*/
WEEK(7),
/**
*
*/
MONTH(30),
/**
*
*/
YEAR(365),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TimeRangeTypeEnum::getType).toArray();
/**
* 类型
*/
private final Integer type;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,35 +1,203 @@
package cn.hangtag.module.oms.controller.admin.app;
import cn.hangtag.framework.apilog.core.annotation.ApiAccessLog;
import cn.hangtag.framework.common.pojo.CommonResult;
import cn.hangtag.framework.common.pojo.PageParam;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.util.number.NumberUtils;
import cn.hangtag.framework.common.util.object.BeanUtils;
import cn.hangtag.framework.excel.core.util.ExcelUtils;
import cn.hangtag.framework.security.core.LoginUser;
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
import cn.hangtag.module.oms.controller.admin.productinfo.vo.ProductInfoPageReqVO;
import cn.hangtag.module.oms.controller.admin.productinfo.vo.ProductInfoRespVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRemarkReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRespVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
import cn.hangtag.module.oms.convert.saleorder.SaleOrderConvert;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.service.customer.CustomerService;
import cn.hangtag.module.oms.service.productinfo.ProductInfoService;
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
import cn.hangtag.module.system.api.user.AdminUserApi;
import cn.hangtag.module.system.api.user.dto.AdminUserRespDTO;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static cn.hangtag.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
@Tag(name = "APP - 销售订单")
@RestController
@RequestMapping("/oms/app/saleorder")
@RequestMapping("/oms/app/sale-order")
@Validated
public class AppSaleOrderController{
@Resource
private SaleOrderService saleOrderService;
@Resource
private CustomerService customerService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建销售订单")
public CommonResult<Long> createSaleOrder(@Valid @RequestBody SaleOrderSaveReqVO createReqVO) {
return success(saleOrderService.createSaleOrder(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新销售订单")
public CommonResult<Boolean> updateSaleOrder(@Valid @RequestBody SaleOrderSaveReqVO updateReqVO) {
saleOrderService.updateSaleOrder(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除销售订单")
@Parameter(name = "id", description = "编号", required = true)
public CommonResult<Boolean> deleteSaleOrder(@RequestParam("id") Long id) {
saleOrderService.deleteSaleOrder(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得销售订单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<SaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) {
SaleOrderDO saleOrder = saleOrderService.getSaleOrder(id);
if(saleOrder == null){
return success(null);
}
// 拼接数据
List<cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO> entrys = saleOrderService.getSaleOrderEntryListByParentId(id);
CustomerDO customer = customerService.getCustomer(saleOrder.getCustomerId());
// 1.2 获取修改人
AdminUserRespDTO updater = adminUserApi.getUser(NumberUtils.parseLong(saleOrder.getUpdater()));
AdminUserRespDTO auditor = adminUserApi.getUser(NumberUtils.parseLong(saleOrder.getAuditor()));
return success(SaleOrderConvert.INSTANCE.convert(saleOrder,entrys,customer,updater,auditor));
//return success(BeanUtils.toBean(saleOrder, SaleOrderRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得销售订单分页")
public CommonResult<PageResult<SaleOrderRespVO>> getSaleOrderPage(@Valid SaleOrderPageReqVO pageReqVO) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
pageReqVO.setCustomerId(customer.getId());
PageResult<SaleOrderDO> pageResult = saleOrderService.getSaleOrderPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, SaleOrderRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出销售订单 Excel")
@ApiAccessLog(operateType = EXPORT)
public void exportSaleOrderExcel(@Valid SaleOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
pageReqVO.setCustomerId(customer.getId());
List<SaleOrderDO> list = saleOrderService.getSaleOrderPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "销售订单.xls", "数据", SaleOrderRespVO.class,
BeanUtils.toBean(list, SaleOrderRespVO.class));
}
// ==================== 子表销售订单明细 ====================
@GetMapping("/sale-order-entry/list-by-parent-id")
@Operation(summary = "获得销售订单明细列表")
@Parameter(name = "parentId", description = "主表id")
public CommonResult<List<cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO>> getSaleOrderEntryListByParentId(@RequestParam("parentId") Long parentId) {
return success(saleOrderService.getSaleOrderEntryListByParentId(parentId));
}
@GetMapping("/get-count")
@Operation(summary = "获得销售订单 分页 tab count")
public CommonResult<Map<Integer, Long>> getSpuCount() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
Long customerId = null;
if(customer!=null){
customerId = customer.getId();
}
return success(saleOrderService.getTabsCount(customerId));
}
@PostMapping("/updateSaleOrderBillStatus")
@Operation(summary = "更新销售订单的状态")
public CommonResult<Boolean> updateSaleOrderBillStatus(@RequestParam("ids") List<Long> ids,
@RequestParam("status") String status) {
saleOrderService.updateSaleOrderBillStatus(ids, status);
return success(true);
}
@PutMapping("/generateProduceOrder")
@Operation(summary = "生成生成制单")
public CommonResult<Boolean> generateProduceOrder(@RequestParam("ids") List<Long> ids) {
saleOrderService.generateProduceOrder(ids);
return success(true);
}
@PostMapping("/rejectOrder")
@Operation(summary = "驳回")
public CommonResult<Boolean> rejectOrder(@RequestBody JSONObject jobs) {
Long[] ids = jobs.getObject("ids", new Long[0].getClass());
String reason = jobs.getString("reason");
saleOrderService.updateSaleOrderBillStatus(Arrays.asList(ids), "reject", MapUtil.of("rejectReason",reason));
return success(true);
}
/**
* 生成PDF文档并下载
* @param response HTTP响应
* @throws Exception 异常
*/
@GetMapping("/download")
@PermitAll
public void downloadPdf(HttpServletResponse response) throws Exception{
saleOrderService.generatePdf(response);
}
@PutMapping("/update-remark")
@Operation(summary = "订单备注")
public CommonResult<Boolean> updateOrderRemark(@RequestBody SaleOrderRemarkReqVO reqVO) {
saleOrderService.updateOrderRemark(reqVO);
return success(true);
}
@PutMapping("/update-entrys")
@Operation(summary = "更新销售订单")
public CommonResult<Boolean> updateSaleOrderEntry(@Valid @RequestBody SaleOrderSaveReqVO updateReqVO) {
saleOrderService.updateSaleOrder(updateReqVO);
return success(true);
}
}

View File

@ -0,0 +1,86 @@
package cn.hangtag.module.oms.controller.admin.app;
import cn.hangtag.framework.common.pojo.CommonResult;
import cn.hangtag.framework.security.core.LoginUser;
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderCountRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.enums.common.BillStatusEnum;
import cn.hangtag.module.oms.service.customer.CustomerService;
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
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.validation.Valid;
import java.util.List;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 订单统计")
@RestController
@RequestMapping("/oms/app/statistics/trade")
@Validated
@Slf4j
public class AppTradeStatisticsController {
@Resource
private SaleOrderService saleOrderService;
@Resource
private CustomerService customerService;
@GetMapping("/order-comparison")
@Operation(summary = "获得交易订单数量")
//@PreAuthorize("@ss.hasPermission('statistics:order:query')")
public CommonResult<DataComparisonRespVO<TradeOrderSummaryRespVO>> getOrderComparison() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
Long customerId = null;
if(customer!=null){
customerId = customer.getId();
}
return success(saleOrderService.getOrderComparison(customerId));
}
@GetMapping("/order-count")
@Operation(summary = "获得交易订单数量")
public CommonResult<TradeOrderCountRespVO> getOrderCount() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
Long customerId = null;
if(customer!=null){
customerId = customer.getId();
}
TradeOrderCountRespVO tradeOrderCountRespVO = new TradeOrderCountRespVO();
// 订单统计
Long rejectCount = saleOrderService.getCountByBillStatus(BillStatusEnum.REJECT.getValue(),customerId);
Long saveCount = saleOrderService.getCountByBillStatus(BillStatusEnum.SAVE.getValue(),customerId);
Long submitCount = saleOrderService.getCountByBillStatus(BillStatusEnum.SUBMIT.getValue(),customerId);
Long auditCount = saleOrderService.getCountByBillStatus(BillStatusEnum.AUDIT.getValue(),customerId);
tradeOrderCountRespVO.setOrderCountAA(rejectCount);
tradeOrderCountRespVO.setOrderCountA(saveCount);
tradeOrderCountRespVO.setOrderCountB(submitCount);
tradeOrderCountRespVO.setOrderCountC(auditCount);
// 拼接返回
return success(tradeOrderCountRespVO);
}
@GetMapping("/order-count-trend")
@Operation(summary = "获得订单量趋势统计")
public CommonResult<List<DataComparisonRespVO<TradeOrderTrendRespVO>>> getOrderCountTrendComparison(@Valid TradeOrderTrendReqVO reqVO) {
return success(saleOrderService.getOrderCountTrendComparison(reqVO));
}
}

View File

@ -17,4 +17,10 @@ public class DataComparisonRespVO<T> {
@Schema(description = "参照数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private T reference;
@Schema(description = "当前数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private T value2;
@Schema(description = "参照数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private T reference2;
}

View File

@ -1,8 +1,13 @@
package cn.hangtag.module.oms.controller.admin.saleorder;
import cn.hangtag.framework.common.util.number.NumberUtils;
import cn.hangtag.module.oms.convert.saleorder.SaleOrderConvert;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.service.customer.CustomerService;
import cn.hangtag.module.system.api.user.AdminUserApi;
import cn.hangtag.module.system.api.user.dto.AdminUserRespDTO;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -12,7 +17,6 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.annotation.security.PermitAll;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
@ -42,6 +46,10 @@ public class SaleOrderController {
@Resource
private SaleOrderService saleOrderService;
@Resource
private CustomerService customerService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建销售订单")
@ -73,7 +81,20 @@ public class SaleOrderController {
@PreAuthorize("@ss.hasPermission('oms:sale-order:query')")
public CommonResult<SaleOrderRespVO> getSaleOrder(@RequestParam("id") Long id) {
SaleOrderDO saleOrder = saleOrderService.getSaleOrder(id);
return success(BeanUtils.toBean(saleOrder, SaleOrderRespVO.class));
if(saleOrder == null){
return success(null);
}
// 拼接数据
List<SaleOrderEntryDO> entrys = saleOrderService.getSaleOrderEntryListByParentId(id);
CustomerDO customer = customerService.getCustomer(saleOrder.getCustomerId());
// 1.2 获取修改人
AdminUserRespDTO updater = adminUserApi.getUser(NumberUtils.parseLong(saleOrder.getUpdater()));
AdminUserRespDTO auditor = adminUserApi.getUser(NumberUtils.parseLong(saleOrder.getAuditor()));
return success(SaleOrderConvert.INSTANCE.convert(saleOrder,entrys,customer,updater,auditor));
//return success(BeanUtils.toBean(saleOrder, SaleOrderRespVO.class));
}
@GetMapping("/page")
@ -112,7 +133,7 @@ public class SaleOrderController {
@Operation(summary = "获得销售订单 分页 tab count")
@PreAuthorize("@ss.hasPermission('oms:sale-order:query')")
public CommonResult<Map<Integer, Long>> getSpuCount() {
return success(saleOrderService.getTabsCount());
return success(saleOrderService.getTabsCount(null));
}
@PostMapping("/updateSaleOrderBillStatus")
@ -153,5 +174,21 @@ public class SaleOrderController {
public void downloadPdf(HttpServletResponse response) throws Exception{
saleOrderService.generatePdf(response);
}
@PutMapping("/update-remark")
@Operation(summary = "订单备注")
@PreAuthorize("@ss.hasPermission('oms:sale-order:update')")
public CommonResult<Boolean> updateOrderRemark(@RequestBody SaleOrderRemarkReqVO reqVO) {
saleOrderService.updateOrderRemark(reqVO);
return success(true);
}
@PutMapping("/update-entrys")
@Operation(summary = "更新销售订单")
@PreAuthorize("@ss.hasPermission('oms:sale-order:update')")
public CommonResult<Boolean> updateSaleOrderEntry(@Valid @RequestBody SaleOrderSaveReqVO updateReqVO) {
saleOrderService.updateSaleOrder(updateReqVO);
return success(true);
}
}

View File

@ -0,0 +1,21 @@
package cn.hangtag.module.oms.controller.admin.saleorder.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 SaleOrderRemarkReqVO {
@Schema(description = "订单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "订单编号不能为空")
private Long id;
@Schema(description = "商家备注", example = "你猜一下")
@NotEmpty(message = "订单备注不能为空")
private String remark;
}

View File

@ -2,6 +2,8 @@ package cn.hangtag.module.oms.controller.admin.saleorder.vo;
import cn.hangtag.framework.excel.core.annotations.DictFormat;
import cn.hangtag.framework.excel.core.convert.DictConvert;
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerRespVO;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.enums.DictTypeConstants;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@ -70,8 +72,43 @@ public class SaleOrderRespVO {
@ExcelProperty("备注")
private String remarks;
@Schema(description = "发票抬头")
@ExcelProperty("发票抬头")
private String invoiceCode;
@Schema(description = "发票名称")
@ExcelProperty("发票名称")
private String invoiceName;
@Schema(description = "发票地址")
@ExcelProperty("发票地址")
private String address;
@Schema(description = "货币")
@ExcelProperty("货币")
private String currency;
@Schema(description = "发票备注")
@ExcelProperty("发票备注")
private String invoiceRemarks;
@Schema(description = "驳回原因")
@ExcelProperty("驳回原因")
private String rejectReason;
@Schema(description = "修改人")
private String updaterName;
@Schema(description = "审核人")
private String auditorName;
@Schema(description = "审核时间")
private LocalDateTime auditorTime;
@Schema(description = "客户")
private CustomerRespVO customer;
@Schema(description = "产品明细")
private List<cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO> entrys;
}

View File

@ -66,6 +66,6 @@ public class SaleOrderSaveReqVO {
private String rejectReason;
@Schema(description = "销售订单明细列表")
private List<SaleOrderEntryDO> saleOrderEntrys;
private List<SaleOrderEntryDO> entrys;
}

View File

@ -2,7 +2,11 @@ package cn.hangtag.module.oms.controller.admin.trade;
import cn.hangtag.framework.common.pojo.CommonResult;
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderCountRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.enums.common.BillStatusEnum;
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -14,6 +18,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
@ -34,4 +41,32 @@ public class TradeStatisticsController {
public CommonResult<DataComparisonRespVO<TradeOrderSummaryRespVO>> getOrderComparison() {
return success(saleOrderService.getOrderComparison());
}
@GetMapping("/order-count")
@Operation(summary = "获得交易订单数量")
@PreAuthorize("@ss.hasPermission('statistics:trade:query')")
public CommonResult<TradeOrderCountRespVO> getOrderCount() {
TradeOrderCountRespVO tradeOrderCountRespVO = new TradeOrderCountRespVO();
// 订单统计
Long rejectCount = saleOrderService.getCountByBillStatus(BillStatusEnum.REJECT.getValue());
Long saveCount = saleOrderService.getCountByBillStatus(BillStatusEnum.SAVE.getValue());
Long submitCount = saleOrderService.getCountByBillStatus(BillStatusEnum.SUBMIT.getValue());
Long auditCount = saleOrderService.getCountByBillStatus(BillStatusEnum.AUDIT.getValue());
tradeOrderCountRespVO.setOrderCountAA(rejectCount);
tradeOrderCountRespVO.setOrderCountA(saveCount);
tradeOrderCountRespVO.setOrderCountB(submitCount);
tradeOrderCountRespVO.setOrderCountC(auditCount);
// 拼接返回
return success(tradeOrderCountRespVO);
}
@GetMapping("/order-count-trend")
@Operation(summary = "获得订单量趋势统计")
@PreAuthorize("@ss.hasPermission('statistics:trade:query')")
public CommonResult<List<DataComparisonRespVO<TradeOrderTrendRespVO>>> getOrderCountTrendComparison(@Valid TradeOrderTrendReqVO reqVO) {
return success(saleOrderService.getOrderCountTrendComparison(reqVO));
}
}

View File

@ -7,16 +7,16 @@ import lombok.Data;
@Data
public class TradeOrderCountRespVO {
@Schema(description = "待发货", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long undelivered;
@Schema(description = "已驳回", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long orderCountAA;
@Schema(description = "核销", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long pickUp;
@Schema(description = "提交", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long orderCountA;
@Schema(description = "退款中", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long afterSaleApply;
@Schema(description = "待审核", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long orderCountB;
@Schema(description = "提现待审核", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long auditingWithdraw;
@Schema(description = "已完成", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long orderCountC;
}

View File

@ -3,14 +3,16 @@ package cn.hangtag.module.oms.controller.admin.trade.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 交易订单统计 Response VO")
@Data
public class TradeOrderSummaryRespVO {
@Schema(description = "支付订单商品", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderPayCount;
@Schema(description = "销售订单", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderCount;
@Schema(description = "总支付金", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderPayPrice;
@Schema(description = "销售订单", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private BigDecimal orderAmount;
}

View File

@ -11,9 +11,9 @@ public class TradeOrderTrendRespVO {
private String date;
@Schema(description = "订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderPayCount;
private Integer orderCount;
@Schema(description = "订单支付金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderPayPrice;
@Schema(description = "订单金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Integer orderAmount;
}

View File

@ -0,0 +1,54 @@
package cn.hangtag.module.oms.convert.saleorder;
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerRespVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRemarkReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRespVO;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface SaleOrderConvert {
SaleOrderConvert INSTANCE = Mappers.getMapper(SaleOrderConvert.class);
@Mappings({
// @Mapping(target = "id", ignore = true),
@Mapping(source = "invoiceCode", target = "invoiceCode"),
@Mapping(source = "invoiceName", target = "invoiceName"),
@Mapping(source = "address", target = "address")
})
SaleOrderRespVO convert(SaleOrderDO bean);
CustomerRespVO convert(CustomerDO bean);
SaleOrderDO convert(SaleOrderRemarkReqVO reqVO);
default SaleOrderRespVO convert(SaleOrderDO saleOrder, List<cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO> entrys, CustomerDO customer, AdminUserRespDTO updater, AdminUserRespDTO auditor){
SaleOrderRespVO orderVO = convert(saleOrder);
// 处理客户信息
orderVO.setCustomer(convert(customer));
if(updater!=null){
orderVO.setUpdaterName(updater.getNickname());
}
if(auditor!=null){
orderVO.setAuditorName(auditor.getNickname());
}
orderVO.setEntrys(entrys);
return orderVO;
}
}

View File

@ -1,6 +1,8 @@
package cn.hangtag.module.oms.dal.dataobject.saleorder;
import lombok.*;
import java.math.BigDecimal;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
@ -74,6 +76,10 @@ public class SaleOrderDO extends BaseDO {
* 传真
*/
private String fax;
/**
* 订单总金额
*/
private BigDecimal orderAmount;
/**
* 备注
*/
@ -106,5 +112,13 @@ public class SaleOrderDO extends BaseDO {
* 驳回原因
*/
private String rejectReason;
/**
* 审核人
*/
private String auditor;
/**
* 审核时间
*/
private LocalDateTime auditorTime;
}

View File

@ -46,9 +46,17 @@ public class SaleOrderEntryDO extends BaseDO {
* 单价
*/
private BigDecimal price;
/**
* 折扣率
*/
private BigDecimal discount;
/**
* 数量
*/
private Integer qty;
/**
* 金额
*/
private BigDecimal amount;
}

View File

@ -5,6 +5,7 @@ import cn.hangtag.framework.mybatis.core.mapper.BaseMapperX;
import cn.hangtag.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.enums.saleorder.SaleOrderStatusEnum;
import cn.hutool.core.util.ObjectUtil;
@ -12,6 +13,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
/**
* 销售订单 Mapper
@ -65,7 +67,26 @@ public interface SaleOrderMapper extends BaseMapperX<SaleOrderDO> {
TradeOrderSummaryRespVO selectOrderQtySummaryByOrderStatusAndCreateTimeBetween(@Param("orderStatus") String orderStatus,
@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
@Param("endTime") LocalDateTime endTime,@Param("customerId") Long customerId);
/**
* 按照支付时间统计订单按天分组
*
* @param beginTime 支付起始时间
* @param endTime 支付截止时间
* @return 订单统计列表
*/
List<TradeOrderTrendRespVO> selectListByPayTimeBetweenAndGroupByDay(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
/**
* 按照支付时间统计订单按月分组
*
* @param beginTime 支付起始时间
* @param endTime 支付截止时间
* @return 订单统计列表
*/
List<TradeOrderTrendRespVO> selectListByPayTimeBetweenAndGroupByMonth(@Param("beginTime") LocalDateTime beginTime,
@Param("endTime") LocalDateTime endTime);
}

View File

@ -100,7 +100,7 @@ public class CustomerServiceImpl implements CustomerService {
// 校验存在
CustomerDO customerDO = validateCustomerExists(updateReqVO.getId());
if(StringUtils.isNotBlank(updateReqVO.getNumber()) && !customerDO.getNumber().equals(updateReqVO.getNumber())){//编码不一致
if(StringUtils.isNotBlank(updateReqVO.getNumber()) && !updateReqVO.getNumber().equals(customerDO.getNumber())){//编码不一致
checkCode(customerDO.getId(),updateReqVO.getNumber());
}else {
updateReqVO.setNumber(customerDO.getNumber());

View File

@ -8,10 +8,11 @@ import javax.validation.*;
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.pojo.PageParam;
/**
* 销售订单 Service 接口
@ -68,7 +69,7 @@ public interface SaleOrderService {
*/
List<SaleOrderEntryDO> getSaleOrderEntryListByParentId(Long parentId);
Map<Integer, Long> getTabsCount();
Map<Integer, Long> getTabsCount(Long customerId);
default void updateSaleOrderBillStatus(List<Long> ids, String status){
updateSaleOrderBillStatus(ids,status,null);
@ -79,10 +80,23 @@ public interface SaleOrderService {
void generatePdf(HttpServletResponse response) throws IOException;
default DataComparisonRespVO<TradeOrderSummaryRespVO> getOrderComparison(){
return getOrderComparison(null);
}
/**
* 交易订单销售额对照
*
* @return 销售额对照
*/
DataComparisonRespVO<TradeOrderSummaryRespVO> getOrderComparison();
DataComparisonRespVO<TradeOrderSummaryRespVO> getOrderComparison(Long customerId);
void updateOrderRemark(SaleOrderRemarkReqVO reqVO);
default Long getCountByBillStatus(String value){
return getCountByBillStatus(value,null);
}
Long getCountByBillStatus(String value, Long customerId);
List<DataComparisonRespVO<TradeOrderTrendRespVO>> getOrderCountTrendComparison(TradeOrderTrendReqVO reqVO);
}

View File

@ -1,18 +1,21 @@
package cn.hangtag.module.oms.service.saleorder;
import cn.hangtag.framework.common.exception.ServiceException;
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.util.object.BeanUtils;
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
import cn.hangtag.module.oms.common.utils.NumberChineseFormatterUtils;
import cn.hangtag.module.oms.common.utils.WKHtmlToPdfUtil;
import cn.hangtag.module.oms.controller.admin.common.vo.DataComparisonRespVO;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.ProduceOrderSaveReqVO;
import cn.hangtag.module.oms.controller.admin.product.vo.ProductPriceSaveReqVO;
import cn.hangtag.module.oms.controller.admin.salecontract.vo.SaleContractSaveReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderRemarkReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendReqVO;
import cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO;
import cn.hangtag.module.oms.convert.saleorder.SaleOrderConvert;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.dal.dataobject.product.ProductPriceDO;
import cn.hangtag.module.oms.dal.dataobject.productinfo.ProductInfoDO;
@ -23,6 +26,7 @@ import cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO;
import cn.hangtag.module.oms.dal.mysql.saleorder.SaleOrderMapper;
import cn.hangtag.module.oms.dal.mysql.saleorderentry.SaleOrderEntryMapper;
import cn.hangtag.module.oms.enums.ErrorCodeConstants;
import cn.hangtag.module.oms.enums.TimeRangeTypeEnum;
import cn.hangtag.module.oms.enums.common.BillStatusEnum;
import cn.hangtag.module.oms.enums.saleorder.SaleOrderStatusEnum;
import cn.hangtag.module.oms.service.customer.CustomerService;
@ -30,14 +34,15 @@ import cn.hangtag.module.oms.service.produceorder.ProduceOrderService;
import cn.hangtag.module.oms.service.product.ProductPriceService;
import cn.hangtag.module.oms.service.productinfo.ProductInfoService;
import cn.hangtag.module.oms.service.salecontract.SaleContractService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@ -46,15 +51,19 @@ import org.thymeleaf.context.Context;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXISTS;
@ -94,7 +103,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
saleOrder.setOrderStatus(SaleOrderStatusEnum.YXD.getValue());
saleOrderMapper.insert(saleOrder);
// 插入子表
createSaleOrderEntryList(saleOrder.getId(), createReqVO.getSaleOrderEntrys());
createSaleOrderEntryList(saleOrder.getId(), createReqVO.getEntrys());
// 返回
return saleOrder.getId();
}
@ -109,7 +118,7 @@ public class SaleOrderServiceImpl implements SaleOrderService {
saleOrderMapper.updateById(updateObj);
// 更新子表
updateSaleOrderEntryList(updateReqVO.getId(), updateReqVO.getSaleOrderEntrys());
updateSaleOrderEntryList(updateReqVO.getId(), updateReqVO.getEntrys());
}
@Override
@ -159,17 +168,35 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
@Override
public Map<Integer, Long> getTabsCount() {
public Map<Integer, Long> getTabsCount(Long customerId) {
Map<Integer, Long> counts = Maps.newLinkedHashMapWithExpectedSize(3);
LambdaQueryWrapper<SaleOrderDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YXD.getValue());
if(customerId!=null){
lambdaQueryWrapper.eq(SaleOrderDO::getCustomerId, customerId);
}
LambdaQueryWrapper<SaleOrderDO> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
lambdaQueryWrapper1.eq(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.SCZ.getValue());
if(customerId!=null){
lambdaQueryWrapper1.eq(SaleOrderDO::getCustomerId, customerId);
}
LambdaQueryWrapper<SaleOrderDO> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
lambdaQueryWrapper2.eq(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YWC.getValue());
if(customerId!=null){
lambdaQueryWrapper2.eq(SaleOrderDO::getCustomerId, customerId);
}
// 查询已下单订单数量
counts.put(SaleOrderStatusEnum.YXD.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YXD.getValue()));
saleOrderMapper.selectCount(lambdaQueryWrapper));
// 查询已生产订单数量
counts.put(SaleOrderStatusEnum.SCZ.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.SCZ.getValue()));
saleOrderMapper.selectCount(lambdaQueryWrapper1));
// 查询已完成订单数量
counts.put(SaleOrderStatusEnum.YWC.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YWC.getValue()));
saleOrderMapper.selectCount(lambdaQueryWrapper2));
return counts;
}
@ -208,10 +235,11 @@ public class SaleOrderServiceImpl implements SaleOrderService {
case "audit":
for (SaleOrderDO saleOrder : saleOrders) {
if(BillStatusEnum.SUBMIT.getValue().equals(saleOrder.getBillStatus())){
saleOrder.setBillStatus(BillStatusEnum.AUDIT.getValue());
saleOrder.setOrderStatus(SaleOrderStatusEnum.YWC.getValue());
saleOrderMapper.updateById(saleOrder);
List<SaleOrderEntryDO> entrys = getSaleOrderEntryListByParentId(saleOrder.getId());
if(entrys==null||entrys.isEmpty()){
throw new ServiceException(001,"产品明细为空");
}
for (cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO entry : entrys) {
BigDecimal price = entry.getPrice();
if(price==null){
@ -219,6 +247,14 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
}
saleOrder.setBillStatus(BillStatusEnum.AUDIT.getValue());
saleOrder.setOrderStatus(SaleOrderStatusEnum.YWC.getValue());
Long userId = SecurityFrameworkUtils.getLoginUserId();
saleOrder.setAuditor(userId.toString());
saleOrder.setAuditorTime(LocalDateTime.now());
saleOrderMapper.updateById(saleOrder);
//生成产品单价记录
for (cn.hangtag.module.oms.dal.dataobject.saleorderentry.SaleOrderEntryDO entry : entrys) {
Long parentId = entry.getParentId();
@ -353,20 +389,84 @@ public class SaleOrderServiceImpl implements SaleOrderService {
}
@Override
public DataComparisonRespVO<TradeOrderSummaryRespVO> getOrderComparison() {
public DataComparisonRespVO<TradeOrderSummaryRespVO> getOrderComparison(Long customerId) {
LocalDateTime dayDate = LocalDateTime.now();
LocalDateTime lastDayDate = LocalDateTime.now().minusDays(1);
LocalDateTime beginWeekDate = DateUtil.beginOfWeek(DateUtil.date()).toLocalDateTime();
LocalDateTime endWeekDate = DateUtil.endOfWeek(DateUtil.date()).toLocalDateTime();
LocalDateTime lastBeginWeekDate = DateUtil.beginOfWeek(DateUtil.lastWeek()).toLocalDateTime();
LocalDateTime lastEndWeekDate = DateUtil.endOfWeek(DateUtil.lastWeek()).toLocalDateTime();
return new DataComparisonRespVO<TradeOrderSummaryRespVO>()
.setValue(getOrderQtySummary(LocalDateTime.now()))
.setReference(getOrderQtySummary(LocalDateTime.now().minusDays(1)));
.setValue(getOrderQtySummary(dayDate,dayDate,customerId))//今日
.setReference(getOrderQtySummary(lastDayDate,lastDayDate,customerId))//昨日
.setValue2(getOrderQtySummary(beginWeekDate,endWeekDate,customerId))//本周
.setReference2(getOrderQtySummary(lastBeginWeekDate,lastEndWeekDate,customerId));//上周
}
private TradeOrderSummaryRespVO getOrderQtySummary(LocalDateTime date) {
LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(date);
LocalDateTime endTime = LocalDateTimeUtil.endOfDay(date);
@Override
public void updateOrderRemark(SaleOrderRemarkReqVO reqVO) {
// 校验并获得交易订单
validateOrderExists(reqVO.getId());
// 更新
SaleOrderDO order = SaleOrderConvert.INSTANCE.convert(reqVO);
saleOrderMapper.updateById(order);
}
@Override
public Long getCountByBillStatus(String billstatus, Long customerId) {
LambdaQueryWrapper<SaleOrderDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(SaleOrderDO::getBillStatus,billstatus);
if(customerId!=null){
lambdaQueryWrapper.eq(SaleOrderDO::getCustomerId,customerId);
}
return saleOrderMapper.selectCount(lambdaQueryWrapper);
}
@Override
public List<DataComparisonRespVO<TradeOrderTrendRespVO>> getOrderCountTrendComparison(TradeOrderTrendReqVO reqVO) {
// 查询当前数据
List<TradeOrderTrendRespVO> value = getOrderCountTrend(reqVO.getType(), reqVO.getBeginTime(), reqVO.getEndTime());
// 查询对照数据
LocalDateTime referenceEndTime = reqVO.getBeginTime().minusDays(1);
LocalDateTime referenceBeginTime = referenceEndTime.minus(Duration.between(reqVO.getBeginTime(), reqVO.getEndTime()));
List<TradeOrderTrendRespVO> reference = getOrderCountTrend(reqVO.getType(), referenceBeginTime, referenceEndTime);
// 顺序对比返回
return IntStream.range(0, value.size())
.mapToObj(index -> new DataComparisonRespVO<TradeOrderTrendRespVO>()
.setValue(CollUtil.get(value, index))
.setReference(CollUtil.get(reference, index)))
.collect(Collectors.toList());
}
private List<TradeOrderTrendRespVO> getOrderCountTrend(Integer timeRangeType, LocalDateTime beginTime, LocalDateTime endTime) {
// 情况一按年统计时以月份分组
if (TimeRangeTypeEnum.YEAR.getType().equals(timeRangeType)) {
return saleOrderMapper.selectListByPayTimeBetweenAndGroupByMonth(beginTime, endTime);
}
// 情况二其它以天分组
return saleOrderMapper.selectListByPayTimeBetweenAndGroupByDay(beginTime, endTime);
}
private TradeOrderSummaryRespVO getOrderQtySummary(LocalDateTime beginDate, LocalDateTime endDate, Long customerId) {
LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(beginDate);
LocalDateTime endTime = LocalDateTimeUtil.endOfDay(endDate);
return saleOrderMapper.selectOrderQtySummaryByOrderStatusAndCreateTimeBetween(
null, beginTime, endTime);
null, beginTime, endTime,customerId);
}
@NotNull
private SaleOrderDO validateOrderExists(Long id) {
// 校验订单是否存在
SaleOrderDO order = saleOrderMapper.selectById(id);
if (order == null) {
throw exception(SALE_ORDER_NOT_EXISTS);
}
return order;
}
private void createSaleOrderEntryList(Long parentId, List<SaleOrderEntryDO> list) {
list.forEach(o -> o.setParentId(parentId));
saleOrderEntryMapper.insertBatch(list);

View File

@ -6,16 +6,46 @@
<select id="selectOrderQtySummaryByOrderStatusAndCreateTimeBetween"
resultType="cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderSummaryRespVO">
SELECT IFNULL(SUM(0), 0) AS orderPayPrice,
COUNT(1) AS orderPayCount
SELECT IFNULL(SUM(0), 0) AS orderCount,
COUNT(1) AS orderAmount
FROM oms_saleorder
WHERE deleted = FALSE
<if test="orderStatus != null">
AND order_status = #{orderStatus}
</if>
<if test="customerId != null">
AND customer_id = #{customerId}
</if>
AND create_time BETWEEN #{beginTime} AND #{endTime}
</select>
<select id="selectListByPayTimeBetweenAndGroupByDay"
resultType="cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO">
SELECT DATE_FORMAT(create_time, '%Y-%m-%d') AS date,
COUNT(1) AS orderCount,
SUM(order_amount) AS orderAmount
FROM oms_saleorder
WHERE bill_status = 'C'
AND create_time BETWEEN #{beginTime} AND #{endTime}
AND deleted = FALSE
GROUP BY date
</select>
<select id="selectListByPayTimeBetweenAndGroupByMonth"
resultType="cn.hangtag.module.oms.controller.admin.trade.vo.TradeOrderTrendRespVO">
SELECT DATE_FORMAT(create_time, '%Y-%m') AS date,
COUNT(1) AS orderCount,
SUM(order_amount) AS orderAmount
FROM oms_saleorder
WHERE bill_status = 'C'
AND create_time BETWEEN #{beginTime} AND #{endTime}
AND deleted = FALSE
GROUP BY date
</select>
</mapper>

View File

@ -1,138 +0,0 @@
package cn.hangtag.module.oms.service.product;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import javax.annotation.Resource;
import cn.hangtag.framework.test.core.ut.BaseDbUnitTest;
import cn.hangtag.module.oms.controller.admin.product.vo.*;
import cn.hangtag.module.oms.dal.dataobject.product.ProductPriceDO;
import cn.hangtag.module.oms.dal.mysql.product.ProductPriceMapper;
import cn.hangtag.framework.common.pojo.PageResult;
import javax.annotation.Resource;
import org.springframework.context.annotation.Import;
import java.util.*;
import java.time.LocalDateTime;
import static cn.hutool.core.util.RandomUtil.*;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
import static cn.hangtag.framework.test.core.util.AssertUtils.*;
import static cn.hangtag.framework.test.core.util.RandomUtils.*;
import static cn.hangtag.framework.common.util.date.LocalDateTimeUtils.*;
import static cn.hangtag.framework.common.util.object.ObjectUtils.*;
import static cn.hangtag.framework.common.util.date.DateUtils.*;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
/**
* {@link ProductPriceServiceImpl} 的单元测试类
*
* @author wwb
*/
@Import(ProductPriceServiceImpl.class)
public class ProductPriceServiceImplTest extends BaseDbUnitTest {
@Resource
private ProductPriceServiceImpl productPriceService;
@Resource
private ProductPriceMapper productPriceMapper;
@Test
public void testCreateProductPrice_success() {
// 准备参数
ProductPriceSaveReqVO createReqVO = randomPojo(ProductPriceSaveReqVO.class).setId(null);
// 调用
Integer productPriceId = productPriceService.createProductPrice(createReqVO);
// 断言
assertNotNull(productPriceId);
// 校验记录的属性是否正确
ProductPriceDO productPrice = productPriceMapper.selectById(productPriceId);
assertPojoEquals(createReqVO, productPrice, "id");
}
@Test
public void testUpdateProductPrice_success() {
// mock 数据
ProductPriceDO dbProductPrice = randomPojo(ProductPriceDO.class);
productPriceMapper.insert(dbProductPrice);// @Sql: 先插入出一条存在的数据
// 准备参数
ProductPriceSaveReqVO updateReqVO = randomPojo(ProductPriceSaveReqVO.class, o -> {
o.setId(dbProductPrice.getId()); // 设置更新的 ID
});
// 调用
productPriceService.updateProductPrice(updateReqVO);
// 校验是否更新正确
ProductPriceDO productPrice = productPriceMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, productPrice);
}
@Test
public void testUpdateProductPrice_notExists() {
// 准备参数
ProductPriceSaveReqVO updateReqVO = randomPojo(ProductPriceSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> productPriceService.updateProductPrice(updateReqVO), PRODUCT_PRICE_NOT_EXISTS);
}
@Test
public void testDeleteProductPrice_success() {
// mock 数据
ProductPriceDO dbProductPrice = randomPojo(ProductPriceDO.class);
productPriceMapper.insert(dbProductPrice);// @Sql: 先插入出一条存在的数据
// 准备参数
Integer id = dbProductPrice.getId();
// 调用
productPriceService.deleteProductPrice(id);
// 校验数据不存在了
assertNull(productPriceMapper.selectById(id));
}
@Test
public void testDeleteProductPrice_notExists() {
// 准备参数
Integer id = randomIntegerId();
// 调用, 并断言异常
assertServiceException(() -> productPriceService.deleteProductPrice(id), PRODUCT_PRICE_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值然后删除 @Disabled 注解
public void testGetProductPricePage() {
// mock 数据
ProductPriceDO dbProductPrice = randomPojo(ProductPriceDO.class, o -> { // 等会查询到
o.setProductId(null);
o.setPrice(null);
o.setCreateTime(null);
});
productPriceMapper.insert(dbProductPrice);
// 测试 productId 不匹配
productPriceMapper.insert(cloneIgnoreId(dbProductPrice, o -> o.setProductId(null)));
// 测试 price 不匹配
productPriceMapper.insert(cloneIgnoreId(dbProductPrice, o -> o.setPrice(null)));
// 测试 createTime 不匹配
productPriceMapper.insert(cloneIgnoreId(dbProductPrice, o -> o.setCreateTime(null)));
// 准备参数
ProductPricePageReqVO reqVO = new ProductPricePageReqVO();
reqVO.setProductId(null);
reqVO.setPrice(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<ProductPriceDO> pageResult = productPriceService.getProductPricePage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbProductPrice, pageResult.getList().get(0));
}
}

View File

@ -103,6 +103,14 @@ public class AuthController {
return success(null);
}
if(user.getDeptId()==999999L){//当前账号等于客户类型
AuthPermissionInfoRespVO convert = AuthConvert.INSTANCE.convert(user, null, null);
String customerMenuJson = ResourceUtil.readUtf8Str("json/customer_menu.json");
List<AuthPermissionInfoRespVO.MenuVO> list = JSONUtil.toList(customerMenuJson, AuthPermissionInfoRespVO.MenuVO.class);
convert.setMenus(list);
return success(convert);
}
// 1.2 获得角色列表
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(getLoginUserId());
if (CollUtil.isEmpty(roleIds)) {
@ -117,11 +125,6 @@ public class AuthController {
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
AuthPermissionInfoRespVO convert = AuthConvert.INSTANCE.convert(user, roles, menuList);
if(user.getDeptId()==999999L){//当前账号等于客户类型
String customerMenuJson = ResourceUtil.readUtf8Str("json/customer_menu.json");
List<AuthPermissionInfoRespVO.MenuVO> list = JSONUtil.toList(customerMenuJson, AuthPermissionInfoRespVO.MenuVO.class);
convert.setMenus(list);
}
// 2. 拼接结果返回
return success(convert);
}

View File

@ -11,6 +11,19 @@
"keepAlive": true,
"alwaysShow": true,
"children": [
{
"id": 2830,
"parentId": 2828,
"name": "销售订单",
"path": "sale-order",
"component": "oms/saleorder/index",
"componentName": "SaleOrder",
"icon": "",
"visible": true,
"keepAlive": true,
"alwaysShow": true,
"children": null
},
{
"id": 2818,
"parentId": 2804,

View File

@ -1 +0,0 @@
cn.hangtag.module.system.framework.captcha.core.RedisCaptchaServiceImpl

View File

@ -1,42 +0,0 @@
{
"groups": [
{
"name": "hangtag.sms-code",
"type": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
}
],
"properties": [
{
"name": "hangtag.sms-code.begin-code",
"type": "java.lang.Integer",
"description": "验证码最小值",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
},
{
"name": "hangtag.sms-code.end-code",
"type": "java.lang.Integer",
"description": "验证码最大值",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
},
{
"name": "hangtag.sms-code.expire-times",
"type": "java.time.Duration",
"description": "过期时间",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
},
{
"name": "hangtag.sms-code.send-frequency",
"type": "java.time.Duration",
"description": "短信发送频率",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
},
{
"name": "hangtag.sms-code.send-maximum-quantity-per-day",
"type": "java.lang.Integer",
"description": "每日发送最大数量",
"sourceType": "cn.hangtag.module.system.framework.sms.config.SmsCodeProperties"
}
],
"hints": []
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,11 +0,0 @@
package cn.hangtag.module.system.convert.oauth2;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-09-15T11:57:57+0800",
comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_401 (Oracle Corporation)"
)
public class OAuth2OpenConvertImpl implements OAuth2OpenConvert {
}

View File

@ -1,32 +0,0 @@
package cn.hangtag.module.system.convert.social;
import cn.hangtag.module.system.api.social.dto.SocialUserBindReqDTO;
import cn.hangtag.module.system.controller.admin.socail.vo.user.SocialUserBindReqVO;
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-09-15T11:57:57+0800",
comments = "version: 1.5.5.Final, compiler: javac, environment: Java 1.8.0_401 (Oracle Corporation)"
)
public class SocialUserConvertImpl implements SocialUserConvert {
@Override
public SocialUserBindReqDTO convert(Long userId, Integer userType, SocialUserBindReqVO reqVO) {
if ( userId == null && userType == null && reqVO == null ) {
return null;
}
SocialUserBindReqDTO socialUserBindReqDTO = new SocialUserBindReqDTO();
if ( reqVO != null ) {
socialUserBindReqDTO.setSocialType( reqVO.getType() );
socialUserBindReqDTO.setCode( reqVO.getCode() );
socialUserBindReqDTO.setState( reqVO.getState() );
}
socialUserBindReqDTO.setUserId( userId );
socialUserBindReqDTO.setUserType( userType );
return socialUserBindReqDTO;
}
}

View File

@ -1,53 +0,0 @@
spring:
main:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
datasource:
name: ruoyi-vue-pro
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
initial-size: 1 # 单元测试,配置为 1提升启动速度
sql:
init:
schema-locations: classpath:/sql/create_tables.sql
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
mybatis:
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
--- #################### 定时任务相关配置 ####################
--- #################### 配置中心相关配置 ####################
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项(单元测试,禁用 Lock4j
--- #################### 监控相关配置 ####################
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
hangtag:
info:
base-package: cn.hangtag.module
captcha:
timeout: 5m
width: 160
height: 60
enable: true

View File

@ -1,4 +0,0 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
</configuration>

View File

@ -1,33 +0,0 @@
DELETE FROM "system_dept";
DELETE FROM "system_dict_data";
DELETE FROM "system_role";
DELETE FROM "system_role_menu";
DELETE FROM "system_menu";
DELETE FROM "system_user_role";
DELETE FROM "system_dict_type";
DELETE FROM "system_user_session";
DELETE FROM "system_post";
DELETE FROM "system_user_post";
DELETE FROM "system_notice";
DELETE FROM "system_login_log";
DELETE FROM "system_operate_log";
DELETE FROM "system_users";
DELETE FROM "system_sms_channel";
DELETE FROM "system_sms_template";
DELETE FROM "system_sms_log";
DELETE FROM "system_sms_code";
DELETE FROM "system_social_client";
DELETE FROM "system_social_user";
DELETE FROM "system_social_user_bind";
DELETE FROM "system_tenant";
DELETE FROM "system_tenant_package";
DELETE FROM "system_oauth2_client";
DELETE FROM "system_oauth2_approve";
DELETE FROM "system_oauth2_access_token";
DELETE FROM "system_oauth2_refresh_token";
DELETE FROM "system_oauth2_code";
DELETE FROM "system_mail_account";
DELETE FROM "system_mail_template";
DELETE FROM "system_mail_log";
DELETE FROM "system_notify_template";
DELETE FROM "system_notify_message";

View File

@ -1,614 +0,0 @@
CREATE TABLE IF NOT EXISTS "system_dept" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(30) NOT NULL DEFAULT '',
"parent_id" bigint NOT NULL DEFAULT '0',
"sort" int NOT NULL DEFAULT '0',
"leader_user_id" bigint DEFAULT NULL,
"phone" varchar(11) DEFAULT NULL,
"email" varchar(50) DEFAULT NULL,
"status" tinyint NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '部门表';
CREATE TABLE IF NOT EXISTS "system_dict_data" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"sort" int NOT NULL DEFAULT '0',
"label" varchar(100) NOT NULL DEFAULT '',
"value" varchar(100) NOT NULL DEFAULT '',
"dict_type" varchar(100) NOT NULL DEFAULT '',
"status" tinyint NOT NULL DEFAULT '0',
"color_type" varchar(100) NOT NULL DEFAULT '',
"css_class" varchar(100) NOT NULL DEFAULT '',
"remark" varchar(500) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '字典数据表';
CREATE TABLE IF NOT EXISTS "system_role" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(30) NOT NULL,
"code" varchar(100) NOT NULL,
"sort" int NOT NULL,
"data_scope" tinyint NOT NULL DEFAULT '1',
"data_scope_dept_ids" varchar(500) NOT NULL DEFAULT '',
"status" tinyint NOT NULL,
"type" tinyint NOT NULL,
"remark" varchar(500) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '角色信息表';
CREATE TABLE IF NOT EXISTS "system_role_menu" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"role_id" bigint NOT NULL,
"menu_id" bigint NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '角色和菜单关联表';
CREATE TABLE IF NOT EXISTS "system_menu" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(50) NOT NULL,
"permission" varchar(100) NOT NULL DEFAULT '',
"type" tinyint NOT NULL,
"sort" int NOT NULL DEFAULT '0',
"parent_id" bigint NOT NULL DEFAULT '0',
"path" varchar(200) DEFAULT '',
"icon" varchar(100) DEFAULT '#',
"component" varchar(255) DEFAULT NULL,
"component_name" varchar(255) DEFAULT NULL,
"status" tinyint NOT NULL DEFAULT '0',
"visible" bit NOT NULL DEFAULT TRUE,
"keep_alive" bit NOT NULL DEFAULT TRUE,
"always_show" bit NOT NULL DEFAULT TRUE,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '菜单权限表';
CREATE TABLE IF NOT EXISTS "system_user_role" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"role_id" bigint NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp DEFAULT NULL,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp DEFAULT NULL,
"deleted" bit DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '用户和角色关联表';
CREATE TABLE IF NOT EXISTS "system_dict_type" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(100) NOT NULL DEFAULT '',
"type" varchar(100) NOT NULL DEFAULT '',
"status" tinyint NOT NULL DEFAULT '0',
"remark" varchar(500) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"deleted_time" timestamp NOT NULL,
PRIMARY KEY ("id")
) COMMENT '字典类型表';
CREATE TABLE IF NOT EXISTS `system_user_session` (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`token` varchar(32) NOT NULL,
`user_id` bigint DEFAULT NULL,
"user_type" tinyint NOT NULL,
`username` varchar(50) NOT NULL DEFAULT '',
`user_ip` varchar(50) DEFAULT NULL,
`user_agent` varchar(512) DEFAULT NULL,
`session_timeout` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) DEFAULT '' ,
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY (`id`)
) COMMENT '用户在线 Session';
CREATE TABLE IF NOT EXISTS "system_post" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"code" varchar(64) NOT NULL,
"name" varchar(50) NOT NULL,
"sort" integer NOT NULL,
"status" tinyint NOT NULL,
"remark" varchar(500) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '岗位信息表';
CREATE TABLE IF NOT EXISTS `system_user_post`(
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint DEFAULT NULL,
"post_id" bigint DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY (`id`)
) COMMENT ='用户岗位表';
CREATE TABLE IF NOT EXISTS "system_notice" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"title" varchar(50) NOT NULL COMMENT '公告标题',
"content" text NOT NULL COMMENT '公告内容',
"type" tinyint NOT NULL COMMENT '公告类型1通知 2公告',
"status" tinyint NOT NULL DEFAULT '0' COMMENT '公告状态0正常 1关闭',
"creator" varchar(64) DEFAULT '' COMMENT '创建者',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
"updater" varchar(64) DEFAULT '' COMMENT '更新者',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
"deleted" bit NOT NULL DEFAULT 0 COMMENT '是否删除',
"tenant_id" bigint not null default '0',
PRIMARY KEY("id")
) COMMENT '通知公告表';
CREATE TABLE IF NOT EXISTS `system_login_log` (
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`log_type` bigint(4) NOT NULL,
"user_id" bigint not null default '0',
"user_type" tinyint NOT NULL,
`trace_id` varchar(64) NOT NULL DEFAULT '',
`username` varchar(50) NOT NULL DEFAULT '',
`result` tinyint(4) NOT NULL,
`user_ip` varchar(50) NOT NULL,
`user_agent` varchar(512) NOT NULL,
`creator` varchar(64) DEFAULT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) DEFAULT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted` bit(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) COMMENT ='系统访问记录';
CREATE TABLE IF NOT EXISTS `system_operate_log` (
`id` bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY,
`trace_id` varchar(64) NOT NULL DEFAULT '',
`user_id` bigint(20) NOT NULL,
"user_type" tinyint not null default '0',
`type` varchar(50) NOT NULL,
`sub_type` varchar(50) NOT NULL,
`biz_id` bigint(20) NOT NULL,
`action` varchar(2000) NOT NULL DEFAULT '',
`extra` varchar(512) NOT NULL DEFAULT '',
`request_method` varchar(16) DEFAULT '',
`request_url` varchar(255) DEFAULT '',
`user_ip` varchar(50) DEFAULT NULL,
`user_agent` varchar(200) DEFAULT NULL,
`creator` varchar(64) DEFAULT '',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updater` varchar(64) DEFAULT '',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted` bit(1) NOT NULL DEFAULT '0',
"tenant_id" bigint not null default '0',
PRIMARY KEY (`id`)
) COMMENT ='操作日志记录';
CREATE TABLE IF NOT EXISTS "system_users" (
"id" bigint not null GENERATED BY DEFAULT AS IDENTITY,
"username" varchar(30) not null,
"password" varchar(100) not null default '',
"nickname" varchar(30) not null,
"remark" varchar(500) default null,
"dept_id" bigint default null,
"post_ids" varchar(255) default null,
"email" varchar(50) default '',
"mobile" varchar(11) default '',
"sex" tinyint default '0',
"avatar" varchar(100) default '',
"status" tinyint not null default '0',
"login_ip" varchar(50) default '',
"login_date" timestamp default null,
"creator" varchar(64) default '',
"create_time" timestamp not null default current_timestamp,
"updater" varchar(64) default '',
"update_time" timestamp not null default current_timestamp,
"deleted" bit not null default false,
"tenant_id" bigint not null default '0',
primary key ("id")
) comment '用户信息表';
CREATE TABLE IF NOT EXISTS "system_sms_channel" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"signature" varchar(10) NOT NULL,
"code" varchar(63) NOT NULL,
"status" tinyint NOT NULL,
"remark" varchar(255) DEFAULT NULL,
"api_key" varchar(63) NOT NULL,
"api_secret" varchar(63) DEFAULT NULL,
"callback_url" varchar(255) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '短信渠道';
CREATE TABLE IF NOT EXISTS "system_sms_template" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"type" tinyint NOT NULL,
"status" tinyint NOT NULL,
"code" varchar(63) NOT NULL,
"name" varchar(63) NOT NULL,
"content" varchar(255) NOT NULL,
"params" varchar(255) NOT NULL,
"remark" varchar(255) DEFAULT NULL,
"api_template_id" varchar(63) NOT NULL,
"channel_id" bigint NOT NULL,
"channel_code" varchar(63) NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '短信模板';
CREATE TABLE IF NOT EXISTS "system_sms_log" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"channel_id" bigint NOT NULL,
"channel_code" varchar(63) NOT NULL,
"template_id" bigint NOT NULL,
"template_code" varchar(63) NOT NULL,
"template_type" tinyint NOT NULL,
"template_content" varchar(255) NOT NULL,
"template_params" varchar(255) NOT NULL,
"api_template_id" varchar(63) NOT NULL,
"mobile" varchar(11) NOT NULL,
"user_id" bigint DEFAULT '0',
"user_type" tinyint DEFAULT '0',
"send_status" tinyint NOT NULL DEFAULT '0',
"send_time" timestamp DEFAULT NULL,
"send_code" int DEFAULT NULL,
"send_msg" varchar(255) DEFAULT NULL,
"api_send_code" varchar(63) DEFAULT NULL,
"api_send_msg" varchar(255) DEFAULT NULL,
"api_request_id" varchar(255) DEFAULT NULL,
"api_serial_no" varchar(255) DEFAULT NULL,
"receive_status" tinyint NOT NULL DEFAULT '0',
"receive_time" timestamp DEFAULT NULL,
"api_receive_code" varchar(63) DEFAULT NULL,
"api_receive_msg" varchar(255) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '短信日志';
CREATE TABLE IF NOT EXISTS "system_sms_code" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"mobile" varchar(11) NOT NULL,
"code" varchar(11) NOT NULL,
"scene" bigint NOT NULL,
"create_ip" varchar NOT NULL,
"today_index" int NOT NULL,
"used" bit NOT NULL DEFAULT FALSE,
"used_time" timestamp DEFAULT NULL,
"used_ip" varchar NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '短信日志';
CREATE TABLE IF NOT EXISTS "system_social_client" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(255) NOT NULL,
"social_type" int NOT NULL,
"user_type" int NOT NULL,
"client_id" varchar(255) NOT NULL,
"client_secret" varchar(255) NOT NULL,
"agent_id" varchar(255) NOT NULL,
"status" int NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '社交客户端表';
CREATE TABLE IF NOT EXISTS "system_social_user" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"type" tinyint NOT NULL,
"openid" varchar(64) NOT NULL,
"token" varchar(256) DEFAULT NULL,
"raw_token_info" varchar(1024) NOT NULL,
"nickname" varchar(32) NOT NULL,
"avatar" varchar(255) DEFAULT NULL,
"raw_user_info" varchar(1024) NOT NULL,
"code" varchar(64) NOT NULL,
"state" varchar(64),
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '社交用户';
CREATE TABLE IF NOT EXISTS "system_social_user_bind" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" tinyint NOT NULL,
"social_type" tinyint NOT NULL,
"social_user_id" number NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '社交用户的绑定';
CREATE TABLE IF NOT EXISTS "system_tenant" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(63) NOT NULL,
"contact_user_id" bigint NOT NULL DEFAULT '0',
"contact_name" varchar(255) NOT NULL,
"contact_mobile" varchar(255),
"status" tinyint NOT NULL,
"website" varchar(63) DEFAULT '',
"package_id" bigint NOT NULL,
"expire_time" timestamp NOT NULL,
"account_count" int NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '租户';
CREATE TABLE IF NOT EXISTS "system_tenant_package" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar(30) NOT NULL,
"status" tinyint NOT NULL,
"remark" varchar(256),
"menu_ids" varchar(2048) NOT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '租户套餐表';
CREATE TABLE IF NOT EXISTS "system_oauth2_client" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"client_id" varchar NOT NULL,
"secret" varchar NOT NULL,
"name" varchar NOT NULL,
"logo" varchar NOT NULL,
"description" varchar,
"status" int NOT NULL,
"access_token_validity_seconds" int NOT NULL,
"refresh_token_validity_seconds" int NOT NULL,
"redirect_uris" varchar NOT NULL,
"authorized_grant_types" varchar NOT NULL,
"scopes" varchar NOT NULL DEFAULT '',
"auto_approve_scopes" varchar NOT NULL DEFAULT '',
"authorities" varchar NOT NULL DEFAULT '',
"resource_ids" varchar NOT NULL DEFAULT '',
"additional_information" varchar NOT NULL DEFAULT '',
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT 'OAuth2 客户端表';
CREATE TABLE IF NOT EXISTS "system_oauth2_approve" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" tinyint NOT NULL,
"client_id" varchar NOT NULL,
"scope" varchar NOT NULL,
"approved" bit NOT NULL DEFAULT FALSE,
"expires_time" datetime NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT 'OAuth2 批准表';
CREATE TABLE IF NOT EXISTS "system_oauth2_access_token" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" tinyint NOT NULL,
"user_info" varchar NOT NULL,
"access_token" varchar NOT NULL,
"refresh_token" varchar NOT NULL,
"client_id" varchar NOT NULL,
"scopes" varchar NOT NULL,
"approved" bit NOT NULL DEFAULT FALSE,
"expires_time" datetime NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint NOT NULL,
PRIMARY KEY ("id")
) COMMENT 'OAuth2 访问令牌';
CREATE TABLE IF NOT EXISTS "system_oauth2_refresh_token" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" tinyint NOT NULL,
"refresh_token" varchar NOT NULL,
"client_id" varchar NOT NULL,
"scopes" varchar NOT NULL,
"approved" bit NOT NULL DEFAULT FALSE,
"expires_time" datetime NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT 'OAuth2 刷新令牌';
CREATE TABLE IF NOT EXISTS "system_oauth2_code" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" tinyint NOT NULL,
"code" varchar NOT NULL,
"client_id" varchar NOT NULL,
"scopes" varchar NOT NULL,
"expires_time" datetime NOT NULL,
"redirect_uri" varchar NOT NULL,
"state" varchar NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT 'OAuth2 刷新令牌';
CREATE TABLE IF NOT EXISTS "system_mail_account" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"mail" varchar NOT NULL,
"username" varchar NOT NULL,
"password" varchar NOT NULL,
"host" varchar NOT NULL,
"port" int NOT NULL,
"ssl_enable" bit NOT NULL,
"starttls_enable" bit NOT NULL,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '邮箱账号表';
CREATE TABLE IF NOT EXISTS "system_mail_template" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar NOT NULL,
"code" varchar NOT NULL,
"account_id" bigint NOT NULL,
"nickname" varchar,
"title" varchar NOT NULL,
"content" varchar NOT NULL,
"params" varchar NOT NULL,
"status" varchar NOT NULL,
"remark" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '邮件模版表';
CREATE TABLE IF NOT EXISTS "system_mail_log" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint,
"user_type" varchar,
"to_mail" varchar NOT NULL,
"account_id" bigint NOT NULL,
"from_mail" varchar NOT NULL,
"template_id" bigint NOT NULL,
"template_code" varchar NOT NULL,
"template_nickname" varchar,
"template_title" varchar NOT NULL,
"template_content" varchar NOT NULL,
"template_params" varchar NOT NULL,
"send_status" varchar NOT NULL,
"send_time" datetime,
"send_message_id" varchar,
"send_exception" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '邮件日志表';
-- 将该建表 SQL 语句,添加到 hangtag-module-system-biz 模块的 test/resources/sql/create_tables.sql 文件里
CREATE TABLE IF NOT EXISTS "system_notify_template" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"name" varchar NOT NULL,
"code" varchar NOT NULL,
"nickname" varchar NOT NULL,
"content" varchar NOT NULL,
"type" varchar NOT NULL,
"params" varchar,
"status" varchar NOT NULL,
"remark" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '站内信模板表';
CREATE TABLE IF NOT EXISTS "system_notify_message" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"user_type" varchar NOT NULL,
"template_id" bigint NOT NULL,
"template_code" varchar NOT NULL,
"template_nickname" varchar NOT NULL,
"template_content" varchar NOT NULL,
"template_type" int NOT NULL,
"template_params" varchar NOT NULL,
"read_status" bit NOT NULL,
"read_time" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '站内信消息表';

View File

@ -1,203 +0,0 @@
server:
port: 48080
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
autoconfigure:
exclude:
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
datasource:
druid: # Druid 【监控】相关的全局配置
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
allow: # 设置白名单,不填则允许所有访问
url-pattern: /druid/*
login-username: # 控制台管理用户名和密码
login-password:
filter:
stat:
enabled: true
log-slow-sql: true # 慢 SQL 记录
slow-sql-millis: 100
merge-sql: true
wall:
config:
multi-statement-allow: true
dynamic: # 多数据源配置
druid: # Druid 【连接池】相关的全局配置
initial-size: 5 # 初始连接数
min-idle: 10 # 最小连接池数量
max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
validation-query: SELECT 1 # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
primary: master
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: Admin11039
# slave: # 模拟从库,可根据自己需要修改 # 模拟从库,可根据自己需要修改
# lazy: true # 开启懒加载,保证启动速度
# url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# username: root
# password: 123456
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 400-infra.server.iocoder.cn # 地址
port: 6379 # 端口
database: 1 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
--- #################### 定时任务相关配置 ####################
# Quartz 配置项,对应 QuartzProperties 配置类
spring:
quartz:
auto-startup: true # 测试环境,需要开启 Job
scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
org:
quartz:
# Scheduler 相关配置
scheduler:
instanceName: schedulerName
instanceId: AUTO # 自动生成 instance ID
# JobStore 相关配置
jobStore:
# JobStore 实现类。可见博客https://blog.csdn.net/weixin_42458219/article/details/122247162
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
isClustered: true # 是集群模式
clusterCheckinInterval: 15000 # 集群检查频率,单位:毫秒。默认为 15000即 15 秒
misfireThreshold: 60000 # misfire 阀值,单位:毫秒。
# 线程池相关配置
threadPool:
threadCount: 25 # 线程池大小。默认为 10 。
threadPriority: 5 # 线程优先级
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
jdbc: # 使用 JDBC 的 JobStore 的时候JDBC 的配置
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
--- #################### 消息队列相关 ####################
# rocketmq 配置项,对应 RocketMQProperties 配置类
rocketmq:
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: guest # RabbitMQ 服务的账号
password: guest # RabbitMQ 服务的密码
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
# Spring Boot Admin 配置项
spring:
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# Spring Boot Admin Server 服务端的相关配置
context-path: /admin # 配置 Spring
# 日志文件配置
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
--- #################### 微信公众号相关配置 ####################
wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
mp:
# 公众号配置(必填)
app-id: wx041349c6f39b268b
secret: 5abee519483bc9f8cb37ce280e814bd0
# 存储配置,解决 AccessToken 的跨节点的共享
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wx # Redis Key 的前缀
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
appid: wx63c280fe3248a3e7
secret: 6f270509224a7ae1296bbf1c8cb97aed
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wa # Redis Key 的前缀
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
hangtag:
xss:
enable: false
exclude-urls: # 如下两个 url仅仅是为了演示去掉配置也没关系
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
pay:
order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
demo: true # 开启演示模式
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
justauth:
enabled: true
type:
DINGTALK: # 钉钉
client-id: dingvrnreaje3yqvzhxg
client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
ignore-check-redirect-uri: true
WECHAT_ENTERPRISE: # 企业微信
client-id: wwd411c69a39ad2e54
client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
agent-id: 1000004
ignore-check-redirect-uri: true
# noinspection SpringBootApplicationYaml
WECHAT_MINI_APP: # 微信小程序
client-id: ${wx.miniapp.appid}
client-secret: ${wx.miniapp.secret}
ignore-check-redirect-uri: true
ignore-check-state: true # 微信小程序,不会使用到 state所以不进行校验
WECHAT_MP: # 微信公众号
client-id: ${wx.mp.app-id}
client-secret: ${wx.mp.secret}
ignore-check-redirect-uri: true
cache:
type: REDIS
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟

View File

@ -1,242 +0,0 @@
server:
port: 48080
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
autoconfigure:
exclude:
- com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
- org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
- de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
- de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置
- de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
datasource:
druid: # Druid 【监控】相关的全局配置
web-stat-filter:
enabled: true
stat-view-servlet:
enabled: true
allow: # 设置白名单,不填则允许所有访问
url-pattern: /druid/*
login-username: # 控制台管理用户名和密码
login-password:
filter:
stat:
enabled: true
log-slow-sql: true # 慢 SQL 记录
slow-sql-millis: 100
merge-sql: true
wall:
config:
multi-statement-allow: true
dynamic: # 多数据源配置
druid: # Druid 【连接池】相关的全局配置
initial-size: 1 # 初始连接数
min-idle: 1 # 最小连接池数量
max-active: 20 # 最大连接池数量
max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
test-while-idle: true
test-on-borrow: false
test-on-return: false
primary: master
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/hangtag?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
username: root
password: 123456
# slave: # 模拟从库,可根据自己需要修改
# lazy: true # 开启懒加载,保证启动速度
# url: jdbc:mysql://43.136.71.164:3306/hangtag?allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=UTF-8
# username: test
# password: test@123
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 0 # 数据库索引
# password: dev # 密码,建议生产环境开启
--- #################### 定时任务相关配置 ####################
# Quartz 配置项,对应 QuartzProperties 配置类
spring:
quartz:
auto-startup: true # 本地开发环境,尽量不要开启 Job
scheduler-name: schedulerName # Scheduler 名字。默认为 schedulerName
job-store-type: jdbc # Job 存储器类型。默认为 memory 表示内存,可选 jdbc 使用数据库。
wait-for-jobs-to-complete-on-shutdown: true # 应用关闭时,是否等待定时任务执行完成。默认为 false ,建议设置为 true
properties: # 添加 Quartz Scheduler 附加属性,更多可以看 http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 文档
org:
quartz:
# Scheduler 相关配置
scheduler:
instanceName: schedulerName
instanceId: AUTO # 自动生成 instance ID
# JobStore 相关配置
jobStore:
# JobStore 实现类。可见博客https://blog.csdn.net/weixin_42458219/article/details/122247162
class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
isClustered: true # 是集群模式
clusterCheckinInterval: 15000 # 集群检查频率,单位:毫秒。默认为 15000即 15 秒
misfireThreshold: 60000 # misfire 阀值,单位:毫秒。
# 线程池相关配置
threadPool:
threadCount: 25 # 线程池大小。默认为 10 。
threadPriority: 5 # 线程优先级
class: org.quartz.simpl.SimpleThreadPool # 线程池类型
jdbc: # 使用 JDBC 的 JobStore 的时候JDBC 的配置
initialize-schema: NEVER # 是否自动使用 SQL 初始化 Quartz 表结构。这里设置成 never ,我们手动创建表结构。
--- #################### 消息队列相关 ####################
# rocketmq 配置项,对应 RocketMQProperties 配置类
rocketmq:
name-server: 127.0.0.1:9876 # RocketMQ Namesrv
spring:
# RabbitMQ 配置项,对应 RabbitProperties 配置类
rabbitmq:
host: 127.0.0.1 # RabbitMQ 服务的地址
port: 5672 # RabbitMQ 服务的端口
username: rabbit # RabbitMQ 服务的账号
password: rabbit # RabbitMQ 服务的密码
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
bootstrap-servers: 127.0.0.1:9092 # 指定 Kafka Broker 地址,可以设置多个,以逗号分隔
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
# Spring Boot Admin 配置项
spring:
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server 地址
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# Spring Boot Admin Server 服务端的相关配置
context-path: /admin # 配置 Spring
# 日志文件配置
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
level:
# 配置自己写的 MyBatis Mapper 打印日志
cn.hangtag.module.bpm.dal.mysql: debug
cn.hangtag.module.infra.dal.mysql: debug
cn.hangtag.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 配置 ApiErrorLogMapper 的日志级别为 info避免和 GlobalExceptionHandler 重复打印
cn.hangtag.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info
cn.hangtag.module.infra.dal.mysql.file.FileConfigMapper: INFO # 配置 FileConfigMapper 的日志级别为 info
cn.hangtag.module.pay.dal.mysql: debug
cn.hangtag.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 PayNotifyTaskMapper 的日志级别为 info
cn.hangtag.module.system.dal.mysql: debug
cn.hangtag.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
cn.hangtag.module.tool.dal.mysql: debug
cn.hangtag.module.member.dal.mysql: debug
cn.hangtag.module.trade.dal.mysql: debug
cn.hangtag.module.promotion.dal.mysql: debug
cn.hangtag.module.statistics.dal.mysql: debug
cn.hangtag.module.crm.dal.mysql: debug
cn.hangtag.module.erp.dal.mysql: debug
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿先禁用Spring Boot 3.X 存在部分错误的 WARN 提示
debug: false
--- #################### 微信公众号、小程序相关配置 ####################
wx:
mp: # 公众号配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
# app-id: wx041349c6f39b268b # 测试号(牛希尧提供的)
# secret: 5abee519483bc9f8cb37ce280e814bd0
app-id: wx5b23ba7a5589ecbb # 测试号(自己的)
secret: 2a7b3b20c537e52e74afd395eb85f61f
# app-id: wxa69ab825b163be19 # 测试号Kongdy 提供的)
# secret: bd4f9fab889591b62aeac0d7b8d8b4a0
# 存储配置,解决 AccessToken 的跨节点的共享
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wx # Redis Key 的前缀
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档
# appid: wx62056c0d5e8db250 # 测试号(牛希尧提供的)
# secret: 333ae72f41552af1e998fe1f54e1584a
appid: wx63c280fe3248a3e7 # wenhualian的接口测试号
secret: 6f270509224a7ae1296bbf1c8cb97aed
# appid: wxc4598c446f8a9cb3 # 测试号Kongdy 提供的)
# secret: 4a1a04e07f6a4a0751b39c3064a92c8b
config-storage:
type: RedisTemplate # 采用 RedisTemplate 操作 Redis会自动从 Spring 中获取
key-prefix: wa # Redis Key 的前缀
http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
--- #################### 芋道相关配置 ####################
# 芋道配置项,设置当前项目所有自定义的配置
hangtag:
captcha:
enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
security:
mock-enable: true
xss:
enable: false
exclude-urls: # 如下两个 url仅仅是为了演示去掉配置也没关系
- ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
pay:
order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
access-log: # 访问日志的配置项
enable: false
demo: false # 关闭演示模式
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
justauth:
enabled: true
type:
DINGTALK: # 钉钉
client-id: dingvrnreaje3yqvzhxg
client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
ignore-check-redirect-uri: true
WECHAT_ENTERPRISE: # 企业微信
client-id: wwd411c69a39ad2e54
client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
agent-id: 1000004
ignore-check-redirect-uri: true
# noinspection SpringBootApplicationYaml
WECHAT_MINI_APP: # 微信小程序
client-id: ${wx.miniapp.appid}
client-secret: ${wx.miniapp.secret}
ignore-check-redirect-uri: true
ignore-check-state: true # 微信小程序,不会使用到 state所以不进行校验
WECHAT_MP: # 微信公众号
client-id: ${wx.mp.app-id}
client-secret: ${wx.mp.secret}
ignore-check-redirect-uri: true
cache:
type: REDIS
prefix: 'social_auth_state:' # 缓存前缀,目前只对 Redis 缓存生效,默认 JUSTAUTH::STATE::
timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟

View File

@ -1,276 +0,0 @@
# 本地文件上传配置
#localupload:
# port: 18080
# domain: http://127.0.0.1
spring:
application:
name: hangtag-server
profiles:
active: local
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
# Servlet 配置
servlet:
# 文件上传相关配置项
multipart:
max-file-size: 16MB # 单个文件大小
max-request-size: 32MB # 设置总上传的文件大小
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
# throw-exception-if-no-handler-found: true # 404 错误时抛出异常,方便统一处理
# static-path-pattern: /static/** # 静态资源路径; 注意:如果不配置,则 throw-exception-if-no-handler-found 不生效!!! TODO 芋艿:不能配置,会导致 swagger 不生效
# Jackson 配置项
jackson:
serialization:
write-dates-as-timestamps: true # 设置 Date 的格式,使用时间戳
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
fail-on-empty-beans: false # 允许序列化无属性的 Bean
# Cache 配置项
cache:
type: REDIS
redis:
time-to-live: 1h # 设置过期时间为 1 小时
thymeleaf:
prefix: classpath:/templates/
suffix: .html
mode: HTML
encoding: UTF-8
cache: false
--- #################### 接口文档配置 ####################
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
swagger-ui:
enabled: true
path: /swagger-ui
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
knife4j:
enable: true
setting:
language: zh_cn
# 工作流 Flowable 配置
flowable:
# 1. false: 默认值Flowable 启动时,对比数据库表中保存的版本,如果不匹配。将抛出异常
# 2. true: 启动时会对数据库中所有表进行更新操作,如果表存在,不做处理,反之,自动创建表
# 3. create_drop: 启动时自动创建表,关闭时自动删除表
# 4. drop_create: 启动时,删除旧表,再创建新表
database-schema-update: true # 设置为 false可通过 https://github.com/flowable/flowable-sql 初始化
db-history-used: true # flowable6 默认 true 生成信息表,无需手动设置
check-process-definitions: false # 设置为 false禁用 /resources/processes 自动部署 BPMN XML 流程
history-level: audit # full保存历史数据的最高级别可保存全部流程相关细节包括流程流转各节点参数
# MyBatis Plus 的配置项
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: NONE # “智能”模式,基于 IdTypeEnvironmentPostProcessor + 数据源的类型,自动适配成 AUTO、INPUT 模式。
# id-type: AUTO # 自增 ID适合 MySQL 等直接自增的数据库
# id-type: INPUT # 用户输入 ID适合 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库
# id-type: ASSIGN_ID # 分配 ID默认使用雪花算法。注意Oracle、PostgreSQL、Kingbase、DB2、H2 数据库时,需要去除实体类上的 @KeySequence 注解
# logic-delete-value: 1 # 逻辑已删除值(默认为 1)
# logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
banner: false # 关闭控制台的 Banner 打印
type-aliases-package: ${hangtag.info.base-package}.module.*.dal.dataobject
encryptor:
password: xwlVOxFax2o+OOVQksI7Ie9A # 加解密的秘钥,可使用 https://www.imaegoo.com/2020/aes-key-generator/ 网站生成
mybatis-plus-join:
banner: false # 是否打印 mybatis plus join banner默认true
sub-table-logic: true # 全局启用副表逻辑删除默认true。关闭后关联查询不会加副表逻辑删除
ms-cache: true # 拦截器MappedStatement缓存默认 true
table-alias: t # 表别名(默认 t)
logic-del-type: on # 副表逻辑删除条件的位置,支持 WHERE、ON默认 ON
# Spring Data Redis 配置
spring:
data:
redis:
repositories:
enabled: false # 项目未使用到 Spring Data Redis 的 Repository所以直接禁用保证启动速度
# VO 转换(数据翻译)相关
easy-trans:
is-enable-global: true # 启用全局翻译(拦截所有 SpringMVC ResponseBody 进行自动翻译 )。如果对于性能要求很高可关闭此配置,或通过 @IgnoreTrans 忽略某个接口
is-enable-cloud: false # 禁用 TransType.RPC 微服务模式
--- #################### 验证码相关配置 ####################
aj:
captcha:
jigsaw: classpath:images/jigsaw # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
pic-click: classpath:images/pic-click # 滑动验证,底图路径,不配置将使用默认图片;以 classpath: 开头,取 resource 目录下路径
cache-type: redis # 缓存 local/redis...
cache-number: 1000 # local 缓存的阈值,达到这个值,清除缓存
timing-clear: 180 # local定时清除过期缓存(单位秒),设置为0代表不执行
type: blockPuzzle # 验证码类型 default两种都实例化。 blockPuzzle 滑块拼图 clickWord 文字点选
water-mark: 芋道源码 # 右下角水印文字(我的水印),可使用 https://tool.chinaz.com/tools/unicode.aspx 中文转 UnicodeLinux 可能需要转 unicode
interference-options: 0 # 滑动干扰项(0/1/2)
req-frequency-limit-enable: false # 接口请求次数一分钟限制是否开启 true|false
req-get-lock-limit: 5 # 验证失败 5 次get接口锁定
req-get-lock-seconds: 10 # 验证失败后,锁定时间间隔
req-get-minute-limit: 30 # get 接口一分钟内请求数限制
req-check-minute-limit: 60 # check 接口一分钟内请求数限制
req-verify-minute-limit: 60 # verify 接口一分钟内请求数限制
--- #################### 消息队列相关 ####################
# rocketmq 配置项,对应 RocketMQProperties 配置类
rocketmq:
# Producer 配置项
producer:
group: ${spring.application.name}_PRODUCER # 生产者分组
spring:
# Kafka 配置项,对应 KafkaProperties 配置类
kafka:
# Kafka Producer 配置项
producer:
acks: 1 # 0-不应答。1-leader 应答。all-所有 leader 和 follower 应答。
retries: 3 # 发送失败时,重试发送的次数
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer # 消息的 value 的序列化
# Kafka Consumer 配置项
consumer:
auto-offset-reset: earliest # 设置消费者分组最初的消费进度为 earliest 。可参考博客 https://blog.csdn.net/lishuangzhe7047/article/details/74530417 理解
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring.json.trusted.packages: '*'
# Kafka Consumer Listener 监听器配置
listener:
missing-topics-fatal: false # 消费监听接口监听的主题不存在时,默认会报错。所以通过设置为 false ,解决报错
--- #################### 芋道相关配置 ####################
hangtag:
info:
version: 1.0.0
base-package: cn.hangtag
web:
admin-ui:
url: http://dashboard.hangtag.iocoder.cn # Admin 管理后台 UI 的地址
security:
permit-all_urls:
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,不需要登录
websocket:
enable: true # websocket的开关
path: /infra/ws # 路径
sender-type: local # 消息发送的类型,可选值为 local、redis、rocketmq、kafka、rabbitmq
sender-rocketmq:
topic: ${spring.application.name}-websocket # 消息发送的 RocketMQ Topic
consumer-group: ${spring.application.name}-websocket-consumer # 消息发送的 RocketMQ Consumer Group
sender-rabbitmq:
exchange: ${spring.application.name}-websocket-exchange # 消息发送的 RabbitMQ Exchange
queue: ${spring.application.name}-websocket-queue # 消息发送的 RabbitMQ Queue
sender-kafka:
topic: ${spring.application.name}-websocket # 消息发送的 Kafka Topic
consumer-group: ${spring.application.name}-websocket-consumer # 消息发送的 Kafka Consumer Group
swagger:
title: 芋道快速开发平台
description: 提供管理后台、用户 App 的所有功能
version: ${hangtag.info.version}
url: ${hangtag.web.admin-ui.url}
email: xingyu4j@vip.qq.com
license: MIT
license-url: https://gitee.com/zhijiantianya/ruoyi-vue-pro/blob/master/LICENSE
captcha:
enable: true # 验证码的开关,默认为 true
codegen:
base-package: ${hangtag.info.base-package}
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
front-type: 10 # 前端模版的类型,参见 CodegenFrontTypeEnum 枚举类
tenant: # 多租户相关配置项
enable: true
ignore-urls:
- /admin-api/system/tenant/get-id-by-name # 基于名字获取租户,不许带租户编号
- /admin-api/system/tenant/get-by-website # 基于域名获取租户,不许带租户编号
- /admin-api/system/captcha/get # 获取图片验证码,和租户无关
- /admin-api/system/captcha/check # 校验图片验证码,和租户无关
- /admin-api/infra/file/*/get/** # 获取图片,和租户无关
- /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
- /admin-api/pay/notify/** # 支付回调通知,不携带租户编号
- /jmreport/* # 积木报表,无法携带租户编号
- /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号
ignore-tables:
- system_tenant
- system_tenant_package
- system_dict_data
- system_dict_type
- system_error_code
- system_menu
- system_sms_channel
- system_sms_template
- system_sms_log
- system_sensitive_word
- system_oauth2_client
- system_mail_account
- system_mail_template
- system_mail_log
- system_notify_template
- infra_codegen_column
- infra_codegen_table
- infra_config
- infra_file_config
- infra_file
- infra_file_content
- infra_job
- infra_job_log
- infra_job_log
- infra_data_source_config
- jimu_dict
- jimu_dict_item
- jimu_report
- jimu_report_data_source
- jimu_report_db
- jimu_report_db_field
- jimu_report_db_param
- jimu_report_link
- jimu_report_map
- jimu_report_share
- rep_demo_dxtj
- rep_demo_employee
- rep_demo_gongsi
- rep_demo_jianpiao
- tmp_report_data_1
- tmp_report_data_income
sms-code: # 短信验证码相关的配置项
expire-times: 10m
send-frequency: 1m
send-maximum-quantity-per-day: 10
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
trade:
order:
app-id: 1 # 商户编号
pay-expire-time: 2h # 支付的过期时间
receive-expire-time: 14d # 收货的过期时间
comment-expire-time: 7d # 评论的过期时间
express:
client: kd_niao
kd-niao:
api-key: cb022f1e-48f1-4c4a-a723-9001ac9676b8
business-id: 1809751
kd100:
key: pLXUGAwK5305
customer: E77DF18BE109F454A5CD319E44BF5177
debug: false
# 积木报表配置
jeecg:
jmreport:
saas-mode: tenant

View File

@ -1,76 +0,0 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 hangtag.info.base-package基础业务包 -->
<springProperty scope="context" name="hangtag.info.base-package" source="hangtag.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration>

View File

@ -2,6 +2,7 @@ import request from '@/config/axios'
// 销售订单 VO
export interface SaleOrderVO {
id: number // 客户id
customerId: number // 客户id
bizdate: Date // 业务日期
remark: string // 备注
@ -89,6 +90,19 @@ export const SaleOrderApi = {
})
},
// 修改订单地址
updateOrderAddress: async (data: any) => {
return await request.put({ url: `/oms/sale-order/update-address`, data })
},
// 订单备注
updateOrderRemark: async (data: any) => {
return await request.put({ url: `/oms/sale-order/update-remark`, data })
},
// 更新分录数据
updateOrderEntrys: async (data: SaleOrderVO) => {
return await request.put({ url: `/oms/sale-order/update-entrys`, data })
}
}

View File

@ -2,4 +2,6 @@
export interface DataComparisonRespVO<T> {
value: T
reference: T
value2: T
reference2: T
}

View File

@ -16,36 +16,24 @@ export interface TradeTrendReqVO {
times: [dayjs.ConfigType, dayjs.ConfigType]
}
/** 交易状况统计 Response VO */
export interface TradeTrendSummaryRespVO {
time: string
turnoverPrice: number
orderPayPrice: number
rechargePrice: number
expensePrice: number
walletPayPrice: number
brokerageSettlementPrice: number
afterSaleRefundPrice: number
}
/** 交易订单数量 Response VO */
export interface TradeOrderCountRespVO {
/** 待发货 */
undelivered?: number
/** 待核销 */
pickUp?: number
/** 退款中 */
afterSaleApply?: number
/** 提现待审核 */
auditingWithdraw?: number
/** 驳回 */
orderCountAA?: number
/** 待提交 */
orderCountA?: number
/** 提交中 */
orderCountB?: number
/** 已审核 */
orderCountC?: number
}
/** 交易订单统计 Response VO */
export interface TradeOrderSummaryRespVO {
/** 支付订单商品数 */
orderPayCount?: number
orderCount?: number
/** 总支付金额,单位:分 */
orderPayPrice?: number
orderAmount?: number
}
/** 订单量趋势统计 Response VO */
@ -53,30 +41,24 @@ export interface TradeOrderTrendRespVO {
/** 日期 */
date: string
/** 订单数量 */
orderPayCount: number
orderCount: number
/** 订单支付金额 */
orderPayPrice: number
orderAmount: number
}
// 查询交易统计
export const getTradeStatisticsSummary = () => {
return request.get<DataComparisonRespVO<TradeSummaryRespVO>>({
url: '/statistics/trade/summary'
url: '/oms/statistics/trade/summary'
})
}
// 获得交易状况统计
export const getTradeStatisticsAnalyse = (params: TradeTrendReqVO) => {
return request.get<DataComparisonRespVO<TradeTrendSummaryRespVO>>({
url: '/statistics/trade/analyse',
params: formatDateParam(params)
})
}
// 获得交易状况明细
export const getTradeStatisticsList = (params: TradeTrendReqVO) => {
return request.get<TradeTrendSummaryRespVO[]>({
url: '/statistics/trade/list',
url: '/oms/statistics/trade/list',
params: formatDateParam(params)
})
}
@ -84,14 +66,14 @@ export const getTradeStatisticsList = (params: TradeTrendReqVO) => {
// 导出交易状况明细
export const exportTradeStatisticsExcel = (params: TradeTrendReqVO) => {
return request.download({
url: '/statistics/trade/export-excel',
url: '/oms/statistics/trade/export-excel',
params: formatDateParam(params)
})
}
// 获得交易订单数量
export const getOrderCount = async () => {
return await request.get<TradeOrderCountRespVO>({ url: `/statistics/trade/order-count` })
return await request.get<TradeOrderCountRespVO>({ url: `/oms/statistics/trade/order-count` })
}
// 获得交易订单数量对照
@ -108,7 +90,7 @@ export const getOrderCountTrendComparison = (
endTime: dayjs.ConfigType
) => {
return request.get<DataComparisonRespVO<TradeOrderTrendRespVO>[]>({
url: '/statistics/trade/order-count-trend',
url: '/oms/statistics/trade/order-count-trend',
params: { type, beginTime: formatDate(beginTime), endTime: formatDate(endTime) }
})
}

View File

@ -237,11 +237,21 @@ const remainingRouter: AppRouteRecordRaw[] = [
{
path: '/oms/produceorder', // 订单管理
component: Layout,
name: 'ProduceOrderCenter',
name: 'OrderCenter',
meta: {
hidden: true
},
children: [
{
path: 'order/detail/:id(\\d+)',
component: () => import('@/views/oms/saleorder/detail/index.vue'),
name: 'SaleOrderDetail',
meta: {
title: '订单详情',
icon: 'ep:view',
activeMenu: '/oms/saleorder'
}
},
{
path: 'produceorder/add',
component: () => import('@/views/oms/produceorder/form/index.vue'),

View File

@ -1,49 +1,101 @@
<template>
<div class="flex flex-col">
<!--
&lt;!&ndash; 数据对照 &ndash;&gt;
<!-- 数据对照 -->
<el-row :gutter="16" class="row">
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<ComparisonCard
tag="今日"
lasttag="昨日数据"
title="订单量"
:value="orderComparison?.value?.orderPayCount || 0"
:reference="orderComparison?.reference?.orderPayCount || 0"
:value="orderComparison?.value?.orderCount || 0"
:reference="orderComparison?.reference?.orderCount || 0"
/>
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<ComparisonCard
tag="今日"
lasttag="昨日数据"
title="销售额"
prefix="¥"
:decimals="2"
:value="orderComparison?.value?.orderAmount || 0"
:reference="orderComparison?.reference?.orderAmount || 0"
/>
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<ComparisonCard
tag="本周"
lasttag="上周数据"
title="订单量"
:value="orderComparison?.value?.orderPayCount || 0"
:reference="orderComparison?.reference?.orderPayCount || 0"
:value="orderComparison?.value2?.orderCount || 0"
:reference="orderComparison?.reference2?.orderCount || 0"
/>
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<ComparisonCard
tag="本月"
title="订单量"
:value="orderComparison?.value?.orderPayCount || 0"
:reference="orderComparison?.reference?.orderPayCount || 0"
/>
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<ComparisonCard
tag="本年"
title="订单量"
:value="orderComparison?.value?.orderPayCount || 0"
:reference="orderComparison?.reference?.orderPayCount || 0"
tag="本周"
lasttag="上周数据"
title="销售额"
prefix="¥"
:decimals="2"
:value="orderComparison?.value2?.orderAmount || 0"
:reference="orderComparison?.reference2?.orderAmount || 0"
/>
</el-col>
</el-row>
-->
<el-row :gutter="16" class="row">
<el-col :md="12">
<!-- 快捷入口 -->
<ShortcutCard />
</el-col>
<el-col :md="12">
<!-- 运营数据 -->
<OperationDataCard />
</el-col>
</el-row>
<!-- 交易量趋势 -->
<TradeTrendCard class="mb-4" />
</div>
</template>
<script lang="ts" setup>
import * as TradeStatisticsApi from '@/api/oms/statistics/trade'
import {TradeOrderSummaryRespVO} from '@/api/oms/statistics/trade'
import {DataComparisonRespVO} from '@/api/oms/statistics/common'
import ComparisonCard from './components/ComparisonCard.vue'
import ShortcutCard from './components/ShortcutCard.vue'
import OperationDataCard from './components/OperationDataCard.vue'
import TradeTrendCard from './components/TradeTrendCard.vue'
import { fenToYuan } from '@/utils'
/** 商城首页 */
defineOptions({ name: 'MallHome' })
const loading = ref(true) //
const orderComparison = ref<DataComparisonRespVO<TradeOrderSummaryRespVO>>() //
/** 查询交易对照卡片数据 */
const getOrderComparison = async () => {
orderComparison.value = await TradeStatisticsApi.getOrderComparison()
}
/** 查询会员用户数量对照卡片数据 */
/*const getUserCountComparison = async () => {
userComparison.value = await MemberStatisticsApi.getUserCountComparison()
}*/
/** 初始化 **/
onMounted(async () => {
loading.value = true
await Promise.all([getOrderComparison()])
loading.value = false
})
</script>
<style lang="scss" scoped>
.row {

View File

@ -0,0 +1,43 @@
<template>
<div class="flex flex-col gap-2 bg-[var(--el-bg-color-overlay)] p-6">
<div class="flex items-center justify-between text-gray-500">
<span>{{ title }}</span>
<el-tag>{{ tag }}</el-tag>
</div>
<div class="flex flex-row items-baseline justify-between">
<CountTo :prefix="prefix" :end-val="value" :decimals="decimals" class="text-3xl" />
<span :class="toNumber(percent) > 0 ? 'text-red-500' : 'text-green-500'">
{{ Math.abs(toNumber(percent)) }}%
<Icon :icon="toNumber(percent) > 0 ? 'ep:caret-top' : 'ep:caret-bottom'" class="!text-sm" />
</span>
</div>
<el-divider class="mb-1! mt-2!" />
<div class="flex flex-row items-center justify-between text-sm">
<span class="text-gray-500">{{lasttag}}</span>
<span>{{ prefix || '' }}{{ reference }}</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
import { toNumber } from 'lodash-es'
import { calculateRelativeRate } from '@/utils'
/** 交易对照卡片 */
defineOptions({ name: 'ComparisonCard' })
const props = defineProps({
title: propTypes.string.def('').isRequired,
tag: propTypes.string.def(''),
lasttag: propTypes.string.def(''),
prefix: propTypes.string.def(''),
value: propTypes.number.def(0).isRequired,
reference: propTypes.number.def(0).isRequired,
decimals: propTypes.number.def(0)
})
//
const percent = computed(() =>
calculateRelativeRate(props.value as number, props.reference as number)
)
</script>

Some files were not shown because too many files have changed in this diff Show More