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

# Conflicts:
#	hangtag-ui/hangtag-ui-admin/src/utils/dict.ts
This commit is contained in:
YuanFeng 2024-09-08 16:42:12 +08:00
commit c1a7bee638
22 changed files with 601 additions and 426 deletions

View File

@ -121,7 +121,7 @@ public interface BaseMapperX<T> extends MPJBaseMapper<T> {
return selectList(new LambdaQueryWrapper<T>().eq(field, value));
}
default List<T> selectList(String field, Collection<?> values) {
default List<T> selectList(String field, Collection<?> values) {
if (CollUtil.isEmpty(values)) {
return CollUtil.newArrayList();
}

View File

@ -0,0 +1,14 @@
package cn.hangtag.module.oms.enums;
/**
* OMS 字典类型的枚举类
*
* @author 芋道源码
*/
public interface DictTypeConstants {
// ========== OMS 模块 ==========
String BILL_STATUS = "oms_bill_status"; // 单据状态
String ORDER_STATUS = "oms_order_status"; // 订单状态
}

View File

@ -0,0 +1,29 @@
package cn.hangtag.module.oms.enums.common;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 单据状态
* @author wwb
*/
@Getter
@AllArgsConstructor
public enum BillStatusEnum {
//订单状态已下单生产中已完成
//单据状态暂存已提交已审核
SAVE("A", "暂存"),
SUBMIT("B", "已提交"),
AUDIT("C", "已审核");
/**
* 状态
*/
private final String value;
/**
* 状态名
*/
private final String name;
}

View File

@ -0,0 +1,41 @@
package cn.hangtag.module.oms.enums.saleorder;
import cn.hangtag.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* 销售订单状态
*
* @author wwb
*/
@Getter
@AllArgsConstructor
public enum SaleOrderStatusEnum implements IntArrayValuable {
//订单状态已下单生产中已完成
//单据状态暂存已提交已审核
YXD(0, "已下单"),
SCZ(1, "生产中"),
YWC(2, "已完成");
/**
* 状态
*/
private final Integer value;
/**
* 状态名
*/
private final String name;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(SaleOrderStatusEnum::getValue).toArray();
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -12,18 +12,14 @@ import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.service.customer.CustomerService;
import cn.hutool.core.collection.CollUtil;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;

View File

@ -1,18 +1,35 @@
package cn.hangtag.module.oms.controller.admin.app;
import cn.hangtag.framework.common.pojo.CommonResult;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.util.object.BeanUtils;
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.dal.dataobject.productinfo.ProductInfoDO;
import cn.hangtag.module.oms.service.productinfo.ProductInfoService;
import cn.hangtag.module.oms.service.saleorder.SaleOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Map;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
@Tag(name = "APP - 销售订单")
@RestController
@RequestMapping("/oms/app/saleorder")
@Validated
public class AppSaleOrderController{
@Resource
private SaleOrderService saleOrderService;
}

View File

@ -24,7 +24,7 @@ public class ProduceOrderSaveReqVO {
private String customerCode;
@Schema(description = "产品id", example = "29732")
private Integer productId;
private Long productId;
@Schema(description = "产品编号")
private String productCode;
@ -36,7 +36,7 @@ public class ProduceOrderSaveReqVO {
private Integer saleContractNo;
@Schema(description = "合约日期")
private LocalDateTime contractDate;
private Date contractDate;
@Schema(description = "合约数量")
private Long contractQty;
@ -47,14 +47,14 @@ public class ProduceOrderSaveReqVO {
@Schema(description = "交货地点")
private String deliveryPlace;
@Schema(description = "职员")
@Schema(description = "职员")
private String clerk;
@Schema(description = "报告日期")
private LocalDateTime reportDate;
private Date reportDate;
@Schema(description = "生产日期")
private LocalDateTime produceDate;
private Date produceDate;
@Schema(description = "天数")
private Long days;
@ -66,10 +66,10 @@ public class ProduceOrderSaveReqVO {
private String deliveryMethod;
@Schema(description = "验货日期")
private LocalDateTime inspectionDate;
private Date inspectionDate;
@Schema(description = "交货日期")
private LocalDateTime deliverydate;
private Date deliverydate;
@Schema(description = "交货数量")
private Integer deliveryQty;

View File

@ -103,4 +103,35 @@ public class SaleOrderController {
return success(saleOrderService.getSaleOrderEntryListByParentId(parentId));
}
@GetMapping("/get-count")
@Operation(summary = "获得销售订单 分页 tab count")
@PreAuthorize("@ss.hasPermission('oms:sale-order:query')")
public CommonResult<Map<Integer, Long>> getSpuCount() {
return success(saleOrderService.getTabsCount());
}
@PutMapping("/updateSaleOrderBillStatus")
@Operation(summary = "更新销售订单的状态")
@PreAuthorize("@ss.hasPermission('oms:sale-order:update-status')")
public CommonResult<Boolean> updateSaleOrderBillStatus(@RequestParam("ids") List<Long> ids,
@RequestParam("status") String status) {
saleOrderService.updateSaleOrderBillStatus(ids, status);
return success(true);
}
@PutMapping("/generateProduceOrder")
@Operation(summary = "生成生成制单")
@PreAuthorize("@ss.hasPermission('oms:sale-order:generate-produceorder')")
public CommonResult<Boolean> generateProduceOrder(@RequestParam("ids") List<Long> ids) {
saleOrderService.generateProduceOrder(ids);
return success(true);
}
}

View File

@ -36,7 +36,15 @@ public class SaleOrderPageReqVO extends PageParam {
@Schema(description = "手机")
private String phone;
@Schema(description = "单据状态")
private String billStatus;
@Schema(description = "订单状态")
private String orderStatus;
@Schema(description = "备注")
private String remarks;
@Schema(description = "前端请求的tab类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer tabType;
}

View File

@ -1,5 +1,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.enums.DictTypeConstants;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
@ -12,6 +15,10 @@ import com.alibaba.excel.annotation.*;
@ExcelIgnoreUnannotated
public class SaleOrderRespVO {
@Schema(description = "ID")
@ExcelProperty("ID")
private Long id;
@Schema(description = "单据编号")
@ExcelProperty("单据编号")
private String billno;
@ -20,6 +27,17 @@ public class SaleOrderRespVO {
@ExcelProperty("客户id")
private Long customerId;
@Schema(description = "单据状态", example = "2")
@ExcelProperty(value = "单据状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.BILL_STATUS)
private String billStatus;
@Schema(description = "订单状态", example = "2")
@ExcelProperty(value = "订单状态", converter = DictConvert.class)
@DictFormat(DictTypeConstants.ORDER_STATUS)
private Integer orderStatus;
@Schema(description = "业务日期")
@ExcelProperty("业务日期")
private LocalDateTime bizdate;
@ -30,11 +48,11 @@ public class SaleOrderRespVO {
@Schema(description = "更新时间")
@ExcelProperty("更新时间")
private LocalDateTime udate;
private LocalDateTime updateTime;
@Schema(description = "创建时间")
@ExcelProperty("创建时间")
private LocalDateTime cdate;
private LocalDateTime createTime;
@Schema(description = "确认日期")
@ExcelProperty("确认日期")

View File

@ -56,6 +56,12 @@ public class SaleOrderSaveReqVO {
@Schema(description = "发票备注")
private String invoiceRemarks;
@Schema(description = "单据状态", example = "2")
private String billStatus;
@Schema(description = "订单状态", example = "2")
private Integer orderStatus;
@Schema(description = "销售订单明细列表")
private List<SaleOrderEntryDO> saleOrderEntrys;

View File

@ -46,14 +46,6 @@ public class SaleOrderDO extends BaseDO {
* 备注
*/
private String remark;
/**
* 更新时间
*/
private LocalDateTime udate;
/**
* 创建时间
*/
private LocalDateTime cdate;
/**
* 确认日期
*/
@ -66,6 +58,14 @@ public class SaleOrderDO extends BaseDO {
* 订单类型
*/
private String orderType;
/**
* 订单状态
*/
private Integer orderStatus;
/**
* 单据状态
*/
private String billStatus;
/**
* 手机
*/

View File

@ -30,8 +30,11 @@ public interface BrandMapper extends BaseMapperX<BrandDO> {
}
default List<BrandDO> selectList(BrandListReqVO reqVO){
return selectList(new LambdaQueryWrapperX<BrandDO>()
.in(BrandDO::getId, reqVO.getIds())
.likeIfPresent(BrandDO::getName, reqVO.getName()));
LambdaQueryWrapperX<BrandDO> queryWrapper = new LambdaQueryWrapperX<>();
if(reqVO.getIds()!=null&&reqVO.getIds().size()>0){
queryWrapper.in(BrandDO::getId, reqVO.getIds());
}
queryWrapper.likeIfPresent(BrandDO::getName, reqVO.getName());
return selectList(queryWrapper);
}
}

View File

@ -1,13 +1,13 @@
package cn.hangtag.module.oms.dal.mysql.saleorder;
import java.util.*;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.mybatis.core.query.LambdaQueryWrapperX;
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.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.enums.saleorder.SaleOrderStatusEnum;
import cn.hutool.core.util.ObjectUtil;
import org.apache.ibatis.annotations.Mapper;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
/**
* 销售订单 Mapper
@ -18,7 +18,8 @@ import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
public interface SaleOrderMapper extends BaseMapperX<SaleOrderDO> {
default PageResult<SaleOrderDO> selectPage(SaleOrderPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<SaleOrderDO>()
Integer tabType = reqVO.getTabType();
LambdaQueryWrapperX<SaleOrderDO> queryWrapper = new LambdaQueryWrapperX<SaleOrderDO>()
.eqIfPresent(SaleOrderDO::getBillno, reqVO.getBillno())
.eqIfPresent(SaleOrderDO::getCustomerId, reqVO.getCustomerId())
.betweenIfPresent(SaleOrderDO::getBizdate, reqVO.getBizdate())
@ -26,7 +27,37 @@ public interface SaleOrderMapper extends BaseMapperX<SaleOrderDO> {
.betweenIfPresent(SaleOrderDO::getPlansenddate, reqVO.getPlansenddate())
.eqIfPresent(SaleOrderDO::getPhone, reqVO.getPhone())
.eqIfPresent(SaleOrderDO::getRemarks, reqVO.getRemarks())
.orderByDesc(SaleOrderDO::getId));
.eqIfPresent(SaleOrderDO::getBillStatus, reqVO.getBillStatus())
.eqIfPresent(SaleOrderDO::getOrderStatus, reqVO.getOrderStatus())
.orderByDesc(SaleOrderDO::getId);
appendTabQuery(tabType, queryWrapper);
queryWrapper.orderByDesc(SaleOrderDO::getCreateTime);
return selectPage(reqVO,queryWrapper );
}
/**
* 添加后台 Tab 选项的查询条件
*
* @param tabType 标签类型
* @param query 查询条件
*/
default void appendTabQuery(Integer tabType, LambdaQueryWrapperX<SaleOrderDO> query) {
// 已下单
if (ObjectUtil.equals(SaleOrderStatusEnum.YXD.getValue(), tabType)) {
query.eqIfPresent(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YXD.getValue());
}
// 生产中
if (ObjectUtil.equals(SaleOrderStatusEnum.SCZ.getValue(), tabType)) {
query.eqIfPresent(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.SCZ.getValue());
}
// 已完成
if (ObjectUtil.equals(SaleOrderStatusEnum.YWC.getValue(), tabType)) {
query.eqIfPresent(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YWC.getValue());
}
}
}

View File

@ -1,5 +1,13 @@
package cn.hangtag.module.oms.service.produceorder;
import cn.hangtag.framework.common.exception.ServiceException;
import cn.hangtag.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.hangtag.framework.common.util.FuncUtil;
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
import cn.hangtag.module.oms.dal.dataobject.saleorder.SaleOrderDO;
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
@ -24,6 +32,7 @@ import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class ProduceOrderServiceImpl implements ProduceOrderService {
@Resource
@ -33,6 +42,12 @@ public class ProduceOrderServiceImpl implements ProduceOrderService {
public Long createProduceOrder(ProduceOrderSaveReqVO createReqVO) {
// 插入
ProduceOrderDO produceOrder = BeanUtils.toBean(createReqVO, ProduceOrderDO.class);
String code = produceOrder.getBillno();
if(FuncUtil.isNotEmpty(code)){
checkCode(produceOrder.getId(),code);
}else {
produceOrder.setBillno(getNewCode());
}
produceOrderMapper.insert(produceOrder);
// 返回
return produceOrder.getId();
@ -71,4 +86,47 @@ public class ProduceOrderServiceImpl implements ProduceOrderService {
return produceOrderMapper.selectPage(pageReqVO);
}
private String getNewCode() {
String s = "";
int count = 10;
while (true){
count --;
try {
s = CodingRulesUtils.generateCode(3L, false);
checkCode(null,s);
return s;
}catch (ServiceException e){
log.warn("重复或者下一个编码");
if(count < 0){
log.error("编码获取失败");
return "";
}
}
}
}
private void checkCode(Long id,String code){
if(FuncUtil.isNotEmpty(code)){
LambdaQueryWrapper<ProduceOrderDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.select(ProduceOrderDO::getId,ProduceOrderDO::getBillno, BaseDO::getDeleted);
lambdaQueryWrapper.eq(ProduceOrderDO::getBillno, code);
lambdaQueryWrapper.eq(ProduceOrderDO::getDeleted,false);
List<ProduceOrderDO> dos = produceOrderMapper.selectList(lambdaQueryWrapper);
if(FuncUtil.isEmpty(id) && FuncUtil.isNotEmpty(dos)){
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
}
if (FuncUtil.isNotEmpty(id) && FuncUtil.isNotEmpty(dos)) {
for (ProduceOrderDO aDo : dos) {
// 出现重复并当前id 不一致
if(!FuncUtil.equals(aDo.getId(), id)){
throw exception(GlobalErrorCodeConstants.DATA_DUPLICATE);
}
}
}
}
}
}

View File

@ -63,4 +63,9 @@ public interface SaleOrderService {
*/
List<SaleOrderEntryDO> getSaleOrderEntryListByParentId(Long parentId);
Map<Integer, Long> getTabsCount();
void updateSaleOrderBillStatus(List<Long> ids, String status);
void generateProduceOrder(List<Long> ids);
}

View File

@ -1,23 +1,36 @@
package cn.hangtag.module.oms.service.saleorder;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.*;
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.FuncUtil;
import cn.hangtag.framework.common.util.object.BeanUtils;
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.ProduceOrderSaveReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderPageReqVO;
import cn.hangtag.module.oms.controller.admin.saleorder.vo.SaleOrderSaveReqVO;
import cn.hangtag.module.oms.dal.dataobject.brand.BrandDO;
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;
import cn.hangtag.framework.common.util.object.BeanUtils;
import cn.hangtag.module.oms.dal.mysql.saleorder.SaleOrderMapper;
import cn.hangtag.module.oms.dal.mysql.saleorderentry.SaleOrderEntryMapper;
import cn.hangtag.module.oms.enums.saleorder.SaleOrderStatusEnum;
import cn.hangtag.module.oms.serialnumber.CodingRulesUtils;
import cn.hangtag.module.oms.service.produceorder.ProduceOrderService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.SALE_ORDER_NOT_EXISTS;
/**
* 销售订单 Service 实现类
@ -26,12 +39,15 @@ import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class SaleOrderServiceImpl implements SaleOrderService {
@Resource
private SaleOrderMapper saleOrderMapper;
@Resource
private SaleOrderEntryMapper saleOrderEntryMapper;
@Resource
private ProduceOrderService produceOrderService;
@Override
@Transactional(rollbackFor = Exception.class)
@ -94,6 +110,52 @@ public class SaleOrderServiceImpl implements SaleOrderService {
return saleOrderEntryMapper.selectListByParentId(parentId);
}
@Override
public Map<Integer, Long> getTabsCount() {
Map<Integer, Long> counts = Maps.newLinkedHashMapWithExpectedSize(3);
// 查询已下单订单数量
counts.put(SaleOrderStatusEnum.YXD.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YXD.getValue()));
// 查询已生产订单数量
counts.put(SaleOrderStatusEnum.SCZ.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.SCZ.getValue()));
// 查询已完成订单数量
counts.put(SaleOrderStatusEnum.YWC.getValue(),
saleOrderMapper.selectCount(SaleOrderDO::getOrderStatus, SaleOrderStatusEnum.YWC.getValue()));
return counts;
}
@Override
public void updateSaleOrderBillStatus(List<Long> ids, String status) {
}
@Override
public void generateProduceOrder(List<Long> ids) {
List<SaleOrderDO> saleOrders = saleOrderMapper.selectList(SaleOrderDO::getId, ids);
for (SaleOrderDO saleOrder : saleOrders) {
ProduceOrderSaveReqVO saveReqVO = new ProduceOrderSaveReqVO();
saveReqVO.setOrderNo(saleOrder.getBillno());
saveReqVO.setCustomerCode("客户编号");
saveReqVO.setProductId(0L);
saveReqVO.setProduceLine("测试线");
saveReqVO.setDeliveryMethod("交货方式");
saveReqVO.setDeliveryQty(1111111);
saveReqVO.setDays(5L);
saveReqVO.setClerk("职员");
saveReqVO.setContractDate(new Date());
Long produceOrderId = produceOrderService.createProduceOrder(saveReqVO);
//更新销售订单已完成
/*if(produceOrderId!=null){
SaleOrderSaveReqVO saleOrderSaveReqVO = new SaleOrderSaveReqVO();
saleOrderSaveReqVO.setId(saleOrder.getId());
saleOrderSaveReqVO.setOrderStatus(SaleOrderStatusEnum.YWC.getValue());
updateSaleOrder(saleOrderSaveReqVO);
}*/
}
}
private void createSaleOrderEntryList(Long parentId, List<SaleOrderEntryDO> list) {
list.forEach(o -> o.setParentId(parentId));
saleOrderEntryMapper.insertBatch(list);
@ -109,4 +171,6 @@ public class SaleOrderServiceImpl implements SaleOrderService {
saleOrderEntryMapper.deleteByParentId(parentId);
}
}

View File

@ -1,58 +1,84 @@
import request from '@/config/axios'
// 销售订单 VO
export interface SaleOrderVO {
customerId: number // 客户id
bizdate: Date // 业务日期
remark: string // 备注
confirmdate: Date // 确认日期
plansenddate: Date // 计划日期
phone: string // 手机
remarks: string // 备注
emails: string // 邮件列表数据格式xxx@xx.com;xxx@xx.com;
invoiceCode: string // 发票抬头
invoiceName: string // 发票名称
address: string // 地址
currency: string // 货币
invoiceRemarks: string // 发票备注
}
// 销售订单 API
export const SaleOrderApi = {
// 查询销售订单分页
getSaleOrderPage: async (params: any) => {
return await request.get({ url: `/oms/sale-order/page`, params })
},
// 查询销售订单详情
getSaleOrder: async (id: number) => {
return await request.get({ url: `/oms/sale-order/get?id=` + id })
},
// 新增销售订单
createSaleOrder: async (data: SaleOrderVO) => {
return await request.post({ url: `/oms/sale-order/create`, data })
},
// 修改销售订单
updateSaleOrder: async (data: SaleOrderVO) => {
return await request.put({ url: `/oms/sale-order/update`, data })
},
// 删除销售订单
deleteSaleOrder: async (id: number) => {
return await request.delete({ url: `/oms/sale-order/delete?id=` + id })
},
// 导出销售订单 Excel
exportSaleOrder: async (params) => {
return await request.download({ url: `/oms/sale-order/export-excel`, params })
},
// ==================== 子表(销售订单明细) ====================
// 获得销售订单明细列表
getSaleOrderEntryListByParentId: async (parentId) => {
return await request.get({ url: `/oms/sale-order/sale-order-entry/list-by-parent-id?parentId=` + parentId })
},
}
import request from '@/config/axios'
// 销售订单 VO
export interface SaleOrderVO {
customerId: number // 客户id
bizdate: Date // 业务日期
remark: string // 备注
confirmdate: Date // 确认日期
plansenddate: Date // 计划日期
phone: string // 手机
remarks: string // 备注
emails: string // 邮件列表数据格式xxx@xx.com;xxx@xx.com;
invoiceCode: string // 发票抬头
invoiceName: string // 发票名称
address: string // 地址
currency: string // 货币
invoiceRemarks: string // 发票备注
}
// 销售订单 API
export const SaleOrderApi = {
// 查询销售订单分页
getSaleOrderPage: async (params: any) => {
return await request.get({ url: `/oms/sale-order/page`, params })
},
// 查询销售订单详情
getSaleOrder: async (id: number) => {
return await request.get({ url: `/oms/sale-order/get?id=` + id })
},
// 新增销售订单
createSaleOrder: async (data: SaleOrderVO) => {
return await request.post({ url: `/oms/sale-order/create`, data })
},
// 修改销售订单
updateSaleOrder: async (data: SaleOrderVO) => {
return await request.put({ url: `/oms/sale-order/update`, data })
},
// 删除销售订单
deleteSaleOrder: async (id: number) => {
return await request.delete({ url: `/oms/sale-order/delete?id=` + id })
},
// 导出销售订单 Excel
exportSaleOrder: async (params) => {
return await request.download({ url: `/oms/sale-order/export-excel`, params })
},
// ==================== 子表(销售订单明细) ====================
// 获得销售订单明细列表
getSaleOrderEntryListByParentId: async (parentId) => {
return await request.get({ url: `/oms/sale-order/sale-order-entry/list-by-parent-id?parentId=` + parentId })
},
// 获得 销售 列表 tabsCount
getTabsCount: async () => {
return request.get({ url: '/oms/sale-order/get-count' })
},
// 更新订单状态
updateSaleOrderBillStatus: async (ids: number[],status: string) => {
return await request.post({
url: `/oms/sale-order/updateSaleOrderBillStatus`,
params: {
ids: ids.join(','),
status: status
}
})
},
// 更新订单状态
generateProduceOrder: async (ids: number[]) => {
return await request.put({
url: `/oms/sale-order/generateProduceOrder`,
params: {
ids: ids.join(',')
}
})
},
}

View File

@ -212,7 +212,10 @@ export enum DICT_TYPE {
ERP_AUDIT_STATUS = 'erp_audit_status', // ERP 审批状态
ERP_STOCK_RECORD_BIZ_TYPE = 'erp_stock_record_biz_type', // 库存明细的业务类型
// ========== OMS - 企业订单管理模块 ==========
OMS_DATA_STATUS = 'oms_data_status', // 库存明细的业务类型
OMS_PRODUCT_CARE_ITEM_TYPE= 'oms_product_care_item_type', //产品保养项目类型 1.成分说明 2.洗涤说明 3.使用说明 4.尺码
// ========== OMS模块 ==========
OMS_DATA_STATUS = 'oms_data_status', // 数据状态
OMS_BILL_STATUS = 'oms_bill_status', // 单据状态
OMS_ORDER_STATUS = 'oms_order_status',// 订单状态
OMS_PRODUCT_CARE_ITEM_TYPE = 'oms_product_care_item_type', //产品保养项目类型 1.成分说明 2.洗涤说明 3.使用说明 4.尺码
}

View File

@ -1,295 +0,0 @@
<template>
<ContentWrap>
<el-row :gutter="10">
<el-card header="基本信息" style="width: 100%; margin-top: 20px" shadow="never" class="box-card">
<template #header>
<CardTitle title="基本信息" />
</template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="150px"
v-loading="formLoading"
>
<el-row>
<el-col :span="12">
<el-form-item label="订单号码" prop="name">
<el-input v-model="formData.name" disabled="true" placeholder="*** New ***" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="订单状态" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户名称" prop="contacts">
<el-input v-model="formData.contacts" placeholder="请输入联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="创建日期 (GMT+8)" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系人手机号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数据状态" prop="status">
<el-switch
v-model="formData.status"
:active-text="formData.status==1?'可用':'禁用'"
active-value="1"
inactive-value="0"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<el-card header="电子邮件通知" style="width: 100%; margin-top: 20px" shadow="never">
<template #header>
<CardTitle title="电子邮件通知" />
</template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="150px"
v-loading="formLoading"
>
<el-row>
<el-col :span="12">
<el-form-item label="订单号码" prop="name">
<el-input v-model="formData.name" disabled="true" placeholder="*** New ***" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="订单状态" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户名称" prop="contacts">
<el-input v-model="formData.contacts" placeholder="请输入联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="创建日期 (GMT+8)" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系人手机号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数据状态" prop="status">
<el-switch
v-model="formData.status"
:active-text="formData.status==1?'可用':'禁用'"
active-value="1"
inactive-value="0"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 右上角账户信息 -->
<el-col :span="12" class="detail-info-item" style="padding-left: 0px; margin-top: 20px">
<el-card shadow="never" class="h-full">
<template #header>
<CardTitle title="发票信息" />
</template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="150px"
v-loading="formLoading"
>
<el-row>
<el-col :span="1655">
<el-form-item label="订单号码" prop="name">
<el-input v-model="formData.name" disabled="true" placeholder="*** New ***" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="订单状态" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户名称" prop="contacts">
<el-input v-model="formData.contacts" placeholder="请输入联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="创建日期 (GMT+8)" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系人手机号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数据状态" prop="status">
<el-switch
v-model="formData.status"
:active-text="formData.status==1?'可用':'禁用'"
active-value="1"
inactive-value="0"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-col>
<!-- 右上角账户信息 -->
<el-col :span="12" class="detail-info-item" style="padding-right: 0px; margin-top: 20px">
<el-card shadow="never" class="h-full">
<template #header>
<CardTitle title="账户信息" />
</template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="150px"
v-loading="formLoading"
>
<el-row>
<el-col :span="12">
<el-form-item label="订单号码" prop="name">
<el-input v-model="formData.name" disabled="true" placeholder="*** New ***" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="订单状态" prop="email">
<el-input v-model="formData.email" placeholder="请输入邮箱" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户名称" prop="contacts">
<el-input v-model="formData.contacts" placeholder="请输入联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="创建日期 (GMT+8)" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系人手机号" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="数据状态" prop="status">
<el-switch
v-model="formData.status"
:active-text="formData.status==1?'可用':'禁用'"
active-value="1"
inactive-value="0"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks" placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
</el-col>
</el-row>
<el-row style="margin-top: 20px;" justify="end">
<el-col :span="2">
<el-button type="primary" plain size="mini" @click="openForm(undefined)">下一步</el-button>
</el-col>
</el-row>
</ContentWrap>
</template>
<script setup lang="ts">
import {defaultProps} from "@/utils/tree";
const formData = ref({
name: undefined,
email: undefined,
contacts: undefined,
phone: undefined,
areaId: undefined,
status: undefined,
type: undefined,
remarks: undefined,
})
const formRules = reactive({
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
contacts: [{ required: true, message: '联系人不能为空', trigger: 'blur' }],
phone: [{ required: true, message: '联系人手机号不能为空', trigger: 'blur' },
{
pattern: /^(?:(?:\+|00)86)?1(?:3[\d]|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8[\d]|9[189])\d{8}$/,
message: '请输入正确的手机号码',
trigger: 'blur'
}
],
email: [
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change']
}
]
})
const formRef = ref() // Ref
</script>
<style scoped lang="scss">
</style>

View File

@ -1,13 +0,0 @@
<script setup lang="ts">
</script>
<template>
<div>
</div>
</template>
<style scoped lang="scss">
</style>

View File

@ -59,6 +59,36 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item label="单据状态" prop="billStatus">
<el-select
v-model="queryParams.billStatus"
placeholder="请选择单据状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.OMS_BILL_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="订单状态" prop="orderStatus">
<el-select
v-model="queryParams.orderStatus"
placeholder="请选择订单状态"
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.OMS_ORDER_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="手机" prop="phone">
<el-input
v-model="queryParams.phone"
@ -86,15 +116,40 @@
<el-row :gutter="10" class="-mb-1px">
<el-col :span="1.5">
<el-button
type="primary"
type="danger"
plain
>生产中
:disabled="selectionList.length === 0"
>驳回
</el-button>
<el-button
type="warning"
plain
:disabled="selectionList.length === 0"
>提交
</el-button>
<el-button
type="primary"
plain
@click="handleUpdateBillStatus(selectionList.map((item) => item.id),'C')"
:disabled="selectionList.length === 0"
>
已完成
审核
</el-button>
<el-button
type="primary"
plain
@click="handleUpdateBillStatus(selectionList.map((item) => item.id),'B')"
:disabled="selectionList.length === 0"
>
反审核
</el-button>
<el-button
type="primary"
plain
@click="generateProduceOrder(selectionList.map((item) => item.id),'B')"
:disabled="selectionList.length === 0 || queryParams.tabType === 0"
>
生成制单
</el-button>
<el-button
type="success"
@ -119,31 +174,44 @@
:name="item.type"
/>
</el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table v-loading="loading" :data="list" :stripe="true"
:show-overflow-tooltip="true"
@selection-change="handleSelectionChange"
>
<el-table-column width="30" label="选择" type="selection" />
<el-table-column label="单据编号" align="center" prop="billno" width="120px"/>
<el-table-column label="客户" align="center" prop="customerId" width="120px"/>
<el-table-column label="销售员" align="center" prop="customerId" width="180px"/>
<el-table-column label="跟单员" align="center" prop="customerId" width="180px"/>
<el-table-column label="订单状态" align="center" prop="customerId" width="180px"/>
<el-table-column label="单据状态" align="center" prop="billStatus" width="180px">
<template #default="scope">
<dict-tag :type="DICT_TYPE.OMS_BILL_STATUS" :value="scope.row.billStatus" />
</template>
</el-table-column>
<el-table-column label="订单状态" align="center" prop="orderStatus" width="180px">
<template #default="scope">
<dict-tag :type="DICT_TYPE.OMS_ORDER_STATUS" :value="scope.row.orderStatus" />
</template>
</el-table-column>
<el-table-column
label="业务日期"
align="center"
prop="bizdate"
:formatter="dateFormatter"
:formatter="dateFormatter2"
width="180px"
/>
<el-table-column
label="确认日期"
align="center"
prop="confirmdate"
:formatter="dateFormatter"
:formatter="dateFormatter2"
width="180px"
/>
<el-table-column
label="计划日期"
align="center"
prop="plansenddate"
:formatter="dateFormatter"
:formatter="dateFormatter2"
width="180px"
/>
<el-table-column label="手机" align="center" prop="phone" />
@ -151,18 +219,18 @@
<el-table-column
label="创建时间"
align="center"
prop="cdate"
prop="createTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="更新时间"
align="center"
prop="udate"
prop="updateTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<el-table-column label="操作" align="center" width="150" fixed="right">
<template #default="scope">
<el-button
link
@ -197,10 +265,12 @@
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
import {dateFormatter, dateFormatter2} from '@/utils/formatTime'
import download from '@/utils/download'
import { SaleOrderApi, SaleOrderVO } from '@/api/oms/saleorder'
import SaleOrderForm from './SaleOrderForm.vue'
import {checkPermi} from "@/utils/permission";
/** 销售订单 列表 */
defineOptions({ name: 'SaleOrder' })
@ -238,6 +308,7 @@ const queryParams = reactive({
pageSize: 10,
billno: undefined,
customerId: undefined,
tabType: 0,
bizdate: [],
confirmdate: [],
plansenddate: [],
@ -259,6 +330,15 @@ const getList = async () => {
}
}
/** 获得每个 Tab 的数量 */
const getTabsCount = async () => {
const res = await SaleOrderApi.getTabsCount()
for (let objName in res) {
tabsData.value[Number(objName)].count = res[objName]
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
@ -280,6 +360,7 @@ const openForm = (type: string, id?: number) => {
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
debugger;
//
await message.delConfirm()
//
@ -290,6 +371,38 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 审批/反审批操作 */
const handleUpdateBillStatus = async (ids: number[], status: number) => {
try {
//
await message.confirm(`确定${status === 'C' ? '审核' : '反审核'}该订单吗?`)
//
await SaleOrderApi.updateSaleOrderBillStatus(ids, status)
message.success(`${status === 'C' ? '审核' : '反审核'}成功`)
//
await getList()
selectionList.value = selectionList.value.filter((item) => !ids.includes(item.id))
} catch {}
}
/** 审批/反审批操作 */
const generateProduceOrder = async (ids: number[], status: number) => {
try {
//
await message.confirm(`是否生成生产制单?`)
//
await SaleOrderApi.generateProduceOrder(ids)
message.success(`生成成功!`)
//
await getList()
selectionList.value = selectionList.value.filter((item) => !ids.includes(item.id))
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
@ -305,8 +418,28 @@ const handleExport = async () => {
}
}
/** 切换 Tab */
const handleTabClick = (tab: TabsPaneContext) => {
queryParams.tabType = tab.paneName as number
getList()
}
/** 选中操作 */
const selectionList = ref<SaleOrderVO[]>([])
const handleSelectionChange = (rows: SaleOrderVO[]) => {
selectionList.value = rows
}
/** 激活时 */
onActivated(() => {
getList()
})
/** 初始化 **/
onMounted(() => {
getList()
//
getTabsCount()
})
</script>