Merge branch 'claude/gallant-shamir': fix 销售订单新增页面3个Bug

This commit is contained in:
panchengyong
2026-03-11 12:59:54 +08:00
2 changed files with 46 additions and 32 deletions

View File

@@ -16,6 +16,7 @@ export interface MaterialQuery {
name?: string name?: string
category?: string category?: string
itemOrProduct?: string itemOrProduct?: string
enableFlag?: string
page?: number page?: number
pageSize?: number pageSize?: number
} }
@@ -51,6 +52,9 @@ export async function getMaterialList(params: MaterialQuery): Promise<MaterialLi
if (params.itemOrProduct) { if (params.itemOrProduct) {
query.itemOrProduct = params.itemOrProduct query.itemOrProduct = params.itemOrProduct
} }
if (params.enableFlag) {
query.enableFlag = params.enableFlag
}
const res = await listMdItem(query) const res = await listMdItem(query)
// 返回所有物料,让用户自行选择 // 返回所有物料,让用户自行选择

View File

@@ -118,21 +118,17 @@
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label="销售部门" prop="deptId"> <el-form-item label="销售部门" prop="deptId">
<el-select <el-tree-select
v-model="formData.deptId" v-model="formData.deptId"
:data="deptOptions"
:props="{ value: 'deptId', label: 'deptName', children: 'children' }"
placeholder="请选择销售部门" placeholder="请选择销售部门"
clearable clearable
check-strictly
filterable filterable
style="width: 100%" style="width: 100%"
@change="onDeptChange" @change="onDeptChange"
> />
<el-option
v-for="item in deptOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
@@ -507,12 +503,20 @@
width="55" width="55"
:reserve-selection="true" :reserve-selection="true"
/> />
<el-table-column <el-table-column
v-else v-else
type="index"
width="55" width="55"
/> align="center"
<el-table-column prop="code" label="物料编码" width="120" /> >
<template #default="{ row }">
<el-radio
v-model="selectedRadioId"
:value="row.id"
@change="handleRadioSelect(row)"
/>
</template>
</el-table-column>
<el-table-column prop="code" label="物料编码" min-width="160" show-overflow-tooltip />
<el-table-column prop="name" label="物料名称" min-width="180" show-overflow-tooltip /> <el-table-column prop="name" label="物料名称" min-width="180" show-overflow-tooltip />
<el-table-column prop="spec" label="规格型号" width="150" show-overflow-tooltip /> <el-table-column prop="spec" label="规格型号" width="150" show-overflow-tooltip />
<el-table-column prop="unit" label="单位" width="80" /> <el-table-column prop="unit" label="单位" width="80" />
@@ -566,7 +570,7 @@ import PrintDialog from '@/components/print/PrintDialog.vue'
import type { PrintConfig } from '@/components/print/types' import type { PrintConfig } from '@/components/print/types'
import { getCustomerList, type Customer } from '@/api/customer' import { getCustomerList, type Customer } from '@/api/customer'
import { getMaterialList, type Material } from '@/api/material' import { getMaterialList, type Material } from '@/api/material'
import { listDept, type Dept } from '@/api/system/dept' import { listDept, handleTree, type Dept } from '@/api/system/dept'
import { listUser, type User } from '@/api/system/user' import { listUser, type User } from '@/api/system/user'
const route = useRoute() const route = useRoute()
@@ -662,6 +666,7 @@ const materialLoading = ref(false)
const selectedMaterials = ref<Material[]>([]) const selectedMaterials = ref<Material[]>([])
const currentEditingRow = ref<SalesOrderLine | null>(null) const currentEditingRow = ref<SalesOrderLine | null>(null)
const materialTableRef = ref() const materialTableRef = ref()
const selectedRadioId = ref<number | undefined>(undefined)
/** 销售部门、销售人员选项 */ /** 销售部门、销售人员选项 */
const deptOptions = ref<Dept[]>([]) const deptOptions = ref<Dept[]>([])
@@ -769,26 +774,25 @@ async function loadOrderData() {
} }
} }
/** 部门树扁平化为列表(若接口返回树形) */ /** 部门树中递归查找指定部门 */
function flattenDepts(list: Dept[]): Dept[] { function findDeptInTree(list: Dept[], deptId: number): Dept | undefined {
const out: Dept[] = [] for (const d of list) {
function walk(items: Dept[]) { if (d.deptId === deptId) return d
items.forEach(d => { if (d.children?.length) {
out.push(d) const found = findDeptInTree(d.children, deptId)
if (d.children?.length) walk(d.children) if (found) return found
}) }
} }
walk(list) return undefined
return out
} }
/** 加载部门列表 */ /** 加载部门列表(树形结构) */
async function loadDeptList() { async function loadDeptList() {
try { try {
const res: any = await listDept() const res: any = await listDept()
const data = res?.data ?? res const data = res?.data ?? res
const raw = Array.isArray(data) ? data : (data?.list ?? data?.rows ?? []) const raw = Array.isArray(data) ? data : (data?.list ?? data?.rows ?? [])
deptOptions.value = flattenDepts(raw) deptOptions.value = handleTree(raw)
} catch (e) { } catch (e) {
console.error('加载部门列表失败', e) console.error('加载部门列表失败', e)
deptOptions.value = [] deptOptions.value = []
@@ -809,7 +813,7 @@ async function loadUserList() {
/** 销售部门变更:同步名称,清空不在该部门下的销售人员 */ /** 销售部门变更:同步名称,清空不在该部门下的销售人员 */
function onDeptChange(deptId: number | undefined) { function onDeptChange(deptId: number | undefined) {
if (deptId) { if (deptId) {
const dept = deptOptions.value.find(d => d.deptId === deptId) const dept = findDeptInTree(deptOptions.value, deptId)
formData.deptName = dept?.deptName ?? '' formData.deptName = dept?.deptName ?? ''
const inDept = salesmanOptions.value.some(u => u.userId === formData.salesmanId) const inDept = salesmanOptions.value.some(u => u.userId === formData.salesmanId)
if (!inDept) { if (!inDept) {
@@ -863,7 +867,8 @@ async function loadMaterials() {
// 支持按编码或名称搜索;仅显示产品物料(产品物料标识=PRODUCT // 支持按编码或名称搜索;仅显示产品物料(产品物料标识=PRODUCT
const params: any = { const params: any = {
pageSize: 100, // 物料选择对话框不分页,一次性加载更多 pageSize: 100, // 物料选择对话框不分页,一次性加载更多
itemOrProduct: 'PRODUCT' itemOrProduct: 'PRODUCT',
enableFlag: 'Y' // 只显示启用状态的物料
} }
if (searchText) { if (searchText) {
@@ -899,14 +904,17 @@ function handleMaterialSelectionChange(rows: Material[]) {
} }
} }
/** 单选框选择(单行模式) */
function handleRadioSelect(row: Material) {
selectedMaterials.value = [row]
}
/** 物料行点击(单行选择模式) */ /** 物料行点击(单行选择模式) */
function handleMaterialRowClick(row: Material) { function handleMaterialRowClick(row: Material) {
if (currentEditingRow.value) { if (currentEditingRow.value) {
// 单行选择模式:直接选中该行并高亮 // 单行选择模式:选中该行并同步单选框
selectedRadioId.value = row.id
selectedMaterials.value = [row] selectedMaterials.value = [row]
// 清除所有选择,然后选中当前行
materialTableRef.value?.clearSelection()
materialTableRef.value?.toggleRowSelection(row, true)
} }
} }
@@ -1206,6 +1214,7 @@ watch(showMaterialDialog, (val) => {
loadMaterials() loadMaterials()
// 清空之前的选择 // 清空之前的选择
selectedMaterials.value = [] selectedMaterials.value = []
selectedRadioId.value = undefined
// 清空表格选择状态 // 清空表格选择状态
nextTick(() => { nextTick(() => {
materialTableRef.value?.clearSelection() materialTableRef.value?.clearSelection()
@@ -1213,6 +1222,7 @@ watch(showMaterialDialog, (val) => {
} else { } else {
// 关闭对话框时清空状态 // 关闭对话框时清空状态
selectedMaterials.value = [] selectedMaterials.value = []
selectedRadioId.value = undefined
currentEditingRow.value = null currentEditingRow.value = null
materialSearch.value = '' materialSearch.value = ''
} }