Files
xgy-oa/klp-ui/src/views/wms/delivery/permi/index.vue
砂糖 1b5efc00f6 fix(wms): 修正钢卷选择器筛选条件及显示逻辑
- 统一钢卷选择器的selectType为'product'并添加status过滤
- 修复materialType与selectType的映射关系
- 移除分页组件的rangeMode条件限制
- 更新部分字段显示名称
2026-01-15 17:33:54 +08:00

590 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- 销售权限 -->
<el-row :gutter="10" class="sales-permission-container">
<!-- 销售列表 -->
<el-col :span="3" class="sales-tree-container">
<div class="tree-title">销售列表</div>
<!-- 用树展示销售用户列表 -->
<el-tree ref="salesTree" :data="userTreeData" :props="treeProps" node-key="id" @node-click="handleTreeNodeClick"
highlight-current :expand-on-click-node="false">
</el-tree>
</el-col>
<el-col :span="21" class="coil-table-container">
<!-- 待分配卷表格标题 -->
<div class="table-title">
<span>待分配钢卷</span>
<!-- 搜索区域 -->
<div style="display: flex; align-items: center; justify-content: flex-end;">
<el-form :inline="true" :model="queryParamsWithUnAssignedId" class="search-form">
<el-form-item label="卷号">
<el-input style="width: 100px;" v-model="queryParamsWithUnAssignedId.currentCoilNo" placeholder="输入卷号"
clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料">
<muti-select style="width: 100px;" v-model="queryParamsWithUnAssignedId.itemName"
:options="dict.type.coil_itemname" placeholder="请选择物料" clearable />
</el-form-item>
<el-form-item label="规格">
<memo-input style="width: 100px;" storageKey="coilSpec"
v-model="queryParamsWithUnAssignedId.specification" placeholder="请输入规格" clearable size="small"
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质">
<muti-select style="width: 100px;" v-model="queryParamsWithUnAssignedId.itemMaterial"
:options="dict.type.coil_material" placeholder="请选择材质" clearable />
</el-form-item>
<el-form-item label="厂家">
<muti-select style="width: 100px;" v-model="queryParamsWithUnAssignedId.itemManufacturer"
:options="dict.type.coil_manufacturer" placeholder="请选择厂家" clearable />
</el-form-item>
</el-form>
<pagination v-show="unAssignedTotal > 0" :total="unAssignedTotal"
:page.sync="queryParamsWithUnAssignedId.pageNum" :limit.sync="queryParamsWithUnAssignedId.pageSize"
@pagination="listUnAssignedCoil" />
<el-button type="primary" size="mini" icon="el-icon-refresh" @click="listUnAssignedCoil">刷新</el-button>
</div>
</div>
<!-- 上方是待分配的卷 -->
<KLPTable height="40vh" v-loading="unAssignedLoading" :data="unAssignedCoilList" :floatLayer="true"
:floatLayerConfig="floatLayerConfig">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" />
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row.product" />
<RawMaterialInfo v-else-if="scope.row.itemType === 'raw_material'" :material="scope.row.rawMaterial" />
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime">
<template slot-scope="scope">
{{ scope.row.updateTime }}
</template>
</el-table-column>
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="关联信息" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.parentCoilNos && scope.row.hasMergeSplit === 1 && scope.row.dataType === 1">
<el-tag type="warning" size="mini">来自母卷{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else-if="scope.row.parentCoilNos && scope.row.dataType === 0">
<el-tag type="info" size="mini">分为子卷{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else-if="scope.row.parentCoilNos && scope.row.hasMergeSplit === 2">
<el-tag type="success" size="mini">合并自{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="primary" size="mini" @click="handleAssign(scope.row)"
:disabled="!currentUser.id">分配</el-button>
</template>
</el-table-column>
</KLPTable>
<!-- 已分配卷区域有选中销售才显示表格否则显示空提示 -->
<div v-if="currentUser.id">
<!-- 已分配卷表格标题 -->
<div class="table-title" style="margin-top: 20px">
<span>已分配给 {{ currentUser.nickName || '未选择销售' }} 的钢卷</span>
<div style="display: flex; align-items: center; justify-content: flex-end;">
<!-- 搜索区域 -->
<el-form :inline="true" :model="queryParamsWithSalesId">
<el-form-item label="卷号">
<el-input style="width: 100px;" v-model="queryParamsWithSalesId.currentCoilNo" placeholder="请输入卷号"
clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="物料">
<muti-select style="width: 100px;" v-model="queryParamsWithSalesId.itemName"
:options="dict.type.coil_itemname" placeholder="请选择物料" clearable />
</el-form-item>
<el-form-item label="规格">
<memo-input style="width: 100px;" storageKey="coilSpec" v-model="queryParamsWithSalesId.specification"
placeholder="请输入规格" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="材质">
<muti-select style="width: 100px;" v-model="queryParamsWithSalesId.itemMaterial"
:options="dict.type.coil_material" placeholder="请选择材质" clearable />
</el-form-item>
<el-form-item label="厂家">
<muti-select style="width: 100px;" v-model="queryParamsWithSalesId.itemManufacturer"
:options="dict.type.coil_manufacturer" placeholder="请选择厂家" clearable />
</el-form-item>
</el-form>
<pagination v-show="salesTotal > 0" :total="salesTotal" :page.sync="queryParamsWithSalesId.pageNum"
:limit.sync="queryParamsWithSalesId.pageSize" @pagination="listSalesCoil" />
<el-button type="primary" size="mini" icon="el-icon-refresh" @click="listSalesCoil"
:disabled="!currentUser.id">刷新</el-button>
</div>
</div>
<!-- 下方是已分配的卷 -->
<KLPTable height="40vh" v-loading="salesLoading" :data="salesCoilList" :floatLayer="true"
:floatLayerConfig="floatLayerConfig">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.enterCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="当前钢卷号" align="center" prop="currentCoilNo">
<template slot-scope="scope">
<coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
</template>
</el-table-column>
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
<el-table-column label="实际库区" align="center" prop="actualWarehouseName" />
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row.product" />
<RawMaterialInfo v-else-if="scope.row.itemType === 'raw_material'" :material="scope.row.rawMaterial" />
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updateTime">
<template slot-scope="scope">
{{ scope.row.updateTime }}
</template>
</el-table-column>
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="关联信息" align="center" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span v-if="scope.row.parentCoilNos && scope.row.hasMergeSplit === 1 && scope.row.dataType === 1">
<el-tag type="warning" size="mini">来自母卷{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else-if="scope.row.parentCoilNos && scope.row.dataType === 0">
<el-tag type="info" size="mini">分为子卷{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else-if="scope.row.parentCoilNos && scope.row.hasMergeSplit === 2">
<el-tag type="success" size="mini">合并自{{ scope.row.parentCoilNos }}</el-tag>
</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button type="danger" size="mini" @click="handleRemove(scope.row)">移除</el-button>
</template>
</el-table-column>
</KLPTable>
</div>
<!-- 未选择销售时的空提示 -->
<div v-else class="empty-container">
<el-empty description="请先从左侧选择销售用户"></el-empty>
</div>
</el-col>
</el-row>
</template>
<script>
import { listUser } from '@/api/system/user'
import { listMaterialCoil, updateMaterialCoilSimple } from '@/api/wms/coil'
import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
import MutiSelect from "@/components/MutiSelect";
import MemoInput from "@/components/MemoInput";
export default {
name: 'SalesCoilPermission',
components: {
CoilNo,
ProductInfo,
RawMaterialInfo,
MutiSelect,
MemoInput
},
dicts: ['coil_itemname', 'coil_material', 'coil_manufacturer'],
data() {
return {
// 用户列表(原始数据)
userList: [],
// 树形结构用户数据
userTreeData: [],
// 树组件配置
treeProps: {
label: 'nickName',
children: 'children'
},
// 部门ID销售部门
deptId: '2001463253405609986',
// 已分配钢卷查询参数
queryParamsWithSalesId: {
selectType: 'product',
materialType: '成品',
dataType: 1,
status: 0,
saleId: undefined,
pageNum: 1,
pageSize: 10
},
// 待分配钢卷查询参数
queryParamsWithUnAssignedId: {
selectType: 'product',
materialType: '成品',
dataType: 1,
status: 0,
saleId: -1,
pageNum: 1,
pageSize: 10
},
// 待分配钢卷列表
unAssignedCoilList: [],
// 待分配钢卷总数
unAssignedTotal: 0,
// 已分配钢卷列表
salesCoilList: [],
// 已分配钢卷总数
salesTotal: 0,
// 当前选中的销售用户
currentUser: {},
// 浮动层配置
floatLayerConfig: {
columns: [
{ label: '入场钢卷号', prop: 'enterCoilNo' },
{ label: '当前钢卷号', prop: 'currentCoilNo' },
{ label: '厂家卷号', prop: 'supplierCoilNo' },
{ label: '逻辑库位', prop: 'warehouseName' },
{ label: '实际库位', prop: 'actualWarehouseName' },
{ label: '物料类型', prop: 'materialType' },
{ label: '班组', prop: 'team' },
{ label: '净重', prop: 'netWeight' },
{ label: '毛重', prop: 'grossWeight' },
{ label: '备注', prop: 'remark' },
{ label: '质量状态', prop: 'qualityStatus' },
{ label: '打包状态', prop: 'packingStatus' },
{ label: '切边要求', prop: 'edgeRequirement' },
{ label: '包装要求', prop: 'packagingRequirement' },
{ label: '厂家', prop: 'itemManufacturer' }
],
title: '详细信息'
},
// 拆分loading状态分别控制两个表格
unAssignedLoading: false, // 待分配表格loading
salesLoading: false, // 已分配表格loading
// 选中的待分配钢卷
selectedUnAssignedCoils: [],
// 选中的已分配钢卷
selectedSalesCoils: []
}
},
created() {
this.listUser()
// 初始化加载待分配钢卷
this.listUnAssignedCoil()
},
methods: {
/**
* 获取销售用户列表并构建树形结构
*/
async listUser() {
try {
const res = await listUser({ deptId: this.deptId, pageSize: 999 })
this.userList = res.rows || []
// 构建树形结构(如果用户有层级关系,这里简单处理为平级)
this.userTreeData = this.userList.map(user => ({
id: user.userId,
nickName: user.nickName,
userName: user.userName,
deptId: user.deptId,
children: [] // 如果有子级可以在这里处理
}))
} catch (error) {
this.$message.error('获取销售列表失败:' + error.message)
}
},
/**
* 树形节点点击事件
* @param {Object} node 选中的节点
*/
handleTreeNodeClick(node) {
this.currentUser = node
console.log(node)
this.queryParamsWithSalesId.saleId = node.id
// 清空之前选中的已分配钢卷
this.selectedSalesCoils = []
// 加载该销售的已分配钢卷
this.listSalesCoil()
},
/**
* 获取待分配钢卷列表
*/
async listUnAssignedCoil() {
this.unAssignedLoading = true
try {
const res = await listMaterialCoil(this.queryParamsWithUnAssignedId)
console.log(res)
this.unAssignedCoilList = res.rows || []
this.unAssignedTotal = res.total || 0
} catch (error) {
this.$message.error('获取待分配钢卷失败:' + error.message)
this.unAssignedCoilList = []
this.unAssignedTotal = 0
} finally {
this.unAssignedLoading = false
}
},
/**
* 获取已分配钢卷列表
*/
async listSalesCoil() {
if (!this.currentUser.id) return
this.salesLoading = true
try {
const res = await listMaterialCoil(this.queryParamsWithSalesId)
this.salesCoilList = res.rows || []
this.salesTotal = res.total || 0
} catch (error) {
this.$message.error('获取已分配钢卷失败:' + error.message)
this.salesCoilList = []
this.salesTotal = 0
} finally {
this.salesLoading = false
}
},
/**
* 单个钢卷分配操作
* @param {Object} row 钢卷数据
*/
async handleAssign(row) {
try {
await this.$confirm('确定要将该钢卷分配给 ' + this.currentUser.nickName + ' 吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const res = await updateMaterialCoilSimple({
...row,
saleId: this.currentUser.id
})
if (res.code === 200) {
this.$message.success('分配成功!')
// 刷新列表
this.listUnAssignedCoil()
this.listSalesCoil()
} else {
this.$message.error(res.msg || '分配失败')
}
} catch (error) {
if (error !== 'cancel') {
this.$message.error('分配操作失败:' + error.message)
}
}
},
/**
* 单个钢卷移除操作
* @param {Object} row 钢卷数据
*/
async handleRemove(row) {
try {
await this.$confirm('确定要移除该钢卷的分配权限吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
const res = await updateMaterialCoilSimple({
...row,
saleId: null
})
if (res.code === 200) {
this.$message.success('移除成功!')
// 刷新列表
this.listUnAssignedCoil()
this.listSalesCoil()
} else {
this.$message.error(res.msg || '移除失败')
}
} catch (error) {
if (error !== 'cancel') {
this.$message.error('移除操作失败:' + error.message)
}
}
},
/**
* 待分配钢卷选择事件
* @param {Array} val 选中的钢卷列表
*/
handleUnAssignedSelectionChange(val) {
this.selectedUnAssignedCoils = val
},
/**
* 已分配钢卷选择事件
* @param {Array} val 选中的钢卷列表
*/
handleSalesSelectionChange(val) {
this.selectedSalesCoils = val
},
/**
* 批量分配钢卷
*/
async handleBatchAssign() {
if (this.selectedUnAssignedCoils.length === 0) {
return this.$message.warning('请选择要分配的钢卷!')
}
try {
await this.$confirm(
`确定要将选中的 ${this.selectedUnAssignedCoils.length} 个钢卷分配给 ${this.currentUser.nickName} 吗?`,
'批量分配',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
const coilIds = this.selectedUnAssignedCoils.map(item => item.id)
for (const coilId of coilIds) {
await updateMaterialCoilSimple({
coilId: coilId,
saleId: this.currentUser.id
})
}
if (res.code === 200) {
this.$message.success('批量分配成功!')
// 刷新列表
this.listUnAssignedCoil()
this.listSalesCoil()
// 清空选中
this.selectedUnAssignedCoils = []
} else {
this.$message.error(res.msg || '批量分配失败')
}
} catch (error) {
if (error !== 'cancel') {
this.$message.error('批量分配操作失败:' + error.message)
}
}
},
/**
* 批量移除钢卷
*/
async handleBatchRemove() {
if (this.selectedSalesCoils.length === 0) {
return this.$message.warning('请选择要移除的钢卷!')
}
try {
await this.$confirm(
`确定要移除选中的 ${this.selectedSalesCoils.length} 个钢卷的分配权限吗?`,
'批量移除',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}
)
const coilIds = this.selectedSalesCoils.map(item => item.id)
for (const coilId of coilIds) {
await updateMaterialCoilSimple({
coilId: coilId,
saleId: null
})
}
if (res.code === 200) {
this.$message.success('批量移除成功!')
// 刷新列表
this.listUnAssignedCoil()
this.listSalesCoil()
// 清空选中
this.selectedSalesCoils = []
} else {
this.$message.error(res.msg || '批量移除失败')
}
} catch (error) {
if (error !== 'cancel') {
this.$message.error('批量移除操作失败:' + error.message)
}
}
}
}
}
</script>
<style scoped>
.sales-permission-container {
padding: 10px;
height: 100%;
}
.sales-tree-container {
background: #f5f7fa;
padding: 10px;
border-radius: 4px;
height: calc(100vh - 40px);
overflow: auto;
}
.tree-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 10px;
color: #303133;
}
.coil-table-container {
height: calc(100vh - 40px);
overflow: auto;
}
.table-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
font-size: 16px;
font-weight: bold;
color: #303133;
}
.batch-operation {
margin: 10px 0;
text-align: right;
}
/* 空提示容器样式 */
.empty-container {
margin-top: 20px;
padding: 40px 0;
background: #fff;
border-radius: 4px;
text-align: center;
}
/* vue2的样式穿透 */
::v-deep .el-form-item {
margin-bottom: 0 !important;
}
::v-deep .el-pagination {
margin-top: 0 !important;
}
</style>