feat(biz): 添加客户下拉框功能并优化订单页面

This commit is contained in:
zxy 2026-05-13 10:11:00 +08:00
parent afd2914819
commit 51b7227c5f
13 changed files with 507 additions and 183 deletions

View File

@ -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));
}
}

View File

@ -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")

View File

@ -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 = "附件信息")

View File

@ -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));
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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) => {

View File

@ -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;
}
// 查询部门数据

View File

@ -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
*/

View File

@ -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,

View File

@ -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))
//
// responseCommonResultdata
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;
}

View File

@ -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) //