增加生产制单

This commit is contained in:
Mrking 2024-09-03 13:05:46 +08:00
parent 2cfd3db67a
commit 96b087489f
39 changed files with 2423 additions and 50 deletions

View File

@ -12,6 +12,8 @@ public interface ErrorCodeConstants extends cn.hangtag.module.system.enums.Erro
ErrorCode SALE_ORDER_NOT_EXISTS = new ErrorCode(3600, "OMS销售订单主表不存在");
ErrorCode SALE_ORDER_ENTRY_NOT_EXISTS = new ErrorCode(3700, "OMS销售订单明细不存在");
ErrorCode CUSTOMER_BRAND_NOT_EXISTS = new ErrorCode(3800, "客户和品牌关联不存在");
ErrorCode PRODUCT_CARE_ITEM_NOT_EXISTS = new ErrorCode(3800, "产品保养项 不存在");
ErrorCode PRODUCT_CARE_ITEM_NOT_EXISTS = new ErrorCode(3900, "产品保养项 不存在");
ErrorCode PRODUCE_ORDER_NOT_EXISTS = new ErrorCode(4000, "生产制单不存在");
}

View File

@ -9,7 +9,11 @@ import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
import cn.hangtag.module.oms.controller.admin.brand.vo.BrandListReqVO;
import cn.hangtag.module.oms.controller.admin.brand.vo.BrandSimpleRespVO;
import cn.hangtag.module.oms.dal.dataobject.brand.BrandDO;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
import cn.hangtag.module.oms.dal.dataobject.customerbrand.CustomerBrandDO;
import cn.hangtag.module.oms.service.brand.BrandService;
import cn.hangtag.module.oms.service.customer.CustomerService;
import cn.hangtag.module.oms.service.customerbrand.CustomerBrandService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
@ -18,6 +22,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
@ -31,14 +36,28 @@ public class AppBrandController {
@Resource
private BrandService brandService;
@Resource
private CustomerService customerService;
@Resource
private CustomerBrandService customerBrandService;
@GetMapping({"/list-all-simple", "simple-list"})
@Operation(summary = "获取品牌精简信息列表", description = "只包含被开启的菜单,用于【客户分配品牌】功能的选项。" +
"在多租户的场景下,会只返回租户所在套餐有的菜单")
public CommonResult<List<BrandSimpleRespVO>> getSimpleBrandList() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
List<CustomerBrandDO> listByCustomerId = customerBrandService.getListByCustomerId(customer.getId());
List<Long> brandIds = new ArrayList<>();
for (CustomerBrandDO customerBrandDO : listByCustomerId) {
brandIds.add(customerBrandDO.getBrandId());
}
List<BrandDO> list = brandService.getBrandList(
new BrandListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
new BrandListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()).setIds(brandIds));
return success(BeanUtils.toBean(list, BrandSimpleRespVO.class));
}

View File

@ -4,6 +4,8 @@ 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.framework.ip.core.utils.AreaUtils;
import cn.hangtag.framework.security.core.LoginUser;
import cn.hangtag.framework.security.core.util.SecurityFrameworkUtils;
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerPageReqVO;
import cn.hangtag.module.oms.controller.admin.customer.vo.CustomerRespVO;
import cn.hangtag.module.oms.dal.dataobject.customer.CustomerDO;
@ -45,10 +47,9 @@ public class AppCustomerController {
@GetMapping("/get")
@Operation(summary = "获得客户")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('oms:customer:query')")
public CommonResult<CustomerRespVO> getCustomer(@RequestParam("id") Long id) {
CustomerDO customer = customerService.getCustomer(id);
public CommonResult<CustomerRespVO> getCustomer() {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
CustomerDO customer = customerService.getCustomerByUserId(loginUser.getId());
return success(buildClueDetail(customer));
}

View File

@ -3,11 +3,16 @@ package cn.hangtag.module.oms.controller.admin.brand.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 菜单列表 Request VO")
import java.util.List;
@Schema(description = "管理后台 - 品牌列表 Request VO")
@Data
public class BrandListReqVO {
@Schema(description = "菜单名称,模糊匹配", example = "芋道")
@Schema(description = "品牌ID模糊匹配", example = "芋道")
private List<Long> ids;
@Schema(description = "品牌名称,模糊匹配", example = "芋道")
private String name;
@Schema(description = "展示状态,参见 CommonStatusEnum 枚举类", example = "1")

View File

@ -38,6 +38,14 @@ public class CustomerRespVO {
@ExcelProperty("联系人手机号")
private String phone;
@Schema(description = "跟单员")
@ExcelProperty("跟单员")
private String gdperson;
@Schema(description = "销售员")
@ExcelProperty("销售员")
private String saleperson;
@Schema(description = "所属地区", example = "1024")
@ExcelProperty("所属地区")
private Integer areaId;

View File

@ -30,6 +30,12 @@ public class CustomerSaveReqVO {
@Schema(description = "联系人手机号")
private String phone;
@Schema(description = "跟单员")
private String gdperson;
@Schema(description = "销售员")
private String saleperson;
@Schema(description = "所属地区")
private Integer areaId;

View File

@ -0,0 +1,95 @@
package cn.hangtag.module.oms.controller.admin.produceorder;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.hangtag.framework.common.pojo.PageParam;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.pojo.CommonResult;
import cn.hangtag.framework.common.util.object.BeanUtils;
import static cn.hangtag.framework.common.pojo.CommonResult.success;
import cn.hangtag.framework.excel.core.util.ExcelUtils;
import cn.hangtag.framework.apilog.core.annotation.ApiAccessLog;
import static cn.hangtag.framework.apilog.core.enums.OperateTypeEnum.*;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.*;
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
import cn.hangtag.module.oms.service.produceorder.ProduceOrderService;
@Tag(name = "管理后台 - 生产制单")
@RestController
@RequestMapping("/oms/produce-order")
@Validated
public class ProduceOrderController {
@Resource
private ProduceOrderService produceOrderService;
@PostMapping("/create")
@Operation(summary = "创建生产制单")
@PreAuthorize("@ss.hasPermission('oms:produce-order:create')")
public CommonResult<Long> createProduceOrder(@Valid @RequestBody ProduceOrderSaveReqVO createReqVO) {
return success(produceOrderService.createProduceOrder(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新生产制单")
@PreAuthorize("@ss.hasPermission('oms:produce-order:update')")
public CommonResult<Boolean> updateProduceOrder(@Valid @RequestBody ProduceOrderSaveReqVO updateReqVO) {
produceOrderService.updateProduceOrder(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除生产制单")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('oms:produce-order:delete')")
public CommonResult<Boolean> deleteProduceOrder(@RequestParam("id") Long id) {
produceOrderService.deleteProduceOrder(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得生产制单")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('oms:produce-order:query')")
public CommonResult<ProduceOrderRespVO> getProduceOrder(@RequestParam("id") Long id) {
ProduceOrderDO produceOrder = produceOrderService.getProduceOrder(id);
return success(BeanUtils.toBean(produceOrder, ProduceOrderRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得生产制单分页")
@PreAuthorize("@ss.hasPermission('oms:produce-order:query')")
public CommonResult<PageResult<ProduceOrderRespVO>> getProduceOrderPage(@Valid ProduceOrderPageReqVO pageReqVO) {
PageResult<ProduceOrderDO> pageResult = produceOrderService.getProduceOrderPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ProduceOrderRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出生产制单 Excel")
@PreAuthorize("@ss.hasPermission('oms:produce-order:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportProduceOrderExcel(@Valid ProduceOrderPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<ProduceOrderDO> list = produceOrderService.getProduceOrderPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "生产制单.xls", "数据", ProduceOrderRespVO.class,
BeanUtils.toBean(list, ProduceOrderRespVO.class));
}
}

View File

@ -0,0 +1,52 @@
package cn.hangtag.module.oms.controller.admin.produceorder.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.hangtag.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.hangtag.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 生产制单分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProduceOrderPageReqVO extends PageParam {
@Schema(description = "单据编号")
private String billno;
@Schema(description = "订单号")
private String orderNo;
@Schema(description = "客户编号")
private String customerCode;
@Schema(description = "合约号")
private Integer saleContractNo;
@Schema(description = "报告日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] reportDate;
@Schema(description = "生产日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] produceDate;
@Schema(description = "生产线")
private String produceLine;
@Schema(description = "交货方式")
private String deliveryMethod;
@Schema(description = "验货日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] inspectionDate;
@Schema(description = "交货日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] deliverydate;
}

View File

@ -0,0 +1,91 @@
package cn.hangtag.module.oms.controller.admin.produceorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 生产制单 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ProduceOrderRespVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3271")
@ExcelProperty("ID")
private Long id;
@Schema(description = "单据编号")
@ExcelProperty("单据编号")
private String billno;
@Schema(description = "订单号")
@ExcelProperty("订单号")
private String orderNo;
@Schema(description = "客户编号")
@ExcelProperty("客户编号")
private String customerCode;
@Schema(description = "产品名称", example = "王五")
@ExcelProperty("产品名称")
private String productName;
@Schema(description = "合约号")
@ExcelProperty("合约号")
private Integer saleContractNo;
@Schema(description = "合约日期")
@ExcelProperty("合约日期")
private LocalDateTime contractDate;
@Schema(description = "合约数量")
@ExcelProperty("合约数量")
private Long contractQty;
@Schema(description = "生产数量")
@ExcelProperty("生产数量")
private Long produceQty;
@Schema(description = "交货地点")
@ExcelProperty("交货地点")
private String deliveryPlace;
@Schema(description = "职员")
@ExcelProperty("职员")
private String clerk;
@Schema(description = "报告日期")
@ExcelProperty("报告日期")
private LocalDateTime reportDate;
@Schema(description = "生产日期")
@ExcelProperty("生产日期")
private LocalDateTime produceDate;
@Schema(description = "天数")
@ExcelProperty("天数")
private Long days;
@Schema(description = "生产线")
@ExcelProperty("生产线")
private String produceLine;
@Schema(description = "交货方式")
@ExcelProperty("交货方式")
private String deliveryMethod;
@Schema(description = "验货日期")
@ExcelProperty("验货日期")
private LocalDateTime inspectionDate;
@Schema(description = "交货日期")
@ExcelProperty("交货日期")
private LocalDateTime deliverydate;
@Schema(description = "交货数量")
@ExcelProperty("交货数量")
private Integer deliveryQty;
}

View File

@ -0,0 +1,77 @@
package cn.hangtag.module.oms.controller.admin.produceorder.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 生产制单新增/修改 Request VO")
@Data
public class ProduceOrderSaveReqVO {
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "3271")
private Long id;
@Schema(description = "单据编号")
private String billno;
@Schema(description = "订单号")
private String orderNo;
@Schema(description = "客户编号")
private String customerCode;
@Schema(description = "产品id", example = "29732")
private Integer productId;
@Schema(description = "产品编号")
private String productCode;
@Schema(description = "产品名称", example = "王五")
private String productName;
@Schema(description = "合约号")
private Integer saleContractNo;
@Schema(description = "合约日期")
private LocalDateTime contractDate;
@Schema(description = "合约数量")
private Long contractQty;
@Schema(description = "生产数量")
private Long produceQty;
@Schema(description = "交货地点")
private String deliveryPlace;
@Schema(description = "职员")
private String clerk;
@Schema(description = "报告日期")
private LocalDateTime reportDate;
@Schema(description = "生产日期")
private LocalDateTime produceDate;
@Schema(description = "天数")
private Long days;
@Schema(description = "生产线")
private String produceLine;
@Schema(description = "交货方式")
private String deliveryMethod;
@Schema(description = "验货日期")
private LocalDateTime inspectionDate;
@Schema(description = "交货日期")
private LocalDateTime deliverydate;
@Schema(description = "交货数量")
private Integer deliveryQty;
}

View File

@ -51,6 +51,14 @@ public class CustomerDO extends BaseDO {
* 联系人手机号
*/
private String phone;
/**
* 跟单员
*/
private String gdperson;
/**
* 销售员
*/
private String saleperson;
/**
* 所属地区
*/

View File

@ -0,0 +1,120 @@
package cn.hangtag.module.oms.dal.dataobject.produceorder;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.hangtag.framework.mybatis.core.dataobject.BaseDO;
/**
* 生产制单 DO
*
* @author wwb
*/
@TableName("oms_produce_order")
@KeySequence("oms_produce_order_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProduceOrderDO extends BaseDO {
/**
* ID
*/
@TableId
private Long id;
/**
* 单据编号
*/
private String billno;
/**
* 客户ID
*/
private Integer customerId;
/**
* 订单号
*/
private String orderNo;
/**
* 客户编号
*/
private String customerCode;
/**
* 产品id
*/
private Integer productId;
/**
* 产品编号
*/
private String productCode;
/**
* 产品名称
*/
private String productName;
/**
* 合约号
*/
private Integer saleContractNo;
/**
* 合约日期
*/
private LocalDateTime contractDate;
/**
* 合约数量
*/
private Long contractQty;
/**
* 生产数量
*/
private Long produceQty;
/**
* 交货地点
*/
private String deliveryPlace;
/**
* 职员
*/
private String clerk;
/**
* 报告日期
*/
private LocalDateTime reportDate;
/**
* 生产日期
*/
private LocalDateTime produceDate;
/**
* 天数
*/
private Long days;
/**
* 生产线
*/
private String produceLine;
/**
* 交货方式
*/
private String deliveryMethod;
/**
* 验货日期
*/
private LocalDateTime inspectionDate;
/**
* 交货日期
*/
private LocalDateTime deliverydate;
/**
* 交货数量
*/
private Integer deliveryQty;
}

View File

@ -31,6 +31,7 @@ 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()));
}
}

View File

@ -0,0 +1,35 @@
package cn.hangtag.module.oms.dal.mysql.produceorder;
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.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
import org.apache.ibatis.annotations.Mapper;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.*;
/**
* 生产制单 Mapper
*
* @author wwb
*/
@Mapper
public interface ProduceOrderMapper extends BaseMapperX<ProduceOrderDO> {
default PageResult<ProduceOrderDO> selectPage(ProduceOrderPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProduceOrderDO>()
.eqIfPresent(ProduceOrderDO::getBillno, reqVO.getBillno())
.eqIfPresent(ProduceOrderDO::getOrderNo, reqVO.getOrderNo())
.eqIfPresent(ProduceOrderDO::getCustomerCode, reqVO.getCustomerCode())
.eqIfPresent(ProduceOrderDO::getSaleContractNo, reqVO.getSaleContractNo())
.betweenIfPresent(ProduceOrderDO::getReportDate, reqVO.getReportDate())
.betweenIfPresent(ProduceOrderDO::getProduceDate, reqVO.getProduceDate())
.eqIfPresent(ProduceOrderDO::getProduceLine, reqVO.getProduceLine())
.eqIfPresent(ProduceOrderDO::getDeliveryMethod, reqVO.getDeliveryMethod())
.betweenIfPresent(ProduceOrderDO::getInspectionDate, reqVO.getInspectionDate())
.betweenIfPresent(ProduceOrderDO::getDeliverydate, reqVO.getDeliverydate())
.orderByDesc(ProduceOrderDO::getId));
}
}

View File

@ -63,4 +63,6 @@ public interface CustomerService {
*/
List<CustomerAddressDO> getCustomerAddressListByCustomerId(Long customerId);
CustomerDO getCustomerByUserId(Long userId);
}

View File

@ -112,6 +112,12 @@ public class CustomerServiceImpl implements CustomerService {
return customerAddressMapper.selectListByCustomerId(customerId);
}
@Override
public CustomerDO getCustomerByUserId(Long userId) {
CustomerDO customerDO = customerMapper.selectOne(CustomerDO::getUserId, userId);
return customerDO;
}
private void createCustomerAddressList(Long customerId, List<CustomerAddressDO> list) {
list.forEach(o -> o.setCustomerId(customerId));
customerAddressMapper.insertBatch(list);

View File

@ -53,4 +53,6 @@ public interface CustomerBrandService {
PageResult<CustomerBrandDO> getCustomerBrandPage(CustomerBrandPageReqVO pageReqVO);
void assignCustomerBrand(Long customerId, Set<Long> brandIds);
List<CustomerBrandDO> getListByCustomerId(Long customerId);
}

View File

@ -104,4 +104,9 @@ public class CustomerBrandServiceImpl implements CustomerBrandService {
}
}
@Override
public List<CustomerBrandDO> getListByCustomerId(Long customerId) {
return customerBrandMapper.selectListByCustomerId(customerId);
}
}

View File

@ -0,0 +1,55 @@
package cn.hangtag.module.oms.service.produceorder;
import java.util.*;
import javax.validation.*;
import cn.hangtag.module.oms.controller.admin.produceorder.vo.*;
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
import cn.hangtag.framework.common.pojo.PageResult;
import cn.hangtag.framework.common.pojo.PageParam;
/**
* 生产制单 Service 接口
*
* @author wwb
*/
public interface ProduceOrderService {
/**
* 创建生产制单
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createProduceOrder(@Valid ProduceOrderSaveReqVO createReqVO);
/**
* 更新生产制单
*
* @param updateReqVO 更新信息
*/
void updateProduceOrder(@Valid ProduceOrderSaveReqVO updateReqVO);
/**
* 删除生产制单
*
* @param id 编号
*/
void deleteProduceOrder(Long id);
/**
* 获得生产制单
*
* @param id 编号
* @return 生产制单
*/
ProduceOrderDO getProduceOrder(Long id);
/**
* 获得生产制单分页
*
* @param pageReqVO 分页查询
* @return 生产制单分页
*/
PageResult<ProduceOrderDO> getProduceOrderPage(ProduceOrderPageReqVO pageReqVO);
}

View File

@ -0,0 +1,74 @@
package cn.hangtag.module.oms.service.produceorder;
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.produceorder.vo.*;
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
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.produceorder.ProduceOrderMapper;
import static cn.hangtag.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.hangtag.module.oms.enums.ErrorCodeConstants.*;
/**
* 生产制单 Service 实现类
*
* @author wwb
*/
@Service
@Validated
public class ProduceOrderServiceImpl implements ProduceOrderService {
@Resource
private ProduceOrderMapper produceOrderMapper;
@Override
public Long createProduceOrder(ProduceOrderSaveReqVO createReqVO) {
// 插入
ProduceOrderDO produceOrder = BeanUtils.toBean(createReqVO, ProduceOrderDO.class);
produceOrderMapper.insert(produceOrder);
// 返回
return produceOrder.getId();
}
@Override
public void updateProduceOrder(ProduceOrderSaveReqVO updateReqVO) {
// 校验存在
validateProduceOrderExists(updateReqVO.getId());
// 更新
ProduceOrderDO updateObj = BeanUtils.toBean(updateReqVO, ProduceOrderDO.class);
produceOrderMapper.updateById(updateObj);
}
@Override
public void deleteProduceOrder(Long id) {
// 校验存在
validateProduceOrderExists(id);
// 删除
produceOrderMapper.deleteById(id);
}
private void validateProduceOrderExists(Long id) {
if (produceOrderMapper.selectById(id) == null) {
throw exception(PRODUCE_ORDER_NOT_EXISTS);
}
}
@Override
public ProduceOrderDO getProduceOrder(Long id) {
return produceOrderMapper.selectById(id);
}
@Override
public PageResult<ProduceOrderDO> getProduceOrderPage(ProduceOrderPageReqVO pageReqVO) {
return produceOrderMapper.selectPage(pageReqVO);
}
}

View File

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

View File

@ -0,0 +1,166 @@
package cn.hangtag.module.oms.service.produceorder;
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.produceorder.vo.*;
import cn.hangtag.module.oms.dal.dataobject.produceorder.ProduceOrderDO;
import cn.hangtag.module.oms.dal.mysql.produceorder.ProduceOrderMapper;
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 ProduceOrderServiceImpl} 的单元测试类
*
* @author wwb
*/
@Import(ProduceOrderServiceImpl.class)
public class ProduceOrderServiceImplTest extends BaseDbUnitTest {
@Resource
private ProduceOrderServiceImpl produceOrderService;
@Resource
private ProduceOrderMapper produceOrderMapper;
@Test
public void testCreateProduceOrder_success() {
// 准备参数
ProduceOrderSaveReqVO createReqVO = randomPojo(ProduceOrderSaveReqVO.class).setId(null);
// 调用
Long produceOrderId = produceOrderService.createProduceOrder(createReqVO);
// 断言
assertNotNull(produceOrderId);
// 校验记录的属性是否正确
ProduceOrderDO produceOrder = produceOrderMapper.selectById(produceOrderId);
assertPojoEquals(createReqVO, produceOrder, "id");
}
@Test
public void testUpdateProduceOrder_success() {
// mock 数据
ProduceOrderDO dbProduceOrder = randomPojo(ProduceOrderDO.class);
produceOrderMapper.insert(dbProduceOrder);// @Sql: 先插入出一条存在的数据
// 准备参数
ProduceOrderSaveReqVO updateReqVO = randomPojo(ProduceOrderSaveReqVO.class, o -> {
o.setId(dbProduceOrder.getId()); // 设置更新的 ID
});
// 调用
produceOrderService.updateProduceOrder(updateReqVO);
// 校验是否更新正确
ProduceOrderDO produceOrder = produceOrderMapper.selectById(updateReqVO.getId()); // 获取最新的
assertPojoEquals(updateReqVO, produceOrder);
}
@Test
public void testUpdateProduceOrder_notExists() {
// 准备参数
ProduceOrderSaveReqVO updateReqVO = randomPojo(ProduceOrderSaveReqVO.class);
// 调用, 并断言异常
assertServiceException(() -> produceOrderService.updateProduceOrder(updateReqVO), PRODUCE_ORDER_NOT_EXISTS);
}
@Test
public void testDeleteProduceOrder_success() {
// mock 数据
ProduceOrderDO dbProduceOrder = randomPojo(ProduceOrderDO.class);
produceOrderMapper.insert(dbProduceOrder);// @Sql: 先插入出一条存在的数据
// 准备参数
Long id = dbProduceOrder.getId();
// 调用
produceOrderService.deleteProduceOrder(id);
// 校验数据不存在了
assertNull(produceOrderMapper.selectById(id));
}
@Test
public void testDeleteProduceOrder_notExists() {
// 准备参数
Long id = randomLongId();
// 调用, 并断言异常
assertServiceException(() -> produceOrderService.deleteProduceOrder(id), PRODUCE_ORDER_NOT_EXISTS);
}
@Test
@Disabled // TODO 请修改 null 为需要的值然后删除 @Disabled 注解
public void testGetProduceOrderPage() {
// mock 数据
ProduceOrderDO dbProduceOrder = randomPojo(ProduceOrderDO.class, o -> { // 等会查询到
o.setBillno(null);
o.setOrderNo(null);
o.setCustomerCode(null);
o.setSaleContractNo(null);
o.setReportDate(null);
o.setProduceDate(null);
o.setProduceLine(null);
o.setDeliveryMethod(null);
o.setInspectionDate(null);
o.setDeliverydate(null);
});
produceOrderMapper.insert(dbProduceOrder);
// 测试 billno 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setBillno(null)));
// 测试 orderNo 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setOrderNo(null)));
// 测试 customerCode 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setCustomerCode(null)));
// 测试 saleContractNo 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setSaleContractNo(null)));
// 测试 reportDate 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setReportDate(null)));
// 测试 produceDate 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setProduceDate(null)));
// 测试 produceLine 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setProduceLine(null)));
// 测试 deliveryMethod 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setDeliveryMethod(null)));
// 测试 inspectionDate 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setInspectionDate(null)));
// 测试 deliverydate 不匹配
produceOrderMapper.insert(cloneIgnoreId(dbProduceOrder, o -> o.setDeliverydate(null)));
// 准备参数
ProduceOrderPageReqVO reqVO = new ProduceOrderPageReqVO();
reqVO.setBillno(null);
reqVO.setOrderNo(null);
reqVO.setCustomerCode(null);
reqVO.setSaleContractNo(null);
reqVO.setReportDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setProduceDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setProduceLine(null);
reqVO.setDeliveryMethod(null);
reqVO.setInspectionDate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
reqVO.setDeliverydate(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<ProduceOrderDO> pageResult = produceOrderService.getProduceOrderPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbProduceOrder, pageResult.getList().get(0));
}
}

View File

@ -4,12 +4,12 @@ NODE_ENV=production
VITE_DEV=true
# 请求路径
VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
VITE_BASE_URL='http://localhost:8080'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server
# 上传路径
VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
VITE_UPLOAD_URL='http://localhost:8080/admin-api/infra/file/upload'
# 接口地址
VITE_API_URL=/admin-api
@ -33,4 +33,4 @@ VITE_OUT_DIR=dist
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
VITE_APP_CAPTCHA_ENABLE=false

View File

@ -4,7 +4,7 @@ NODE_ENV=production
VITE_DEV=false
# 请求路径
VITE_BASE_URL='http://localhost:48080'
VITE_BASE_URL='http://202.74.40.60:8080'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server

View File

@ -6,6 +6,8 @@ export interface CustomerVO {
company: string // 公司
email: string // 邮箱
contacts: string // 联系人
gdperson: string // 跟单员
saleperson: string // 销售员
phone: string // 联系人手机号
areaId: number // 所在地
areaName?: string // 所在地名称

View File

@ -0,0 +1,59 @@
import request from '@/config/axios'
// 生产制单 VO
export interface ProduceOrderVO {
id: number // ID
billno: string // 单据编号
orderNo: string // 订单号
customerCode: string // 客户编号
productId: number // 产品id
productCode: string // 产品编号
productName: string // 产品名称
saleContractNo: number // 合约号
contractDate: Date // 合约日期
contractQty: number // 合约数量
produceQty: number // 生产数量
deliveryPlace: string // 交货地点
clerk: string // 职员
reportDate: Date // 报告日期
produceDate: Date // 生产日期
days: number // 天数
produceLine: string // 生产线
deliveryMethod: string // 交货方式
inspectionDate: Date // 验货日期
deliverydate: Date // 交货日期
deliveryQty: number // 交货数量
}
// 生产制单 API
export const ProduceOrderApi = {
// 查询生产制单分页
getProduceOrderPage: async (params: any) => {
return await request.get({ url: `/oms/produce-order/page`, params })
},
// 查询生产制单详情
getProduceOrder: async (id: number) => {
return await request.get({ url: `/oms/produce-order/get?id=` + id })
},
// 新增生产制单
createProduceOrder: async (data: ProduceOrderVO) => {
return await request.post({ url: `/oms/produce-order/create`, data })
},
// 修改生产制单
updateProduceOrder: async (data: ProduceOrderVO) => {
return await request.put({ url: `/oms/produce-order/update`, data })
},
// 删除生产制单
deleteProduceOrder: async (id: number) => {
return await request.delete({ url: `/oms/produce-order/delete?id=` + id })
},
// 导出生产制单 Excel
exportProduceOrder: async (params) => {
return await request.download({ url: `/oms/produce-order/export-excel`, params })
},
}

View File

@ -22,6 +22,12 @@
<el-form-item label="联系人手机号" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系人手机号" />
</el-form-item>
<el-form-item label="跟单员" prop="gdperson">
<el-input v-model="formData.gdperson" placeholder="请输入跟单员" />
</el-form-item>
<el-form-item label="销售员" prop="saleperson">
<el-input v-model="formData.saleperson" placeholder="请输入销售员" />
</el-form-item>
<el-form-item label="所属地区" prop="areaId">
<el-cascader
v-model="formData.areaId"
@ -41,11 +47,11 @@
inactive-value="0"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<!-- <el-form-item label="类型" prop="type">
<el-select v-model="formData.type" placeholder="请选择类型">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks" placeholder="请输入备注" />
</el-form-item>
@ -85,6 +91,8 @@ const formData = ref({
email: undefined,
contacts: undefined,
phone: undefined,
gdperson: undefined,
saleperson: undefined,
areaId: undefined,
status: undefined,
type: undefined,

View File

@ -35,7 +35,7 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item label="类型" prop="type">
<!-- <el-form-item label="类型" prop="type">
<el-select
v-model="queryParams.type"
placeholder="请选择类型"
@ -44,7 +44,7 @@
>
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
</el-form-item>-->
<el-form-item label="数据状态" prop="status">
<el-select
v-model="queryParams.status"
@ -115,7 +115,6 @@
<el-table-column label="联系人" align="center" prop="contacts" />
<el-table-column label="联系人手机号" align="center" prop="phone" />
<el-table-column label="所属地区" align="center" prop="areaId" />
<el-table-column label="类型" align="center" prop="type" />
<el-table-column label="数据状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.OMS_DATA_STATUS" :value="scope.row.status" />
@ -146,7 +145,6 @@
编辑
</el-button>
<el-button
v-hasPermi="['oms:customer:update']"
link
preIcon="ep:basketball"
title="品牌权限"

View File

@ -0,0 +1,211 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="单据编号" prop="billno">
<el-input v-model="formData.billno" placeholder="请输入单据编号" />
</el-form-item>
<el-form-item label="订单号" prop="orderNo">
<el-input v-model="formData.orderNo" placeholder="请输入订单号" />
</el-form-item>
<el-form-item label="客户编号" prop="customerCode">
<el-input v-model="formData.customerCode" placeholder="请输入客户编号" />
</el-form-item>
<el-form-item label="产品id" prop="productId">
<el-input v-model="formData.productId" placeholder="请输入产品id" />
</el-form-item>
<el-form-item label="产品编号" prop="productCode">
<el-input v-model="formData.productCode" placeholder="请输入产品编号" />
</el-form-item>
<el-form-item label="产品名称" prop="productName">
<el-input v-model="formData.productName" placeholder="请输入产品名称" />
</el-form-item>
<el-form-item label="合约号" prop="saleContractNo">
<el-input v-model="formData.saleContractNo" placeholder="请输入合约号" />
</el-form-item>
<el-form-item label="合约日期" prop="contractDate">
<el-date-picker
v-model="formData.contractDate"
type="date"
value-format="x"
placeholder="选择合约日期"
/>
</el-form-item>
<el-form-item label="合约数量" prop="contractQty">
<el-input v-model="formData.contractQty" placeholder="请输入合约数量" />
</el-form-item>
<el-form-item label="生产数量" prop="produceQty">
<el-input v-model="formData.produceQty" placeholder="请输入生产数量" />
</el-form-item>
<el-form-item label="交货地点" prop="deliveryPlace">
<el-input v-model="formData.deliveryPlace" placeholder="请输入交货地点" />
</el-form-item>
<el-form-item label="职员" prop="clerk">
<el-input v-model="formData.clerk" placeholder="请输入职员" />
</el-form-item>
<el-form-item label="报告日期" prop="reportDate">
<el-date-picker
v-model="formData.reportDate"
type="date"
value-format="x"
placeholder="选择报告日期"
/>
</el-form-item>
<el-form-item label="生产日期" prop="produceDate">
<el-date-picker
v-model="formData.produceDate"
type="date"
value-format="x"
placeholder="选择生产日期"
/>
</el-form-item>
<el-form-item label="天数" prop="days">
<el-input v-model="formData.days" placeholder="请输入天数" />
</el-form-item>
<el-form-item label="生产线" prop="produceLine">
<el-input v-model="formData.produceLine" placeholder="请输入生产线" />
</el-form-item>
<el-form-item label="交货方式" prop="deliveryMethod">
<el-input v-model="formData.deliveryMethod" placeholder="请输入交货方式" />
</el-form-item>
<el-form-item label="验货日期" prop="inspectionDate">
<el-date-picker
v-model="formData.inspectionDate"
type="date"
value-format="x"
placeholder="选择验货日期"
/>
</el-form-item>
<el-form-item label="交货日期" prop="deliverydate">
<el-date-picker
v-model="formData.deliverydate"
type="date"
value-format="x"
placeholder="选择交货日期"
/>
</el-form-item>
<el-form-item label="交货数量" prop="deliveryQty">
<el-input v-model="formData.deliveryQty" placeholder="请输入交货数量" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ProduceOrderApi, ProduceOrderVO } from '@/api/oms/produceorder'
/** 生产制单 表单 */
defineOptions({ name: 'ProduceOrderForm' })
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
billno: undefined,
orderNo: undefined,
customerCode: undefined,
productId: undefined,
productCode: undefined,
productName: undefined,
saleContractNo: undefined,
contractDate: undefined,
contractQty: undefined,
produceQty: undefined,
deliveryPlace: undefined,
clerk: undefined,
reportDate: undefined,
produceDate: undefined,
days: undefined,
produceLine: undefined,
deliveryMethod: undefined,
inspectionDate: undefined,
deliverydate: undefined,
deliveryQty: undefined,
})
const formRules = reactive({
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await ProduceOrderApi.getProduceOrder(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as ProduceOrderVO
if (formType.value === 'create') {
await ProduceOrderApi.createProduceOrder(data)
message.success(t('common.createSuccess'))
} else {
await ProduceOrderApi.updateProduceOrder(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
billno: undefined,
orderNo: undefined,
customerCode: undefined,
productId: undefined,
productCode: undefined,
productName: undefined,
saleContractNo: undefined,
contractDate: undefined,
contractQty: undefined,
produceQty: undefined,
deliveryPlace: undefined,
clerk: undefined,
reportDate: undefined,
produceDate: undefined,
days: undefined,
produceLine: undefined,
deliveryMethod: undefined,
inspectionDate: undefined,
deliverydate: undefined,
deliveryQty: undefined,
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,318 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb1px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="单据编号" prop="billno">
<el-input
v-model="queryParams.billno"
placeholder="请输入单据编号"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="订单号" prop="orderNo">
<el-input
v-model="queryParams.orderNo"
placeholder="请输入订单号"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="客户编号" prop="customerCode">
<el-input
v-model="queryParams.customerCode"
placeholder="请输入客户编号"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="合约号" prop="saleContractNo">
<el-input
v-model="queryParams.saleContractNo"
placeholder="请输入合约号"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="报告日期" prop="reportDate">
<el-date-picker
v-model="queryParams.reportDate"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="生产日期" prop="produceDate">
<el-date-picker
v-model="queryParams.produceDate"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="生产线" prop="produceLine">
<el-input
v-model="queryParams.produceLine"
placeholder="请输入生产线"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="交货方式" prop="deliveryMethod">
<el-input
v-model="queryParams.deliveryMethod"
placeholder="请输入交货方式"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="验货日期" prop="inspectionDate">
<el-date-picker
v-model="queryParams.inspectionDate"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="交货日期" prop="deliverydate">
<el-date-picker
v-model="queryParams.deliverydate"
value-format="YYYY-MM-DD HH:mm:ss"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="-mb-1px">
<el-col :span="1.5">
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['oms:produce-order:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['oms:produce-order:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-col>
</el-row>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="ID" align="center" prop="id" />
<el-table-column label="单据编号" align="center" prop="billno" />
<el-table-column label="订单号" align="center" prop="orderNo" />
<el-table-column label="客户编号" align="center" prop="customerCode" />
<el-table-column label="产品名称" align="center" prop="productName" />
<el-table-column label="合约号" align="center" prop="saleContractNo" />
<el-table-column
label="合约日期"
align="center"
prop="contractDate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="合约数量" align="center" prop="contractQty" />
<el-table-column label="生产数量" align="center" prop="produceQty" />
<el-table-column label="交货地点" align="center" prop="deliveryPlace" />
<el-table-column label="职员" align="center" prop="clerk" />
<el-table-column
label="报告日期"
align="center"
prop="reportDate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="生产日期"
align="center"
prop="produceDate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="天数" align="center" prop="days" />
<el-table-column label="生产线" align="center" prop="produceLine" />
<el-table-column label="交货方式" align="center" prop="deliveryMethod" />
<el-table-column
label="验货日期"
align="center"
prop="inspectionDate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="交货日期"
align="center"
prop="deliverydate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="交货数量" align="center" prop="deliveryQty" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
link
type="primary"
@click="openForm('update', scope.row.id)"
v-hasPermi="['oms:produce-order:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(scope.row.id)"
v-hasPermi="['oms:produce-order:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ProduceOrderForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import { ProduceOrderApi, ProduceOrderVO } from '@/api/oms/produceorder'
import ProduceOrderForm from './ProduceOrderForm.vue'
/** 生产制单 列表 */
defineOptions({ name: 'ProduceOrder' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref<ProduceOrderVO[]>([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
billno: undefined,
orderNo: undefined,
customerCode: undefined,
saleContractNo: undefined,
reportDate: [],
produceDate: [],
produceLine: undefined,
deliveryMethod: undefined,
inspectionDate: [],
deliverydate: [],
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ProduceOrderApi.getProduceOrderPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await ProduceOrderApi.deleteProduceOrder(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await ProduceOrderApi.exportProduceOrder(queryParams)
download.excel(data, '生产制单.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

View File

@ -2,7 +2,7 @@
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
class="-mb1px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
@ -17,10 +17,10 @@
class="!w-240px"
/>
</el-form-item>
<el-form-item label="客户id" prop="customerId">
<el-form-item label="客户" prop="customerId">
<el-input
v-model="queryParams.customerId"
placeholder="请输入客户id"
placeholder="请输入客户"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
@ -80,13 +80,21 @@
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="-mb-1px">
<el-col :span="1.5">
<el-button
type="primary"
plain
>生产中
</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['oms:sale-order:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
已完成
</el-button>
<el-button
type="success"
@ -97,15 +105,26 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-tabs v-model="queryParams.tabType" @tab-click="handleTabClick">
<el-tab-pane
v-for="item in tabsData"
:key="item.type"
:label="item.name + '(' + item.count + ')'"
:name="item.type"
/>
</el-tabs>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<el-table-column label="单据编号" align="center" prop="billno" />
<el-table-column label="客户id" align="center" prop="customerId" />
<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"
@ -113,21 +132,6 @@
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column
label="更新时间"
align="center"
prop="udate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="创建时间"
align="center"
prop="cdate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="确认日期"
align="center"
@ -144,6 +148,20 @@
/>
<el-table-column label="手机" align="center" prop="phone" />
<el-table-column label="备注" align="center" prop="remarks" />
<el-table-column
label="创建时间"
align="center"
prop="cdate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column
label="更新时间"
align="center"
prop="udate"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button
@ -193,6 +211,28 @@ const { t } = useI18n() // 国际化
const loading = ref(true) //
const list = ref<SaleOrderVO[]>([]) //
const total = ref(0) //
// tabs
const tabsData = ref([
{
name: '已下单',
type: 0,
count: 0
},
{
name: '生产中',
type: 1,
count: 0
},
{
name: '已完成',
type: 2,
count: 0
}
])
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
@ -269,4 +309,4 @@ const handleExport = async () => {
onMounted(() => {
getList()
})
</script>
</script>

View File

@ -4,12 +4,12 @@ NODE_ENV=production
VITE_DEV=true
# 请求路径
VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
VITE_BASE_URL='http://localhost:8080'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server
# 上传路径
VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
VITE_UPLOAD_URL='http://localhost:8080/admin-api/infra/file/upload'
# 接口地址
VITE_API_URL=/admin-api
@ -33,4 +33,4 @@ VITE_OUT_DIR=dist
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# 验证码的开关
VITE_APP_CAPTCHA_ENABLE=true
VITE_APP_CAPTCHA_ENABLE=false

View File

@ -4,7 +4,7 @@ NODE_ENV=production
VITE_DEV=false
# 请求路径
VITE_BASE_URL='http://localhost:48080'
VITE_BASE_URL='http://202.74.40.60:8080'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server

View File

@ -20,8 +20,8 @@ export const CustomerApi = {
},
// 查询客户详情
getCustomer: async (id: number) => {
return await request.get({ url: `/oms/customer/get?id=` + id })
getCustomer: async () => {
return await request.get({ url: `/oms/app/customer/get`})
},
// 新增客户
@ -51,3 +51,6 @@ export const CustomerApi = {
return await request.get({ url: `/oms/customer/customer-address/list-by-customer-id?customerId=` + customerId })
},
}

View File

@ -0,0 +1,121 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="名字" prop="name">
<el-input v-model="formData.name" placeholder="请输入名字" />
</el-form-item>
<el-form-item label="性别" prop="sex">
<el-radio-group v-model="formData.sex">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="出生日期" prop="birthday">
<el-date-picker
v-model="formData.birthday"
type="date"
value-format="x"
placeholder="选择出生日期"
/>
</el-form-item>
<el-form-item label="简介" prop="description">
<Editor v-model="formData.description" height="150px" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
})
const formRules = reactive({
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
sex: [{ required: true, message: '性别不能为空', trigger: 'blur' }],
birthday: [{ required: true, message: '出生日期不能为空', trigger: 'blur' }],
description: [{ required: true, message: '简介不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
formData.value = await Demo03StudentApi.getDemo03Student(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value as unknown as Demo03StudentApi.Demo03StudentVO
if (formType.value === 'create') {
await Demo03StudentApi.createDemo03Student(data)
message.success(t('common.createSuccess'))
} else {
await Demo03StudentApi.updateDemo03Student(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: undefined,
sex: undefined,
birthday: undefined,
description: undefined
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,99 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="名字" prop="name">
<el-input v-model="formData.name" placeholder="请输入名字" />
</el-form-item>
<el-form-item label="分数" prop="score">
<el-input v-model="formData.score" placeholder="请输入分数" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
const { t } = useI18n() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref('') // create - update -
const formData = ref({
id: undefined,
studentId: undefined,
name: undefined,
score: undefined
})
const formRules = reactive({
studentId: [{ required: true, message: '学生编号不能为空', trigger: 'blur' }],
name: [{ required: true, message: '名字不能为空', trigger: 'blur' }],
score: [{ required: true, message: '分数不能为空', trigger: 'blur' }]
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number, studentId: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.studentId = studentId
//
if (id) {
formLoading.value = true
try {
formData.value = await Demo03StudentApi.getDemo03Course(id)
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // open
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
await formRef.value.validate()
//
formLoading.value = true
try {
const data = formData.value
if (formType.value === 'create') {
await Demo03StudentApi.createDemo03Course(data)
message.success(t('common.createSuccess'))
} else {
await Demo03StudentApi.updateDemo03Course(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
//
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
studentId: undefined,
name: undefined,
score: undefined
}
formRef.value?.resetFields()
}
</script>

View File

@ -0,0 +1,122 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-button
plain
type="primary"
@click="openForm('create')"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
</el-button>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column align="center" label="订货数量" prop="id" />
<el-table-column align="center" label="REF" prop="name" />
<el-table-column align="center" label="操作">
<template #default="scope">
<el-button
v-hasPermi="['infra:demo03-student:update']"
link
type="primary"
@click="openForm('update', scope.row.id)"
>
编辑
</el-button>
<el-button
v-hasPermi="['infra:demo03-student:delete']"
link
type="danger"
@click="handleDelete(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<Demo03CourseForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
import { dateFormatter } from '@/utils/formatTime'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import Demo03CourseForm from './Demo03CourseForm.vue'
const { t } = useI18n() //
const message = useMessage() //
const props = defineProps<{
studentId?: number //
}>()
const loading = ref(false) //
const list = ref([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
studentId: undefined as unknown
})
/** 监听主表的关联字段的变化,加载对应的子表数据 */
watch(
() => props.studentId,
(val: number) => {
if (!val) {
return
}
queryParams.studentId = val
handleQuery()
},
{ immediate: true, deep: true }
)
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await Demo03StudentApi.getDemo03CoursePage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
if (!props.studentId) {
message.error('请选择一个产品内容')
return
}
formRef.value.open(type, id, props.studentId)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await Demo03StudentApi.deleteDemo03Course(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
</script>

View File

@ -0,0 +1,397 @@
<template>
<ContentWrap>
<el-row :gutter="10">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="150px"
v-loading="formLoading"
>
<div>
<el-card header="基本资料" style="width: 100%; margin-top: 20px" shadow="never" class="box-card">
<template #header>
<CardTitle title="基本资料" />
</template>
<el-row>
<el-col :span="12">
<el-form-item label="订单号码" prop="orderNo">
<el-input v-model="formData.orderNo" disabled="true" placeholder="*** New ***" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="订单状态" prop="orderstatus">
<el-input v-model="formData.orderstatus" disabled="true" placeholder="INITIAL" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="用户名称" prop="username">
<el-input v-model="formData.username" disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="创建日期 (GMT+8)" prop="bizdate">
<el-date-picker
prefix-icon=""
style="width: 760px"
v-model="formData.bizdate"
type="date"
value-format="YYYY-MM-DD"
disabled="true"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="客户号" prop="customerId">
<el-input v-model="formData.customerId" disabled="true" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="企业公司" prop="company">
<el-input v-model="formData.company" disabled="true" placeholder="" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="品牌" prop="brandId">
<el-select v-model="formData.brandId" filterable placeholder="请选择品牌">
<el-option
v-for="brand in brandList"
:key="brand.id"
:label="brand.name"
:value="brand.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="要求交货日期" prop="plansenddate">
<el-date-picker
style="width: 760px"
v-model="formData.plansenddate"
type="date"
:size="size"
/>
</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="手机" 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="tel">
<el-input v-model="formData.tel" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="传真" prop="fax">
<el-input v-model="formData.fax" placeholder="" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="合同号" prop="contract">
<el-input v-model="formData.contractNo" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="零售商单号" prop="retailerno">
<el-input v-model="formData.retailerNo" placeholder="" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-form-item label="备注" prop="remarks">
<el-input v-model="formData.remarks"
:autosize="{ minRows: 4, maxRows: 6 }"
type="textarea"
placeholder="请输入备注" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<el-card header="电子邮件通知" style="width: 100%; margin-top: 20px" shadow="never">
<template #header>
<CardTitle title="电子邮件通知" />
</template>
<el-row>
<el-col :span="12">
<el-form-item label="电子邮件" prop="newEmail">
<el-input v-model="formData.newEmail" placeholder="" />
</el-form-item>
</el-col>
<el-col :span="12" >
<div style="margin-left: 30px">
<el-button size="Default" @click="onAddEmail">增加</el-button>
<el-button size="Default" @click="onDelEmail">删除</el-button>
</div>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="" prop="">
<div style="border: 1px solid #dcdfe6;width:100%;height: 200px;">
<el-scrollbar height="200px">
<ul style="padding-left: 4px;margin-top: 4px;">
<li style="list-style-type: none" v-for="(item, index) in formData.newEmails" :key="index" @click="selectItem(index)" :class="{'selected': selectedIndex === index}">
{{ item }}
</li>
</ul>
</el-scrollbar>
</div>
</el-form-item>
</el-col>
</el-row>
</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-row>
<el-col :span="12">
<el-form-item label="发票抬头" prop="invoiceCode">
<el-input v-model="formData.invoiceCode" placeholder="请输入发票抬头" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发票名称" prop="invoiceName">
<el-input v-model="formData.invoiceName" placeholder="请输入发票名称" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="发票地址" prop="invoiceAddress">
<el-input v-model="formData.invoiceAddress" placeholder="请输入发票地址" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发票备注" prop="invoiceRemarks">
<el-input v-model="formData.invoiceRemarks"
:autosize="{ minRows: 4, maxRows: 6 }"
type="textarea"
placeholder="请输入发票备注" />
</el-form-item>
</el-col>
</el-row>
</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>
<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>-->
</div>
</el-form>
</el-row>
<!-- <el-affix position="bottom" :offset="20">
<el-row style="margin-top: 20px;border-top: #1e83e9" justify="end" >
<el-col :span="2">
<el-button type="primary" plain size="mini" @click="openForm(undefined)">下一步</el-button>
</el-col>
</el-row>
</el-affix>
-->
</ContentWrap>
<!-- 固定在底部的行面板 -->
<el-affix position="bottom" :offset="20">
<div style="background-color: #909399; padding: 20px; text-align: right;">
<!-- 使用 el-row el-col 来控制布局虽然在这个简单场景下可能不是必需的 -->
<el-row>
<el-col :span="24">
<!-- 结算按钮 -->
<!-- <el-button type="primary">结算</el-button>-->
<!-- 下一步按钮 -->
<el-button type="success" style="margin-left: 10px;">下一步</el-button>
</el-col>
</el-row>
</div>
</el-affix>
</template>
<script setup lang="ts">
import {defaultProps} from "@/utils/tree";
import * as BrandApi from "@/api/oms/brand";
import {CustomerApi, getCustomer} from "@/api/oms/customer";
//
const calculateDateAfterDays = (days) => {
const now = new Date();
now.setDate(now.getDate() + days);
// 'YYYY-MM-DD'
return now.toISOString().split('T')[0];
}
const formRef = ref() // Ref
const selectedIndex = ref(-1)
const emails = ref([])
const customerData = ref()
const formData = ref({
name: undefined,
email: undefined,
contacts: undefined,
phone: undefined,
invoiceAddress: undefined,
areaId: undefined,
status: undefined,
type: undefined,
remarks: undefined,
orderNo: undefined,
invoiceName: undefined,
newEmail: '',
newEmails: [],
bizdate: new Date().toISOString(),
plansenddate: calculateDateAfterDays(7)
})
const formRules = reactive({
name: [{ required: true, message: '名称不能为空', trigger: 'blur' }],
contacts: [{ required: true, message: '联系人不能为空', trigger: 'blur' }],
brandId: [{ 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 onAddEmail = () => {
debugger;
if (formData.value.newEmail.trim() !== '') {
formData.value.newEmails.push(formData.value.newEmail);
formData.value.newEmail = ''; //
}
}
const selectItem = async (index:number) => {
selectedIndex.value = index;
}
const onDelEmail = () => {
if(selectedIndex.value>=0){
debugger;
formData.value.newEmails.splice(selectedIndex.value, 1); //
//
if(selectedIndex.value === selectedIndex.value) {
selectedIndex.value = -1;
}
}
selectedIndex.value = -1;
}
/** 查询列表 */
const getCustomer = async () => {
loading.value = true
try {
const data = await CustomerApi.getCustomerPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 初始化 **/
const brandList = ref<any[]>([]) //
onMounted(async () => {
//
brandList.value = await BrandApi.getSimpleBrandList()
customerData.value = await CustomerApi.getCustomer()
formData.value.customerId = customerData.value.id;
formData.value.username = customerData.value.name;
formData.value.company = customerData.value.company;
})
</script>
<style scoped lang="scss">
/* 为选中的行添加背景色 */
.selected {
background-color: #dddee0; /* 浅绿色,可以根据需要调整 */
}
</style>

View File

@ -0,0 +1,153 @@
<template>
<!-- 列表 -->
<ContentWrap>
<el-tabs model-value="productContent">
<el-tab-pane label="产品内容" name="productContent">
<el-row :gutter="10" class="mb0px">
<el-col>
<el-button
plain
type="primary"
>
<Icon class="mr-5px" icon="ep:plus" />
新增
</el-button>
</el-col>
</el-row>
<el-table
v-loading="loading"
:data="list"
:s how-overflow-tooltip="true"
:stripe="true"
highlight-current-row
@current-change="handleCurrentChange"
>
<el-table-column align="center" label="客户产品编码" prop="id" />
<el-table-column align="center" label="产品描述" prop="name" />
<el-table-column align="center" label="产品图片" prop="name" />
<el-table-column align="center" label="数量单位" prop="name" />
<el-table-column align="center" label="订货数量" prop="name" />
<el-table-column align="center" label="补足数量" prop="name" />
<el-table-column align="center" label="总数量" prop="name" />
<el-table-column align="center" label="要求交货日期" prop="name" />
</el-table>
<!-- 分页 -->
<Pagination
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNo"
:total="total"
@pagination="getList"
/>
</el-tab-pane>
</el-tabs>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<Demo03StudentForm ref="formRef" @success="getList" />
<!-- 子表的列表 -->
<ContentWrap>
<el-tabs model-value="variantCodeContent">
<el-tab-pane label="变码内容" name="variantCodeContent">
<Demo03CourseList :student-id="currentRow?.id" />
</el-tab-pane>
</el-tabs>
</ContentWrap>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as Demo03StudentApi from '@/api/infra/demo/demo03/erp'
import Demo03StudentForm from './Demo03StudentForm.vue'
import Demo03CourseList from './components/Demo03CourseList.vue'
import Demo03GradeList from './components/Demo03GradeList.vue'
defineOptions({ name: 'Demo03Student' })
const message = useMessage() //
const { t } = useI18n() //
const loading = ref(true) //
const list = ref([]) //
const total = ref(0) //
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
name: null,
sex: null,
description: null,
createTime: []
})
const queryFormRef = ref() //
const exportLoading = ref(false) //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await Demo03StudentApi.getDemo03StudentPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
//
await message.delConfirm()
//
await Demo03StudentApi.deleteDemo03Student(id)
message.success(t('common.delSuccess'))
//
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
//
await message.exportConfirm()
//
exportLoading.value = true
const data = await Demo03StudentApi.exportDemo03Student(queryParams)
download.excel(data, '学生.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 选中行操作 */
const currentRow = ref({}) //
const handleCurrentChange = (row) => {
currentRow.value = row
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>