feat: 优化库位树UI层级颜色,并将入库页面库位输入升级为级联选择器
This commit is contained in:
180
inventory-backend/app/api/v1/warehouse.py
Normal file
180
inventory-backend/app/api/v1/warehouse.py
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
# inventory-backend/app/api/v1/warehouse.py
|
||||||
|
from flask import Blueprint, request, jsonify
|
||||||
|
from app.extensions import db
|
||||||
|
from app.models.system import SysWarehouseLocation
|
||||||
|
|
||||||
|
warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/api/v1/warehouse')
|
||||||
|
|
||||||
|
|
||||||
|
def build_tree(nodes, parent_id=None):
|
||||||
|
"""
|
||||||
|
将平铺的数据构建为树形结构
|
||||||
|
"""
|
||||||
|
tree = []
|
||||||
|
for node in nodes:
|
||||||
|
if node.parent_id == parent_id:
|
||||||
|
children = build_tree(nodes, node.id)
|
||||||
|
node_dict = node.to_dict()
|
||||||
|
if children:
|
||||||
|
node_dict['children'] = children
|
||||||
|
else:
|
||||||
|
node_dict['children'] = []
|
||||||
|
tree.append(node_dict)
|
||||||
|
return tree
|
||||||
|
|
||||||
|
|
||||||
|
@warehouse_bp.route('/tree', methods=['GET'])
|
||||||
|
def get_tree():
|
||||||
|
"""
|
||||||
|
获取库位树形结构
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 查询所有库位
|
||||||
|
all_locations = SysWarehouseLocation.query.order_by(SysWarehouseLocation.level, SysWarehouseLocation.id).all()
|
||||||
|
|
||||||
|
# 构建树形结构
|
||||||
|
tree_data = build_tree(all_locations, parent_id=None)
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'code': 200,
|
||||||
|
'msg': 'success',
|
||||||
|
'data': tree_data
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({
|
||||||
|
'code': 500,
|
||||||
|
'msg': str(e),
|
||||||
|
'data': None
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@warehouse_bp.route('', methods=['POST'])
|
||||||
|
def create_location():
|
||||||
|
"""
|
||||||
|
创建库位
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
name = data.get('name', '').strip()
|
||||||
|
parent_id = data.get('parent_id') # None 表示顶级
|
||||||
|
is_enabled = data.get('is_enabled', True)
|
||||||
|
|
||||||
|
if not name:
|
||||||
|
return jsonify({'code': 400, 'msg': '库位名称不能为空', 'data': None})
|
||||||
|
|
||||||
|
# 计算 level 和 full_path
|
||||||
|
if parent_id is None:
|
||||||
|
level = 0
|
||||||
|
full_path = name
|
||||||
|
parent_full_path = ''
|
||||||
|
else:
|
||||||
|
parent = SysWarehouseLocation.query.get(parent_id)
|
||||||
|
if not parent:
|
||||||
|
return jsonify({'code': 400, 'msg': '父级库位不存在', 'data': None})
|
||||||
|
level = parent.level + 1
|
||||||
|
parent_full_path = parent.full_path or ''
|
||||||
|
full_path = f"{parent_full_path}/{name}" if parent_full_path else name
|
||||||
|
|
||||||
|
location = SysWarehouseLocation(
|
||||||
|
name=name,
|
||||||
|
parent_id=parent_id,
|
||||||
|
full_path=full_path,
|
||||||
|
level=level,
|
||||||
|
is_enabled=is_enabled
|
||||||
|
)
|
||||||
|
db.session.add(location)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'code': 200,
|
||||||
|
'msg': '创建成功',
|
||||||
|
'data': location.to_dict()
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({
|
||||||
|
'code': 500,
|
||||||
|
'msg': str(e),
|
||||||
|
'data': None
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@warehouse_bp.route('/<int:location_id>', methods=['PUT'])
|
||||||
|
def update_location(location_id):
|
||||||
|
"""
|
||||||
|
更新库位
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
location = SysWarehouseLocation.query.get(location_id)
|
||||||
|
|
||||||
|
if not location:
|
||||||
|
return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
|
||||||
|
|
||||||
|
# 更新名称
|
||||||
|
if 'name' in data and data['name']:
|
||||||
|
new_name = data['name'].strip()
|
||||||
|
if new_name != location.name:
|
||||||
|
# 需要更新 full_path
|
||||||
|
parent = location.parent
|
||||||
|
if parent:
|
||||||
|
location.full_path = f"{parent.full_path}/{new_name}" if parent.full_path else new_name
|
||||||
|
else:
|
||||||
|
location.full_path = new_name
|
||||||
|
location.name = new_name
|
||||||
|
|
||||||
|
# 更新启用状态
|
||||||
|
if 'is_enabled' in data:
|
||||||
|
location.is_enabled = data['is_enabled']
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'code': 200,
|
||||||
|
'msg': '更新成功',
|
||||||
|
'data': location.to_dict()
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({
|
||||||
|
'code': 500,
|
||||||
|
'msg': str(e),
|
||||||
|
'data': None
|
||||||
|
}), 500
|
||||||
|
|
||||||
|
|
||||||
|
@warehouse_bp.route('/<int:location_id>', methods=['DELETE'])
|
||||||
|
def delete_location(location_id):
|
||||||
|
"""
|
||||||
|
删除库位(级联删除子库位)
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
location = SysWarehouseLocation.query.get(location_id)
|
||||||
|
|
||||||
|
if not location:
|
||||||
|
return jsonify({'code': 404, 'msg': '库位不存在', 'data': None})
|
||||||
|
|
||||||
|
# 递归删除所有子库位
|
||||||
|
def delete_recursive(loc):
|
||||||
|
# 先删除所有子节点
|
||||||
|
children = SysWarehouseLocation.query.filter_by(parent_id=loc.id).all()
|
||||||
|
for child in children:
|
||||||
|
delete_recursive(child)
|
||||||
|
# 再删除自身
|
||||||
|
db.session.delete(loc)
|
||||||
|
|
||||||
|
delete_recursive(location)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
'code': 200,
|
||||||
|
'msg': '删除成功',
|
||||||
|
'data': None
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
db.session.rollback()
|
||||||
|
return jsonify({
|
||||||
|
'code': 500,
|
||||||
|
'msg': str(e),
|
||||||
|
'data': None
|
||||||
|
}), 500
|
||||||
@ -168,10 +168,14 @@ class SysWarehouseLocation(db.Model):
|
|||||||
level = db.Column(db.Integer, default=0) # 层级深度,顶级为0
|
level = db.Column(db.Integer, default=0) # 层级深度,顶级为0
|
||||||
is_enabled = db.Column(db.Boolean, default=True)
|
is_enabled = db.Column(db.Boolean, default=True)
|
||||||
created_at = db.Column(db.DateTime, default=datetime.now)
|
created_at = db.Column(db.DateTime, default=datetime.now)
|
||||||
updated_at = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now)
|
# 注意:数据库表中没有 updated_at 字段,不要添加!
|
||||||
|
|
||||||
# 自关联
|
# 自关联 - 使用 backref 定义父节点的反向引用
|
||||||
children = db.relationship('SysWarehouseLocation', backref=db.backref('parent', remote_side=[id]), lazy='dynamic')
|
children = db.relationship(
|
||||||
|
'SysWarehouseLocation',
|
||||||
|
backref=db.backref('parent', remote_side=[id]),
|
||||||
|
lazy='dynamic'
|
||||||
|
)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
return {
|
return {
|
||||||
@ -181,6 +185,5 @@ class SysWarehouseLocation(db.Model):
|
|||||||
'full_path': self.full_path,
|
'full_path': self.full_path,
|
||||||
'level': self.level,
|
'level': self.level,
|
||||||
'is_enabled': self.is_enabled,
|
'is_enabled': self.is_enabled,
|
||||||
'created_at': self.created_at.isoformat() if self.created_at else None,
|
'created_at': self.created_at.isoformat() if self.created_at else None
|
||||||
'updated_at': self.updated_at.isoformat() if self.updated_at else None
|
|
||||||
}
|
}
|
||||||
35
inventory-web/src/api/common/warehouse.ts
Normal file
35
inventory-web/src/api/common/warehouse.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
// 获取库位树形结构
|
||||||
|
export function getWarehouseTree() {
|
||||||
|
return request({
|
||||||
|
url: '/v1/warehouse/tree',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建库位
|
||||||
|
export function createWarehouse(data: any) {
|
||||||
|
return request({
|
||||||
|
url: '/v1/warehouse',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新库位
|
||||||
|
export function updateWarehouse(data: any) {
|
||||||
|
return request({
|
||||||
|
url: `/v1/warehouse/${data.id}`,
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除库位
|
||||||
|
export function deleteWarehouse(id: number) {
|
||||||
|
return request({
|
||||||
|
url: `/v1/warehouse/${id}`,
|
||||||
|
method: 'delete'
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -84,13 +84,31 @@
|
|||||||
<div class="tree-node">
|
<div class="tree-node">
|
||||||
<span class="node-label">{{ node.label }}</span>
|
<span class="node-label">{{ node.label }}</span>
|
||||||
<span class="node-actions">
|
<span class="node-actions">
|
||||||
<el-button type="primary" link size="small" @click="handleAddChild(data)" :icon="Plus">
|
<el-button
|
||||||
|
:type="getLevelButtonType(node.level, 'add')"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleAddChild(data)"
|
||||||
|
:icon="Plus"
|
||||||
|
>
|
||||||
新增下级
|
新增下级
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="warning" link size="small" @click="handleEdit(data)" :icon="Edit">
|
<el-button
|
||||||
|
:type="getLevelButtonType(node.level, 'edit')"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleEdit(data)"
|
||||||
|
:icon="Edit"
|
||||||
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="danger" link size="small" @click="handleDelete(data)" :icon="Delete">
|
<el-button
|
||||||
|
:type="getLevelButtonType(node.level, 'delete')"
|
||||||
|
link
|
||||||
|
size="small"
|
||||||
|
@click="handleDelete(data)"
|
||||||
|
:icon="Delete"
|
||||||
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</span>
|
</span>
|
||||||
@ -195,6 +213,21 @@ const savePrinterConfig = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 库位管理相关 ====================
|
// ==================== 库位管理相关 ====================
|
||||||
|
// 根据层级返回按钮颜色类型
|
||||||
|
const getLevelButtonType = (level: number, action: string) => {
|
||||||
|
// 层级颜色映射
|
||||||
|
const levelColors: Record<number, Record<string, string>> = {
|
||||||
|
0: { add: 'primary', edit: 'info', delete: 'danger' }, // 顶级: 蓝/灰/红
|
||||||
|
1: { add: 'success', edit: 'warning', delete: 'danger' }, // 二级: 绿/橙/红
|
||||||
|
2: { add: 'warning', edit: 'info', delete: 'danger' }, // 三级: 橙/灰/红
|
||||||
|
}
|
||||||
|
// 4级及以上统一使用危险色
|
||||||
|
if (level >= 3) {
|
||||||
|
return 'danger'
|
||||||
|
}
|
||||||
|
return levelColors[level]?.[action] || 'primary'
|
||||||
|
}
|
||||||
|
|
||||||
const warehouseDialogVisible = ref(false)
|
const warehouseDialogVisible = ref(false)
|
||||||
const treeRef = ref()
|
const treeRef = ref()
|
||||||
const treeData = ref<any[]>([])
|
const treeData = ref<any[]>([])
|
||||||
|
|||||||
@ -327,16 +327,15 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="6">
|
<el-col :span="6">
|
||||||
<el-form-item label="库位" prop="warehouse_location">
|
<el-form-item label="库位" prop="warehouse_location">
|
||||||
<el-autocomplete
|
<el-cascader
|
||||||
v-model="form.warehouse_location"
|
v-model="form.warehouse_location"
|
||||||
:fetch-suggestions="querySearchLocation"
|
:options="warehouseOptions"
|
||||||
placeholder="例如: A-01-02"
|
:props="{ value: 'full_path', label: 'name', children: 'children', checkStrictly: true, emitPath: false }"
|
||||||
|
placeholder="请选择库位"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
clearable
|
clearable
|
||||||
:trigger-on-focus="true"
|
filterable
|
||||||
>
|
/>
|
||||||
<template #default="{ item }"><div style="font-weight: 500">{{ item.value }}</div></template>
|
|
||||||
</el-autocomplete>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -653,6 +652,7 @@ import {
|
|||||||
getFilterOptions
|
getFilterOptions
|
||||||
} from '@/api/inbound/buy'
|
} from '@/api/inbound/buy'
|
||||||
import {getLabelPreview, executePrint} from '@/api/common/print'
|
import {getLabelPreview, executePrint} from '@/api/common/print'
|
||||||
|
import { getWarehouseTree } from '@/api/common/warehouse'
|
||||||
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
@ -782,6 +782,9 @@ const cameraRef = ref<InstanceType<typeof WebRtcCamera> | null>(null)
|
|||||||
const currentCameraField = ref<'arrival_photo' | 'inspection_report'>('arrival_photo')
|
const currentCameraField = ref<'arrival_photo' | 'inspection_report'>('arrival_photo')
|
||||||
const inspection_report_url = ref('')
|
const inspection_report_url = ref('')
|
||||||
|
|
||||||
|
// 库位级联选择器数据
|
||||||
|
const warehouseOptions = ref<any[]>([])
|
||||||
|
|
||||||
const advancedFilterVisible = ref(false)
|
const advancedFilterVisible = ref(false)
|
||||||
const advancedConditions = ref([{ field: '', operator: '', value: '' }])
|
const advancedConditions = ref([{ field: '', operator: '', value: '' }])
|
||||||
const fieldOptions = computed(() => {
|
const fieldOptions = computed(() => {
|
||||||
@ -1227,6 +1230,18 @@ const fetchOptions = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载库位树数据
|
||||||
|
const loadWarehouseTree = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getWarehouseTree()
|
||||||
|
if (res.code === 200) {
|
||||||
|
warehouseOptions.value = res.data || []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('加载库位树失败', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryParams.keyword = ''
|
queryParams.keyword = ''
|
||||||
queryParams.category = ''
|
queryParams.category = ''
|
||||||
@ -1524,6 +1539,7 @@ onMounted(() => {
|
|||||||
initColumnPermissions()
|
initColumnPermissions()
|
||||||
fetchData()
|
fetchData()
|
||||||
fetchOptions()
|
fetchOptions()
|
||||||
|
loadWarehouseTree()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -286,7 +286,17 @@
|
|||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="6"><el-form-item label="SKU" prop="sku"><el-input v-model="form.sku" placeholder="自动生成" disabled /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="SKU" prop="sku"><el-input v-model="form.sku" placeholder="自动生成" disabled /></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="库位" prop="warehouse_location"><el-input v-model="form.warehouse_location" placeholder="例如: B-01-01" clearable /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="库位" prop="warehouse_location">
|
||||||
|
<el-cascader
|
||||||
|
v-model="form.warehouse_location"
|
||||||
|
:options="warehouseOptions"
|
||||||
|
:props="{ value: 'full_path', label: 'name', children: 'children', checkStrictly: true, emitPath: false }"
|
||||||
|
placeholder="请选择库位"
|
||||||
|
style="width: 100%"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
/>
|
||||||
|
</el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="入库日期"><el-date-picker v-model="form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%" disabled /></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="入库日期"><el-date-picker v-model="form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%" disabled /></el-form-item></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
@ -513,6 +523,7 @@ import {
|
|||||||
import { uploadFile, deleteFile } from '@/api/inbound/buy'
|
import { uploadFile, deleteFile } from '@/api/inbound/buy'
|
||||||
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
||||||
import { getLabelPreview, executePrint } from '@/api/common/print'
|
import { getLabelPreview, executePrint } from '@/api/common/print'
|
||||||
|
import { getWarehouseTree } from '@/api/common/warehouse'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
@ -628,6 +639,9 @@ const currentCameraField = ref<'product_photo' | 'quality_report_link' | 'inspec
|
|||||||
const quality_url = ref('')
|
const quality_url = ref('')
|
||||||
const inspection_url = ref('')
|
const inspection_url = ref('')
|
||||||
|
|
||||||
|
// 库位级联选择器数据
|
||||||
|
const warehouseOptions = ref<any[]>([])
|
||||||
|
|
||||||
// [核心优化] 所有列定义
|
// [核心优化] 所有列定义
|
||||||
const allColumns = [
|
const allColumns = [
|
||||||
{ prop: 'company_name', label: '所属公司', minWidth: '100', sortable: true }, // [新增]
|
{ prop: 'company_name', label: '所属公司', minWidth: '100', sortable: true }, // [新增]
|
||||||
@ -958,6 +972,18 @@ const fetchOptions = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载库位树数据
|
||||||
|
const loadWarehouseTree = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getWarehouseTree()
|
||||||
|
if (res.code === 200) {
|
||||||
|
warehouseOptions.value = res.data || []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('加载库位树失败', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryParams.keyword = ''
|
queryParams.keyword = ''
|
||||||
queryParams.category = ''
|
queryParams.category = ''
|
||||||
@ -1178,6 +1204,7 @@ onMounted(() => {
|
|||||||
initColumnPermissions()
|
initColumnPermissions()
|
||||||
fetchData()
|
fetchData()
|
||||||
fetchOptions()
|
fetchOptions()
|
||||||
|
loadWarehouseTree()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 成本计算监听
|
// 成本计算监听
|
||||||
|
|||||||
@ -345,7 +345,17 @@
|
|||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="6"><el-form-item label="编码/SKU" prop="sku"><el-input v-model="form.sku" placeholder="系统自动生成" disabled/></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="编码/SKU" prop="sku"><el-input v-model="form.sku" placeholder="系统自动生成" disabled/></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="入库日期" prop="in_date"><el-date-picker v-model="form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%" disabled/></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="入库日期" prop="in_date"><el-date-picker v-model="form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%" disabled/></el-form-item></el-col>
|
||||||
<el-col :span="6"><el-form-item label="库位" prop="warehouse_location"><el-input v-model="form.warehouse_location" placeholder="例如: B-01-01" clearable/></el-form-item></el-col>
|
<el-col :span="6"><el-form-item label="库位" prop="warehouse_location">
|
||||||
|
<el-cascader
|
||||||
|
v-model="form.warehouse_location"
|
||||||
|
:options="warehouseOptions"
|
||||||
|
:props="{ value: 'full_path', label: 'name', children: 'children', checkStrictly: true, emitPath: false }"
|
||||||
|
placeholder="请选择库位"
|
||||||
|
style="width: 100%"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
/>
|
||||||
|
</el-form-item></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<div class="identity-panel">
|
<div class="identity-panel">
|
||||||
@ -577,6 +587,7 @@ import {
|
|||||||
import { uploadFile, deleteFile } from '@/api/inbound/buy'
|
import { uploadFile, deleteFile } from '@/api/inbound/buy'
|
||||||
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
import WebRtcCamera from '@/components/Camera/WebRtcCamera.vue'
|
||||||
import {getLabelPreview, executePrint} from '@/api/common/print'
|
import {getLabelPreview, executePrint} from '@/api/common/print'
|
||||||
|
import { getWarehouseTree } from '@/api/common/warehouse'
|
||||||
import { useUserStore } from '@/stores/user'
|
import { useUserStore } from '@/stores/user'
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
@ -691,6 +702,9 @@ const cameraRef = ref<InstanceType<typeof WebRtcCamera> | null>(null)
|
|||||||
const currentCameraField = ref<'arrival_photo' | 'quality_report_link'>('arrival_photo')
|
const currentCameraField = ref<'arrival_photo' | 'quality_report_link'>('arrival_photo')
|
||||||
const quality_report_url = ref('')
|
const quality_report_url = ref('')
|
||||||
|
|
||||||
|
// 库位级联选择器数据
|
||||||
|
const warehouseOptions = ref<any[]>([])
|
||||||
|
|
||||||
const entryMode = ref('batch')
|
const entryMode = ref('batch')
|
||||||
const modeLocked = ref(false)
|
const modeLocked = ref(false)
|
||||||
|
|
||||||
@ -1092,6 +1106,18 @@ const fetchOptions = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 加载库位树数据
|
||||||
|
const loadWarehouseTree = async () => {
|
||||||
|
try {
|
||||||
|
const res = await getWarehouseTree()
|
||||||
|
if (res.code === 200) {
|
||||||
|
warehouseOptions.value = res.data || []
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('加载库位树失败', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resetQuery = () => {
|
const resetQuery = () => {
|
||||||
queryParams.keyword = ''
|
queryParams.keyword = ''
|
||||||
queryParams.category = ''
|
queryParams.category = ''
|
||||||
@ -1306,6 +1332,7 @@ onMounted(() => {
|
|||||||
initColumnPermissions()
|
initColumnPermissions()
|
||||||
fetchData()
|
fetchData()
|
||||||
fetchOptions()
|
fetchOptions()
|
||||||
|
loadWarehouseTree()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user