no message
parent
d308c16400
commit
bf33b23154
|
|
@ -5,6 +5,7 @@ const { createConfirm } = useMessage();
|
|||
|
||||
enum Api {
|
||||
list = '/base/area/list',
|
||||
queryById='/base/area/queryById',
|
||||
save = '/base/area/add',
|
||||
edit = '/base/area/edit',
|
||||
deleteOne = '/base/area/delete',
|
||||
|
|
@ -30,6 +31,11 @@ export const getImportUrl = Api.importExcel;
|
|||
*/
|
||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
||||
|
||||
/**
|
||||
* id查询
|
||||
* @param params
|
||||
*/
|
||||
export const queryById = (params) => defHttp.get({ url: Api.queryById, params });
|
||||
/**
|
||||
* 删除单个
|
||||
* @param params
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- 库区下拉选择-->
|
||||
<!-- 库区选择 -->
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="selectedValue"
|
||||
|
|
@ -12,350 +12,407 @@
|
|||
@change="handleChange"
|
||||
@search="handleSearch"
|
||||
@focus="handleFocus"
|
||||
@popupScroll="handlePopupScroll"
|
||||
@popup-scroll="handlePopupScroll"
|
||||
:getPopupContainer="getParentContainer"
|
||||
v-bind="attrs"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<span v-else>暂无库区数据</span>
|
||||
|
||||
</template>
|
||||
<a-select-option v-for="option in areaOptions" :key="option.id" :value="getOptionValue(option)">
|
||||
<a-select-option v-for="option in Options" :key="option.id" :value="getOptionValue(option)">
|
||||
{{ getOptionLabel(option) }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, watch, computed, onMounted } from 'vue';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { setPopContainer } from '/@/utils';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { defineComponent, ref, watch, computed, onMounted } from 'vue';
|
||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { defHttp } from '/@/utils/http/axios';
|
||||
import { queryById } from '@/views/base/area/Area.api';
|
||||
import { setPopContainer } from '/@/utils';
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
// 库区数据接口
|
||||
interface Area {
|
||||
id: string;
|
||||
areaCode: string;
|
||||
areaName: string;
|
||||
}
|
||||
// 库区数据接口
|
||||
interface Area {
|
||||
id: string;
|
||||
areaCode: string;
|
||||
areaName: string;
|
||||
}
|
||||
|
||||
//响应数据接口
|
||||
interface ResponseData {
|
||||
records: Area[];
|
||||
total: number;
|
||||
size: number;
|
||||
current: number;
|
||||
page: number;
|
||||
}
|
||||
//响应数据接口
|
||||
interface ResponseData {
|
||||
records: Area[];
|
||||
total: number;
|
||||
size: number;
|
||||
current: number;
|
||||
page: number;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AreaSelect',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
// 选中值,支持v-model
|
||||
value: propTypes.oneOfType([propTypes.string, propTypes.array, propTypes.object]),
|
||||
// 占位符
|
||||
placeholder: propTypes.string.def('请选择库区'),
|
||||
// 是否多选
|
||||
multiple: propTypes.bool.def(false),
|
||||
// 是否异步加载数据
|
||||
async: propTypes.bool.def(true),
|
||||
// 分页大小
|
||||
pageSize: propTypes.number.def(20),
|
||||
// 弹出层容器
|
||||
popContainer: propTypes.string,
|
||||
// 自定义弹出层容器函数
|
||||
getPopupContainer: {
|
||||
type: Function,
|
||||
default: (node: HTMLElement) => node?.parentNode,
|
||||
},
|
||||
// 是否立即触发change事件
|
||||
immediateChange: propTypes.bool.def(false),
|
||||
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||
returnValue: propTypes.string.def('id'),
|
||||
//默认启用
|
||||
izActive: propTypes.number.def(1),
|
||||
export default defineComponent({
|
||||
name: 'AreaSelect',
|
||||
inheritAttrs: false,
|
||||
props: {
|
||||
// 选中值,支持v-model
|
||||
value: propTypes.oneOfType([propTypes.string, propTypes.array, propTypes.object]),
|
||||
// 占位符
|
||||
placeholder: propTypes.string.def('请选择库区'),
|
||||
// 是否多选
|
||||
multiple: propTypes.bool.def(false),
|
||||
// 是否异步加载数据
|
||||
async: propTypes.bool.def(true),
|
||||
// 分页大小
|
||||
pageSize: propTypes.number.def(10),
|
||||
// 弹出层容器
|
||||
popContainer: propTypes.string,
|
||||
// 自定义弹出层容器函数
|
||||
getPopupContainer: {
|
||||
type: Function,
|
||||
default: (node: HTMLElement) => node?.parentNode,
|
||||
},
|
||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||
setup(props, { emit }) {
|
||||
const areaOptions = ref<Area[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const allAreas = ref<Area[]>([]);
|
||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||
// 是否立即触发change事件
|
||||
immediateChange: propTypes.bool.def(false),
|
||||
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||
returnValue: propTypes.string.def('id'),
|
||||
//默认启用
|
||||
izActive: propTypes.number.def(1),
|
||||
//默认未删除
|
||||
delFlag:propTypes.number.def(0)
|
||||
},
|
||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||
setup(props, { emit }) {
|
||||
const Options = ref<Area[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
const allAreas = ref<Area[]>([]);
|
||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||
|
||||
// 分页相关
|
||||
const pageNo = ref(1);
|
||||
const isHasData = ref(true);
|
||||
const scrollLoading = ref(false);
|
||||
const searchKeyword = ref('');
|
||||
// 分页相关
|
||||
const pageNo = ref(1);
|
||||
const isHasData = ref(true);
|
||||
const scrollLoading = ref(false);
|
||||
const searchKeyword = ref('');
|
||||
|
||||
// 选中值
|
||||
const selectedValue = ref<string | string[] | undefined>(undefined);
|
||||
// 选中值
|
||||
const selectedValue = ref<string | string[] | undefined>(undefined);
|
||||
|
||||
// 未找到内容
|
||||
const notFoundContent = computed(() => {
|
||||
return loading.value ? undefined : null;
|
||||
});
|
||||
// 未找到内容
|
||||
const notFoundContent = computed(() => {
|
||||
return loading.value ? undefined : '暂无数据';
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取选项显示文本 - 始终显示完整格式
|
||||
*/
|
||||
function getOptionLabel(option: Area) {
|
||||
return `${option.areaCode} - ${option.areaName}`;
|
||||
/**
|
||||
* 获取选项显示文本 - 始终显示完整格式
|
||||
*/
|
||||
function getOptionLabel(option: Area) {
|
||||
return `${option.areaCode} - ${option.areaName}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选项值 - 根据returnValue确定实际存储的值
|
||||
*/
|
||||
function getOptionValue(option: Area) {
|
||||
if (props.returnValue === 'object') {
|
||||
return option.id; // 对于object类型,仍然使用id作为选项值,但在change事件中返回完整对象
|
||||
} else if (props.returnValue === 'id') {
|
||||
return option.id;
|
||||
} else {
|
||||
return option[props.returnValue as keyof Area] as string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取选项值 - 根据returnValue确定实际存储的值
|
||||
*/
|
||||
function getOptionValue(option: Area) {
|
||||
if (props.returnValue === 'object') {
|
||||
return option.id; // 对于object类型,仍然使用id作为选项值,但在change事件中返回完整对象
|
||||
} else if (props.returnValue === 'id') {
|
||||
return option.id;
|
||||
/**
|
||||
* 获取弹出层容器
|
||||
*/
|
||||
function getParentContainer(node: HTMLElement) {
|
||||
if (props.popContainer) {
|
||||
return setPopContainer(node, props.popContainer);
|
||||
} else {
|
||||
if (typeof props.getPopupContainer === 'function') {
|
||||
return props.getPopupContainer(node);
|
||||
} else {
|
||||
return option[props.returnValue as keyof Area] as string;
|
||||
return node?.parentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取弹出层容器
|
||||
*/
|
||||
function getParentContainer(node: HTMLElement) {
|
||||
if (props.popContainer) {
|
||||
return setPopContainer(node, props.popContainer);
|
||||
/**
|
||||
* 过滤选项 - 禁用前端过滤,使用后端搜索
|
||||
*/
|
||||
function filterOption(_input: string, _option: any) {
|
||||
return true; // 禁用前端过滤,完全依赖后端搜索
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保库区唯一性的辅助函数
|
||||
*/
|
||||
function ensureUnique(Areas: Area[], newArea: Area): Area[] {
|
||||
// 如果已经存在相同id的库区,先移除旧的再添加新的
|
||||
const filtered = Areas.filter(Area => Area.id !== newArea.id);
|
||||
return [newArea, ...filtered];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库区数据
|
||||
*/
|
||||
const queryData = async (page = 1, keyword = '', isSearch = false) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
|
||||
const res = await defHttp.get<ResponseData>({
|
||||
url: '/base/Area/list',
|
||||
params: {
|
||||
pageSize: props.pageSize,
|
||||
pageNo: page,
|
||||
keyword: keyword,
|
||||
izActive: props.izActive,
|
||||
delFlag: props.delFlag
|
||||
},
|
||||
});
|
||||
|
||||
const records = res.records || [];
|
||||
|
||||
if (page === 1 || isSearch) {
|
||||
// 第一页或搜索时,重置数据
|
||||
allAreas.value = records;
|
||||
Options.value = records;
|
||||
} else {
|
||||
if (typeof props.getPopupContainer === 'function') {
|
||||
return props.getPopupContainer(node);
|
||||
} else {
|
||||
return node?.parentNode;
|
||||
// 滚动加载时,追加数据(确保不重复)
|
||||
const newRecords = records.filter(record =>
|
||||
!allAreas.value.some(Area => Area.id === record.id)
|
||||
);
|
||||
allAreas.value = [...allAreas.value, ...newRecords];
|
||||
Options.value = [...Options.value, ...newRecords];
|
||||
}
|
||||
|
||||
// 修正分页判断逻辑
|
||||
isHasData.value = records.length >= props.pageSize;
|
||||
|
||||
emit('optionsLoaded', allAreas.value);
|
||||
} catch (error) {
|
||||
if (page === 1) {
|
||||
allAreas.value = [];
|
||||
Options.value = [];
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
scrollLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
async function queryDataById(value: string) {
|
||||
try {
|
||||
const res = await queryById({ id: value });
|
||||
if (res) {
|
||||
// 将查询到的单个库区信息添加到列表中,确保唯一性
|
||||
const Area = Array.isArray(res) ? res[0] : res;
|
||||
if (Area) {
|
||||
// 使用ensureUnique确保库区不重复
|
||||
allAreas.value = ensureUnique(allAreas.value, Area);
|
||||
Options.value = ensureUnique(Options.value, Area);
|
||||
}
|
||||
return Area;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询库区失败:', error);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据选项值找到对应的选项对象
|
||||
*/
|
||||
function findOptionByValue(value: string): Area | undefined {
|
||||
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
||||
return allAreas.value.find((Area) => Area.id === value);
|
||||
} else {
|
||||
return allAreas.value.find((Area) => Area[props.returnValue as keyof Area] === value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要返回的值
|
||||
*/
|
||||
function getReturnValue(value: string | string[]) {
|
||||
if (!value) {
|
||||
return props.multiple ? [] : undefined;
|
||||
}
|
||||
|
||||
// 如果返回整个对象
|
||||
if (props.returnValue === 'object') {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((v) => findOptionByValue(v)).filter(Boolean);
|
||||
} else {
|
||||
return findOptionByValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤选项 - 禁用前端过滤,使用后端搜索
|
||||
*/
|
||||
function filterOption(_input: string, _option: any) {
|
||||
return true; // 禁用前端过滤,完全依赖后端搜索
|
||||
// 如果返回ID(默认情况)
|
||||
else if (props.returnValue === 'id') {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取库区数据
|
||||
*/
|
||||
const fetchAreas = async (page = 1, keyword = '', isSearch = false) => {
|
||||
try {
|
||||
loading.value = true;
|
||||
|
||||
const res = await defHttp.get<ResponseData>({
|
||||
url: '/base/area/list',
|
||||
params: {
|
||||
pageSize: props.pageSize,
|
||||
pageNo: page,
|
||||
keyword: keyword,
|
||||
izActive: props.izActive,
|
||||
},
|
||||
// 如果返回对象中的某个字段
|
||||
else {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((v) => {
|
||||
const option = findOptionByValue(v);
|
||||
return option ? option[props.returnValue as keyof Area] : v;
|
||||
});
|
||||
|
||||
console.log('获取库区数据成功:', res);
|
||||
const records = res.records || [];
|
||||
|
||||
if (page === 1 || isSearch) {
|
||||
// 第一页或搜索时,重置数据
|
||||
allAreas.value = records;
|
||||
areaOptions.value = records;
|
||||
} else {
|
||||
// 滚动加载时,追加数据
|
||||
allAreas.value = [...allAreas.value, ...records];
|
||||
areaOptions.value = [...areaOptions.value, ...records];
|
||||
}
|
||||
|
||||
// 修正分页判断逻辑
|
||||
isHasData.value = records.length >= props.pageSize;
|
||||
console.log('是否还有更多数据:', records.length);
|
||||
|
||||
emit('optionsLoaded', allAreas.value);
|
||||
} catch (error) {
|
||||
console.error('获取库区数据失败:', error);
|
||||
if (page === 1) {
|
||||
allAreas.value = [];
|
||||
areaOptions.value = [];
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
scrollLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据选项值找到对应的选项对象
|
||||
*/
|
||||
function findOptionByValue(value: string): Area | undefined {
|
||||
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
||||
return allAreas.value.find((item) => item.id === value);
|
||||
} else {
|
||||
return allAreas.value.find((item) => item[props.returnValue as keyof Area] === value);
|
||||
const option = findOptionByValue(value);
|
||||
return option ? option[props.returnValue as keyof Area] : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要返回的值
|
||||
*/
|
||||
function getReturnValue(value: string | string[]) {
|
||||
if (!value) {
|
||||
return props.multiple ? [] : undefined;
|
||||
}
|
||||
/**
|
||||
* 搜索处理(防抖)
|
||||
*/
|
||||
const handleSearch = debounce(function (value: string) {
|
||||
searchKeyword.value = value;
|
||||
pageNo.value = 1;
|
||||
isHasData.value = true;
|
||||
|
||||
// 如果返回整个对象
|
||||
if (props.returnValue === 'object') {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((v) => findOptionByValue(v)).filter(Boolean);
|
||||
} else {
|
||||
return findOptionByValue(value);
|
||||
}
|
||||
}
|
||||
// 如果返回ID(默认情况)
|
||||
else if (props.returnValue === 'id') {
|
||||
return value;
|
||||
}
|
||||
// 如果返回对象中的某个字段
|
||||
else {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((v) => {
|
||||
const option = findOptionByValue(v);
|
||||
return option ? option[props.returnValue as keyof Area] : v;
|
||||
});
|
||||
} else {
|
||||
const option = findOptionByValue(value);
|
||||
return option ? option[props.returnValue as keyof Area] : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 直接调用API进行搜索
|
||||
queryData(1, value, true);
|
||||
}, 300);
|
||||
|
||||
/**
|
||||
* 搜索处理(防抖)
|
||||
*/
|
||||
const handleSearch = debounce(function (value: string) {
|
||||
searchKeyword.value = value;
|
||||
/**
|
||||
* 处理焦点事件
|
||||
*/
|
||||
function handleFocus() {
|
||||
// 如果还没有数据,加载数据
|
||||
if (allAreas.value.length === 0 && props.async) {
|
||||
pageNo.value = 1;
|
||||
isHasData.value = true;
|
||||
queryData(1, '');
|
||||
}
|
||||
attrs.onFocus?.();
|
||||
}
|
||||
|
||||
// 直接调用API进行搜索
|
||||
fetchAreas(1, value, true);
|
||||
}, 300);
|
||||
/**
|
||||
* 处理值变化
|
||||
*/
|
||||
function handleChange(value: string | string[]) {
|
||||
selectedValue.value = value;
|
||||
|
||||
/**
|
||||
* 处理焦点事件
|
||||
*/
|
||||
function handleFocus() {
|
||||
// 如果还没有数据,加载数据
|
||||
if (allAreas.value.length === 0 && props.async) {
|
||||
pageNo.value = 1;
|
||||
isHasData.value = true;
|
||||
fetchAreas(1, '');
|
||||
}
|
||||
attrs.onFocus?.();
|
||||
// 根据配置返回相应的值
|
||||
const returnValue = getReturnValue(value);
|
||||
emit('update:value', returnValue);
|
||||
emit('change', returnValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动加载处理
|
||||
*/
|
||||
function handlePopupScroll(e: Event) {
|
||||
const target = e.target as HTMLElement;
|
||||
const { scrollTop, scrollHeight, clientHeight } = target;
|
||||
|
||||
if (!scrollLoading.value && isHasData.value && scrollTop + clientHeight >= scrollHeight - 10) {
|
||||
scrollLoading.value = true;
|
||||
pageNo.value++;
|
||||
|
||||
queryData(pageNo.value, searchKeyword.value)
|
||||
.finally(() => {
|
||||
scrollLoading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
pageNo.value--;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据选中值初始化显示文本
|
||||
*/
|
||||
const initSelectValue = async () => {
|
||||
if (!props.value) {
|
||||
selectedValue.value = props.multiple ? [] : undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理值变化
|
||||
*/
|
||||
function handleChange(value: string | string[]) {
|
||||
selectedValue.value = value;
|
||||
|
||||
// 根据配置返回相应的值
|
||||
const returnValue = getReturnValue(value);
|
||||
console.log('值变化:', returnValue);
|
||||
emit('update:value', returnValue);
|
||||
emit('change', returnValue);
|
||||
// 如果是异步模式且还没有加载数据,则先加载数据
|
||||
if (props.async && allAreas.value.length === 0) {
|
||||
await queryData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动加载处理
|
||||
*/
|
||||
function handlePopupScroll(e: Event) {
|
||||
const target = e.target as HTMLElement;
|
||||
const { scrollTop, scrollHeight, clientHeight } = target;
|
||||
// 根据不同的returnValue设置选中的值
|
||||
let valueIds: string[] = [];
|
||||
|
||||
if (!scrollLoading.value && isHasData.value && scrollTop + clientHeight >= scrollHeight - 10) {
|
||||
console.log('滚动加载更多');
|
||||
scrollLoading.value = true;
|
||||
pageNo.value++;
|
||||
|
||||
fetchAreas(pageNo.value, searchKeyword.value)
|
||||
.finally(() => {
|
||||
scrollLoading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
pageNo.value--;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据选中值初始化显示文本
|
||||
*/
|
||||
const initSelectValue = async () => {
|
||||
if (!props.value) {
|
||||
selectedValue.value = props.multiple ? [] : undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是异步模式且还没有加载数据,则先加载数据
|
||||
if (props.async && allAreas.value.length === 0) {
|
||||
await fetchAreas();
|
||||
}
|
||||
|
||||
// 根据不同的returnValue设置选中的值
|
||||
if (props.returnValue === 'object') {
|
||||
// 如果返回的是对象,value可能是对象或对象数组
|
||||
if (Array.isArray(props.value)) {
|
||||
selectedValue.value = props.value.map((item: any) => item.id);
|
||||
} else {
|
||||
selectedValue.value = (props.value as any).id;
|
||||
}
|
||||
} else if (props.returnValue === 'id') {
|
||||
selectedValue.value = props.value as string | string[];
|
||||
if (props.returnValue === 'object') {
|
||||
// 如果返回的是对象,value可能是对象或对象数组
|
||||
if (Array.isArray(props.value)) {
|
||||
valueIds = props.value.map((Area: any) => Area.id);
|
||||
selectedValue.value = valueIds;
|
||||
} else {
|
||||
// 对于其他字段类型,直接使用传入的值
|
||||
selectedValue.value = props.value as string | string[];
|
||||
valueIds = [(props.value as any).id];
|
||||
selectedValue.value = valueIds[0];
|
||||
}
|
||||
};
|
||||
|
||||
// 监听value变化
|
||||
watch(
|
||||
() => props.value,
|
||||
() => {
|
||||
initSelectValue();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 组件挂载时初始化
|
||||
onMounted(() => {
|
||||
if (!props.async) {
|
||||
fetchAreas();
|
||||
} else if (props.returnValue === 'id') {
|
||||
if (Array.isArray(props.value)) {
|
||||
valueIds = props.value as string[];
|
||||
selectedValue.value = valueIds;
|
||||
} else {
|
||||
valueIds = [props.value as string];
|
||||
selectedValue.value = valueIds[0];
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 对于其他字段类型,直接使用传入的值
|
||||
selectedValue.value = props.value as string | string[];
|
||||
// 这里需要根据字段值查找对应的ID
|
||||
if (Array.isArray(props.value)) {
|
||||
valueIds = props.value.map((v) => {
|
||||
const option = allAreas.value.find((Area) => Area[props.returnValue as keyof Area] === v);
|
||||
return option ? option.id : v;
|
||||
});
|
||||
} else {
|
||||
const option = allAreas.value.find((Area) => Area[props.returnValue as keyof Area] === props.value);
|
||||
valueIds = option ? [option.id] : [props.value as string];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
attrs,
|
||||
areaOptions,
|
||||
loading,
|
||||
selectedValue,
|
||||
notFoundContent,
|
||||
getParentContainer,
|
||||
filterOption,
|
||||
handleChange,
|
||||
handleSearch,
|
||||
handleFocus,
|
||||
getOptionLabel,
|
||||
getOptionValue,
|
||||
handlePopupScroll,
|
||||
};
|
||||
},
|
||||
});
|
||||
// 检查是否有值不在当前列表中,如果有则查询
|
||||
const missingIds = valueIds.filter((id) => !allAreas.value.some((Area) => Area.id === id));
|
||||
if (missingIds.length > 0) {
|
||||
// 对每个不在列表中的ID进行查询
|
||||
const queryPromises = missingIds.map((id) => queryDataById(id));
|
||||
await Promise.all(queryPromises);
|
||||
}
|
||||
};
|
||||
|
||||
// 监听value变化
|
||||
watch(
|
||||
() => props.value,
|
||||
() => {
|
||||
initSelectValue();
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 组件挂载时初始化
|
||||
onMounted(() => {
|
||||
if (!props.async) {
|
||||
queryData();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
attrs,
|
||||
Options,
|
||||
loading,
|
||||
selectedValue,
|
||||
notFoundContent,
|
||||
getParentContainer,
|
||||
filterOption,
|
||||
handleChange,
|
||||
handleSearch,
|
||||
handleFocus,
|
||||
getOptionLabel,
|
||||
getOptionValue,
|
||||
handlePopupScroll,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
v-bind="attrs"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<span v-else>暂无物料数据</span>
|
||||
|
||||
</template>
|
||||
<a-select-option v-for="option in Options" :key="option.id" :value="getOptionValue(option)">
|
||||
{{ getOptionLabel(option) }}
|
||||
|
|
@ -78,6 +77,8 @@
|
|||
returnValue: propTypes.string.def('id'),
|
||||
//默认启用
|
||||
izActive: propTypes.number.def(1),
|
||||
//默认未删除
|
||||
delFlag: propTypes.number.def(0),
|
||||
},
|
||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||
setup(props, { emit }) {
|
||||
|
|
@ -97,7 +98,7 @@
|
|||
|
||||
// 未找到内容
|
||||
const notFoundContent = computed(() => {
|
||||
return loading.value ? undefined : null;
|
||||
return loading.value ? undefined : '暂无数据';
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -165,6 +166,7 @@
|
|||
pageNo: page,
|
||||
keyword: keyword,
|
||||
izActive: props.izActive,
|
||||
delFlag: props.delFlag,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -16,10 +16,7 @@
|
|||
:getPopupContainer="getParentContainer"
|
||||
v-bind="attrs"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<span v-else>暂无库位数据</span>
|
||||
</template>
|
||||
<template #notFoundContent></template>
|
||||
<a-select-option v-for="option in Options" :key="option.id" :value="getOptionValue(option)">
|
||||
{{ getOptionLabel(option) }}
|
||||
</a-select-option>
|
||||
|
|
@ -76,8 +73,14 @@
|
|||
immediateChange: propTypes.bool.def(false),
|
||||
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||
returnValue: propTypes.string.def('id'),
|
||||
//默认空闲
|
||||
status: propTypes.number.def(0),
|
||||
//默认启用
|
||||
izActive: propTypes.number.def(1),
|
||||
//默认未删除
|
||||
delFlag: propTypes.number.def(0),
|
||||
//库区ID
|
||||
areaCode: propTypes.array,
|
||||
},
|
||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||
setup(props, { emit }) {
|
||||
|
|
@ -97,7 +100,7 @@
|
|||
|
||||
// 未找到内容
|
||||
const notFoundContent = computed(() => {
|
||||
return loading.value ? undefined : null;
|
||||
return loading.value ? undefined : '暂无数据';
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -147,7 +150,7 @@
|
|||
*/
|
||||
function ensureUnique(Points: Point[], newPoint: Point): Point[] {
|
||||
// 如果已经存在相同id的库位,先移除旧的再添加新的
|
||||
const filtered = Points.filter(Point => Point.id !== newPoint.id);
|
||||
const filtered = Points.filter((Point) => Point.id !== newPoint.id);
|
||||
return [newPoint, ...filtered];
|
||||
}
|
||||
|
||||
|
|
@ -164,7 +167,10 @@
|
|||
pageSize: props.pageSize,
|
||||
pageNo: page,
|
||||
keyword: keyword,
|
||||
status: props.status,
|
||||
izActive: props.izActive,
|
||||
delFlag: props.delFlag,
|
||||
areaCode: props.areaCode,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -176,9 +182,7 @@
|
|||
Options.value = records;
|
||||
} else {
|
||||
// 滚动加载时,追加数据(确保不重复)
|
||||
const newRecords = records.filter(record =>
|
||||
!allPoints.value.some(Point => Point.id === record.id)
|
||||
);
|
||||
const newRecords = records.filter((record) => !allPoints.value.some((Point) => Point.id === record.id));
|
||||
allPoints.value = [...allPoints.value, ...newRecords];
|
||||
Options.value = [...Options.value, ...newRecords];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,6 @@ export const columns: BasicColumn[] = [
|
|||
return render.renderTag(text, color);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '库位',
|
||||
align: "center",
|
||||
dataIndex: 'pointId_dictText'
|
||||
},
|
||||
{
|
||||
title: '是否启用',
|
||||
align: 'center',
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@
|
|||
<JInput v-model:value="queryParam.stockCode" :placeholder="'请输入容器编码'" :type="JInputTypeEnum.JINPUT_RIGHT_LIKE" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6">
|
||||
<a-form-item name="pointId">
|
||||
<template #label><span title="库位">库位</span></template>
|
||||
<PointSelect v-model:value="queryParam.pointId" placeholder="请选择库位" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6">
|
||||
<a-form-item name="status">
|
||||
<template #label><span title="状态">状态</span></template>
|
||||
|
|
@ -88,21 +82,16 @@
|
|||
import { list, deleteOne, batchDelete, saveOrUpdate, getImportUrl, getExportUrl } from './Stock.api';
|
||||
import StockModal from './components/StockModal.vue';
|
||||
import SwitchStatus from '/@/views/base/SwitchStatus.vue';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDateByPicker } from '/@/utils';
|
||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
||||
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
||||
import JInput from '../../../components/Form/src/jeecg/components/JInput.vue';
|
||||
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||
const fieldPickers = reactive({});
|
||||
|
||||
const formRef = ref();
|
||||
const queryParam = reactive<any>({});
|
||||
const toggleSearchStatus = ref<boolean>(false);
|
||||
const registerModal = ref();
|
||||
const userStore = useUserStore();
|
||||
const { createMessage } = useMessage();
|
||||
|
||||
//将是否启用转换成开关
|
||||
const enhancedColumns = columns.map((col) => {
|
||||
|
|
@ -130,7 +119,7 @@
|
|||
});
|
||||
|
||||
//注册table数据
|
||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
||||
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||
tableProps: {
|
||||
title: '容器',
|
||||
api: list,
|
||||
|
|
@ -164,7 +153,7 @@
|
|||
success: handleSuccess,
|
||||
},
|
||||
});
|
||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
||||
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] =
|
||||
tableContext;
|
||||
const labelCol = reactive({
|
||||
xs: 24,
|
||||
|
|
|
|||
|
|
@ -25,11 +25,6 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="库位" v-bind="validateInfos.pointId" id="StockForm-pointId" name="pointId">
|
||||
<PointSelect v-model:value="formData.pointId" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="描述" v-bind="validateInfos.description" id="StockForm-description" name="description">
|
||||
<a-textarea v-model:value="formData.description" :rows="4" placeholder="请输入描述" />
|
||||
|
|
@ -57,7 +52,6 @@
|
|||
import JSwitch from '@/components/Form/src/jeecg/components/JSwitch.vue';
|
||||
import { JDictSelectTag } from '@/components/Form';
|
||||
import { getTenantId } from '@/utils/auth';
|
||||
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||
|
||||
const props = defineProps({
|
||||
formDisabled: { type: Boolean, default: false },
|
||||
|
|
@ -71,7 +65,6 @@
|
|||
let tenantId = getTenantId();
|
||||
const formData = reactive<Record<string, any>>({
|
||||
id: '',
|
||||
pointId: '',
|
||||
stockCode: '',
|
||||
stockType: 'TRAY',
|
||||
status: 0,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@
|
|||
v-bind="attrs"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="loading" size="small" />
|
||||
<span v-else>暂无容器数据</span>
|
||||
|
||||
</template>
|
||||
<a-select-option v-for="option in Options" :key="option.id" :value="getOptionValue(option)">
|
||||
{{ getOptionLabel(option) }}
|
||||
|
|
@ -75,8 +74,14 @@
|
|||
immediateChange: propTypes.bool.def(false),
|
||||
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||
returnValue: propTypes.string.def('id'),
|
||||
//默认空闲
|
||||
status: propTypes.number.def(0),
|
||||
//默认启用
|
||||
izActive: propTypes.number.def(1),
|
||||
//默认未删除
|
||||
delFlag: propTypes.number.def(0),
|
||||
//是否扫描
|
||||
izScan: propTypes.bool.def(false),
|
||||
},
|
||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||
setup(props, { emit }) {
|
||||
|
|
@ -96,7 +101,7 @@
|
|||
|
||||
// 未找到内容
|
||||
const notFoundContent = computed(() => {
|
||||
return loading.value ? undefined : null;
|
||||
return loading.value ? undefined : '暂无数据';
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -146,7 +151,7 @@
|
|||
*/
|
||||
function ensureUnique(Stocks: Stock[], newStock: Stock): Stock[] {
|
||||
// 如果已经存在相同id的容器,先移除旧的再添加新的
|
||||
const filtered = Stocks.filter(Stock => Stock.id !== newStock.id);
|
||||
const filtered = Stocks.filter((Stock) => Stock.id !== newStock.id);
|
||||
return [newStock, ...filtered];
|
||||
}
|
||||
|
||||
|
|
@ -163,11 +168,15 @@
|
|||
pageSize: props.pageSize,
|
||||
pageNo: page,
|
||||
keyword: keyword,
|
||||
status: props.status,
|
||||
izActive: props.izActive,
|
||||
delFlag: props.delFlag,
|
||||
izScan: props.izScan,
|
||||
},
|
||||
});
|
||||
|
||||
const records = res.records || [];
|
||||
console.log('res', records)
|
||||
|
||||
if (page === 1 || isSearch) {
|
||||
// 第一页或搜索时,重置数据
|
||||
|
|
@ -175,9 +184,7 @@
|
|||
Options.value = records;
|
||||
} else {
|
||||
// 滚动加载时,追加数据(确保不重复)
|
||||
const newRecords = records.filter(record =>
|
||||
!allStocks.value.some(Stock => Stock.id === record.id)
|
||||
);
|
||||
const newRecords = records.filter((record) => !allStocks.value.some((Stock) => Stock.id === record.id));
|
||||
allStocks.value = [...allStocks.value, ...newRecords];
|
||||
Options.value = [...Options.value, ...newRecords];
|
||||
}
|
||||
|
|
@ -296,6 +303,7 @@
|
|||
const returnValue = getReturnValue(value);
|
||||
emit('update:value', returnValue);
|
||||
emit('change', returnValue);
|
||||
console.log('值变化:', returnValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<a-col :lg="6">
|
||||
<a-form-item name="pointId">
|
||||
<template #label><span title="库位">库位</span></template>
|
||||
<PointSelect v-model:value="queryParam.pointId" />
|
||||
<PointSelect v-model:value="queryParam.pointId" :area-code="['CPCCQ', 'MJCCQ']" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :lg="6">
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@ export const columns: BasicColumn[] = [
|
|||
dataIndex: 'logType_dictText',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '业务单号',
|
||||
align: 'center',
|
||||
dataIndex: 'businessNo',
|
||||
width: 130,
|
||||
},
|
||||
{
|
||||
title: '物料',
|
||||
align: 'center',
|
||||
|
|
@ -17,19 +23,19 @@ export const columns: BasicColumn[] = [
|
|||
title: '原库位',
|
||||
align: 'center',
|
||||
dataIndex: 'fromPointId_dictText',
|
||||
width: 120,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '目标库位',
|
||||
align: 'center',
|
||||
dataIndex: 'toPointId_dictText',
|
||||
width: 120,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '容器',
|
||||
align: 'center',
|
||||
dataIndex: 'stockId_dictText',
|
||||
width: 120,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '变动前数量',
|
||||
|
|
@ -50,15 +56,36 @@ export const columns: BasicColumn[] = [
|
|||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '变动前分配数量',
|
||||
title: '分配前数量',
|
||||
align: 'center',
|
||||
dataIndex: 'beforeAllocatedQty',
|
||||
width: 120,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '变动后分配数量',
|
||||
title: '分配数量',
|
||||
align: 'center',
|
||||
dataIndex: 'allocatedQty',
|
||||
width: 100,
|
||||
customRender: ({ record }) => {
|
||||
// 从记录中获取分配前和分配后的数量
|
||||
const before = record.beforeAllocatedQty || 0;
|
||||
const after = record.afterAllocatedQty || 0;
|
||||
if(record.logType_dictText==='分配'){
|
||||
if(before>0){
|
||||
return after - before;
|
||||
}
|
||||
return before + after;
|
||||
}else if(record.logType_dictText==='取消分配'){
|
||||
return before - after;
|
||||
}else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '分配后数量',
|
||||
align: 'center',
|
||||
dataIndex: 'afterAllocatedQty',
|
||||
width: 120,
|
||||
width: 100,
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -6,12 +6,7 @@
|
|||
<a-row>
|
||||
<a-col :span="24">
|
||||
<a-form-item label="托盘" v-bind="validateInfos.stockCode" id="ScanTrayForm-stockCode" name="stockCode">
|
||||
<JSearchSelect
|
||||
v-model:value="formData.stockCode"
|
||||
placeholder="请选择托盘"
|
||||
dict="base_stock where status=1 and iz_active=1 and del_flag=0,stock_code,stock_code"
|
||||
allowClear
|
||||
/>
|
||||
<StockSelect v-model:value="formData.stockCode" :return-value="'stockCode'" :status="1" :iz-scan="true" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
|
|
@ -38,6 +33,7 @@
|
|||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||
import { JSearchSelect } from '@/components/Form';
|
||||
import { scanTray } from '@/views/conveyorLine/ConveyorLine.api';
|
||||
import StockSelect from '@/views/base/stock/components/StockSelect.vue';
|
||||
|
||||
const props = defineProps({
|
||||
formDisabled: { type: Boolean, default: false },
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ enum Api {
|
|||
queryTaskByMainId = '/shipping/pick/queryTaskByMainId',
|
||||
allocatePick = '/shipping/pick/allocatePick',
|
||||
cancelAllocate = '/shipping/pick/cancelAllocate',
|
||||
pickTask = '/shipping/pick/pickTask',
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,3 +124,13 @@ export const cancelAllocate = (ids,handleSuccess) => {
|
|||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 出库单拣货
|
||||
* @param params
|
||||
*/
|
||||
export const pickTask = (ids,handleSuccess) => {
|
||||
return defHttp.get({ url: Api.pickTask, params: { ids } }, { joinParamsToUrl: true }).then(() => {
|
||||
handleSuccess();
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@
|
|||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :lg="6">
|
||||
<a-form-item name="status">
|
||||
<a-form-item name="status_MultiString">
|
||||
<template #label><span title="状态">状态</span></template>
|
||||
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="pick_status" mode="multiple" allowClear />
|
||||
<JSelectMultiple v-model:value="queryParam.status_MultiString" dictCode="pick_status" />
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
|
@ -53,22 +53,34 @@
|
|||
<a-button
|
||||
type="primary"
|
||||
:loading="allocate_loading"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
v-auth="'shipping:data_pick:allocatePick'"
|
||||
@click="handleAllocatePick"
|
||||
preIcon="ant-design:edit-outlined"
|
||||
>
|
||||
分配
|
||||
批量分配
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
danger
|
||||
:loading="cancel_loading"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
v-auth="'shipping:data_pick:cancelAllocate'"
|
||||
@click="handleCancelAllocate"
|
||||
preIcon="ant-design:edit-outlined"
|
||||
>
|
||||
取消分配
|
||||
</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="pick_loading"
|
||||
:disabled="selectedRowKeys.length === 0"
|
||||
v-auth="'shipping:data_pick:pickTask'"
|
||||
@click="handlePick"
|
||||
preIcon="ant-design:edit-outlined"
|
||||
>
|
||||
批量拣货
|
||||
</a-button>
|
||||
<a-button type="primary" v-auth="'shipping:data_pick:exportXls'" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出 </a-button>
|
||||
<j-upload-button type="primary" v-auth="'shipping:data_pick:importExcel'" preIcon="ant-design:import-outlined" @click="onImportXls"
|
||||
>导入
|
||||
|
|
@ -107,15 +119,17 @@
|
|||
import { useModal } from '/@/components/Modal';
|
||||
import PickModal from './components/PickModal.vue';
|
||||
import { columns } from './Pick.data';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, allocatePick, cancelAllocate } from './Pick.api';
|
||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, allocatePick, cancelAllocate, pickTask } from './Pick.api';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDateByPicker } from '/@/utils';
|
||||
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
||||
import { JInput, JDictSelectTag } from '@/components/Form';
|
||||
import JRangeDate from '@/components/Form/src/jeecg/components/JRangeDate.vue';
|
||||
import JSelectMultiple from '/@/components/Form/src/jeecg/components/JSelectMultiple.vue';
|
||||
|
||||
const allocate_loading = ref(false);
|
||||
const cancel_loading = ref(false);
|
||||
const pick_loading = ref(false);
|
||||
const fieldPickers = reactive({});
|
||||
const formRef = ref();
|
||||
const queryParam = reactive<any>({});
|
||||
|
|
@ -184,10 +198,6 @@
|
|||
* 分配事件
|
||||
*/
|
||||
async function handleAllocatePick() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return createMessage.error('请选择出库单');
|
||||
}
|
||||
|
||||
// 选中的数据中状态有1、2、4 返回true,否则返回false
|
||||
const validStatuses = [1, 2, 4];
|
||||
const allValidStatus = selectedRows.value.every((row: any) => validStatuses.includes(row.status));
|
||||
|
|
@ -214,10 +224,6 @@
|
|||
* 取消分配
|
||||
*/
|
||||
async function handleCancelAllocate() {
|
||||
if (selectedRowKeys.value.length === 0) {
|
||||
return createMessage.error('请选择出库单');
|
||||
}
|
||||
|
||||
// 选中的数据中状态有2、3 返回true,否则返回false
|
||||
const validStatuses = [2, 3];
|
||||
const allValidStatus = selectedRows.value.every((row: any) => validStatuses.includes(row.status));
|
||||
|
|
@ -240,6 +246,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拣货事件
|
||||
*/
|
||||
async function handlePick() {
|
||||
// 选中的数据中状态有1、2、4 返回true,否则返回false
|
||||
const validStatuses = [2, 3, 4];
|
||||
const allValidStatus = selectedRows.value.every((row: any) => validStatuses.includes(row.status));
|
||||
if (!allValidStatus) {
|
||||
return createMessage.error('【部分分配、已分配、部分拣货】状态的出库单才允许拣货');
|
||||
}
|
||||
if (pick_loading.value) {
|
||||
return;
|
||||
}
|
||||
// 设置加载状态,防止重复提交
|
||||
pick_loading.value = true;
|
||||
try {
|
||||
await pickTask(selectedRowKeys.value, handleSuccess);
|
||||
} catch (e) {
|
||||
console.error('拣货失败:', e);
|
||||
handleSuccess();
|
||||
} finally {
|
||||
// 重置加载状态
|
||||
pick_loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑事件
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue