feat(biz): 添加客户下拉框功能并优化订单页面
This commit is contained in:
parent
afd2914819
commit
51b7227c5f
@ -11,6 +11,7 @@ import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.Custome
|
||||
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.customer.CustomerDO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.service.customer.CustomerService;
|
||||
import com.ningxia.yunxi.chemmes.module.system.service.user.AdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -36,6 +37,9 @@ public class CustomerController {
|
||||
@Resource
|
||||
private CustomerService customerService;
|
||||
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建客户主数据")
|
||||
@PreAuthorize("@ss.hasPermission('biz:customer:create')")
|
||||
@ -90,4 +94,11 @@ public class CustomerController {
|
||||
BeanUtils.toBean(list, CustomerRespVO.class));
|
||||
}
|
||||
|
||||
// 客户下拉框
|
||||
@GetMapping("/dropdown")
|
||||
@Operation(summary = "获得客户主数据下拉框")
|
||||
@PreAuthorize("@ss.hasPermission('biz:customer:query')")
|
||||
public CommonResult<List<CustomerRespVO>> getCustomerSelect(@RequestParam(value = "keyWord", required = false, defaultValue = "") String keyWord) {
|
||||
return success(BeanUtils.toBean(customerService.getCustomerSelect(keyWord), CustomerRespVO.class));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.ningxia.yunxi.chemmes.module.biz.controller.admin.order;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult;
|
||||
import com.ningxia.yunxi.chemmes.framework.common.pojo.PageParam;
|
||||
import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult;
|
||||
@ -11,6 +12,8 @@ import com.ningxia.yunxi.chemmes.module.biz.controller.admin.order.vo.OrderRespV
|
||||
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.order.vo.OrderSaveReqVO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.order.OrderDO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.service.order.OrderService;
|
||||
import com.ningxia.yunxi.chemmes.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.ningxia.yunxi.chemmes.module.system.service.user.AdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -28,7 +31,6 @@ import static com.ningxia.yunxi.chemmes.framework.common.pojo.CommonResult.succe
|
||||
import static com.ningxia.yunxi.chemmes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
|
||||
|
||||
|
||||
@Tag(name = "管理后台 - 销售订单主")
|
||||
@RestController
|
||||
@RequestMapping("/tso/order")
|
||||
@ -38,6 +40,9 @@ public class TsoOrderController {
|
||||
@Resource
|
||||
private OrderService orderService;
|
||||
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建销售订单主")
|
||||
@PreAuthorize("@ss.hasPermission('tso:order:create')")
|
||||
@ -77,7 +82,16 @@ public class TsoOrderController {
|
||||
@PreAuthorize("@ss.hasPermission('tso:order:query')")
|
||||
public CommonResult<PageResult<OrderRespVO>> getOrderPage(@Valid OrderPageReqVO pageReqVO) {
|
||||
PageResult<OrderDO> pageResult = orderService.getOrderPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, OrderRespVO.class));
|
||||
PageResult<OrderRespVO> respPageResult = BeanUtils.toBean(pageResult, OrderRespVO.class);
|
||||
if (CollUtil.isNotEmpty(respPageResult.getList())) {
|
||||
respPageResult.getList().forEach(item -> {
|
||||
AdminUserDO userEntity = userService.getUser(item.getSaleMan());
|
||||
if (userEntity != null) {
|
||||
item.setSaleManName(userEntity.getUsername());
|
||||
}
|
||||
});
|
||||
}
|
||||
return success(respPageResult);
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
|
||||
@ -2,6 +2,7 @@ package com.ningxia.yunxi.chemmes.module.biz.controller.admin.order.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@ -21,6 +22,7 @@ public class OrderRespVO {
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "销售订单编号(SO+年份+月份+3位流水号)")
|
||||
@ -29,6 +31,7 @@ public class OrderRespVO {
|
||||
|
||||
@Schema(description = "下单日期")
|
||||
@ExcelProperty("下单日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate ordDate;
|
||||
|
||||
@Schema(description = "客户id", example = "23476")
|
||||
@ -51,6 +54,8 @@ public class OrderRespVO {
|
||||
@ExcelProperty("业务员id")
|
||||
private Long saleMan;
|
||||
|
||||
private String saleManName;
|
||||
|
||||
@Schema(description = "业务部门id", example = "11778")
|
||||
@ExcelProperty("业务部门id")
|
||||
private Long saleDeptId;
|
||||
@ -73,6 +78,7 @@ public class OrderRespVO {
|
||||
|
||||
@Schema(description = "要求交货日期")
|
||||
@ExcelProperty("要求交货日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate reqDeliveryDate;
|
||||
|
||||
@Schema(description = "是否急单(0 是 1 否)")
|
||||
@ -109,6 +115,7 @@ public class OrderRespVO {
|
||||
|
||||
@Schema(description = "审核时间")
|
||||
@ExcelProperty("审核时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime auditTime;
|
||||
|
||||
@Schema(description = "附件信息")
|
||||
|
||||
@ -7,6 +7,8 @@ import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.Custome
|
||||
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.customer.CustomerDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客户主数据 Mapper
|
||||
*
|
||||
@ -32,4 +34,9 @@ public interface CustomerMapper extends BaseMapperX<CustomerDO> {
|
||||
return selectOne(CustomerDO::getCustName, custName);
|
||||
}
|
||||
|
||||
default List<CustomerDO> selectCustomerSelect(String keyWord) {
|
||||
return selectList(new LambdaQueryWrapperX<CustomerDO>()
|
||||
.eq(CustomerDO::getEnabledStatus, 0));
|
||||
// .likeIfPresent(CustomerDO::getCustName, keyWord));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
package com.ningxia.yunxi.chemmes.module.biz.service.customer;
|
||||
|
||||
import java.util.*;
|
||||
import javax.validation.*;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.*;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.customer.CustomerDO;
|
||||
import com.ningxia.yunxi.chemmes.framework.common.pojo.PageResult;
|
||||
import com.ningxia.yunxi.chemmes.framework.common.pojo.PageParam;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.CustomerPageReqVO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.controller.admin.customer.vo.CustomerSaveReqVO;
|
||||
import com.ningxia.yunxi.chemmes.module.biz.dal.dataobject.customer.CustomerDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 客户主数据 Service 接口
|
||||
@ -52,4 +53,5 @@ public interface CustomerService {
|
||||
*/
|
||||
PageResult<CustomerDO> getCustomerPage(CustomerPageReqVO pageReqVO);
|
||||
|
||||
List<CustomerDO> getCustomerSelect(String keyWord);
|
||||
}
|
||||
@ -10,6 +10,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.ningxia.yunxi.chemmes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.ningxia.yunxi.chemmes.module.biz.enums.ErrorCodeConstants.CUSTOMER_CODE_DUPLICATE;
|
||||
@ -104,4 +105,8 @@ public class CustomerServiceImpl implements CustomerService {
|
||||
return customerMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CustomerDO> getCustomerSelect(String keyWord) {
|
||||
return customerMapper.selectCustomerSelect(keyWord);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +66,10 @@ public class OrderServiceImpl implements OrderService {
|
||||
return;
|
||||
}
|
||||
List<OrderItemDO> orderItems = BeanUtils.toBean(list, OrderItemDO.class);
|
||||
orderItems.forEach(item -> item.setSaleOrdId(saleOrdId));
|
||||
orderItems.forEach(item ->
|
||||
item.setSaleOrdId(saleOrdId)
|
||||
.setId(null)
|
||||
);
|
||||
orderItemMapper.insertBatch(orderItems);
|
||||
}
|
||||
|
||||
|
||||
@ -29,6 +29,9 @@ export interface CustomerVO {
|
||||
export const getCustomerPage = async (params) => {
|
||||
return await request.get({ url: `/biz/customer/page`, params })
|
||||
}
|
||||
export const getCustomerSelect = async (params) => {
|
||||
return await request.get({ url: `/biz/customer/dropdown`, params })
|
||||
}
|
||||
|
||||
// 查询客户主数据详情
|
||||
export const getCustomer = async (id: number) => {
|
||||
|
||||
@ -44,7 +44,8 @@ export const deleteDept = async (id: number) => {
|
||||
|
||||
export const getDeptSimpleName = async (id: number) => {
|
||||
const dept = await getDept(id);
|
||||
return dept.name;
|
||||
// 兼容CommonResult格式
|
||||
return dept.data?.name || dept.name;
|
||||
}
|
||||
|
||||
// 查询部门数据
|
||||
|
||||
@ -345,7 +345,20 @@ export function getLast1Year(): [dayjs.ConfigType, dayjs.ConfigType] {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定日期的开始时间、截止时间
|
||||
* 获取当月日期范围(当月1号 00:00:00 到当天 23:59:59)
|
||||
* @returns [开始日期, 结束日期]
|
||||
*/
|
||||
export function getCurrentMonthRange(): [string, string] {
|
||||
const now = dayjs()
|
||||
return [
|
||||
now.startOf('month').format('YYYY-MM-DD HH:mm:ss'),
|
||||
now.endOf('day').format('YYYY-MM-DD HH:mm:ss')
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期范围
|
||||
*
|
||||
* @param beginDate 开始日期
|
||||
* @param endDate 截止日期
|
||||
*/
|
||||
|
||||
@ -7,9 +7,9 @@
|
||||
<el-form-item label="部门名称" prop="name">
|
||||
<el-input v-model="formData.name" class="!w-250px" placeholder="请输入部门名称" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="显示排序" prop="sort">
|
||||
<el-form-item label="显示排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort" :min="0 " controls-position="right" class="!w-250px" />
|
||||
</el-form-item> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="负责人" prop="leaderUserId">
|
||||
<UserSelect v-model="formData.leaderUserId" @update:new-value="handleSelectedUser" />
|
||||
</el-form-item>
|
||||
@ -28,7 +28,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<!-- <el-button type="primary" @click="submitForm">确 定</el-button> -->
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</template>
|
||||
</Dialog>
|
||||
@ -57,7 +57,7 @@ const formData: any = ref({
|
||||
title: '',
|
||||
parentId: undefined,
|
||||
name: undefined,
|
||||
sort: undefined,
|
||||
sort: 0,
|
||||
leaderUserId: undefined,
|
||||
phone: undefined,
|
||||
email: undefined,
|
||||
@ -158,7 +158,7 @@ const resetForm = () => {
|
||||
title: '',
|
||||
parentId: undefined,
|
||||
name: undefined,
|
||||
sort: undefined,
|
||||
sort: 0,
|
||||
leaderUserId: undefined,
|
||||
phone: undefined,
|
||||
email: undefined,
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="订单状态" prop="ordStatus" >
|
||||
<el-select v-model="formData.ordStatus" placeholder="请选择订单状态">
|
||||
<el-select v-model="formData.ordStatus" placeholder="请选择订单状态" disabled>
|
||||
<el-option
|
||||
v-for="dict in getIntDictOptions(DICT_TYPE.ORDER_STATUS)"
|
||||
:key="dict.value"
|
||||
@ -62,24 +62,67 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="业务部门" prop="saleDeptId" >
|
||||
<el-input v-model="formData.saleDeptId" placeholder="请输入业务部门" />
|
||||
<el-input
|
||||
v-model="formData.saleDeptName"
|
||||
placeholder="请选择业务部门"
|
||||
readonly
|
||||
@click="openDeptSelect"
|
||||
>
|
||||
<template #suffix>
|
||||
<Icon icon="ep:caret-bottom" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="业务人员" prop="saleMan" >
|
||||
<el-input v-model="formData.saleMan" placeholder="请输入业务人员" />
|
||||
<el-select
|
||||
v-model="formData.saleMan"
|
||||
placeholder="请选择业务人员"
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:remote-method="searchUsers"
|
||||
:loading="userSelectLoading"
|
||||
@change="handleUserChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="user in userList"
|
||||
:key="user.id"
|
||||
:label="user.nickname + ' (' + user.username + ')'"
|
||||
:value="user.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="客户名称" prop="custName" >
|
||||
<el-input v-model="formData.custName" placeholder="请输入客户名称" />
|
||||
<el-form-item label="客户名称" prop="custId" >
|
||||
<el-select
|
||||
v-model="formData.custId"
|
||||
filterable
|
||||
:loading="customerLoading"
|
||||
placeholder="请选择客户名称"
|
||||
@change="handleCustomerChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="customer in customerOptions"
|
||||
:key="customer.id"
|
||||
:label="customer.custName"
|
||||
:value="customer.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="是否急单" prop="isUrgent" >
|
||||
<el-radio-group v-model="formData.isUrgent">
|
||||
<el-radio label="Y">是</el-radio>
|
||||
<el-radio label="N">否</el-radio>
|
||||
<el-radio
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_IS_CELL)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -115,13 +158,19 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="是否变更" prop="isChange">
|
||||
<el-form-item label="是否变更" prop="isChange" >
|
||||
<el-radio-group v-model="formData.isChange" disabled>
|
||||
<el-radio label="Y">是</el-radio>
|
||||
<el-radio label="N">否</el-radio>
|
||||
<el-radio
|
||||
v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_IS_CELL)"
|
||||
:key="dict.value"
|
||||
:label="dict.value"
|
||||
>
|
||||
{{ dict.label }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<!-- 第四行:税率、含税总金额、发货状态 -->
|
||||
<el-row :gutter="20">
|
||||
@ -172,11 +221,22 @@
|
||||
<Icon icon="ep:plus" /> 新增
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="productList" border :show-overflow-tooltip="true" v-bind="{ emptyText: '加载中...' }">
|
||||
<el-table
|
||||
ref="productTableRef"
|
||||
:data="productList"
|
||||
stripe
|
||||
style="width: 100%; display: block;"
|
||||
:show-overflow-tooltip="true"
|
||||
>
|
||||
<el-table-column label="序号" align="center" type="index" width="60px" />
|
||||
<el-table-column label="产品名称(*)" align="center" prop="materialName" />
|
||||
<el-table-column label="规格型号(*)" align="center" prop="spec" />
|
||||
<el-table-column label="单位(*)" align="center" prop="unit" />
|
||||
<el-table-column label="单位(*)" align="center" prop="unit" >
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.UNIT" :value="scope.row.unit" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="订单数量(*)" align="center" prop="ordQty">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.ordQty" placeholder="请输入" />
|
||||
@ -236,15 +296,24 @@
|
||||
ref="materialSelectRef"
|
||||
@confirm="handleMaterialSelect"
|
||||
/>
|
||||
|
||||
<!-- 部门选择弹窗 -->
|
||||
<el-dialog v-model="deptSelectVisible" title="选择部门" width="400px" append-to-body>
|
||||
<DeptTree ref="deptTreeRef" @node-click="handleDeptNodeClick" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, nextTick } from 'vue'
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import * as OrderApi from '@/api/biz/tsoorder/'
|
||||
import * as CustomerApi from '@/api/biz/customer'
|
||||
import { getIntDictOptions, getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { getDeptSimpleName } from '@/api/system/dept'
|
||||
import * as UserApi from '@/api/system/user'
|
||||
import { Icon } from '@/components/Icon'
|
||||
import MaterialSelect from '@/views/biz/material/MaterialSelect.vue'
|
||||
import DeptTree from '@/views/system/user/DeptTree.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const message = useMessage()
|
||||
@ -256,6 +325,11 @@ const formType = ref('')
|
||||
const formRef = ref()
|
||||
const materialSelectRef = ref()
|
||||
const materialSelectVisible = ref(false)
|
||||
const productTableRef = ref()
|
||||
const deptSelectVisible = ref(false)
|
||||
const deptTreeRef = ref()
|
||||
const userList = ref<UserApi.UserVO[]>([])
|
||||
const userSelectLoading = ref(false)
|
||||
|
||||
// 用途数据字典
|
||||
const purposeOptions = ref([])
|
||||
@ -268,6 +342,7 @@ const initDictOptions = () => {
|
||||
// 初始化字典
|
||||
initDictOptions()
|
||||
|
||||
|
||||
const formData = reactive({
|
||||
id: undefined,
|
||||
saleOrdNo: '自动生成',
|
||||
@ -277,7 +352,9 @@ const formData = reactive({
|
||||
contact: undefined,
|
||||
conPhone: undefined,
|
||||
saleMan: undefined,
|
||||
saleManName: undefined,
|
||||
saleDeptId: undefined,
|
||||
saleDeptName: undefined,
|
||||
ordType: undefined,
|
||||
paymentTerms: undefined,
|
||||
taxRate: undefined,
|
||||
@ -285,7 +362,7 @@ const formData = reactive({
|
||||
reqDeliveryDate: undefined,
|
||||
isUrgent: '0',
|
||||
isChange: '0',
|
||||
ordStatus: 0,
|
||||
ordStatus: 1,
|
||||
contractNo: undefined,
|
||||
packReq: undefined,
|
||||
qualityReq: undefined,
|
||||
@ -293,17 +370,22 @@ const formData = reactive({
|
||||
auditId: undefined,
|
||||
auditTime: undefined,
|
||||
attFile: undefined,
|
||||
proStatus: undefined,
|
||||
deliveryStatus: 0,
|
||||
proStatus: 0,
|
||||
deliveryStatus: 1,
|
||||
})
|
||||
|
||||
// 产品列表,默认空数组
|
||||
const productList = ref([])
|
||||
|
||||
// 客户选择相关
|
||||
const customerOptions = ref<any[]>([])
|
||||
const customerLoading = ref(false)
|
||||
|
||||
const formRules = reactive({
|
||||
ordType: [{ required: true, message: '订单类型不能为空', trigger: 'change' }],
|
||||
ordStatus: [{ required: true, message: '订单状态不能为空', trigger: 'change' }],
|
||||
ordDate: [{ required: true, message: '下单日期不能为空', trigger: 'change' }],
|
||||
custId: [{ required: true, message: '客户名称不能为空', trigger: 'change' }],
|
||||
saleDeptId: [{ required: true, message: '业务部门不能为空', trigger: 'change' }],
|
||||
saleMan: [{ required: true, message: '业务人员不能为空', trigger: 'change' }],
|
||||
isUrgent: [{ required: true, message: '是否加急不能为空', trigger: 'change' }],
|
||||
@ -313,6 +395,21 @@ const formRules = reactive({
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
|
||||
/** 详情偶发多包一层:根上无 items,但 data.items 为数组时取内层 */
|
||||
const unwrapOrderDetail = (raw: Record<string, any>) => {
|
||||
if (!raw || typeof raw !== 'object') {
|
||||
return raw
|
||||
}
|
||||
if (Array.isArray(raw.items)) {
|
||||
return raw
|
||||
}
|
||||
const inner = raw.data
|
||||
if (inner && typeof inner === 'object' && !Array.isArray(inner) && Array.isArray(inner.items)) {
|
||||
return inner
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
const open = async (type: string, id?: number) => {
|
||||
formType.value = type
|
||||
dialogTitle.value = t('action.' + type)
|
||||
@ -320,10 +417,18 @@ const open = async (type: string, id?: number) => {
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
const data = await OrderApi.getOrder(id)
|
||||
console.log('编辑模式 - 订单数据:', data)
|
||||
const response = await OrderApi.getOrder(id)
|
||||
console.log('API完整响应:', JSON.stringify(response))
|
||||
|
||||
// 处理字段类型问题:如果字段是数组,取第一个元素
|
||||
// 兼容两种响应格式:response可能是CommonResult或直接是data
|
||||
const data = response.data || response
|
||||
|
||||
if (!data || typeof data !== 'object') {
|
||||
console.error('API响应数据格式异常:', response)
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字段类型问题:如果字段是数组,取第一个元素(明细行 items 等列表字段需整表保留,不可只取首行)
|
||||
const normalizeValue = (val: any) => {
|
||||
if (Array.isArray(val) && val.length > 0) {
|
||||
return val[0]
|
||||
@ -331,27 +436,31 @@ const open = async (type: string, id?: number) => {
|
||||
return val
|
||||
}
|
||||
|
||||
// 处理日期格式:将字符串转换为 dayjs 对象
|
||||
// 处理日期格式
|
||||
const normalizeDate = (val: any) => {
|
||||
if (!val) return undefined
|
||||
if (typeof val === 'string') {
|
||||
// 尝试解析日期字符串
|
||||
return val
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// 清理 data 中的数组字段
|
||||
// 清理 data 中的数组字段;子表 items 只写入 productList
|
||||
const cleanedData: any = {}
|
||||
for (const key in data) {
|
||||
if (key === 'items') {
|
||||
continue
|
||||
}
|
||||
if (key === 'ordDate' || key === 'reqDeliveryDate') {
|
||||
cleanedData[key] = normalizeDate(data[key])
|
||||
} else if (key === 'ordStatus' || key === 'deliveryStatus' || key === 'proStatus') {
|
||||
// 状态字段需要转换为数字类型
|
||||
cleanedData[key] = Number(normalizeValue(data[key])) || 0
|
||||
} else {
|
||||
cleanedData[key] = normalizeValue(data[key])
|
||||
}
|
||||
}
|
||||
|
||||
console.log('清理后的数据:', cleanedData)
|
||||
Object.assign(formData, cleanedData)
|
||||
|
||||
// 确保状态字段有默认值
|
||||
@ -361,16 +470,41 @@ const open = async (type: string, id?: number) => {
|
||||
if (formData.deliveryStatus === undefined || formData.deliveryStatus === null) {
|
||||
formData.deliveryStatus = 0
|
||||
}
|
||||
if (data.items && data.items.length > 0) {
|
||||
console.log('设置产品明细:', data.items)
|
||||
productList.value = [...data.items]
|
||||
console.log('productList:', productList.value)
|
||||
|
||||
// 获取部门名称回显
|
||||
if (formData.saleDeptId) {
|
||||
try {
|
||||
const deptName = await getDeptSimpleName(formData.saleDeptId)
|
||||
formData.saleDeptName = deptName
|
||||
// 加载该部门下的用户列表
|
||||
await searchUsers('')
|
||||
} catch (e) {
|
||||
console.error('获取部门名称失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取业务人员名称回显
|
||||
if (formData.saleMan) {
|
||||
try {
|
||||
formData.saleManName = await getUserNameById(formData.saleMan)
|
||||
} catch (e) {
|
||||
console.error('获取业务人员名称失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理产品明细列表
|
||||
const rawItems = data?.items
|
||||
const rows = Array.isArray(rawItems) ? rawItems : (rawItems != null ? [rawItems] : [])
|
||||
productList.value = rows.length ? rows.map((r) => ({ ...r })) : []
|
||||
|
||||
console.log('处理后productList:', productList.value)
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
dialogVisible.value = true
|
||||
await nextTick()
|
||||
productTableRef.value?.doLayout?.()
|
||||
}
|
||||
|
||||
const handleCancel = async () => {
|
||||
@ -455,15 +589,17 @@ const resetForm = () => {
|
||||
formData.contact = undefined
|
||||
formData.conPhone = undefined
|
||||
formData.saleMan = undefined
|
||||
formData.saleManName = undefined
|
||||
formData.saleDeptId = undefined
|
||||
formData.saleDeptName = undefined
|
||||
formData.ordType = undefined
|
||||
formData.paymentTerms = undefined
|
||||
formData.taxRate = undefined
|
||||
formData.totalAmount = undefined
|
||||
formData.reqDeliveryDate = undefined
|
||||
formData.isUrgent = 'N'
|
||||
formData.isChange = 'N'
|
||||
formData.ordStatus = 0
|
||||
formData.isUrgent = '0'
|
||||
formData.isChange = '0'
|
||||
formData.ordStatus = 1
|
||||
formData.contractNo = undefined
|
||||
formData.packReq = undefined
|
||||
formData.qualityReq = undefined
|
||||
@ -471,9 +607,11 @@ const resetForm = () => {
|
||||
formData.auditId = undefined
|
||||
formData.auditTime = undefined
|
||||
formData.attFile = undefined
|
||||
formData.proStatus = undefined
|
||||
formData.deliveryStatus = 0
|
||||
formData.proStatus = 0
|
||||
formData.deliveryStatus = 1
|
||||
delete (formData as any).items
|
||||
productList.value = []
|
||||
userList.value = []
|
||||
}
|
||||
|
||||
// 打开物料选择弹窗
|
||||
@ -485,6 +623,98 @@ const openMaterialSelect = async () => {
|
||||
materialSelectRef.value?.open(selectedIds)
|
||||
}
|
||||
|
||||
// 打开部门选择弹窗
|
||||
const openDeptSelect = () => {
|
||||
deptSelectVisible.value = true
|
||||
}
|
||||
|
||||
// 处理部门选择
|
||||
const handleDeptNodeClick = (dept: any) => {
|
||||
formData.saleDeptId = dept.id
|
||||
formData.saleDeptName = dept.name
|
||||
// 选择部门后,清空并重新加载该部门下的用户
|
||||
formData.saleMan = undefined
|
||||
formData.saleManName = undefined
|
||||
searchUsers('')
|
||||
deptSelectVisible.value = false
|
||||
}
|
||||
|
||||
// 搜索用户
|
||||
const searchUsers = async (query: string) => {
|
||||
userSelectLoading.value = true
|
||||
try {
|
||||
const params: any = {
|
||||
pageNo: 1,
|
||||
pageSize: 50,
|
||||
status: 0
|
||||
}
|
||||
if (query) {
|
||||
params.nickname = query
|
||||
}
|
||||
// 如果选择了部门,按部门过滤
|
||||
if (formData.saleDeptId) {
|
||||
params.deptId = formData.saleDeptId
|
||||
}
|
||||
const data = await UserApi.getUserPage(params)
|
||||
userList.value = data.list || []
|
||||
} finally {
|
||||
userSelectLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 处理用户选择
|
||||
const handleUserChange = async (userId: number) => {
|
||||
if (userId) {
|
||||
const user = userList.value.find(u => u.id === userId)
|
||||
if (user) {
|
||||
formData.saleManName = user.nickname
|
||||
}
|
||||
} else {
|
||||
formData.saleManName = undefined
|
||||
}
|
||||
}
|
||||
|
||||
// 搜索客户
|
||||
// 加载客户列表(只查询一次)
|
||||
const searchCustomers = async () => {
|
||||
customerLoading.value = true
|
||||
try {
|
||||
const response = await CustomerApi.getCustomerSelect({})
|
||||
const data = response.data || response
|
||||
customerOptions.value = data || []
|
||||
} catch (error) {
|
||||
console.error('加载客户失败:', error)
|
||||
customerOptions.value = []
|
||||
} finally {
|
||||
customerLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 客户选择变化处理
|
||||
const handleCustomerChange = (custId: number) => {
|
||||
if (!custId) {
|
||||
formData.custName = undefined
|
||||
return
|
||||
}
|
||||
const customer = customerOptions.value.find(c => c.id === custId)
|
||||
if (customer) {
|
||||
formData.custName = customer.custName
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化客户列表
|
||||
searchCustomers()
|
||||
|
||||
// 获取用户名称回显
|
||||
const getUserNameById = async (userId: number) => {
|
||||
try {
|
||||
const user = await UserApi.getUser(userId)
|
||||
return user.data?.nickname || user.nickname || ''
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// 处理物料选择(多选)
|
||||
const handleMaterialSelect = (materials: any[]) => {
|
||||
const existingIds = productList.value.map(item => item.materialId)
|
||||
@ -504,6 +734,7 @@ const handleMaterialSelect = (materials: any[]) => {
|
||||
})
|
||||
}
|
||||
})
|
||||
nextTick(() => productTableRef.value?.doLayout?.())
|
||||
}
|
||||
|
||||
// 验证产品列表必填项
|
||||
@ -579,6 +810,8 @@ const removeProductItem = (index: number) => {
|
||||
|
||||
.form-content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
padding-bottom: 80px; /* 预留底部按钮空间 */
|
||||
@ -593,6 +826,10 @@ const removeProductItem = (index: number) => {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.product-detail {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -611,6 +848,10 @@ const removeProductItem = (index: number) => {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.order-product-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@ -84,40 +84,48 @@
|
||||
|
||||
<!-- 列表 -->
|
||||
<ContentWrap>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||
<el-table-column label="序号" align="center" type="index" width="60px"/>
|
||||
<el-table-column label="订单编号" align="center" prop="saleOrdNo" />
|
||||
<el-table-column label="下单日期" align="center" prop="ordDate" />
|
||||
<el-table-column label="客户名称" align="center" prop="custName" />
|
||||
<el-table-column label="订单类型" align="center" prop="ordType" />
|
||||
<el-table-column label="交货日期" align="center" prop="reqDeliveryDate" />
|
||||
<el-table-column label="是否急单" prop="isUrgent">
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" border>
|
||||
<el-table-column label="序号" align="center" type="index" width="60px" fixed="left" />
|
||||
<el-table-column label="订单编号" align="center" prop="saleOrdNo" width="150px" fixed="left" />
|
||||
<el-table-column label="下单日期" align="center" prop="ordDate" width="110px" fixed="left" />
|
||||
<el-table-column label="客户名称" align="center" prop="custName" width="250px" />
|
||||
<el-table-column label="订单类型" align="center" prop="ordType" width="150px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.ORDER_TYPE" :value="scope.row.ordType" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交货日期" align="center" prop="reqDeliveryDate" width="120px" />
|
||||
<el-table-column label="是否急单" prop="isUrgent" align="center" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.SYSTEM_IS_CELL" :value="scope.row.isUrgent" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同编号" align="center" prop="contractNo" />
|
||||
<el-table-column label="业务人员" align="center" prop="saleMan" />
|
||||
<el-table-column label="是否变更" align="center" prop="isChangeOrder" />
|
||||
<el-table-column label="生产状态" prop="proStatus">
|
||||
<el-table-column label="合同编号" align="center" prop="contractNo" width="120px" />
|
||||
<el-table-column label="业务人员" align="center" prop="saleMan" width="120px" />
|
||||
<el-table-column label="是否变更" align="center" prop="isChange" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.SYSTEM_IS_CELL" :value="scope.row.isChange" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产状态" align="center" prop="proStatus" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.PLAN_STATUS" :value="scope.row.proStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="包装要求" align="center" prop="packReq" />
|
||||
<el-table-column label="质量要求" align="center" prop="qualityReq" />
|
||||
<el-table-column label="包装要求" align="center" prop="packReq" width="180px" />
|
||||
<el-table-column label="质量要求" align="center" prop="qualityReq" width="180px" />
|
||||
|
||||
<el-table-column label="订单状态" prop="ordStatus">
|
||||
<el-table-column label="订单状态" prop="ordStatus" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.ORDER_STATUS" :value="scope.row.ordStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货状态" prop="deliveryStatus">
|
||||
<el-table-column label="发货状态" align="center" prop="deliveryStatus" width="120px">
|
||||
<template #default="scope">
|
||||
<dict-tag :type="DICT_TYPE.SHIPPING_STATUS" :value="scope.row.deliveryStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center">
|
||||
<el-table-column label="操作" align="center" width="180px" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
@ -153,7 +161,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { getStrDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||
import { dateFormatter } from '@/utils/formatTime'
|
||||
import { dateFormatter, getCurrentMonthRange } from '@/utils/formatTime'
|
||||
import * as OrderApi from '@/api/biz/tsoorder/index'
|
||||
import OrderForm from './OrderForm.vue'
|
||||
|
||||
@ -173,6 +181,15 @@ const queryParams = reactive({
|
||||
ordType: undefined,
|
||||
ordStatus: undefined,
|
||||
})
|
||||
|
||||
// 设置默认日期范围:当月1号到当天
|
||||
const setDefaultDateRange = () => {
|
||||
queryParams.ordDate = getCurrentMonthRange()
|
||||
}
|
||||
|
||||
// 初始化默认日期范围
|
||||
setDefaultDateRange()
|
||||
|
||||
const queryFormRef = ref() // 搜索的表单
|
||||
const exportLoading = ref(false) // 导出的加载中
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user