新增前端下单首页
This commit is contained in:
parent
eecdbc1c71
commit
7550592b8a
|
|
@ -116,6 +116,10 @@ public class AppSaleOrderController{
|
|||
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,
|
||||
|
|
@ -135,7 +139,13 @@ public class AppSaleOrderController{
|
|||
@GetMapping("/get-count")
|
||||
@Operation(summary = "获得销售订单 分页 tab count")
|
||||
public CommonResult<Map<Integer, Long>> getSpuCount() {
|
||||
return success(saleOrderService.getTabsCount());
|
||||
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")
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ 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;
|
||||
|
|
@ -18,12 +17,10 @@ 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.*;
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import cn.hangtag.framework.common.pojo.PageParam;
|
||||
import cn.hangtag.framework.common.pojo.PageResult;
|
||||
|
|
@ -136,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")
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ 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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ 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 接口
|
||||
|
|
@ -70,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);
|
||||
|
|
@ -81,16 +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);
|
||||
|
||||
Long getCountByBillStatus(String value);
|
||||
default Long getCountByBillStatus(String value){
|
||||
return getCountByBillStatus(value,null);
|
||||
}
|
||||
|
||||
Long getCountByBillStatus(String value, Long customerId);
|
||||
|
||||
List<DataComparisonRespVO<TradeOrderTrendRespVO>> getOrderCountTrendComparison(TradeOrderTrendReqVO reqVO);
|
||||
}
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
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.LoginUser;
|
||||
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.hangtag.framework.web.core.util.WebFrameworkUtils;
|
||||
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;
|
||||
|
|
@ -39,15 +35,14 @@ 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.DateTime;
|
||||
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;
|
||||
|
|
@ -173,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;
|
||||
}
|
||||
|
||||
|
|
@ -376,7 +389,7 @@ 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();
|
||||
|
|
@ -385,10 +398,10 @@ public class SaleOrderServiceImpl implements SaleOrderService {
|
|||
LocalDateTime lastEndWeekDate = DateUtil.endOfWeek(DateUtil.lastWeek()).toLocalDateTime();
|
||||
|
||||
return new DataComparisonRespVO<TradeOrderSummaryRespVO>()
|
||||
.setValue(getOrderQtySummary(dayDate,dayDate))//今日
|
||||
.setReference(getOrderQtySummary(lastDayDate,lastDayDate))//昨日
|
||||
.setValue2(getOrderQtySummary(beginWeekDate,endWeekDate))//本周
|
||||
.setReference2(getOrderQtySummary(lastBeginWeekDate,lastEndWeekDate));//上周
|
||||
.setValue(getOrderQtySummary(dayDate,dayDate,customerId))//今日
|
||||
.setReference(getOrderQtySummary(lastDayDate,lastDayDate,customerId))//昨日
|
||||
.setValue2(getOrderQtySummary(beginWeekDate,endWeekDate,customerId))//本周
|
||||
.setReference2(getOrderQtySummary(lastBeginWeekDate,lastEndWeekDate,customerId));//上周
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -402,8 +415,13 @@ public class SaleOrderServiceImpl implements SaleOrderService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Long getCountByBillStatus(String billstatus) {
|
||||
return saleOrderMapper.selectCount(SaleOrderDO::getBillStatus,billstatus);
|
||||
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
|
||||
|
|
@ -431,11 +449,11 @@ public class SaleOrderServiceImpl implements SaleOrderService {
|
|||
return saleOrderMapper.selectListByPayTimeBetweenAndGroupByDay(beginTime, endTime);
|
||||
}
|
||||
|
||||
private TradeOrderSummaryRespVO getOrderQtySummary(LocalDateTime beginDate,LocalDateTime endDate) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
<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>
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export interface TradeOrderTrendRespVO {
|
|||
// 查询交易统计
|
||||
export const getTradeStatisticsSummary = () => {
|
||||
return request.get<DataComparisonRespVO<TradeSummaryRespVO>>({
|
||||
url: '/statistics/trade/summary'
|
||||
url: '/oms/statistics/trade/summary'
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ export const getTradeStatisticsSummary = () => {
|
|||
// 获得交易状况明细
|
||||
export const getTradeStatisticsList = (params: TradeTrendReqVO) => {
|
||||
return request.get<TradeTrendSummaryRespVO[]>({
|
||||
url: '/statistics/trade/list',
|
||||
url: '/oms/statistics/trade/list',
|
||||
params: formatDateParam(params)
|
||||
})
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ 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)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
/** 数据对照 Response VO */
|
||||
export interface DataComparisonRespVO<T> {
|
||||
value: T
|
||||
reference: T
|
||||
value2: T
|
||||
reference2: T
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
import request from '@/config/axios'
|
||||
import dayjs from 'dayjs'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { DataComparisonRespVO } from '@/api/oms/statistics/common'
|
||||
|
||||
/** 交易统计 Response VO */
|
||||
export interface TradeSummaryRespVO {
|
||||
yesterdayOrderCount: number
|
||||
monthOrderCount: number
|
||||
yesterdayPayPrice: number
|
||||
monthPayPrice: number
|
||||
}
|
||||
|
||||
/** 交易状况 Request VO */
|
||||
export interface TradeTrendReqVO {
|
||||
times: [dayjs.ConfigType, dayjs.ConfigType]
|
||||
}
|
||||
|
||||
/** 交易订单数量 Response VO */
|
||||
export interface TradeOrderCountRespVO {
|
||||
/** 驳回 */
|
||||
orderCountAA?: number
|
||||
/** 待提交 */
|
||||
orderCountA?: number
|
||||
/** 提交中 */
|
||||
orderCountB?: number
|
||||
/** 已审核 */
|
||||
orderCountC?: number
|
||||
}
|
||||
|
||||
/** 交易订单统计 Response VO */
|
||||
export interface TradeOrderSummaryRespVO {
|
||||
/** 支付订单商品数 */
|
||||
orderCount?: number
|
||||
/** 总支付金额,单位:分 */
|
||||
orderAmount?: number
|
||||
}
|
||||
|
||||
/** 订单量趋势统计 Response VO */
|
||||
export interface TradeOrderTrendRespVO {
|
||||
/** 日期 */
|
||||
date: string
|
||||
/** 订单数量 */
|
||||
orderCount: number
|
||||
/** 订单支付金额 */
|
||||
orderAmount: number
|
||||
}
|
||||
|
||||
// 查询交易统计
|
||||
export const getTradeStatisticsSummary = () => {
|
||||
return request.get<DataComparisonRespVO<TradeSummaryRespVO>>({
|
||||
url: '/oms/app/statistics/app/trade/summary'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 获得交易状况明细
|
||||
export const getTradeStatisticsList = (params: TradeTrendReqVO) => {
|
||||
return request.get<TradeTrendSummaryRespVO[]>({
|
||||
url: '/oms/app/statistics/trade/list',
|
||||
params: formatDateParam(params)
|
||||
})
|
||||
}
|
||||
|
||||
// 导出交易状况明细
|
||||
export const exportTradeStatisticsExcel = (params: TradeTrendReqVO) => {
|
||||
return request.download({
|
||||
url: '/oms/app/statistics/trade/export-excel',
|
||||
params: formatDateParam(params)
|
||||
})
|
||||
}
|
||||
|
||||
// 获得交易订单数量
|
||||
export const getOrderCount = async () => {
|
||||
return await request.get<TradeOrderCountRespVO>({ url: `/oms/app/statistics/trade/order-count` })
|
||||
}
|
||||
|
||||
// 获得交易订单数量对照
|
||||
export const getOrderComparison = async () => {
|
||||
return await request.get<DataComparisonRespVO<TradeOrderSummaryRespVO>>({
|
||||
url: `/oms/app/statistics/trade/order-comparison`
|
||||
})
|
||||
}
|
||||
|
||||
// 获得订单量趋势统计
|
||||
export const getOrderCountTrendComparison = (
|
||||
type: number,
|
||||
beginTime: dayjs.ConfigType,
|
||||
endTime: dayjs.ConfigType
|
||||
) => {
|
||||
return request.get<DataComparisonRespVO<TradeOrderTrendRespVO>[]>({
|
||||
url: '/oms/app/statistics/trade/order-count-trend',
|
||||
params: { type, beginTime: formatDate(beginTime), endTime: formatDate(endTime) }
|
||||
})
|
||||
}
|
||||
|
||||
/** 时间参数需要格式化, 确保接口能识别 */
|
||||
const formatDateParam = (params: TradeTrendReqVO) => {
|
||||
return { times: [formatDate(params.times[0]), formatDate(params.times[1])] } as TradeTrendReqVO
|
||||
}
|
||||
|
|
@ -19,6 +19,17 @@
|
|||
</el-row>
|
||||
</el-skeleton>
|
||||
</el-card>
|
||||
|
||||
<el-row :gutter="16" class="row">
|
||||
<el-col :md="12">
|
||||
<!-- 快捷入口 -->
|
||||
<ShortcutCard />
|
||||
</el-col>
|
||||
<el-col :md="12">
|
||||
<!-- 运营数据 -->
|
||||
<OperationDataCard />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<CardTitle title="运营数据" />
|
||||
</template>
|
||||
<div class="flex flex-row flex-wrap items-center gap-8 p-4">
|
||||
<div
|
||||
v-for="item in data"
|
||||
:key="item.name"
|
||||
class="h-20 w-20% flex flex-col cursor-pointer items-center justify-center gap-2"
|
||||
@click="handleClick(item.routerName)"
|
||||
>
|
||||
<CountTo
|
||||
:prefix="item.prefix"
|
||||
:end-val="item.value"
|
||||
:decimals="item.decimals"
|
||||
class="text-3xl"
|
||||
/>
|
||||
<span class="text-center">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import * as TradeStatisticsApi from '@/api/oms/statistics/trade'
|
||||
import { CardTitle } from '@/components/Card'
|
||||
|
||||
/** 运营数据卡片 */
|
||||
defineOptions({ name: 'OperationDataCard' })
|
||||
|
||||
const router = useRouter() // 路由
|
||||
|
||||
/** 数据 */
|
||||
const data = reactive({
|
||||
orderCountAA: { name: '已驳回订单', value: 0, routerName: 'SaleOrder' },
|
||||
orderCountA: { name: '待提交订单', value: 0, routerName: 'SaleOrder' },
|
||||
orderCountB: { name: '待审核订单', value: 0, routerName: 'SaleOrder' },
|
||||
orderCountC: { name: '已完成订单', value: 0, routerName: 'SaleOrder' }
|
||||
})
|
||||
|
||||
/** 查询订单数据 */
|
||||
const getOrderData = async () => {
|
||||
const orderCount = await TradeStatisticsApi.getOrderCount()
|
||||
if (orderCount.orderCountAA != null) {
|
||||
data.orderCountAA.value = orderCount.orderCountAA
|
||||
}
|
||||
if (orderCount.orderCountA != null) {
|
||||
data.orderCountA.value = orderCount.orderCountA
|
||||
}
|
||||
if (orderCount.orderCountB != null) {
|
||||
data.orderCountB.value = orderCount.orderCountB
|
||||
}
|
||||
if (orderCount.orderCountC != null) {
|
||||
data.orderCountC.value = orderCount.orderCountC
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到对应页面
|
||||
*
|
||||
* @param routerName 路由页面组件的名称
|
||||
*/
|
||||
const handleClick = (routerName: string) => {
|
||||
router.push({ name: routerName })
|
||||
}
|
||||
|
||||
/** 激活时 */
|
||||
onActivated(() => {
|
||||
getOrderData()
|
||||
})
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
getOrderData()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<CardTitle title="快捷入口" />
|
||||
</template>
|
||||
<div class="flex flex-row flex-wrap gap-8 p-4">
|
||||
<div
|
||||
v-for="menu in menuList"
|
||||
:key="menu.name"
|
||||
class="h-20 w-20% flex flex-col cursor-pointer items-center justify-center gap-2"
|
||||
@click="handleMenuClick(menu.routerName)"
|
||||
>
|
||||
<div
|
||||
:class="menu.bgColor"
|
||||
class="h-48px w-48px flex items-center justify-center rounded text-white"
|
||||
>
|
||||
<Icon :icon="menu.icon" class="text-7.5!" />
|
||||
</div>
|
||||
<span>{{ menu.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
/** 快捷入口卡片 */
|
||||
import { CardTitle } from '@/components/Card'
|
||||
|
||||
defineOptions({ name: 'ShortcutCard' })
|
||||
|
||||
const router = useRouter() // 路由
|
||||
|
||||
/** 菜单列表 */
|
||||
const menuList = [
|
||||
{ name: '订单管理', icon: 'ep:list', bgColor: 'bg-yellow-500', routerName: 'SaleOrder' },
|
||||
{
|
||||
name: '创建订单',
|
||||
icon: 'fa-solid:project-diagram',
|
||||
bgColor: 'bg-green-600',
|
||||
routerName: 'CreateOrder'
|
||||
}
|
||||
]
|
||||
|
||||
/**
|
||||
* 跳转到菜单对应页面
|
||||
*
|
||||
* @param routerName 路由页面组件的名称
|
||||
*/
|
||||
const handleMenuClick = (routerName: string) => {
|
||||
router.push({ name: routerName })
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
<template>
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<CardTitle title="交易量趋势" />
|
||||
<!-- 查询条件 -->
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<el-radio-group v-model="timeRangeType" @change="handleTimeRangeTypeChange">
|
||||
<el-radio-button v-for="[key, value] in timeRange.entries()" :key="key" :label="key">
|
||||
{{ value.name }}
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 折线图 -->
|
||||
<Echart :height="300" :options="eChartOptions" />
|
||||
</el-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import dayjs, { Dayjs } from 'dayjs'
|
||||
import { EChartsOption } from 'echarts'
|
||||
import * as TradeStatisticsApi from '@/api/oms/statistics/trade'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { CardTitle } from '@/components/Card'
|
||||
|
||||
/** 交易量趋势 */
|
||||
defineOptions({ name: 'TradeTrendCard' })
|
||||
|
||||
enum TimeRangeTypeEnum {
|
||||
DAY30 = 1,
|
||||
WEEK = 7,
|
||||
MONTH = 30,
|
||||
YEAR = 365
|
||||
} // 日期类型
|
||||
const timeRangeType = ref(TimeRangeTypeEnum.DAY30) // 日期快捷选择按钮, 默认30天
|
||||
const loading = ref(true) // 加载中
|
||||
// 时间范围 Map
|
||||
const timeRange = new Map()
|
||||
.set(TimeRangeTypeEnum.DAY30, {
|
||||
name: '30天',
|
||||
series: [
|
||||
{ name: '订单金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '订单数量', type: 'line', smooth: true, data: [] }
|
||||
]
|
||||
})
|
||||
.set(TimeRangeTypeEnum.WEEK, {
|
||||
name: '周',
|
||||
series: [
|
||||
{ name: '上周金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '本周金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '上周数量', type: 'line', smooth: true, data: [] },
|
||||
{ name: '本周数量', type: 'line', smooth: true, data: [] }
|
||||
]
|
||||
})
|
||||
.set(TimeRangeTypeEnum.MONTH, {
|
||||
name: '月',
|
||||
series: [
|
||||
{ name: '上月金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '本月金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '上月数量', type: 'line', smooth: true, data: [] },
|
||||
{ name: '本月数量', type: 'line', smooth: true, data: [] }
|
||||
]
|
||||
})
|
||||
.set(TimeRangeTypeEnum.YEAR, {
|
||||
name: '年',
|
||||
series: [
|
||||
{ name: '去年金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '今年金额', type: 'bar', smooth: true, data: [] },
|
||||
{ name: '去年数量', type: 'line', smooth: true, data: [] },
|
||||
{ name: '今年数量', type: 'line', smooth: true, data: [] }
|
||||
]
|
||||
})
|
||||
/** 图表配置 */
|
||||
const eChartOptions = reactive<EChartsOption>({
|
||||
grid: {
|
||||
left: 20,
|
||||
right: 20,
|
||||
bottom: 20,
|
||||
top: 80,
|
||||
containLabel: true
|
||||
},
|
||||
legend: {
|
||||
top: 50,
|
||||
data: []
|
||||
},
|
||||
series: [],
|
||||
toolbox: {
|
||||
feature: {
|
||||
// 数据区域缩放
|
||||
dataZoom: {
|
||||
yAxisIndex: false // Y轴不缩放
|
||||
},
|
||||
brush: {
|
||||
type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
|
||||
},
|
||||
saveAsImage: { show: true, name: '订单量趋势' } // 保存为图片
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
},
|
||||
padding: [5, 10]
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
inverse: true,
|
||||
boundaryGap: false,
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
data: [],
|
||||
axisLabel: {
|
||||
formatter: (date: string) => {
|
||||
switch (timeRangeType.value) {
|
||||
case TimeRangeTypeEnum.DAY30:
|
||||
return formatDate(date, 'MM-DD')
|
||||
case TimeRangeTypeEnum.WEEK:
|
||||
let weekDay = formatDate(date, 'ddd')
|
||||
if (weekDay == '0') weekDay = '日'
|
||||
return '周' + weekDay
|
||||
case TimeRangeTypeEnum.MONTH:
|
||||
return formatDate(date, 'D')
|
||||
case TimeRangeTypeEnum.YEAR:
|
||||
return formatDate(date, 'M') + '月'
|
||||
default:
|
||||
return date
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
}) as EChartsOption
|
||||
|
||||
/** 时间范围类型单选按钮选中 */
|
||||
const handleTimeRangeTypeChange = async () => {
|
||||
// 设置时间范围
|
||||
let beginTime: Dayjs
|
||||
let endTime: Dayjs
|
||||
switch (timeRangeType.value) {
|
||||
case TimeRangeTypeEnum.WEEK:
|
||||
beginTime = dayjs().startOf('week')
|
||||
endTime = dayjs().endOf('week')
|
||||
break
|
||||
case TimeRangeTypeEnum.MONTH:
|
||||
beginTime = dayjs().startOf('month')
|
||||
endTime = dayjs().endOf('month')
|
||||
break
|
||||
case TimeRangeTypeEnum.YEAR:
|
||||
beginTime = dayjs().startOf('year')
|
||||
endTime = dayjs().endOf('year')
|
||||
break
|
||||
case TimeRangeTypeEnum.DAY30:
|
||||
default:
|
||||
beginTime = dayjs().subtract(30, 'day').startOf('d')
|
||||
endTime = dayjs().endOf('d')
|
||||
break
|
||||
}
|
||||
// 发送时间范围选中事件
|
||||
await getOrderCountTrendComparison(beginTime, endTime)
|
||||
}
|
||||
|
||||
/** 查询订单数量趋势对照数据 */
|
||||
const getOrderCountTrendComparison = async (
|
||||
beginTime: dayjs.ConfigType,
|
||||
endTime: dayjs.ConfigType
|
||||
) => {
|
||||
loading.value = true
|
||||
// 查询数据
|
||||
const list = await TradeStatisticsApi.getOrderCountTrendComparison(
|
||||
timeRangeType.value,
|
||||
beginTime,
|
||||
endTime
|
||||
)
|
||||
// 处理数据
|
||||
const dates: string[] = []
|
||||
const series = [...timeRange.get(timeRangeType.value).series]
|
||||
for (let item of list) {
|
||||
dates.push(item.value.date)
|
||||
if (series.length === 2) {
|
||||
series[0].data.push(item?.value?.orderAmount || 0) // 当前金额
|
||||
series[1].data.push(item?.value?.orderCount || 0) // 当前数量
|
||||
} else {
|
||||
series[0].data.push(item?.reference?.orderAmount || 0) // 对照金额
|
||||
series[1].data.push(item?.value?.orderAmount || 0) // 当前金额
|
||||
series[2].data.push(item?.reference?.orderCount || 0) // 对照数量
|
||||
series[3].data.push(item?.value?.orderCount || 0) // 当前数量
|
||||
}
|
||||
}
|
||||
eChartOptions.xAxis!['data'] = dates
|
||||
eChartOptions.series = series
|
||||
// legend在4个切换到2个的时候,还是显示成4个,需要手动配置一下
|
||||
eChartOptions.legend['data'] = series.map((item) => item.name)
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
/** 初始化 **/
|
||||
onMounted(() => {
|
||||
handleTimeRangeTypeChange()
|
||||
})
|
||||
</script>
|
||||
Loading…
Reference in New Issue