no message
parent
7b2f3fe311
commit
d308c16400
|
|
@ -14,7 +14,7 @@
|
||||||
@focus="handleAsyncFocus"
|
@focus="handleAsyncFocus"
|
||||||
@search="loadData"
|
@search="loadData"
|
||||||
@change="handleAsyncChange"
|
@change="handleAsyncChange"
|
||||||
@popupScroll="handlePopupScroll"
|
@popup-scroll="handlePopupScroll"
|
||||||
:mode="multiple?'multiple':''"
|
:mode="multiple?'multiple':''"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
@deselect="handleDeSelect"
|
@deselect="handleDeSelect"
|
||||||
|
|
@ -176,7 +176,7 @@
|
||||||
isHasData = true;
|
isHasData = true;
|
||||||
searchKeyword = value;
|
searchKeyword = value;
|
||||||
// update-end--author:liaozhiyang---date:20240731---for:【TV360X-1898】JsearchSelect组件传入字典表格式则支持滚动加载
|
// update-end--author:liaozhiyang---date:20240731---for:【TV360X-1898】JsearchSelect组件传入字典表格式则支持滚动加载
|
||||||
|
|
||||||
lastLoad.value += 1;
|
lastLoad.value += 1;
|
||||||
const currentLoad = unref(lastLoad);
|
const currentLoad = unref(lastLoad);
|
||||||
options.value = [];
|
options.value = [];
|
||||||
|
|
@ -399,7 +399,7 @@
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步值取消选中事件
|
* 异步值取消选中事件
|
||||||
* @param selectedObj
|
* @param selectedObj
|
||||||
|
|
@ -423,7 +423,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//update-end---author:wangshuai---date:2025-04-17---for:【issues/8101】前端dict组件导致内存溢出问题:搜索组件支持多选---
|
//update-end---author:wangshuai---date:2025-04-17---for:【issues/8101】前端dict组件导致内存溢出问题:搜索组件支持多选---
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*回调方法
|
*回调方法
|
||||||
* */
|
* */
|
||||||
|
|
@ -480,12 +480,12 @@
|
||||||
// 如果设定了排序信息,需要写入排序信息,在关键词后加 [orderby:create_time,desc]
|
// 如果设定了排序信息,需要写入排序信息,在关键词后加 [orderby:create_time,desc]
|
||||||
if(props.params && props.params.column && props.params.order){
|
if(props.params && props.params.column && props.params.order){
|
||||||
let temp = text||''
|
let temp = text||''
|
||||||
|
|
||||||
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
//update-begin-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||||
temp = temp+'[orderby:'+props.params.column+','+props.params.order+']'
|
temp = temp+'[orderby:'+props.params.column+','+props.params.order+']'
|
||||||
return encodeURI(temp);
|
return encodeURI(temp);
|
||||||
//update-end-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
//update-end-author:taoyan date:2023-5-22 for: /issues/4905 表单生成器字段配置时,选择关联字段,在进行高级配置时,无法加载数据库列表,提示 Sgin签名校验错误! #4905
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setModalHeight(option?) {
|
async function setModalHeight(option?) {
|
||||||
console.log("---------性能监控--------setModalHeight----------")
|
|
||||||
const options = option || {};
|
const options = option || {};
|
||||||
const source = options.source;
|
const source = options.source;
|
||||||
const callBack = options.callBack;
|
const callBack = options.callBack;
|
||||||
|
|
@ -208,7 +207,7 @@
|
||||||
callBack(realHeightRef.value);
|
callBack(realHeightRef.value);
|
||||||
}
|
}
|
||||||
// update-end--author:liaozhiyang---date:2024-04-18---for:【QQYUN-9035】basicModal不设置maxHeight或height会一直执行setModalHeight,需即使销毁MutationObserver
|
// update-end--author:liaozhiyang---date:2024-04-18---for:【QQYUN-9035】basicModal不设置maxHeight或height会一直执行setModalHeight,需即使销毁MutationObserver
|
||||||
|
|
||||||
emit('height-change', unref(realHeightRef));
|
emit('height-change', unref(realHeightRef));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
import { useMessage } from "/@/hooks/web/useMessage";
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
|
|
||||||
const { createConfirm } = useMessage();
|
const { createConfirm } = useMessage();
|
||||||
|
|
||||||
enum Api {
|
enum Api {
|
||||||
list = '/base/item/list',
|
list = '/base/item/list',
|
||||||
save='/base/item/add',
|
queryById = '/base/item/queryById',
|
||||||
edit='/base/item/edit',
|
save = '/base/item/add',
|
||||||
|
edit = '/base/item/edit',
|
||||||
deleteOne = '/base/item/delete',
|
deleteOne = '/base/item/delete',
|
||||||
deleteBatch = '/base/item/deleteBatch',
|
deleteBatch = '/base/item/deleteBatch',
|
||||||
importExcel = '/base/item/importExcel',
|
importExcel = '/base/item/importExcel',
|
||||||
|
|
@ -30,16 +31,22 @@ export const getImportUrl = Api.importExcel;
|
||||||
*/
|
*/
|
||||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
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
|
* @param params
|
||||||
* @param handleSuccess
|
* @param handleSuccess
|
||||||
*/
|
*/
|
||||||
export const deleteOne = (params,handleSuccess) => {
|
export const deleteOne = (params, handleSuccess) => {
|
||||||
return defHttp.delete({url: Api.deleteOne, params}, {joinParamsToUrl: true}).then(() => {
|
return defHttp.delete({ url: Api.deleteOne, params }, { joinParamsToUrl: true }).then(() => {
|
||||||
handleSuccess();
|
handleSuccess();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除
|
* 批量删除
|
||||||
|
|
@ -54,12 +61,20 @@ export const batchDelete = (params, handleSuccess) => {
|
||||||
okText: '确认',
|
okText: '确认',
|
||||||
cancelText: '取消',
|
cancelText: '取消',
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
return defHttp.delete({url: Api.deleteBatch, data: params}, {joinParamsToUrl: true}).then(() => {
|
return defHttp
|
||||||
handleSuccess();
|
.delete(
|
||||||
});
|
{
|
||||||
}
|
url: Api.deleteBatch,
|
||||||
|
data: params,
|
||||||
|
},
|
||||||
|
{ joinParamsToUrl: true }
|
||||||
|
)
|
||||||
|
.then(() => {
|
||||||
|
handleSuccess();
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存或者更新
|
* 保存或者更新
|
||||||
|
|
@ -67,6 +82,6 @@ export const batchDelete = (params, handleSuccess) => {
|
||||||
* @param isUpdate
|
* @param isUpdate
|
||||||
*/
|
*/
|
||||||
export const saveOrUpdate = (params, isUpdate) => {
|
export const saveOrUpdate = (params, isUpdate) => {
|
||||||
let url = isUpdate ? Api.edit : Api.save;
|
const url = isUpdate ? Api.edit : Api.save;
|
||||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,416 @@
|
||||||
|
<!-- 物料选择 -->
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
v-model:value="selectedValue"
|
||||||
|
showSearch
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:loading="loading"
|
||||||
|
:allowClear="true"
|
||||||
|
:filterOption="filterOption"
|
||||||
|
:notFoundContent="notFoundContent"
|
||||||
|
:mode="multiple ? 'multiple' : 'default'"
|
||||||
|
@change="handleChange"
|
||||||
|
@search="handleSearch"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@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 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 { queryById } from '@/views/base/item/Item.api';
|
||||||
|
import { setPopContainer } from '/@/utils';
|
||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
// 物料数据接口
|
||||||
|
interface Item {
|
||||||
|
id: string;
|
||||||
|
itemCode: string;
|
||||||
|
itemName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//响应数据接口
|
||||||
|
interface ResponseData {
|
||||||
|
records: Item[];
|
||||||
|
total: number;
|
||||||
|
size: number;
|
||||||
|
current: number;
|
||||||
|
page: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ItemSelect',
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
// 是否立即触发change事件
|
||||||
|
immediateChange: propTypes.bool.def(false),
|
||||||
|
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||||
|
returnValue: propTypes.string.def('id'),
|
||||||
|
//默认启用
|
||||||
|
izActive: propTypes.number.def(1),
|
||||||
|
},
|
||||||
|
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const Options = ref<Item[]>([]);
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
const allItems = ref<Item[]>([]);
|
||||||
|
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const pageNo = ref(1);
|
||||||
|
const isHasData = ref(true);
|
||||||
|
const scrollLoading = ref(false);
|
||||||
|
const searchKeyword = ref('');
|
||||||
|
|
||||||
|
// 选中值
|
||||||
|
const selectedValue = ref<string | string[] | undefined>(undefined);
|
||||||
|
|
||||||
|
// 未找到内容
|
||||||
|
const notFoundContent = computed(() => {
|
||||||
|
return loading.value ? undefined : null;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取选项显示文本 - 始终显示完整格式
|
||||||
|
*/
|
||||||
|
function getOptionLabel(option: Item) {
|
||||||
|
return `${option.itemCode} - ${option.itemName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取选项值 - 根据returnValue确定实际存储的值
|
||||||
|
*/
|
||||||
|
function getOptionValue(option: Item) {
|
||||||
|
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 Item] as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取弹出层容器
|
||||||
|
*/
|
||||||
|
function getParentContainer(node: HTMLElement) {
|
||||||
|
if (props.popContainer) {
|
||||||
|
return setPopContainer(node, props.popContainer);
|
||||||
|
} else {
|
||||||
|
if (typeof props.getPopupContainer === 'function') {
|
||||||
|
return props.getPopupContainer(node);
|
||||||
|
} else {
|
||||||
|
return node?.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤选项 - 禁用前端过滤,使用后端搜索
|
||||||
|
*/
|
||||||
|
function filterOption(_input: string, _option: any) {
|
||||||
|
return true; // 禁用前端过滤,完全依赖后端搜索
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保物料唯一性的辅助函数
|
||||||
|
*/
|
||||||
|
function ensureUnique(items: Item[], newItem: Item): Item[] {
|
||||||
|
// 如果已经存在相同id的物料,先移除旧的再添加新的
|
||||||
|
const filtered = items.filter(item => item.id !== newItem.id);
|
||||||
|
return [newItem, ...filtered];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取物料数据
|
||||||
|
*/
|
||||||
|
const queryData = async (page = 1, keyword = '', isSearch = false) => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
const res = await defHttp.get<ResponseData>({
|
||||||
|
url: '/base/item/list',
|
||||||
|
params: {
|
||||||
|
pageSize: props.pageSize,
|
||||||
|
pageNo: page,
|
||||||
|
keyword: keyword,
|
||||||
|
izActive: props.izActive,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const records = res.records || [];
|
||||||
|
|
||||||
|
if (page === 1 || isSearch) {
|
||||||
|
// 第一页或搜索时,重置数据
|
||||||
|
allItems.value = records;
|
||||||
|
Options.value = records;
|
||||||
|
} else {
|
||||||
|
// 滚动加载时,追加数据(确保不重复)
|
||||||
|
const newRecords = records.filter(record =>
|
||||||
|
!allItems.value.some(item => item.id === record.id)
|
||||||
|
);
|
||||||
|
allItems.value = [...allItems.value, ...newRecords];
|
||||||
|
Options.value = [...Options.value, ...newRecords];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修正分页判断逻辑
|
||||||
|
isHasData.value = records.length >= props.pageSize;
|
||||||
|
|
||||||
|
emit('optionsLoaded', allItems.value);
|
||||||
|
} catch (error) {
|
||||||
|
if (page === 1) {
|
||||||
|
allItems.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 item = Array.isArray(res) ? res[0] : res;
|
||||||
|
if (item) {
|
||||||
|
// 使用ensureUnique确保物料不重复
|
||||||
|
allItems.value = ensureUnique(allItems.value, item);
|
||||||
|
Options.value = ensureUnique(Options.value, item);
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('查询物料失败:', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据选项值找到对应的选项对象
|
||||||
|
*/
|
||||||
|
function findOptionByValue(value: string): Item | undefined {
|
||||||
|
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
||||||
|
return allItems.value.find((item) => item.id === value);
|
||||||
|
} else {
|
||||||
|
return allItems.value.find((item) => item[props.returnValue as keyof Item] === 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果返回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 Item] : v;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const option = findOptionByValue(value);
|
||||||
|
return option ? option[props.returnValue as keyof Item] : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索处理(防抖)
|
||||||
|
*/
|
||||||
|
const handleSearch = debounce(function (value: string) {
|
||||||
|
searchKeyword.value = value;
|
||||||
|
pageNo.value = 1;
|
||||||
|
isHasData.value = true;
|
||||||
|
|
||||||
|
// 直接调用API进行搜索
|
||||||
|
queryData(1, value, true);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理焦点事件
|
||||||
|
*/
|
||||||
|
function handleFocus() {
|
||||||
|
// 如果还没有数据,加载数据
|
||||||
|
if (allItems.value.length === 0 && props.async) {
|
||||||
|
pageNo.value = 1;
|
||||||
|
isHasData.value = true;
|
||||||
|
queryData(1, '');
|
||||||
|
}
|
||||||
|
attrs.onFocus?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理值变化
|
||||||
|
*/
|
||||||
|
function handleChange(value: string | string[]) {
|
||||||
|
selectedValue.value = value;
|
||||||
|
|
||||||
|
// 根据配置返回相应的值
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是异步模式且还没有加载数据,则先加载数据
|
||||||
|
if (props.async && allItems.value.length === 0) {
|
||||||
|
await queryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据不同的returnValue设置选中的值
|
||||||
|
let valueIds: string[] = [];
|
||||||
|
|
||||||
|
if (props.returnValue === 'object') {
|
||||||
|
// 如果返回的是对象,value可能是对象或对象数组
|
||||||
|
if (Array.isArray(props.value)) {
|
||||||
|
valueIds = props.value.map((item: any) => item.id);
|
||||||
|
selectedValue.value = valueIds;
|
||||||
|
} else {
|
||||||
|
valueIds = [(props.value as any).id];
|
||||||
|
selectedValue.value = valueIds[0];
|
||||||
|
}
|
||||||
|
} 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 = allItems.value.find((item) => item[props.returnValue as keyof Item] === v);
|
||||||
|
return option ? option.id : v;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const option = allItems.value.find((item) => item[props.returnValue as keyof Item] === props.value);
|
||||||
|
valueIds = option ? [option.id] : [props.value as string];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有值不在当前列表中,如果有则查询
|
||||||
|
const missingIds = valueIds.filter((id) => !allItems.value.some((item) => item.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>
|
||||||
|
|
@ -5,6 +5,7 @@ const { createConfirm } = useMessage();
|
||||||
|
|
||||||
enum Api {
|
enum Api {
|
||||||
list = '/base/point/list',
|
list = '/base/point/list',
|
||||||
|
queryById='/base/point/queryById',
|
||||||
save='/base/point/add',
|
save='/base/point/add',
|
||||||
edit='/base/point/edit',
|
edit='/base/point/edit',
|
||||||
deleteOne = '/base/point/delete',
|
deleteOne = '/base/point/delete',
|
||||||
|
|
@ -30,6 +31,13 @@ export const getImportUrl = Api.importExcel;
|
||||||
*/
|
*/
|
||||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
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
|
* @param params
|
||||||
|
|
@ -67,6 +75,6 @@ export const batchDelete = (params, handleSuccess) => {
|
||||||
* @param isUpdate
|
* @param isUpdate
|
||||||
*/
|
*/
|
||||||
export const saveOrUpdate = (params, isUpdate) => {
|
export const saveOrUpdate = (params, isUpdate) => {
|
||||||
let url = isUpdate ? Api.edit : Api.save;
|
const url = isUpdate ? Api.edit : Api.save;
|
||||||
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
return defHttp.post({ url: url, params }, { isTransformResponse: false });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,6 @@
|
||||||
import { columns } from './Point.data';
|
import { columns } from './Point.data';
|
||||||
import { list, deleteOne, batchDelete, saveOrUpdate, getImportUrl, getExportUrl } from './Point.api';
|
import { list, deleteOne, batchDelete, saveOrUpdate, getImportUrl, getExportUrl } from './Point.api';
|
||||||
import PointModal from './components/PointModal.vue';
|
import PointModal from './components/PointModal.vue';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
|
||||||
import { getDateByPicker } from '/@/utils';
|
import { getDateByPicker } from '/@/utils';
|
||||||
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
||||||
import JInput from '../../../components/Form/src/jeecg/components/JInput.vue';
|
import JInput from '../../../components/Form/src/jeecg/components/JInput.vue';
|
||||||
|
|
@ -106,8 +104,6 @@
|
||||||
const queryParam = reactive<any>({});
|
const queryParam = reactive<any>({});
|
||||||
const toggleSearchStatus = ref<boolean>(false);
|
const toggleSearchStatus = ref<boolean>(false);
|
||||||
const registerModal = ref();
|
const registerModal = ref();
|
||||||
const userStore = useUserStore();
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
|
|
||||||
//将是否启用转换成开关
|
//将是否启用转换成开关
|
||||||
const enhancedColumns = columns.map((col) => {
|
const enhancedColumns = columns.map((col) => {
|
||||||
|
|
@ -135,7 +131,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
//注册table数据
|
//注册table数据
|
||||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||||
tableProps: {
|
tableProps: {
|
||||||
title: '库位',
|
title: '库位',
|
||||||
api: list,
|
api: list,
|
||||||
|
|
@ -169,8 +165,7 @@
|
||||||
success: handleSuccess,
|
success: handleSuccess,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||||
tableContext;
|
|
||||||
const labelCol = reactive({
|
const labelCol = reactive({
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm: 4,
|
sm: 4,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- 库位下拉选择-->
|
<!-- 库位选择 -->
|
||||||
<template>
|
<template>
|
||||||
<a-select
|
<a-select
|
||||||
v-model:value="selectedValue"
|
v-model:value="selectedValue"
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@focus="handleFocus"
|
@focus="handleFocus"
|
||||||
@popupScroll="handlePopupScroll"
|
@popup-scroll="handlePopupScroll"
|
||||||
:getPopupContainer="getParentContainer"
|
:getPopupContainer="getParentContainer"
|
||||||
v-bind="attrs"
|
v-bind="attrs"
|
||||||
>
|
>
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
<a-spin v-if="loading" size="small" />
|
<a-spin v-if="loading" size="small" />
|
||||||
<span v-else>暂无库位数据</span>
|
<span v-else>暂无库位数据</span>
|
||||||
</template>
|
</template>
|
||||||
<a-select-option v-for="option in PointOptions" :key="option.id" :value="getOptionValue(option)">
|
<a-select-option v-for="option in Options" :key="option.id" :value="getOptionValue(option)">
|
||||||
{{ getOptionLabel(option) }}
|
{{ getOptionLabel(option) }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
import { useAttrs } from '/@/hooks/core/useAttrs';
|
import { useAttrs } from '/@/hooks/core/useAttrs';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
import { propTypes } from '/@/utils/propTypes';
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
import { queryById } from '@/views/base/point/Point.api';
|
||||||
import { setPopContainer } from '/@/utils';
|
import { setPopContainer } from '/@/utils';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
|
@ -63,7 +64,7 @@
|
||||||
// 是否异步加载数据
|
// 是否异步加载数据
|
||||||
async: propTypes.bool.def(true),
|
async: propTypes.bool.def(true),
|
||||||
// 分页大小
|
// 分页大小
|
||||||
pageSize: propTypes.number.def(20),
|
pageSize: propTypes.number.def(10),
|
||||||
// 弹出层容器
|
// 弹出层容器
|
||||||
popContainer: propTypes.string,
|
popContainer: propTypes.string,
|
||||||
// 自定义弹出层容器函数
|
// 自定义弹出层容器函数
|
||||||
|
|
@ -80,7 +81,7 @@
|
||||||
},
|
},
|
||||||
emits: ['change', 'update:value', 'optionsLoaded'],
|
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const PointOptions = ref<Point[]>([]);
|
const Options = ref<Point[]>([]);
|
||||||
const loading = ref<boolean>(false);
|
const loading = ref<boolean>(false);
|
||||||
const allPoints = ref<Point[]>([]);
|
const allPoints = ref<Point[]>([]);
|
||||||
const attrs = useAttrs({ excludeDefaultKeys: false });
|
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||||
|
|
@ -103,7 +104,7 @@
|
||||||
* 获取选项显示文本 - 始终显示完整格式
|
* 获取选项显示文本 - 始终显示完整格式
|
||||||
*/
|
*/
|
||||||
function getOptionLabel(option: Point) {
|
function getOptionLabel(option: Point) {
|
||||||
return `${option.pointCode} - ${option.areaId_dictText }`;
|
return `${option.pointCode} - ${option.areaId_dictText}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,10 +142,19 @@
|
||||||
return true; // 禁用前端过滤,完全依赖后端搜索
|
return true; // 禁用前端过滤,完全依赖后端搜索
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保库位唯一性的辅助函数
|
||||||
|
*/
|
||||||
|
function ensureUnique(Points: Point[], newPoint: Point): Point[] {
|
||||||
|
// 如果已经存在相同id的库位,先移除旧的再添加新的
|
||||||
|
const filtered = Points.filter(Point => Point.id !== newPoint.id);
|
||||||
|
return [newPoint, ...filtered];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取库位数据
|
* 获取库位数据
|
||||||
*/
|
*/
|
||||||
const fetchPoints = async (page = 1, keyword = '', isSearch = false) => {
|
const queryData = async (page = 1, keyword = '', isSearch = false) => {
|
||||||
try {
|
try {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
|
|
||||||
|
|
@ -158,29 +168,29 @@
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('获取库位数据成功:', res);
|
|
||||||
const records = res.records || [];
|
const records = res.records || [];
|
||||||
|
|
||||||
if (page === 1 || isSearch) {
|
if (page === 1 || isSearch) {
|
||||||
// 第一页或搜索时,重置数据
|
// 第一页或搜索时,重置数据
|
||||||
allPoints.value = records;
|
allPoints.value = records;
|
||||||
PointOptions.value = records;
|
Options.value = records;
|
||||||
} else {
|
} else {
|
||||||
// 滚动加载时,追加数据
|
// 滚动加载时,追加数据(确保不重复)
|
||||||
allPoints.value = [...allPoints.value, ...records];
|
const newRecords = records.filter(record =>
|
||||||
PointOptions.value = [...PointOptions.value, ...records];
|
!allPoints.value.some(Point => Point.id === record.id)
|
||||||
|
);
|
||||||
|
allPoints.value = [...allPoints.value, ...newRecords];
|
||||||
|
Options.value = [...Options.value, ...newRecords];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修正分页判断逻辑
|
// 修正分页判断逻辑
|
||||||
isHasData.value = records.length >= props.pageSize;
|
isHasData.value = records.length >= props.pageSize;
|
||||||
console.log('是否还有更多数据:', records.length);
|
|
||||||
|
|
||||||
emit('optionsLoaded', allPoints.value);
|
emit('optionsLoaded', allPoints.value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取库位数据失败:', error);
|
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
allPoints.value = [];
|
allPoints.value = [];
|
||||||
PointOptions.value = [];
|
Options.value = [];
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|
@ -188,14 +198,33 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function queryDataById(value: string) {
|
||||||
|
try {
|
||||||
|
const res = await queryById({ id: value });
|
||||||
|
if (res) {
|
||||||
|
// 将查询到的单个库位信息添加到列表中,确保唯一性
|
||||||
|
const Point = Array.isArray(res) ? res[0] : res;
|
||||||
|
if (Point) {
|
||||||
|
// 使用ensureUnique确保库位不重复
|
||||||
|
allPoints.value = ensureUnique(allPoints.value, Point);
|
||||||
|
Options.value = ensureUnique(Options.value, Point);
|
||||||
|
}
|
||||||
|
return Point;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('查询库位失败:', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据选项值找到对应的选项对象
|
* 根据选项值找到对应的选项对象
|
||||||
*/
|
*/
|
||||||
function findOptionByValue(value: string): Point | undefined {
|
function findOptionByValue(value: string): Point | undefined {
|
||||||
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
||||||
return allPoints.value.find((item) => item.id === value);
|
return allPoints.value.find((Point) => Point.id === value);
|
||||||
} else {
|
} else {
|
||||||
return allPoints.value.find((item) => item[props.returnValue as keyof Point] === value);
|
return allPoints.value.find((Point) => Point[props.returnValue as keyof Point] === value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,7 +271,7 @@
|
||||||
isHasData.value = true;
|
isHasData.value = true;
|
||||||
|
|
||||||
// 直接调用API进行搜索
|
// 直接调用API进行搜索
|
||||||
fetchPoints(1, value, true);
|
queryData(1, value, true);
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -253,7 +282,7 @@
|
||||||
if (allPoints.value.length === 0 && props.async) {
|
if (allPoints.value.length === 0 && props.async) {
|
||||||
pageNo.value = 1;
|
pageNo.value = 1;
|
||||||
isHasData.value = true;
|
isHasData.value = true;
|
||||||
fetchPoints(1, '');
|
queryData(1, '');
|
||||||
}
|
}
|
||||||
attrs.onFocus?.();
|
attrs.onFocus?.();
|
||||||
}
|
}
|
||||||
|
|
@ -266,7 +295,6 @@
|
||||||
|
|
||||||
// 根据配置返回相应的值
|
// 根据配置返回相应的值
|
||||||
const returnValue = getReturnValue(value);
|
const returnValue = getReturnValue(value);
|
||||||
console.log('值变化:', returnValue);
|
|
||||||
emit('update:value', returnValue);
|
emit('update:value', returnValue);
|
||||||
emit('change', returnValue);
|
emit('change', returnValue);
|
||||||
}
|
}
|
||||||
|
|
@ -279,11 +307,10 @@
|
||||||
const { scrollTop, scrollHeight, clientHeight } = target;
|
const { scrollTop, scrollHeight, clientHeight } = target;
|
||||||
|
|
||||||
if (!scrollLoading.value && isHasData.value && scrollTop + clientHeight >= scrollHeight - 10) {
|
if (!scrollLoading.value && isHasData.value && scrollTop + clientHeight >= scrollHeight - 10) {
|
||||||
console.log('滚动加载更多');
|
|
||||||
scrollLoading.value = true;
|
scrollLoading.value = true;
|
||||||
pageNo.value++;
|
pageNo.value++;
|
||||||
|
|
||||||
fetchPoints(pageNo.value, searchKeyword.value)
|
queryData(pageNo.value, searchKeyword.value)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
scrollLoading.value = false;
|
scrollLoading.value = false;
|
||||||
})
|
})
|
||||||
|
|
@ -304,22 +331,50 @@
|
||||||
|
|
||||||
// 如果是异步模式且还没有加载数据,则先加载数据
|
// 如果是异步模式且还没有加载数据,则先加载数据
|
||||||
if (props.async && allPoints.value.length === 0) {
|
if (props.async && allPoints.value.length === 0) {
|
||||||
await fetchPoints();
|
await queryData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据不同的returnValue设置选中的值
|
// 根据不同的returnValue设置选中的值
|
||||||
|
let valueIds: string[] = [];
|
||||||
|
|
||||||
if (props.returnValue === 'object') {
|
if (props.returnValue === 'object') {
|
||||||
// 如果返回的是对象,value可能是对象或对象数组
|
// 如果返回的是对象,value可能是对象或对象数组
|
||||||
if (Array.isArray(props.value)) {
|
if (Array.isArray(props.value)) {
|
||||||
selectedValue.value = props.value.map((item: any) => item.id);
|
valueIds = props.value.map((Point: any) => Point.id);
|
||||||
|
selectedValue.value = valueIds;
|
||||||
} else {
|
} else {
|
||||||
selectedValue.value = (props.value as any).id;
|
valueIds = [(props.value as any).id];
|
||||||
|
selectedValue.value = valueIds[0];
|
||||||
}
|
}
|
||||||
} else if (props.returnValue === 'id') {
|
} else if (props.returnValue === 'id') {
|
||||||
selectedValue.value = props.value as string | string[];
|
if (Array.isArray(props.value)) {
|
||||||
|
valueIds = props.value as string[];
|
||||||
|
selectedValue.value = valueIds;
|
||||||
|
} else {
|
||||||
|
valueIds = [props.value as string];
|
||||||
|
selectedValue.value = valueIds[0];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 对于其他字段类型,直接使用传入的值
|
// 对于其他字段类型,直接使用传入的值
|
||||||
selectedValue.value = props.value as string | string[];
|
selectedValue.value = props.value as string | string[];
|
||||||
|
// 这里需要根据字段值查找对应的ID
|
||||||
|
if (Array.isArray(props.value)) {
|
||||||
|
valueIds = props.value.map((v) => {
|
||||||
|
const option = allPoints.value.find((Point) => Point[props.returnValue as keyof Point] === v);
|
||||||
|
return option ? option.id : v;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const option = allPoints.value.find((Point) => Point[props.returnValue as keyof Point] === props.value);
|
||||||
|
valueIds = option ? [option.id] : [props.value as string];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有值不在当前列表中,如果有则查询
|
||||||
|
const missingIds = valueIds.filter((id) => !allPoints.value.some((Point) => Point.id === id));
|
||||||
|
if (missingIds.length > 0) {
|
||||||
|
// 对每个不在列表中的ID进行查询
|
||||||
|
const queryPromises = missingIds.map((id) => queryDataById(id));
|
||||||
|
await Promise.all(queryPromises);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -335,13 +390,13 @@
|
||||||
// 组件挂载时初始化
|
// 组件挂载时初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (!props.async) {
|
if (!props.async) {
|
||||||
fetchPoints();
|
queryData();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attrs,
|
attrs,
|
||||||
PointOptions,
|
Options,
|
||||||
loading,
|
loading,
|
||||||
selectedValue,
|
selectedValue,
|
||||||
notFoundContent,
|
notFoundContent,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const { createConfirm } = useMessage();
|
||||||
|
|
||||||
enum Api {
|
enum Api {
|
||||||
list = '/base/stock/list',
|
list = '/base/stock/list',
|
||||||
|
queryById='/base/stock/queryById',
|
||||||
save='/base/stock/add',
|
save='/base/stock/add',
|
||||||
edit='/base/stock/edit',
|
edit='/base/stock/edit',
|
||||||
deleteOne = '/base/stock/delete',
|
deleteOne = '/base/stock/delete',
|
||||||
|
|
@ -30,6 +31,12 @@ export const getImportUrl = Api.importExcel;
|
||||||
*/
|
*/
|
||||||
export const list = (params) => defHttp.get({ url: Api.list, params });
|
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
|
* @param params
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,7 @@
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="pointId">
|
<a-form-item name="pointId">
|
||||||
<template #label><span title="库位">库位</span></template>
|
<template #label><span title="库位">库位</span></template>
|
||||||
<JSearchSelect
|
<PointSelect v-model:value="queryParam.pointId" placeholder="请选择库位" />
|
||||||
v-model:value="queryParam.pointId"
|
|
||||||
placeholder="请选择库位"
|
|
||||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
|
|
@ -99,7 +94,7 @@
|
||||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
||||||
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
||||||
import JInput from '../../../components/Form/src/jeecg/components/JInput.vue';
|
import JInput from '../../../components/Form/src/jeecg/components/JInput.vue';
|
||||||
|
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||||
const fieldPickers = reactive({});
|
const fieldPickers = reactive({});
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,7 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="库位" v-bind="validateInfos.pointId" id="StockForm-pointId" name="pointId">
|
<a-form-item label="库位" v-bind="validateInfos.pointId" id="StockForm-pointId" name="pointId">
|
||||||
<JSearchSelect
|
<PointSelect v-model:value="formData.pointId" />
|
||||||
v-model:value="formData.pointId"
|
|
||||||
placeholder="请选择库位"
|
|
||||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
|
|
@ -60,8 +55,9 @@
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form } from 'ant-design-vue';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||||
import JSwitch from '@/components/Form/src/jeecg/components/JSwitch.vue';
|
import JSwitch from '@/components/Form/src/jeecg/components/JSwitch.vue';
|
||||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
import { JDictSelectTag } from '@/components/Form';
|
||||||
import { getTenantId } from '@/utils/auth';
|
import { getTenantId } from '@/utils/auth';
|
||||||
|
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formDisabled: { type: Boolean, default: false },
|
formDisabled: { type: Boolean, default: false },
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,415 @@
|
||||||
|
<!-- 容器选择 -->
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
v-model:value="selectedValue"
|
||||||
|
showSearch
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:loading="loading"
|
||||||
|
:allowClear="true"
|
||||||
|
:filterOption="filterOption"
|
||||||
|
:notFoundContent="notFoundContent"
|
||||||
|
:mode="multiple ? 'multiple' : 'default'"
|
||||||
|
@change="handleChange"
|
||||||
|
@search="handleSearch"
|
||||||
|
@focus="handleFocus"
|
||||||
|
@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 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 { queryById } from '@/views/base/stock/Stock.api';
|
||||||
|
import { setPopContainer } from '/@/utils';
|
||||||
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
|
// 容器数据接口
|
||||||
|
interface Stock {
|
||||||
|
id: string;
|
||||||
|
stockCode: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
//响应数据接口
|
||||||
|
interface ResponseData {
|
||||||
|
records: Stock[];
|
||||||
|
total: number;
|
||||||
|
size: number;
|
||||||
|
current: number;
|
||||||
|
page: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'StockSelect',
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
// 是否立即触发change事件
|
||||||
|
immediateChange: propTypes.bool.def(false),
|
||||||
|
// 返回值类型: 'id'(默认) | 'object' | 其他字段名
|
||||||
|
returnValue: propTypes.string.def('id'),
|
||||||
|
//默认启用
|
||||||
|
izActive: propTypes.number.def(1),
|
||||||
|
},
|
||||||
|
emits: ['change', 'update:value', 'optionsLoaded'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const Options = ref<Stock[]>([]);
|
||||||
|
const loading = ref<boolean>(false);
|
||||||
|
const allStocks = ref<Stock[]>([]);
|
||||||
|
const attrs = useAttrs({ excludeDefaultKeys: false });
|
||||||
|
|
||||||
|
// 分页相关
|
||||||
|
const pageNo = ref(1);
|
||||||
|
const isHasData = ref(true);
|
||||||
|
const scrollLoading = ref(false);
|
||||||
|
const searchKeyword = ref('');
|
||||||
|
|
||||||
|
// 选中值
|
||||||
|
const selectedValue = ref<string | string[] | undefined>(undefined);
|
||||||
|
|
||||||
|
// 未找到内容
|
||||||
|
const notFoundContent = computed(() => {
|
||||||
|
return loading.value ? undefined : null;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取选项显示文本 - 始终显示完整格式
|
||||||
|
*/
|
||||||
|
function getOptionLabel(option: Stock) {
|
||||||
|
return `${option.stockCode}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取选项值 - 根据returnValue确定实际存储的值
|
||||||
|
*/
|
||||||
|
function getOptionValue(option: Stock) {
|
||||||
|
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 Stock] as string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取弹出层容器
|
||||||
|
*/
|
||||||
|
function getParentContainer(node: HTMLElement) {
|
||||||
|
if (props.popContainer) {
|
||||||
|
return setPopContainer(node, props.popContainer);
|
||||||
|
} else {
|
||||||
|
if (typeof props.getPopupContainer === 'function') {
|
||||||
|
return props.getPopupContainer(node);
|
||||||
|
} else {
|
||||||
|
return node?.parentNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤选项 - 禁用前端过滤,使用后端搜索
|
||||||
|
*/
|
||||||
|
function filterOption(_input: string, _option: any) {
|
||||||
|
return true; // 禁用前端过滤,完全依赖后端搜索
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保容器唯一性的辅助函数
|
||||||
|
*/
|
||||||
|
function ensureUnique(Stocks: Stock[], newStock: Stock): Stock[] {
|
||||||
|
// 如果已经存在相同id的容器,先移除旧的再添加新的
|
||||||
|
const filtered = Stocks.filter(Stock => Stock.id !== newStock.id);
|
||||||
|
return [newStock, ...filtered];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取容器数据
|
||||||
|
*/
|
||||||
|
const queryData = async (page = 1, keyword = '', isSearch = false) => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
const res = await defHttp.get<ResponseData>({
|
||||||
|
url: '/base/stock/list',
|
||||||
|
params: {
|
||||||
|
pageSize: props.pageSize,
|
||||||
|
pageNo: page,
|
||||||
|
keyword: keyword,
|
||||||
|
izActive: props.izActive,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const records = res.records || [];
|
||||||
|
|
||||||
|
if (page === 1 || isSearch) {
|
||||||
|
// 第一页或搜索时,重置数据
|
||||||
|
allStocks.value = records;
|
||||||
|
Options.value = records;
|
||||||
|
} else {
|
||||||
|
// 滚动加载时,追加数据(确保不重复)
|
||||||
|
const newRecords = records.filter(record =>
|
||||||
|
!allStocks.value.some(Stock => Stock.id === record.id)
|
||||||
|
);
|
||||||
|
allStocks.value = [...allStocks.value, ...newRecords];
|
||||||
|
Options.value = [...Options.value, ...newRecords];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修正分页判断逻辑
|
||||||
|
isHasData.value = records.length >= props.pageSize;
|
||||||
|
|
||||||
|
emit('optionsLoaded', allStocks.value);
|
||||||
|
} catch (error) {
|
||||||
|
if (page === 1) {
|
||||||
|
allStocks.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 Stock = Array.isArray(res) ? res[0] : res;
|
||||||
|
if (Stock) {
|
||||||
|
// 使用ensureUnique确保容器不重复
|
||||||
|
allStocks.value = ensureUnique(allStocks.value, Stock);
|
||||||
|
Options.value = ensureUnique(Options.value, Stock);
|
||||||
|
}
|
||||||
|
return Stock;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('查询容器失败:', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据选项值找到对应的选项对象
|
||||||
|
*/
|
||||||
|
function findOptionByValue(value: string): Stock | undefined {
|
||||||
|
if (props.returnValue === 'object' || props.returnValue === 'id') {
|
||||||
|
return allStocks.value.find((Stock) => Stock.id === value);
|
||||||
|
} else {
|
||||||
|
return allStocks.value.find((Stock) => Stock[props.returnValue as keyof Stock] === 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果返回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 Stock] : v;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const option = findOptionByValue(value);
|
||||||
|
return option ? option[props.returnValue as keyof Stock] : value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索处理(防抖)
|
||||||
|
*/
|
||||||
|
const handleSearch = debounce(function (value: string) {
|
||||||
|
searchKeyword.value = value;
|
||||||
|
pageNo.value = 1;
|
||||||
|
isHasData.value = true;
|
||||||
|
|
||||||
|
// 直接调用API进行搜索
|
||||||
|
queryData(1, value, true);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理焦点事件
|
||||||
|
*/
|
||||||
|
function handleFocus() {
|
||||||
|
// 如果还没有数据,加载数据
|
||||||
|
if (allStocks.value.length === 0 && props.async) {
|
||||||
|
pageNo.value = 1;
|
||||||
|
isHasData.value = true;
|
||||||
|
queryData(1, '');
|
||||||
|
}
|
||||||
|
attrs.onFocus?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理值变化
|
||||||
|
*/
|
||||||
|
function handleChange(value: string | string[]) {
|
||||||
|
selectedValue.value = value;
|
||||||
|
|
||||||
|
// 根据配置返回相应的值
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果是异步模式且还没有加载数据,则先加载数据
|
||||||
|
if (props.async && allStocks.value.length === 0) {
|
||||||
|
await queryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据不同的returnValue设置选中的值
|
||||||
|
let valueIds: string[] = [];
|
||||||
|
|
||||||
|
if (props.returnValue === 'object') {
|
||||||
|
// 如果返回的是对象,value可能是对象或对象数组
|
||||||
|
if (Array.isArray(props.value)) {
|
||||||
|
valueIds = props.value.map((Stock: any) => Stock.id);
|
||||||
|
selectedValue.value = valueIds;
|
||||||
|
} else {
|
||||||
|
valueIds = [(props.value as any).id];
|
||||||
|
selectedValue.value = valueIds[0];
|
||||||
|
}
|
||||||
|
} 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 = allStocks.value.find((Stock) => Stock[props.returnValue as keyof Stock] === v);
|
||||||
|
return option ? option.id : v;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const option = allStocks.value.find((Stock) => Stock[props.returnValue as keyof Stock] === props.value);
|
||||||
|
valueIds = option ? [option.id] : [props.value as string];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有值不在当前列表中,如果有则查询
|
||||||
|
const missingIds = valueIds.filter((id) => !allStocks.value.some((Stock) => Stock.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>
|
||||||
|
|
@ -31,7 +31,7 @@
|
||||||
<main class="dashboard-card">
|
<main class="dashboard-card">
|
||||||
<section class="scan-section">
|
<section class="scan-section">
|
||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<span class="label-cn">当前扫描</span>
|
<span class="label-cn">当前托盘</span>
|
||||||
<span class="label-en">CURRENT SCAN</span>
|
<span class="label-en">CURRENT SCAN</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="scan-content">
|
<div class="scan-content">
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
async function queryData() {
|
async function queryData() {
|
||||||
const conveyorLine = 'CKJBK01';
|
const conveyorLine = 'ST102';
|
||||||
const res = await showConveyorLine(conveyorLine);
|
const res = await showConveyorLine(conveyorLine);
|
||||||
scanData.value = {
|
scanData.value = {
|
||||||
stockCode: res.stockCode,
|
stockCode: res.stockCode,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { BasicColumn } from '/@/components/Table';
|
import { BasicColumn } from '/@/components/Table';
|
||||||
|
import { render } from '@/utils/common/renderUtils';
|
||||||
//列表数据
|
//列表数据
|
||||||
export const columns: BasicColumn[] = [
|
export const columns: BasicColumn[] = [
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +37,19 @@ export const columns: BasicColumn[] = [
|
||||||
align: 'center',
|
align: 'center',
|
||||||
dataIndex: 'status_dictText',
|
dataIndex: 'status_dictText',
|
||||||
width: 100,
|
width: 100,
|
||||||
|
customRender: ({ text }) => {
|
||||||
|
const statusColorMap = {
|
||||||
|
禁用: 'red',
|
||||||
|
可用: 'green',
|
||||||
|
已分配: 'orange',
|
||||||
|
出库中: 'cyan',
|
||||||
|
移位中: 'blue',
|
||||||
|
盘点中: 'purple',
|
||||||
|
冻结: 'pink',
|
||||||
|
};
|
||||||
|
const color = statusColorMap[text] || 'red';
|
||||||
|
return render.renderTag(text, color);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '外部仓库',
|
title: '外部仓库',
|
||||||
|
|
|
||||||
|
|
@ -7,34 +7,19 @@
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="itemId">
|
<a-form-item name="itemId">
|
||||||
<template #label><span title="物料">物料</span></template>
|
<template #label><span title="物料">物料</span></template>
|
||||||
<JSearchSelect
|
<ItemSelect v-model:value="queryParam.itemId" />
|
||||||
v-model:value="queryParam.itemId"
|
|
||||||
placeholder="请选择物料"
|
|
||||||
dict="base_item where iz_active=1 and del_flag=0 ,item_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="pointId">
|
<a-form-item name="pointId">
|
||||||
<template #label><span title="库位">库位</span></template>
|
<template #label><span title="库位">库位</span></template>
|
||||||
<JSearchSelect
|
<PointSelect v-model:value="queryParam.pointId" />
|
||||||
v-model:value="queryParam.pointId"
|
|
||||||
placeholder="请选择库位"
|
|
||||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="stockId">
|
<a-form-item name="stockId">
|
||||||
<template #label><span title="容器">容器</span></template>
|
<template #label><span title="容器">容器</span></template>
|
||||||
<JSearchSelect
|
<StockSelect v-model:value="queryParam.stockId" />
|
||||||
v-model:value="queryParam.stockId"
|
|
||||||
placeholder="请选择容器"
|
|
||||||
dict="base_stock where iz_active=1 and del_flag=0 ,stock_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
|
|
@ -52,7 +37,7 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="status">
|
<a-form-item name="status" v-if="toggleSearchStatus">
|
||||||
<template #label><span title="库存状态">库存状态</span></template>
|
<template #label><span title="库存状态">库存状态</span></template>
|
||||||
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="inventory_status" allowClear />
|
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="inventory_status" allowClear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
@ -90,7 +75,7 @@
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:bodyCell="{ column, record, index, text }"> </template>
|
<template v-slot:bodyCell="{ column, record, index, text }"></template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
<InventoryModal ref="registerModal" @success="handleSuccess"></InventoryModal>
|
<InventoryModal ref="registerModal" @success="handleSuccess"></InventoryModal>
|
||||||
|
|
@ -108,6 +93,9 @@
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { getDateByPicker } from '/@/utils';
|
import { getDateByPicker } from '/@/utils';
|
||||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
||||||
|
import ItemSelect from '@/views/base/item/components/ItemSelect.vue';
|
||||||
|
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||||
|
import StockSelect from '@/views/base/stock/components/StockSelect.vue';
|
||||||
|
|
||||||
const fieldPickers = reactive({});
|
const fieldPickers = reactive({});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,17 @@
|
||||||
<a-row class="form-row" :gutter="24">
|
<a-row class="form-row" :gutter="24">
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="物料" v-bind="validateInfos.itemId" id="InventoryForm-itemId" name="itemId">
|
<a-form-item label="物料" v-bind="validateInfos.itemId" id="InventoryForm-itemId" name="itemId">
|
||||||
<JSearchSelect
|
<ItemSelect v-model:value="formData.itemId" />
|
||||||
v-model:value="formData.itemId"
|
|
||||||
placeholder="请选择物料"
|
|
||||||
dict="base_item where iz_active=1 and del_flag=0 ,item_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="库位" v-bind="validateInfos.pointId" id="InventoryForm-pointId" name="pointId">
|
<a-form-item label="库位" v-bind="validateInfos.pointId" id="InventoryForm-pointId" name="pointId">
|
||||||
<JSearchSelect
|
<PointSelect v-model:value="formData.pointId" />
|
||||||
v-model:value="formData.pointId"
|
|
||||||
placeholder="请选择库位"
|
|
||||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="容器" v-bind="validateInfos.stockId" id="InventoryForm-stockId" name="stockId">
|
<a-form-item label="容器" v-bind="validateInfos.stockId" id="InventoryForm-stockId" name="stockId">
|
||||||
<JSearchSelect
|
<StockSelect v-model:value="formData.stockId" />
|
||||||
v-model:value="formData.stockId"
|
|
||||||
placeholder="请选择容器"
|
|
||||||
dict="base_stock where iz_active=1 and del_flag=0 ,stock_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
@ -41,9 +26,32 @@
|
||||||
<a-input-number v-model:value="formData.quantity" placeholder="请输入数量" style="width: 100%" />
|
<a-input-number v-model:value="formData.quantity" placeholder="请输入数量" style="width: 100%" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item label="占用数" v-bind="validateInfos.quantity" id="InventoryForm-queuedQty" name="queuedQty">
|
||||||
|
<a-input-number v-model:value="formData.queuedQty" placeholder="请输入占用数" style="width: 100%" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
<a-form-item label="库存状态" v-bind="validateInfos.status" id="InventoryForm-status" name="status">
|
<a-form-item label="库存状态" v-bind="validateInfos.status" id="InventoryForm-status" name="status">
|
||||||
<JDictSelectTag v-model:value="formData.status" placeholder="请选择" dictCode="inventory_status" string-to-number="true" allowClear />
|
<JDictSelectTag
|
||||||
|
v-model:value="formData.status"
|
||||||
|
placeholder="请选择"
|
||||||
|
dictCode="inventory_status"
|
||||||
|
:string-to-number="true"
|
||||||
|
allowClear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<a-row class="form-row" :gutter="24">
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item label="项目号" v-bind="validateInfos.project" id="InventoryForm-project" name="project">
|
||||||
|
<a-input v-model:value="formData.project" placeholder="请输入项目号" allow-clear></a-input>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="8">
|
||||||
|
<a-form-item label="任务号" v-bind="validateInfos.taskNo" id="InventoryForm-taskNo" name="taskNo">
|
||||||
|
<a-input v-model:value="formData.taskNo" placeholder="请输入任务号" allow-clear></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
<a-col :span="8">
|
||||||
|
|
@ -63,17 +71,6 @@
|
||||||
<a-input v-model:value="formData.propC3" placeholder="请输入外部库存状态" allow-clear></a-input>
|
<a-input v-model:value="formData.propC3" placeholder="请输入外部库存状态" allow-clear></a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="8">
|
|
||||||
<a-form-item label="生产日期" v-bind="validateInfos.propD1" id="InventoryForm-propD1" name="propD1">
|
|
||||||
<a-date-picker
|
|
||||||
placeholder="请选择生产日期"
|
|
||||||
v-model:value="formData.propD1"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
style="width: 100%"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row class="form-row" :gutter="24">
|
<a-row class="form-row" :gutter="24">
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
|
|
@ -103,7 +100,10 @@
|
||||||
import { saveOrUpdate } from '../Inventory.api';
|
import { saveOrUpdate } from '../Inventory.api';
|
||||||
import { Form } from 'ant-design-vue';
|
import { Form } from 'ant-design-vue';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
import { JDictSelectTag } from '@/components/Form';
|
||||||
|
import ItemSelect from '@/views/base/item/components/ItemSelect.vue';
|
||||||
|
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||||
|
import StockSelect from '@/views/base/stock/components/StockSelect.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
formDisabled: { type: Boolean, default: false },
|
formDisabled: { type: Boolean, default: false },
|
||||||
|
|
@ -117,17 +117,17 @@
|
||||||
let tenantId = getTenantId();
|
let tenantId = getTenantId();
|
||||||
const formData = reactive<Record<string, any>>({
|
const formData = reactive<Record<string, any>>({
|
||||||
id: '',
|
id: '',
|
||||||
itemId: undefined,
|
itemId: '',
|
||||||
pointId: undefined,
|
pointId: '',
|
||||||
stockId: undefined,
|
stockId: '',
|
||||||
quantity: '',
|
quantity: '',
|
||||||
queuedQty: 0,
|
queuedQty: 0,
|
||||||
whCode: '',
|
whCode: '',
|
||||||
|
project: '',
|
||||||
|
taskNo: '',
|
||||||
propC1: '',
|
propC1: '',
|
||||||
propC2: '',
|
|
||||||
propC3: '',
|
propC3: '',
|
||||||
status: '',
|
status: 1,
|
||||||
propD1: '',
|
|
||||||
description: '',
|
description: '',
|
||||||
tenantId: tenantId,
|
tenantId: tenantId,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,27 @@
|
||||||
<template><j-modal :title="title" :maxHeight="500" :width="800" :visible="visible" @ok="handleOk" :okButtonProps="{ class: { 'jee-hidden': disableSubmit } }" @cancel="handleCancel" cancelText="关闭">
|
<template>
|
||||||
|
<j-modal
|
||||||
|
:title="title"
|
||||||
|
:maxHeight="600"
|
||||||
|
:width="900"
|
||||||
|
:visible="visible"
|
||||||
|
@ok="handleOk"
|
||||||
|
:okButtonProps="{ class: { 'jee-hidden': disableSubmit } }"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
cancelText="关闭"
|
||||||
|
>
|
||||||
<InventoryForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></InventoryForm>
|
<InventoryForm ref="registerForm" @ok="submitCallback" :formDisabled="disableSubmit" :formBpm="false"></InventoryForm>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button @click="handleCancel">取消</a-button>
|
<a-button @click="handleCancel">取消</a-button>
|
||||||
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认</a-button>
|
<a-button :class="{ 'jee-hidden': disableSubmit }" type="primary" @click="handleOk">确认 </a-button>
|
||||||
</template>
|
</template>
|
||||||
</j-modal>
|
</j-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, nextTick, defineExpose } from 'vue';
|
import { ref, nextTick, defineExpose } from 'vue';
|
||||||
import InventoryForm from './InventoryForm.vue'
|
import InventoryForm from './InventoryForm.vue';
|
||||||
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
import JModal from '/@/components/Modal/src/JModal/JModal.vue';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
const title = ref<string>('');
|
const title = ref<string>('');
|
||||||
const visible = ref<boolean>(false);
|
const visible = ref<boolean>(false);
|
||||||
const disableSubmit = ref<boolean>(false);
|
const disableSubmit = ref<boolean>(false);
|
||||||
|
|
@ -63,6 +72,7 @@
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
add,
|
add,
|
||||||
edit,
|
edit,
|
||||||
|
|
|
||||||
|
|
@ -60,35 +60,5 @@ export const columns: BasicColumn[] = [
|
||||||
align: 'center',
|
align: 'center',
|
||||||
dataIndex: 'afterAllocatedQty',
|
dataIndex: 'afterAllocatedQty',
|
||||||
width: 120,
|
width: 120,
|
||||||
},
|
}
|
||||||
{
|
|
||||||
title: '项目号',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'project',
|
|
||||||
width: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '任务号',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'taskNo',
|
|
||||||
width: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '批次号',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'propC1',
|
|
||||||
width: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '外部库存状态',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'propC3',
|
|
||||||
width: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '备注',
|
|
||||||
align: 'center',
|
|
||||||
dataIndex: 'description',
|
|
||||||
ellipsis: true,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -7,34 +7,19 @@
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="itemId">
|
<a-form-item name="itemId">
|
||||||
<template #label><span title="物料">物料</span></template>
|
<template #label><span title="物料">物料</span></template>
|
||||||
<JSearchSelect
|
<ItemSelect v-model:value="queryParam.itemId" />
|
||||||
v-model:value="queryParam.itemId"
|
|
||||||
placeholder="请选择物料"
|
|
||||||
dict="base_item where iz_active=1 and del_flag=0 ,item_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="pointId">
|
<a-form-item name="pointId">
|
||||||
<template #label><span title="库位">库位</span></template>
|
<template #label><span title="库位">库位</span></template>
|
||||||
<JSearchSelect
|
<PointSelect v-model:value="queryParam.pointId" />
|
||||||
v-model:value="queryParam.pointId"
|
|
||||||
placeholder="请选择库位"
|
|
||||||
dict="base_point where iz_active=1 and del_flag=0 ,point_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="stockId">
|
<a-form-item name="stockId">
|
||||||
<template #label><span title="容器">容器</span></template>
|
<template #label><span title="容器">容器</span></template>
|
||||||
<JSearchSelect
|
<StockSelect v-model:value="queryParam.stockId" />
|
||||||
v-model:value="queryParam.stockId"
|
|
||||||
placeholder="请选择容器"
|
|
||||||
dict="base_stock where iz_active=1 and del_flag=0 ,stock_code,id"
|
|
||||||
allowClear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
|
|
@ -52,7 +37,7 @@
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="logType">
|
<a-form-item name="logType" v-if="toggleSearchStatus">
|
||||||
<template #label><span title="日志类型">日志类型</span></template>
|
<template #label><span title="日志类型">日志类型</span></template>
|
||||||
<JDictSelectTag v-model:value="queryParam.logType" placeholder="请选择" dictCode="inventory_log_type" allowClear />
|
<JDictSelectTag v-model:value="queryParam.logType" placeholder="请选择" dictCode="inventory_log_type" allowClear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
@ -112,10 +97,11 @@
|
||||||
import { columns } from './InventoryLog.data';
|
import { columns } from './InventoryLog.data';
|
||||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './InventoryLog.api';
|
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './InventoryLog.api';
|
||||||
import InventoryLogModal from './components/InventoryLogModal.vue';
|
import InventoryLogModal from './components/InventoryLogModal.vue';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
|
||||||
import { getDateByPicker } from '/@/utils';
|
import { getDateByPicker } from '/@/utils';
|
||||||
import { JDictSelectTag, JSearchSelect } from '@/components/Form';
|
import { JDictSelectTag } from '@/components/Form';
|
||||||
|
import ItemSelect from '@/views/base/item/components/ItemSelect.vue';
|
||||||
|
import PointSelect from '@/views/base/point/components/PointSelect.vue';
|
||||||
|
import StockSelect from '@/views/base/stock/components/StockSelect.vue';
|
||||||
|
|
||||||
const fieldPickers = reactive({});
|
const fieldPickers = reactive({});
|
||||||
|
|
||||||
|
|
@ -123,10 +109,8 @@
|
||||||
const queryParam = reactive<any>({});
|
const queryParam = reactive<any>({});
|
||||||
const toggleSearchStatus = ref<boolean>(false);
|
const toggleSearchStatus = ref<boolean>(false);
|
||||||
const registerModal = ref();
|
const registerModal = ref();
|
||||||
const userStore = useUserStore();
|
|
||||||
const { createMessage } = useMessage();
|
|
||||||
//注册table数据
|
//注册table数据
|
||||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||||
tableProps: {
|
tableProps: {
|
||||||
title: '库存日志',
|
title: '库存日志',
|
||||||
api: list,
|
api: list,
|
||||||
|
|
@ -161,8 +145,7 @@
|
||||||
success: handleSuccess,
|
success: handleSuccess,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||||
tableContext;
|
|
||||||
const labelCol = reactive({
|
const labelCol = reactive({
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm: 4,
|
sm: 4,
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,14 @@ export const columns: BasicColumn[] = [
|
||||||
dataIndex: 'status_dictText',
|
dataIndex: 'status_dictText',
|
||||||
width: '80px',
|
width: '80px',
|
||||||
customRender: ({ text }) => {
|
customRender: ({ text }) => {
|
||||||
//入库状态:1.已创建;2.部分收货;3.收货完成;4.已关闭,5.已取消。
|
//入库状态:1.已创建;2.部分收货;3.收货完成;4.已关闭,5.已取消、6.已扫描。
|
||||||
const statusColorMap = {
|
const statusColorMap = {
|
||||||
已创建: 'orange',
|
已创建: 'orange',
|
||||||
部分收货: 'blue',
|
部分收货: 'blue',
|
||||||
收货完成: 'green',
|
收货完成: 'green',
|
||||||
已关闭: 'green',
|
已关闭: 'green',
|
||||||
已取消: 'red',
|
已取消: 'red',
|
||||||
|
已扫描: 'purple',
|
||||||
};
|
};
|
||||||
const color = statusColorMap[text] || 'red';
|
const color = statusColorMap[text] || 'red';
|
||||||
return render.renderTag(text, color);
|
return render.renderTag(text, color);
|
||||||
|
|
@ -74,8 +75,8 @@ export const columns: BasicColumn[] = [
|
||||||
align: 'center',
|
align: 'center',
|
||||||
dataIndex: 'resMessage',
|
dataIndex: 'resMessage',
|
||||||
customRender: ({ text }) => {
|
customRender: ({ text }) => {
|
||||||
return render.renderTip(text)
|
return render.renderTip(text);
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '订单日期',
|
title: '订单日期',
|
||||||
|
|
@ -181,7 +182,6 @@ export const asnDetailColumns: JVxeColumn[] = [
|
||||||
3: '收货完成',
|
3: '收货完成',
|
||||||
4: '已关闭',
|
4: '已关闭',
|
||||||
5: '已取消',
|
5: '已取消',
|
||||||
|
|
||||||
};
|
};
|
||||||
// 状态颜色映射
|
// 状态颜色映射
|
||||||
const statusColorMap = {
|
const statusColorMap = {
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,6 @@
|
||||||
<div class="jeecg-basic-table-form-container">
|
<div class="jeecg-basic-table-form-container">
|
||||||
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="orderNo">
|
|
||||||
<template #label><span title="系统单号">系统单号</span></template>
|
|
||||||
<JInput v-model:value="queryParam.orderNo" :placeholder="'请输入系统单号'" :type="JInputTypeEnum.JINPUT_RIGHT_LIKE" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="no">
|
<a-form-item name="no">
|
||||||
<template #label><span title="任务号">任务号</span></template>
|
<template #label><span title="任务号">任务号</span></template>
|
||||||
|
|
@ -22,6 +16,12 @@
|
||||||
<JDictSelectTag v-model:value="queryParam.orderType" placeholder="请选择" dictCode="asn_order_type" allowClear />
|
<JDictSelectTag v-model:value="queryParam.orderType" placeholder="请选择" dictCode="asn_order_type" allowClear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :lg="6">
|
||||||
|
<a-form-item name="orderDate">
|
||||||
|
<template #label><span title="订单日期">订单日期</span></template>
|
||||||
|
<JRangeDate v-model:value="queryParam.orderDate" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
|
|
@ -36,18 +36,13 @@
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
<!-- <a-col :lg="6">
|
||||||
<a-form-item name="status">
|
<a-form-item name="status">
|
||||||
<template #label><span title="状态">状态</span></template>
|
<template #label><span title="状态">状态</span></template>
|
||||||
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="asn_status" allowClear />
|
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="asn_status" allowClear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>-->
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="orderDate">
|
|
||||||
<template #label><span title="订单日期">订单日期</span></template>
|
|
||||||
<JRangeDate v-model:value="queryParam.orderDate" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -221,24 +221,37 @@ export const taskColumns: JVxeColumn[] = [
|
||||||
{
|
{
|
||||||
title: '物料',
|
title: '物料',
|
||||||
key: 'itemId',
|
key: 'itemId',
|
||||||
type: JVxeTypes.normal,
|
type: JVxeTypes.selectDictSearch,
|
||||||
|
disabled: true,
|
||||||
async: true, // 异步搜索,默认为 true
|
async: true, // 异步搜索,默认为 true
|
||||||
//查询状态启用、未删除的物料
|
dict: 'base_item,item_code,id',
|
||||||
dict: 'base_item where iz_active=1 and del_flag=0,item_code,id',
|
|
||||||
tipsContent: '请搜索物料',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '单位',
|
title: '原库位',
|
||||||
key: 'unit',
|
key: 'fromPointId',
|
||||||
type: JVxeTypes.normal,
|
type: JVxeTypes.selectDictSearch,
|
||||||
dictCode: 'package_unit',
|
disabled: true,
|
||||||
placeholder: '请选择${title}',
|
async: true, // 异步搜索,默认为 true
|
||||||
defaultValue: '托',
|
dict: 'base_point,point_code,id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '目标库位',
|
||||||
|
key: 'toPointId',
|
||||||
|
type: JVxeTypes.selectDictSearch,
|
||||||
|
disabled: true,
|
||||||
|
async: true, // 异步搜索,默认为 true
|
||||||
|
dict: 'base_point,point_code,id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '分配数量',
|
||||||
|
key: 'planQty',
|
||||||
|
type: JVxeTypes.normal,
|
||||||
|
defaultValue: '0',
|
||||||
|
disabled: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '拣货数量',
|
title: '拣货数量',
|
||||||
key: 'planQty',
|
key: 'moveQty',
|
||||||
type: JVxeTypes.normal,
|
type: JVxeTypes.normal,
|
||||||
defaultValue: '0',
|
defaultValue: '0',
|
||||||
disabled: true,
|
disabled: true,
|
||||||
|
|
@ -247,6 +260,5 @@ export const taskColumns: JVxeColumn[] = [
|
||||||
title: '返回报文',
|
title: '返回报文',
|
||||||
key: 'resMessage',
|
key: 'resMessage',
|
||||||
type: JVxeTypes.normal,
|
type: JVxeTypes.normal,
|
||||||
width: '200px',
|
}
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,6 @@
|
||||||
<div class="jeecg-basic-table-form-container">
|
<div class="jeecg-basic-table-form-container">
|
||||||
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="formRef" @keyup.enter.native="reload" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="orderNo">
|
|
||||||
<template #label><span title="系统单号">系统单号</span></template>
|
|
||||||
<JInput v-model:value="queryParam.orderNo" :placeholder="'请输入系统单号'" :type="JInputTypeEnum.JINPUT_RIGHT_LIKE" />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="no">
|
<a-form-item name="no">
|
||||||
<template #label><span title="任务号">任务号</span></template>
|
<template #label><span title="任务号">任务号</span></template>
|
||||||
|
|
@ -22,6 +16,12 @@
|
||||||
<JDictSelectTag v-model:value="queryParam.orderType" placeholder="请选择" dictCode="pick_order_type" allowClear />
|
<JDictSelectTag v-model:value="queryParam.orderType" placeholder="请选择" dictCode="pick_order_type" allowClear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<a-col :lg="6">
|
||||||
|
<a-form-item name="orderDate">
|
||||||
|
<template #label><span title="订单日期">订单日期</span></template>
|
||||||
|
<JRangeDate v-model:value="queryParam.orderDate" />
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
|
|
@ -39,13 +39,7 @@
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="status">
|
<a-form-item name="status">
|
||||||
<template #label><span title="状态">状态</span></template>
|
<template #label><span title="状态">状态</span></template>
|
||||||
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="pick_status" allowClear />
|
<JDictSelectTag v-model:value="queryParam.status" placeholder="请选择" dictCode="pick_status" mode="multiple" allowClear />
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="orderDate">
|
|
||||||
<template #label><span title="订单日期">订单日期</span></template>
|
|
||||||
<JRangeDate v-model:value="queryParam.orderDate" />
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
@ -116,7 +110,6 @@
|
||||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, allocatePick, cancelAllocate } from './Pick.api';
|
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl, allocatePick, cancelAllocate } from './Pick.api';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { getDateByPicker } from '/@/utils';
|
import { getDateByPicker } from '/@/utils';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
|
||||||
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
import { JInputTypeEnum } from '@/enums/cpteEnum';
|
||||||
import { JInput, JDictSelectTag } from '@/components/Form';
|
import { JInput, JDictSelectTag } from '@/components/Form';
|
||||||
import JRangeDate from '@/components/Form/src/jeecg/components/JRangeDate.vue';
|
import JRangeDate from '@/components/Form/src/jeecg/components/JRangeDate.vue';
|
||||||
|
|
@ -126,13 +119,11 @@
|
||||||
const fieldPickers = reactive({});
|
const fieldPickers = reactive({});
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const queryParam = reactive<any>({});
|
const queryParam = reactive<any>({});
|
||||||
const checkedKeys = ref<Array<string | number>>([]);
|
|
||||||
//注册model
|
//注册model
|
||||||
const [registerModal, { openModal }] = useModal();
|
const [registerModal, { openModal }] = useModal();
|
||||||
const userStore = useUserStore();
|
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
//注册table数据
|
//注册table数据
|
||||||
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
|
const { tableContext, onExportXls, onImportXls } = useListPage({
|
||||||
tableProps: {
|
tableProps: {
|
||||||
title: '出库单',
|
title: '出库单',
|
||||||
api: list,
|
api: list,
|
||||||
|
|
@ -212,11 +203,10 @@
|
||||||
await allocatePick(selectedRowKeys.value, handleSuccess);
|
await allocatePick(selectedRowKeys.value, handleSuccess);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('分配失败:', e);
|
console.error('分配失败:', e);
|
||||||
handleSuccess()
|
handleSuccess();
|
||||||
} finally {
|
} finally {
|
||||||
// 重置加载状态
|
// 重置加载状态
|
||||||
allocate_loading.value = false;
|
allocate_loading.value = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,7 +233,7 @@
|
||||||
await cancelAllocate(selectedRowKeys.value, handleSuccess);
|
await cancelAllocate(selectedRowKeys.value, handleSuccess);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('取消失败:', e);
|
console.error('取消失败:', e);
|
||||||
handleSuccess()
|
handleSuccess();
|
||||||
} finally {
|
} finally {
|
||||||
// 重置加载状态
|
// 重置加载状态
|
||||||
cancel_loading.value = false;
|
cancel_loading.value = false;
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,8 @@
|
||||||
<a-tab-pane tab="出库明细" key="pickDetail" :forceRender="true">
|
<a-tab-pane tab="出库明细" key="pickDetail" :forceRender="true">
|
||||||
<j-vxe-table
|
<j-vxe-table
|
||||||
:keep-source="true"
|
:keep-source="true"
|
||||||
resizable
|
|
||||||
ref="pickDetailTableRef"
|
ref="pickDetailTableRef"
|
||||||
|
resizable
|
||||||
:loading="pickDetailTable.loading"
|
:loading="pickDetailTable.loading"
|
||||||
:columns="pickDetailTable.columns"
|
:columns="pickDetailTable.columns"
|
||||||
:dataSource="pickDetailTable.dataSource"
|
:dataSource="pickDetailTable.dataSource"
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, reactive, computed, toRaw } from 'vue';
|
import { defineComponent, ref, reactive, computed, toRaw } from 'vue';
|
||||||
import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
|
import { useValidateAntFormAndTable } from '/@/hooks/system/useJvxeMethods';
|
||||||
import { queryPickDetailListByMainId, queryDataById, saveOrUpdate } from '../Pick.api';
|
import { queryPickDetailListByMainId, queryDataById, saveOrUpdate,queryTaskByMainId } from '../Pick.api';
|
||||||
import { JVxeTable } from '/@/components/jeecg/JVxeTable';
|
import { JVxeTable } from '/@/components/jeecg/JVxeTable';
|
||||||
import { pickDetailColumns, taskColumns } from '../Pick.data';
|
import { pickDetailColumns, taskColumns } from '../Pick.data';
|
||||||
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
import JFormContainer from '/@/components/Form/src/container/JFormContainer.vue';
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue