fix: 第一版错误修改前的存档。
This commit is contained in:
BIN
public/favicon (2).png
Normal file
BIN
public/favicon (2).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 17 KiB |
BIN
public/logo.png
BIN
public/logo.png
Binary file not shown.
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 20 KiB |
BIN
public/logo1.png
Normal file
BIN
public/logo1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
@@ -18,7 +18,7 @@ import {
|
|||||||
|
|
||||||
export const defaultServiceConfig: ServiceConfig = {
|
export const defaultServiceConfig: ServiceConfig = {
|
||||||
layout: {
|
layout: {
|
||||||
name: "Teek Design Vue3",
|
name: "牛安管理系统",
|
||||||
avatar: "/avatar.png",
|
avatar: "/avatar.png",
|
||||||
titleMode: TitleModeEnum.ProjectPage,
|
titleMode: TitleModeEnum.ProjectPage,
|
||||||
layoutMode: LayoutModeEnum.Vertical,
|
layoutMode: LayoutModeEnum.Vertical,
|
||||||
@@ -36,15 +36,15 @@ export const defaultServiceConfig: ServiceConfig = {
|
|||||||
env: [],
|
env: [],
|
||||||
},
|
},
|
||||||
themePanelTriggerPosition: ThemePanelTriggerPositionEnum.Header,
|
themePanelTriggerPosition: ThemePanelTriggerPositionEnum.Header,
|
||||||
globalAlert: {
|
// globalAlert: {
|
||||||
enabled: false,
|
// enabled: false,
|
||||||
text: "Teek Design Vue3 祝您圣诞快乐,愿节日的欢乐与祝福如雪花般纷至沓来!",
|
// text: "Teek Design Vue3 祝您圣诞快乐,愿节日的欢乐与祝福如雪花般纷至沓来!",
|
||||||
startDate: "2025-12-25",
|
// startDate: "2025-12-25",
|
||||||
endDate: "2025-12-25",
|
// endDate: "2025-12-25",
|
||||||
type: "primary",
|
// type: "primary",
|
||||||
closable: true,
|
// closable: true,
|
||||||
showIcon: false,
|
// showIcon: false,
|
||||||
},
|
// },
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
// 默认与 css var 一致,在这里配置一份,方便生成 1 - 9 的基础色
|
// 默认与 css var 一致,在这里配置一份,方便生成 1 - 9 的基础色
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -898,6 +898,7 @@ export default {
|
|||||||
input_iconName: "请输入图标名称",
|
input_iconName: "请输入图标名称",
|
||||||
input_sort: "请输入排序值",
|
input_sort: "请输入排序值",
|
||||||
input_parentId: "请输入父级权限ID,0表示根节点",
|
input_parentId: "请输入父级权限ID,0表示根节点",
|
||||||
|
select_parentId: "请选择父级权限",
|
||||||
delete_message: "删除权限",
|
delete_message: "删除权限",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -948,6 +949,7 @@ export default {
|
|||||||
},
|
},
|
||||||
production_issue: {
|
production_issue: {
|
||||||
returnDialog: "退料编辑",
|
returnDialog: "退料编辑",
|
||||||
|
showItem: "发料明细",
|
||||||
},
|
},
|
||||||
finishedproductreceipt: {
|
finishedproductreceipt: {
|
||||||
add: "添加成品入库单",
|
add: "添加成品入库单",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Upload } from "@icon-park/vue-next";
|
import { Upload, Download } from "@icon-park/vue-next";
|
||||||
import BaseForm from "../base-form/BaseForm.vue";
|
import BaseForm from "../base-form/BaseForm.vue";
|
||||||
import { ElMessage, type UploadInstance, type UploadUserFile } from "element-plus";
|
import { ElMessage, type UploadInstance, type UploadUserFile } from "element-plus";
|
||||||
import * as XLSX from "xlsx";
|
import * as XLSX from "xlsx";
|
||||||
@@ -15,6 +15,7 @@ const props = defineProps({
|
|||||||
uploadDesc: String,
|
uploadDesc: String,
|
||||||
itemArrayName: { type: String, required: true },
|
itemArrayName: { type: String, required: true },
|
||||||
mappingConfig: { type: Object, required: true },
|
mappingConfig: { type: Object, required: true },
|
||||||
|
templateFileName: { type: String, default: "模板" },
|
||||||
});
|
});
|
||||||
const emit = defineEmits<Emits>();
|
const emit = defineEmits<Emits>();
|
||||||
const form = defineModel<any>("form");
|
const form = defineModel<any>("form");
|
||||||
@@ -104,16 +105,13 @@ const handleFileChange = (file: any) => {
|
|||||||
const maxSize = 10 * 1024 * 1024; // 10MB
|
const maxSize = 10 * 1024 * 1024; // 10MB
|
||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
ElMessage.error("文件大小不能超过 10MB");
|
ElMessage.error("文件大小不能超过 10MB");
|
||||||
clearAllData();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearAllData();
|
|
||||||
|
|
||||||
// 更新当前文件显示
|
// 更新当前文件显示
|
||||||
currentFile.value = file;
|
currentFile.value = file;
|
||||||
|
|
||||||
// 解析 Excel
|
// 解析 Excel(追加模式,不清空原有数据)
|
||||||
parseExcel(file.raw);
|
parseExcel(file.raw);
|
||||||
};
|
};
|
||||||
const parseExcel = (file: any) => {
|
const parseExcel = (file: any) => {
|
||||||
@@ -149,11 +147,15 @@ const parseExcel = (file: any) => {
|
|||||||
form.value[props.itemArrayName] = [];
|
form.value[props.itemArrayName] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用 splice 替换所有内容,这是最安全的触发数组更新的方式
|
// 追加数据到现有数组
|
||||||
form.value[props.itemArrayName].splice(0, form.value[props.itemArrayName].length, ...mappedData);
|
form.value[props.itemArrayName].push(...mappedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElMessage.success(`解析成功,共 ${mappedData.length} 条物料数据`);
|
ElMessage.success(`解析成功,共追加 ${mappedData.length} 条数据`);
|
||||||
|
|
||||||
|
// 清空上传组件的文件列表,允许用户再次选择文件进行追加
|
||||||
|
uploadRef.value?.clearFiles();
|
||||||
|
currentFile.value = null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
ElMessage.error("文件解析失败,请检查文件格式");
|
ElMessage.error("文件解析失败,请检查文件格式");
|
||||||
@@ -165,32 +167,36 @@ const parseExcel = (file: any) => {
|
|||||||
// 【新增】存储当前上传的文件信息,用于显示和移除
|
// 【新增】存储当前上传的文件信息,用于显示和移除
|
||||||
const currentFile = ref<UploadUserFile | null>(null);
|
const currentFile = ref<UploadUserFile | null>(null);
|
||||||
|
|
||||||
// 【新增】深度清理函数
|
// 【新增】只清理表格数据(保留基本表单数据)
|
||||||
const resetFormData = () => {
|
const clearTableData = () => {
|
||||||
// 1. 清空表单验证
|
// 1. 清空表格数据
|
||||||
|
if (form.value && Array.isArray(form.value[props.itemArrayName])) {
|
||||||
|
form.value[props.itemArrayName].splice(0, form.value[props.itemArrayName].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 清空表单验证(仅表格相关)
|
||||||
if (baseFormComponentRef.value) {
|
if (baseFormComponentRef.value) {
|
||||||
// 方式 A: 调用暴露的 clearValidate 方法
|
|
||||||
baseFormComponentRef.value.clearValidate();
|
baseFormComponentRef.value.clearValidate();
|
||||||
// 方式 B: 或者访问内部 formRef (如果暴露了)
|
|
||||||
// baseFormComponentRef.value.formRef?.clearValidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 重置 form 对象 (保留非表格字段?通常重置是全部清空或设为初始值,这里设为空对象)
|
ElMessage.success("表格数据已清空");
|
||||||
if (form.value) {
|
};
|
||||||
// 只清空表格数据,保留其他表单字段?还是全部重置?
|
|
||||||
// 根据需求“数据清理不干净”,通常指表格和文件。
|
// 【新增】深度清理函数(清理表格+文件,保留基本表单数据)
|
||||||
// 这里我们清空表格数组和文件,其他字段由 BaseForm 的 reset 逻辑处理或手动置空
|
const resetFormData = () => {
|
||||||
if (Array.isArray(form.value[props.itemArrayName])) {
|
// 1. 清空表格数据
|
||||||
form.value[props.itemArrayName].splice(0, form.value[props.itemArrayName].length);
|
if (form.value && Array.isArray(form.value[props.itemArrayName])) {
|
||||||
}
|
form.value[props.itemArrayName].splice(0, form.value[props.itemArrayName].length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 清空文件状态
|
// 2. 清空文件状态
|
||||||
currentFile.value = null;
|
currentFile.value = null;
|
||||||
uploadRef.value?.clearFiles();
|
uploadRef.value?.clearFiles();
|
||||||
|
|
||||||
// 4. 如果需要完全重置 form 为初始空对象,取消下面注释
|
// 3. 清空表单验证
|
||||||
form.value = {};
|
if (baseFormComponentRef.value) {
|
||||||
|
baseFormComponentRef.value.clearValidate();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 【新增】增加一行
|
// 【新增】增加一行
|
||||||
@@ -220,6 +226,43 @@ const removeFile = () => {
|
|||||||
clearAllData();
|
clearAllData();
|
||||||
ElMessage.success("文件已移除,表格数据已清空");
|
ElMessage.success("文件已移除,表格数据已清空");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 【新增】下载模板文件
|
||||||
|
const downloadTemplate = () => {
|
||||||
|
// 1. 根据 mappingConfig 生成表头
|
||||||
|
const headers: string[] = [];
|
||||||
|
for (const [targetKey, config] of Object.entries(props.mappingConfig)) {
|
||||||
|
const fieldConfig = config as ExcelDataMapping;
|
||||||
|
// 使用 sourceKey 作为表头,如果是数组则使用第一个
|
||||||
|
let header: string;
|
||||||
|
if (Array.isArray(fieldConfig.sourceKey)) {
|
||||||
|
header = fieldConfig.sourceKey[0];
|
||||||
|
} else {
|
||||||
|
header = fieldConfig.sourceKey;
|
||||||
|
}
|
||||||
|
headers.push(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 创建工作簿
|
||||||
|
const wb = XLSX.utils.book_new();
|
||||||
|
|
||||||
|
// 3. 创建工作表(只有表头,没有数据行)
|
||||||
|
const ws = XLSX.utils.aoa_to_sheet([headers]);
|
||||||
|
|
||||||
|
// 4. 设置列宽
|
||||||
|
const colWidths = headers.map(() => ({ wch: 20 }));
|
||||||
|
ws["!cols"] = colWidths;
|
||||||
|
|
||||||
|
// 5. 将工作表添加到工作簿
|
||||||
|
XLSX.utils.book_append_sheet(wb, ws, "模板");
|
||||||
|
|
||||||
|
// 6. 生成文件并下载
|
||||||
|
const fileName = `${props.templateFileName}.xlsx`;
|
||||||
|
XLSX.writeFile(wb, fileName);
|
||||||
|
|
||||||
|
ElMessage.success("模板文件下载成功");
|
||||||
|
};
|
||||||
|
|
||||||
// 监听 BaseForm 发出的 reset 事件
|
// 监听 BaseForm 发出的 reset 事件
|
||||||
const handleBaseFormReset = () => {
|
const handleBaseFormReset = () => {
|
||||||
resetFormData();
|
resetFormData();
|
||||||
@@ -229,6 +272,8 @@ defineExpose({
|
|||||||
resetFormData,
|
resetFormData,
|
||||||
addRow,
|
addRow,
|
||||||
deleteRow,
|
deleteRow,
|
||||||
|
clearTableData,
|
||||||
|
downloadTemplate,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
@@ -266,6 +311,10 @@ defineExpose({
|
|||||||
<span class="tip-desc" v-if="props.uploadDesc">{{ uploadDesc }}</span>
|
<span class="tip-desc" v-if="props.uploadDesc">{{ uploadDesc }}</span>
|
||||||
</span>
|
</span>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
<el-button type="success" @click="downloadTemplate">
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
下载模板文件
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
@@ -288,7 +337,7 @@ defineExpose({
|
|||||||
<el-icon><Plus /></el-icon>
|
<el-icon><Plus /></el-icon>
|
||||||
增加一行
|
增加一行
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="warning" link @click="resetFormData">
|
<el-button type="warning" link @click="clearTableData">
|
||||||
<el-icon><Delete /></el-icon>
|
<el-icon><Delete /></el-icon>
|
||||||
清空表格
|
清空表格
|
||||||
</el-button>
|
</el-button>
|
||||||
|
|||||||
155
src/components/base/base-tree-select/BaseTreeSelect.vue
Normal file
155
src/components/base/base-tree-select/BaseTreeSelect.vue
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { get } from "@/common/http/request";
|
||||||
|
|
||||||
|
interface TreeNode {
|
||||||
|
id: number | string;
|
||||||
|
label: string;
|
||||||
|
children?: TreeNode[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
url: String,
|
||||||
|
data: Array as () => TreeNode[],
|
||||||
|
placeholder: String,
|
||||||
|
nodeKey: { type: String, default: "id" },
|
||||||
|
labelKey: { type: String, default: "label" },
|
||||||
|
childrenKey: { type: String, default: "children" },
|
||||||
|
clearable: { type: Boolean, default: true },
|
||||||
|
disabled: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
const modelValue = defineModel<number | string | undefined>({ required: true });
|
||||||
|
const treeData = ref<TreeNode[]>([]);
|
||||||
|
const treeSelectRef = ref();
|
||||||
|
const popoverVisible = ref(false);
|
||||||
|
const selectedLabel = ref("");
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
children: props.childrenKey,
|
||||||
|
label: props.labelKey,
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadData = async () => {
|
||||||
|
if (props.url) {
|
||||||
|
const rawData = await get(props.url).then(res => res.data);
|
||||||
|
treeData.value = rawData || [];
|
||||||
|
} else if (props.data) {
|
||||||
|
treeData.value = props.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const findNodeLabel = (nodes: TreeNode[], targetId: number | string): string => {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (node[props.nodeKey as keyof TreeNode] === targetId) {
|
||||||
|
return node[props.labelKey as keyof TreeNode] as string;
|
||||||
|
}
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
const label = findNodeLabel(node.children, targetId);
|
||||||
|
if (label) return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNodeClick = (node: TreeNode) => {
|
||||||
|
modelValue.value = node[props.nodeKey as keyof TreeNode] as number | string;
|
||||||
|
selectedLabel.value = node[props.labelKey as keyof TreeNode] as string;
|
||||||
|
popoverVisible.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleClear = () => {
|
||||||
|
modelValue.value = undefined;
|
||||||
|
selectedLabel.value = "";
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => modelValue.value,
|
||||||
|
newVal => {
|
||||||
|
if (newVal !== undefined && newVal !== null) {
|
||||||
|
selectedLabel.value = findNodeLabel(treeData.value, newVal);
|
||||||
|
} else {
|
||||||
|
selectedLabel.value = "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => treeData.value,
|
||||||
|
() => {
|
||||||
|
if (modelValue.value !== undefined && modelValue.value !== null) {
|
||||||
|
selectedLabel.value = findNodeLabel(treeData.value, modelValue.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(loadData);
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
reload: loadData,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-popover
|
||||||
|
ref="treeSelectRef"
|
||||||
|
v-model:visible="popoverVisible"
|
||||||
|
placement="bottom-start"
|
||||||
|
:width="200"
|
||||||
|
trigger="click"
|
||||||
|
:disabled="disabled"
|
||||||
|
popper-class="tree-select-popover"
|
||||||
|
>
|
||||||
|
<template #reference>
|
||||||
|
<el-input
|
||||||
|
v-model="selectedLabel"
|
||||||
|
readonly
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="disabled"
|
||||||
|
:clearable="clearable"
|
||||||
|
@clear="handleClear"
|
||||||
|
class="tree-select-input"
|
||||||
|
>
|
||||||
|
<template #suffix>
|
||||||
|
<el-icon class="el-input__icon">
|
||||||
|
<arrow-down :class="{ 'is-reverse': popoverVisible }" />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
<div class="tree-select-dropdown">
|
||||||
|
<el-tree
|
||||||
|
:data="treeData"
|
||||||
|
:props="defaultProps"
|
||||||
|
:node-key="nodeKey"
|
||||||
|
default-expand-all
|
||||||
|
highlight-current
|
||||||
|
:current-node-key="modelValue"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tree-select-input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-select-input :deep(.el-input__inner) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-select-input :deep(.el-input__icon) {
|
||||||
|
transition: transform 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-select-input :deep(.el-input__icon.is-reverse) {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-select-dropdown {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -23,6 +23,13 @@ const loadData = async () => {
|
|||||||
if (props.data !== undefined && treeData.value === undefined) {
|
if (props.data !== undefined && treeData.value === undefined) {
|
||||||
treeData.value = props.data;
|
treeData.value = props.data;
|
||||||
}
|
}
|
||||||
|
// 树数据加载完成后,如果有选中的值,使用 setCheckedKeys 设置选中状态
|
||||||
|
// 因为 default-checked-keys 只在组件初始化时生效
|
||||||
|
nextTick(() => {
|
||||||
|
if (treeRef.value && treeCheck.value !== undefined && treeCheck.value.length > 0) {
|
||||||
|
treeRef.value.setCheckedKeys(treeCheck.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSelect = () => {
|
const clearSelect = () => {
|
||||||
@@ -35,7 +42,8 @@ const defaultProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const checkHandle = (checkedNode: any, treeStatus: any) => {
|
const checkHandle = (checkedNode: any, treeStatus: any) => {
|
||||||
treeCheck.value = treeStatus.checkedKeys;
|
// 将字符串类型的 id 转换为数字类型
|
||||||
|
treeCheck.value = treeStatus.checkedKeys.map((id: string | number) => (typeof id === "string" ? Number(id) : id));
|
||||||
};
|
};
|
||||||
|
|
||||||
const clickHandle = (clickNode: any, nodeAttr: any, treeNode: any, event: any) => {
|
const clickHandle = (clickNode: any, nodeAttr: any, treeNode: any, event: any) => {
|
||||||
@@ -43,11 +51,13 @@ const clickHandle = (clickNode: any, nodeAttr: any, treeNode: any, event: any) =
|
|||||||
};
|
};
|
||||||
|
|
||||||
const initSelect = (newV: number[]) => {
|
const initSelect = (newV: number[]) => {
|
||||||
treeRef.value?.setCheckedKeys(newV);
|
if (treeRef.value && newV !== undefined && newV.length > 0) {
|
||||||
|
treeRef.value.setCheckedKeys(newV);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(treeCheck, (newV: number[] | undefined) => {
|
watch(treeCheck, (newV: number[] | undefined) => {
|
||||||
if (newV === undefined) return;
|
if (newV === undefined || newV.length === 0) return;
|
||||||
initSelect(newV);
|
initSelect(newV);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -64,11 +74,12 @@ defineExpose({
|
|||||||
ref="treeRef"
|
ref="treeRef"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
:data="treeData"
|
:data="treeData"
|
||||||
v-model="treeCheck"
|
|
||||||
node-key="id"
|
node-key="id"
|
||||||
default-expand-all
|
default-expand-all
|
||||||
highlight-current
|
highlight-current
|
||||||
:show-checkbox="showCheckbox"
|
:show-checkbox="showCheckbox"
|
||||||
|
:default-checked-keys="treeCheck"
|
||||||
|
check-strictly
|
||||||
@check="checkHandle"
|
@check="checkHandle"
|
||||||
@node-click="clickHandle"
|
@node-click="clickHandle"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { $t } from "@/common/languages";
|
import { $t } from "@/common/languages";
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
authShowFunc: Function,
|
authShowFunc: Function,
|
||||||
@@ -9,6 +10,16 @@ const emit = defineEmits<{ "operate-button-click": [eventName: string, row: any]
|
|||||||
|
|
||||||
const buttonList = useRoute().meta.toolButtonAuth ?? [];
|
const buttonList = useRoute().meta.toolButtonAuth ?? [];
|
||||||
|
|
||||||
|
// 根据按钮数量计算列宽
|
||||||
|
// 中文:2字按钮约40px,4字按钮约60px
|
||||||
|
// 英文:1词按钮约40px,3词按钮约80px
|
||||||
|
// 间隙:每个按钮间8px
|
||||||
|
const columnWidth = computed(() => {
|
||||||
|
const count = buttonList.length;
|
||||||
|
// 基础边距20px + 每个按钮平均45px + 间隙
|
||||||
|
return 20 + count * 45 + (count - 1) * 8;
|
||||||
|
});
|
||||||
|
|
||||||
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||||
if (props.authShowFunc !== undefined) {
|
if (props.authShowFunc !== undefined) {
|
||||||
return props.authShowFunc(row, button);
|
return props.authShowFunc(row, button);
|
||||||
@@ -17,18 +28,49 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-table-column :label="$t('_prop.common.operate')" v-if="buttonList?.length !== 0">
|
<el-table-column
|
||||||
|
:label="$t('_prop.common.operate')"
|
||||||
|
v-if="buttonList?.length !== 0"
|
||||||
|
:min-width="columnWidth"
|
||||||
|
align="center"
|
||||||
|
fixed="right"
|
||||||
|
class-name="operate-column"
|
||||||
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<template v-for="button of buttonList" :key="button.buttonName">
|
<div class="operate-buttons">
|
||||||
<el-button
|
<template v-for="button of buttonList" :key="button.buttonName">
|
||||||
v-if="authShowFunc(row, button)"
|
<el-button
|
||||||
:type="button.colorType || 'primary'"
|
v-if="authShowFunc(row, button)"
|
||||||
@click="emit('operate-button-click', button.eventName, row)"
|
:type="button.colorType || 'primary'"
|
||||||
link
|
@click="emit('operate-button-click', button.eventName, row)"
|
||||||
>
|
link
|
||||||
{{ $t("_button." + button.eventName) }}
|
size="small"
|
||||||
</el-button>
|
class="operate-btn"
|
||||||
</template>
|
>
|
||||||
|
{{ $t("_button." + button.eventName) }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</template>
|
</template>
|
||||||
|
<style scoped>
|
||||||
|
.operate-buttons {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate-btn {
|
||||||
|
padding: 2px 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operate-btn:hover {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ const getTagType = (code: number | null): string => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<el-table-column :label="$t('_prop.common.status')" :prop="statusParamName">
|
<el-table-column :label="$t('_prop.common.status')" :prop="statusParamName" min-width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- 没有权限按钮时,显示带框标签 -->
|
<!-- 没有权限按钮时,显示带框标签 -->
|
||||||
<span v-if="buttonList.length === 0">
|
<span v-if="buttonList.length === 0">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, reactive, nextTick } from "vue";
|
import { ref, reactive, nextTick, computed } from "vue";
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import BasePageableTable from "../base-pageable-table/BasePageableTable.vue";
|
import BasePageableTable from "../base-pageable-table/BasePageableTable.vue";
|
||||||
import type { SearcherProp } from "../search-bar/SearchBarType";
|
import type { SearcherProp } from "../search-bar/SearchBarType";
|
||||||
@@ -19,6 +19,14 @@ const props = defineProps({
|
|||||||
itemIdName: String,
|
itemIdName: String,
|
||||||
itemFieldName: String,
|
itemFieldName: String,
|
||||||
rowKey: { type: String, default: "id" },
|
rowKey: { type: String, default: "id" },
|
||||||
|
useAuth: { type: Boolean, default: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
const buttonList = useRoute().meta.toolButtonAuth ?? [];
|
||||||
|
|
||||||
|
const hasShowItemAuth = computed(() => {
|
||||||
|
if (!props.useAuth) return true;
|
||||||
|
return buttonList.some(item => item.eventName === "showItem");
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Emits {
|
interface Emits {
|
||||||
@@ -209,7 +217,7 @@ defineExpose({
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column v-if="itemUrl || itemFieldName" type="expand" fixed="left" width="50">
|
<el-table-column v-if="(itemUrl || itemFieldName) && hasShowItemAuth" type="expand" fixed="left" width="50">
|
||||||
<template #default="{ row, expanded }">
|
<template #default="{ row, expanded }">
|
||||||
<div :class="['item-container', { 'is-expanded': expanded }]">
|
<div :class="['item-container', { 'is-expanded': expanded }]">
|
||||||
<div v-if="loadingItems[getRowKey(row)]" class="loading-state">
|
<div v-if="loadingItems[getRowKey(row)]" class="loading-state">
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const props = defineProps({
|
|||||||
treeSideNodeName: String,
|
treeSideNodeName: String,
|
||||||
treeSideTitle: String,
|
treeSideTitle: String,
|
||||||
});
|
});
|
||||||
|
const emit = defineEmits(["update:current-node"]);
|
||||||
const page = ref(1);
|
const page = ref(1);
|
||||||
const pageSize = ref(20);
|
const pageSize = ref(20);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
@@ -32,6 +33,10 @@ const resetClick = () => {
|
|||||||
loadData();
|
loadData();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(treeSelect, newVal => {
|
||||||
|
emit("update:current-node", newVal);
|
||||||
|
});
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
if (props.data !== undefined) {
|
if (props.data !== undefined) {
|
||||||
total.value = props.data.length;
|
total.value = props.data.length;
|
||||||
|
|||||||
@@ -181,6 +181,8 @@ export const useRouteFn = () => {
|
|||||||
// 这两个顺序不能互换,因为 translateTitle 函数需要 route.meta.useI18n
|
// 这两个顺序不能互换,因为 translateTitle 函数需要 route.meta.useI18n
|
||||||
if (useI18n === undefined && routeUseI18n !== undefined) route.meta.useI18n = routeUseI18n;
|
if (useI18n === undefined && routeUseI18n !== undefined) route.meta.useI18n = routeUseI18n;
|
||||||
if (!isFunction(title)) {
|
if (!isFunction(title)) {
|
||||||
|
// 保留原始 title,用于语言切换时重新翻译
|
||||||
|
route.meta._rawTitle = String(title);
|
||||||
route.meta.title = translateTitle(String(title), route.name as string, route.meta.useI18n);
|
route.meta.title = translateTitle(String(title), route.name as string, route.meta.useI18n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,15 @@ type Route = RouteLocationNormalizedLoaded | RouterConfigRaw;
|
|||||||
export const formatTitle = (route: Route, reTranslate = false) => {
|
export const formatTitle = (route: Route, reTranslate = false) => {
|
||||||
// 取消 meta 响应式
|
// 取消 meta 响应式
|
||||||
const meta: MetaProps = { ...route.meta };
|
const meta: MetaProps = { ...route.meta };
|
||||||
const { title: routeTitle, useI18n } = meta;
|
const { title: routeTitle, useI18n, _rawTitle } = meta;
|
||||||
const name = route.name as string;
|
const name = route.name as string;
|
||||||
let title = routeTitle ?? "";
|
let title = routeTitle ?? "";
|
||||||
|
|
||||||
if (reTranslate && !isFunction(title)) title = translateTitle(String(title), name, useI18n);
|
// 重新翻译时,优先使用原始的 title(i18n key)
|
||||||
|
if (reTranslate && !isFunction(title)) {
|
||||||
|
const rawTitle = _rawTitle || String(title);
|
||||||
|
title = translateTitle(rawTitle, name, useI18n);
|
||||||
|
}
|
||||||
if (title && !isFunction(title)) return String(title);
|
if (title && !isFunction(title)) return String(title);
|
||||||
if (isFunction(title)) title = title(route as RouteLocationNormalizedLoaded);
|
if (isFunction(title)) title = title(route as RouteLocationNormalizedLoaded);
|
||||||
|
|
||||||
|
|||||||
4
src/types/router.d.ts
vendored
4
src/types/router.d.ts
vendored
@@ -40,6 +40,10 @@ declare global {
|
|||||||
* 是否是动态路由,在编译阶段自动生成
|
* 是否是动态路由,在编译阶段自动生成
|
||||||
*/
|
*/
|
||||||
_dynamic?: boolean;
|
_dynamic?: boolean;
|
||||||
|
/**
|
||||||
|
* 原始的 title(i18n key),用于语言切换时重新翻译
|
||||||
|
*/
|
||||||
|
_rawTitle?: string;
|
||||||
/**
|
/**
|
||||||
* 可访问该页面的权限数组,当前路由设置的权限会影响子路由
|
* 可访问该页面的权限数组,当前路由设置的权限会影响子路由
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -175,6 +175,16 @@ const remove = (row: any) => {
|
|||||||
useRemove(removeUrl, row.id, "_message.production.finishedproductreceipt.delete_message");
|
useRemove(removeUrl, row.id, "_message.production.finishedproductreceipt.delete_message");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 成品入库状态标签类型映射
|
||||||
|
const getFinishedProductReceiptStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
1: "warning", // 待出货
|
||||||
|
3: "primary", // 出货中
|
||||||
|
4: "success", // 已完成
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const outstock = async (row: any) => {
|
const outstock = async (row: any) => {
|
||||||
// 检查单据状态,只有待出货和出货中状态才能出货
|
// 检查单据状态,只有待出货和出货中状态才能出货
|
||||||
if (row.formStatus !== 1 && row.formStatus !== 3) {
|
if (row.formStatus !== 1 && row.formStatus !== 3) {
|
||||||
@@ -320,6 +330,7 @@ const handleReset = () => {
|
|||||||
<DefaultStatusSwitchColumn
|
<DefaultStatusSwitchColumn
|
||||||
status-param-name="formStatus"
|
status-param-name="formStatus"
|
||||||
:status-label-mapping="getFinishedProductReceiptStatusLabel"
|
:status-label-mapping="getFinishedProductReceiptStatusLabel"
|
||||||
|
:tag-type-mapping="getFinishedProductReceiptStatusTagType"
|
||||||
/>
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -146,6 +146,22 @@ const remove = (row: any) => {
|
|||||||
useRemove(removeUrl, row.id, "_message.production.finishedproductshipment.delete_message");
|
useRemove(removeUrl, row.id, "_message.production.finishedproductshipment.delete_message");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const approve = (row: any) => {
|
const approve = (row: any) => {
|
||||||
ElMessageBox.confirm($t("_message.production.finishedproductshipment.approve_confirm"), $t("_level.warning"), {
|
ElMessageBox.confirm($t("_message.production.finishedproductshipment.approve_confirm"), $t("_level.warning"), {
|
||||||
confirmButtonText: $t("_button.confirm"),
|
confirmButtonText: $t("_button.confirm"),
|
||||||
@@ -265,7 +281,11 @@ const handleReset = () => {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('_prop.production.finishedproductshipment.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.production.finishedproductshipment.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { ElMessage, ElMessageBox } from "element-plus";
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
||||||
import { DocumentType } from "@/common/enums/DocumentType";
|
import { DocumentType } from "@/common/enums/DocumentType";
|
||||||
|
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
@@ -28,7 +29,8 @@ const generateProductionReturnUrl = "/production/productionissue/productionRetur
|
|||||||
*/
|
*/
|
||||||
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
||||||
const { getFormStatusLabel } = useStatus();
|
const { getFormStatusLabel } = useStatus();
|
||||||
const { useApprove, useReject } = usePage(tableRef);
|
const { useApprove, useReject, useGeneralPageRef } = usePage(tableRef);
|
||||||
|
const { itemVisible, itemParentId } = useGeneralPageRef();
|
||||||
const productionReturnRef = ref<InstanceType<typeof BaseTableForm>>();
|
const productionReturnRef = ref<InstanceType<typeof BaseTableForm>>();
|
||||||
const productionReturnVisible = ref(false);
|
const productionReturnVisible = ref(false);
|
||||||
const productionReturnTableData = ref([]);
|
const productionReturnTableData = ref([]);
|
||||||
@@ -68,6 +70,11 @@ const productionReturn = async (row: any) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showItem = (row: any) => {
|
||||||
|
itemParentId.value = row.id;
|
||||||
|
itemVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const operateButtonClick = (eventName: string, row: any) => {
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "approve":
|
case "approve":
|
||||||
@@ -79,6 +86,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
case "productionReturn":
|
case "productionReturn":
|
||||||
productionReturn(row);
|
productionReturn(row);
|
||||||
break;
|
break;
|
||||||
|
case "showItem":
|
||||||
|
showItem(row);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||||
@@ -92,6 +102,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const generateProductionReturn = async () => {
|
const generateProductionReturn = async () => {
|
||||||
if (!productionReturnTableData.value || productionReturnTableData.value.length === 0) {
|
if (!productionReturnTableData.value || productionReturnTableData.value.length === 0) {
|
||||||
ElMessage.warning($t("_message.production.production_issue.no_return_data"));
|
ElMessage.warning($t("_message.production.production_issue.no_return_data"));
|
||||||
@@ -165,7 +191,11 @@ const generateProductionReturn = async () => {
|
|||||||
<el-table-column :label="$t('_prop.production.production_issue.storeName')" prop="storeName" />
|
<el-table-column :label="$t('_prop.production.production_issue.storeName')" prop="storeName" />
|
||||||
<el-table-column :label="$t('_prop.production.production_issue.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.production.production_issue.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
@@ -201,4 +231,18 @@ const generateProductionReturn = async () => {
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</BaseTableForm>
|
</BaseTableForm>
|
||||||
|
<BaseItemDialog
|
||||||
|
:title="$t('_title.production.production_issue.showItem')"
|
||||||
|
v-model:visible="itemVisible"
|
||||||
|
:url="getItemUrl"
|
||||||
|
parent-param-name="issueId"
|
||||||
|
v-model:parent-param-value="itemParentId"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.warehouse_item.partNumber')" prop="partNumber" />
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs" />
|
||||||
|
<el-table-column :label="$t('_prop.production.production_issue.requiredQty')" prop="requiredQty" />
|
||||||
|
<el-table-column :label="$t('_prop.production.production_issue.actualQty')" prop="actualQty" />
|
||||||
|
</template>
|
||||||
|
</BaseItemDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -152,6 +152,17 @@ const viewMaterialShortage = async () => {
|
|||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 生产计划状态标签类型映射
|
||||||
|
const getProductionPlanStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未完成
|
||||||
|
1: "success", // 已完成
|
||||||
|
2: "warning", // 审核中
|
||||||
|
3: "primary", // 已审核
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const generatePurchasePlan = (selectedShortageRows: any[]) => {
|
const generatePurchasePlan = (selectedShortageRows: any[]) => {
|
||||||
ElMessageBox.confirm($t("_message.production.production_plan.generate_purchase_plan_confirm"), $t("_level.warning"), {
|
ElMessageBox.confirm($t("_message.production.production_plan.generate_purchase_plan_confirm"), $t("_level.warning"), {
|
||||||
confirmButtonText: $t("_button.confirm"),
|
confirmButtonText: $t("_button.confirm"),
|
||||||
@@ -408,6 +419,7 @@ const handleReset = () => {
|
|||||||
<DefaultStatusSwitchColumn
|
<DefaultStatusSwitchColumn
|
||||||
status-param-name="productionStatus"
|
status-param-name="productionStatus"
|
||||||
:status-label-mapping="getProductionPlanStatusLabel"
|
:status-label-mapping="getProductionPlanStatusLabel"
|
||||||
|
:tag-type-mapping="getProductionPlanStatusTagType"
|
||||||
/>
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultS
|
|||||||
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
||||||
import { usePage } from "@/composables/use-page";
|
import { usePage } from "@/composables/use-page";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
@@ -22,7 +23,8 @@ const rejectUrl = "/production/productionreturn/rejectProductionReturn";
|
|||||||
*/
|
*/
|
||||||
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
||||||
const { getFormStatusLabel } = useStatus();
|
const { getFormStatusLabel } = useStatus();
|
||||||
const { useApprove, useReject } = usePage(tableRef);
|
const { useApprove, useReject, useGeneralPageRef } = usePage(tableRef);
|
||||||
|
const { itemVisible, itemParentId } = useGeneralPageRef();
|
||||||
/**
|
/**
|
||||||
* 可以自定义的变量
|
* 可以自定义的变量
|
||||||
*/
|
*/
|
||||||
@@ -33,6 +35,11 @@ const approve = (row: any) => {
|
|||||||
const reject = (row: any) => {
|
const reject = (row: any) => {
|
||||||
useReject(rejectUrl, row.id);
|
useReject(rejectUrl, row.id);
|
||||||
};
|
};
|
||||||
|
const showItem = (row: any) => {
|
||||||
|
itemParentId.value = row.id;
|
||||||
|
itemVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const operateButtonClick = (eventName: string, row: any) => {
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "approve":
|
case "approve":
|
||||||
@@ -41,6 +48,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
case "reject":
|
case "reject":
|
||||||
reject(row);
|
reject(row);
|
||||||
break;
|
break;
|
||||||
|
case "showItem":
|
||||||
|
showItem(row);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||||
@@ -48,6 +58,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
if (row.formStatus === 1 && button.eventName === "approve") return false;
|
if (row.formStatus === 1 && button.eventName === "approve") return false;
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ExpandablePageableTable
|
<ExpandablePageableTable
|
||||||
@@ -66,7 +92,11 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
<el-table-column :label="$t('_prop.production.production_return.storeName')" prop="storeName" />
|
<el-table-column :label="$t('_prop.production.production_return.storeName')" prop="storeName" />
|
||||||
<el-table-column :label="$t('_prop.production.production_return.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.production.production_return.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
@@ -77,4 +107,17 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
</el-table>
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
</ExpandablePageableTable>
|
</ExpandablePageableTable>
|
||||||
|
<BaseItemDialog
|
||||||
|
:title="$t('_title.production.production_return.showItem')"
|
||||||
|
v-model:visible="itemVisible"
|
||||||
|
:url="getItemUrl"
|
||||||
|
parent-param-name="returnId"
|
||||||
|
v-model:parent-param-value="itemParentId"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.warehouse_item.partNumber')" prop="partNumber" />
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.warehouse_item.productSpecs')" prop="productSpecs" />
|
||||||
|
<el-table-column :label="$t('_prop.production.production_return.returnQty')" prop="returnQty" />
|
||||||
|
</template>
|
||||||
|
</BaseItemDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -343,6 +343,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ExpandablePageableTable
|
<ExpandablePageableTable
|
||||||
@@ -366,7 +382,11 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="$t('_prop.purchase.purchase_order.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.purchase.purchase_order.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" width="180" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" width="180" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
|
|||||||
@@ -111,6 +111,16 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 采购计划状态标签类型映射
|
||||||
|
const getPurchasePlanStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "warning", // 待处理
|
||||||
|
1: "primary", // 进行中
|
||||||
|
2: "success", // 已完成
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const operateButtonClick = (eventName: string, row: any) => {
|
const operateButtonClick = (eventName: string, row: any) => {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case "edit":
|
case "edit":
|
||||||
@@ -364,7 +374,11 @@ const mappingConfig: FieldMappingConfig = {
|
|||||||
<el-table-column :label="$t('_prop.purchase.purchase_plan.planNo')" prop="planNo" />
|
<el-table-column :label="$t('_prop.purchase.purchase_plan.planNo')" prop="planNo" />
|
||||||
<el-table-column :label="$t('_prop.purchase.purchase_plan.planName')" prop="planName" />
|
<el-table-column :label="$t('_prop.purchase.purchase_plan.planName')" prop="planName" />
|
||||||
<el-table-column :label="$t('_prop.purchase.purchase_plan.storeName')" prop="storeName" />
|
<el-table-column :label="$t('_prop.purchase.purchase_plan.storeName')" prop="storeName" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="planStatus" :status-label-mapping="getPurchasePlanStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="planStatus"
|
||||||
|
:status-label-mapping="getPurchasePlanStatusLabel"
|
||||||
|
:tag-type-mapping="getPurchasePlanStatusTagType"
|
||||||
|
/>
|
||||||
<el-table-column :label="$t('_prop.purchase.purchase_plan.remask')" prop="remask" />
|
<el-table-column :label="$t('_prop.purchase.purchase_plan.remask')" prop="remask" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
|
|||||||
@@ -240,6 +240,22 @@ const calculateTotalPrice = (row: any) => {
|
|||||||
row.totalPrice = Number((row.saleCount * row.price).toFixed(2));
|
row.totalPrice = Number((row.saleCount * row.price).toFixed(2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<ExpandablePageableTable
|
<ExpandablePageableTable
|
||||||
@@ -264,6 +280,7 @@ const calculateTotalPrice = (row: any) => {
|
|||||||
<DefaultStatusSwitchColumn
|
<DefaultStatusSwitchColumn
|
||||||
status-param-name="formStatus"
|
status-param-name="formStatus"
|
||||||
:status-label-mapping="getFormStatusLabel"
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
:switch-on-value="1"
|
:switch-on-value="1"
|
||||||
:switch-off-value="0"
|
:switch-off-value="0"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -85,6 +85,15 @@ const handleSuccess = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getDialogTitle = computed(() => (isEdit.value ? "编辑用户" : "新建用户"));
|
const getDialogTitle = computed(() => (isEdit.value ? "编辑用户" : "新建用户"));
|
||||||
|
|
||||||
|
// 通用状态标签类型映射(启用/禁用)
|
||||||
|
const getCommonStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "success", // 启用
|
||||||
|
1: "info", // 禁用
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BasePageableTable ref="tableRef" :url="url" :searchers="searchers">
|
<BasePageableTable ref="tableRef" :url="url" :searchers="searchers">
|
||||||
@@ -106,7 +115,7 @@ const getDialogTitle = computed(() => (isEdit.value ? "编辑用户" : "新建
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建时间" prop="createDate" min-width="160" />
|
<el-table-column label="创建时间" prop="createDate" min-width="160" />
|
||||||
<DefaultStatusSwitchColumn />
|
<DefaultStatusSwitchColumn :tag-type-mapping="getCommonStatusTagType" />
|
||||||
<DefaultOperateButtonColumn />
|
<DefaultOperateButtonColumn />
|
||||||
</template>
|
</template>
|
||||||
</BasePageableTable>
|
</BasePageableTable>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { formatDate } from "@/common/utils/format-utils";
|
|||||||
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
||||||
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.vue";
|
||||||
import StatusSwitch from "@/components/base/base-switch/StatusSwitch.vue";
|
import StatusSwitch from "@/components/base/base-switch/StatusSwitch.vue";
|
||||||
|
import BaseTreeSelect from "@/components/base/base-tree-select/BaseTreeSelect.vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
@@ -68,12 +69,21 @@ const tableRef = ref<InstanceType<typeof TreeSidePageableTable> | null>(null);
|
|||||||
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
const { useAdd, useEdit, useRemove, useGeneralPageRef } = usePage(tableRef);
|
||||||
const { title, visible, formType, form } = useGeneralPageRef();
|
const { title, visible, formType, form } = useGeneralPageRef();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 左侧树当前选中的节点
|
||||||
|
*/
|
||||||
|
const currentTreeNode = ref<any>(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可以自定义的变量
|
* 可以自定义的变量
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const add = () => {
|
const add = () => {
|
||||||
form.value = {};
|
form.value = {};
|
||||||
|
// 如果左侧树有选中节点,自动设置父级权限
|
||||||
|
if (currentTreeNode.value && currentTreeNode.value.id !== undefined) {
|
||||||
|
form.value.parentId = currentTreeNode.value.id;
|
||||||
|
}
|
||||||
title.value = "_title.systemset.permission.add";
|
title.value = "_title.systemset.permission.add";
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
formType.value = false;
|
formType.value = false;
|
||||||
@@ -122,6 +132,15 @@ const formatPermissionType = (row: any) => {
|
|||||||
const type = permissionTypeOptions.find(item => item.code === row.permissionType);
|
const type = permissionTypeOptions.find(item => item.code === row.permissionType);
|
||||||
return type?.description || "";
|
return type?.description || "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通用状态标签类型映射(启用/禁用)
|
||||||
|
const getCommonStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "success", // 启用
|
||||||
|
1: "info", // 禁用
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -132,6 +151,7 @@ const formatPermissionType = (row: any) => {
|
|||||||
:tree-side-url="treeSideUrl"
|
:tree-side-url="treeSideUrl"
|
||||||
tree-side-param-name="parentId"
|
tree-side-param-name="parentId"
|
||||||
tree-side-node-name="id"
|
tree-side-node-name="id"
|
||||||
|
@update:current-node="currentTreeNode = $event"
|
||||||
>
|
>
|
||||||
<template #tool-button>
|
<template #tool-button>
|
||||||
<DefaultToolButton @top-button-click="topButtonClick" />
|
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||||
@@ -158,7 +178,7 @@ const formatPermissionType = (row: any) => {
|
|||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<DefaultStatusSwitchColumn :url="statusUrl" />
|
<DefaultStatusSwitchColumn :url="statusUrl" :tag-type-mapping="getCommonStatusTagType" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
@@ -274,11 +294,10 @@ const formatPermissionType = (row: any) => {
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item :label="$t('_prop.systemset.permission.parentId')" prop="parentId">
|
<el-form-item :label="$t('_prop.systemset.permission.parentId')" prop="parentId">
|
||||||
<el-input-number
|
<BaseTreeSelect
|
||||||
v-model="form.parentId"
|
v-model="form.parentId"
|
||||||
:min="0"
|
:url="treeSideUrl"
|
||||||
:placeholder="$t('_message.systemset.permission.input_parentId')"
|
:placeholder="$t('_message.systemset.permission.select_parentId')"
|
||||||
style="width: 100%"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -87,6 +87,15 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通用状态标签类型映射(启用/禁用)
|
||||||
|
const getCommonStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "success", // 启用
|
||||||
|
1: "info", // 禁用
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<TreeSidePageableTable
|
<TreeSidePageableTable
|
||||||
@@ -109,7 +118,7 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
<el-table-column :label="$t('_prop.systemset.syschannel.channelType')" prop="channelType" />
|
<el-table-column :label="$t('_prop.systemset.syschannel.channelType')" prop="channelType" />
|
||||||
<el-table-column :label="$t('_prop.systemset.syschannel.sort')" prop="sort" />
|
<el-table-column :label="$t('_prop.systemset.syschannel.sort')" prop="sort" />
|
||||||
<el-table-column :label="$t('_prop.systemset.syschannel.show')" prop="show" />
|
<el-table-column :label="$t('_prop.systemset.syschannel.show')" prop="show" />
|
||||||
<DefaultStatusSwitchColumn :url="statusUrl" />
|
<DefaultStatusSwitchColumn :url="statusUrl" :tag-type-mapping="getCommonStatusTagType" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -82,6 +82,15 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通用状态标签类型映射(启用/禁用)
|
||||||
|
const getCommonStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "success", // 启用
|
||||||
|
1: "info", // 禁用
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
||||||
@@ -93,7 +102,7 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
<el-table-column :label="$t('_prop.systemset.sysrole.roleType')" prop="roleType" :formatter="formatRoleType" />
|
<el-table-column :label="$t('_prop.systemset.sysrole.roleType')" prop="roleType" :formatter="formatRoleType" />
|
||||||
<el-table-column :label="$t('_prop.common.remark')" prop="remark" />
|
<el-table-column :label="$t('_prop.common.remark')" prop="remark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn :url="statusUrl" />
|
<DefaultStatusSwitchColumn :url="statusUrl" :tag-type-mapping="getCommonStatusTagType" />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
</BasePageableTable>
|
</BasePageableTable>
|
||||||
|
|||||||
@@ -175,6 +175,15 @@ const getUserTypeLabel = (type: number) => {
|
|||||||
const option = userTypeOptions.find(item => item.code === type);
|
const option = userTypeOptions.find(item => item.code === type);
|
||||||
return option?.description || "-";
|
return option?.description || "-";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 通用状态标签类型映射(启用/禁用)
|
||||||
|
const getCommonStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "success", // 启用
|
||||||
|
1: "info", // 禁用
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
||||||
@@ -191,7 +200,7 @@ const getUserTypeLabel = (type: number) => {
|
|||||||
:formatter="(row: any) => getUserTypeLabel(row.userType)"
|
:formatter="(row: any) => getUserTypeLabel(row.userType)"
|
||||||
/>
|
/>
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn :url="statusUrl" />
|
<DefaultStatusSwitchColumn :url="statusUrl" :tag-type-mapping="getCommonStatusTagType" />
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||||
</template>
|
</template>
|
||||||
</BasePageableTable>
|
</BasePageableTable>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultS
|
|||||||
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
||||||
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
||||||
import { DocumentType } from "@/common/enums/DocumentType";
|
import { DocumentType } from "@/common/enums/DocumentType";
|
||||||
|
import BaseItemDialog from "@/components/base/base-item-dialog/BaseItemDialog.vue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 必须要的变量
|
* 必须要的变量
|
||||||
@@ -137,8 +138,25 @@ const validateProductCount = (index: number) => {
|
|||||||
*/
|
*/
|
||||||
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
const tableRef = ref<InstanceType<typeof ExpandablePageableTable> | null>(null);
|
||||||
const { useAdd, useEdit, useRemove, useGeneralPageRef, useApprove, useReject } = usePage(tableRef);
|
const { useAdd, useEdit, useRemove, useGeneralPageRef, useApprove, useReject } = usePage(tableRef);
|
||||||
const { title, visible, formType, form } = useGeneralPageRef();
|
const { title, visible, formType, form, itemVisible, itemParentId } = useGeneralPageRef();
|
||||||
const { getFormStatusLabel } = useStatus();
|
const { getFormStatusLabel } = useStatus();
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const baseFormWithTableRef = ref<InstanceType<typeof BaseFormWithTable>>();
|
const baseFormWithTableRef = ref<InstanceType<typeof BaseFormWithTable>>();
|
||||||
|
|
||||||
const warehouseOptions = ref<Array<{ label: string; value: number }>>([]);
|
const warehouseOptions = ref<Array<{ label: string; value: number }>>([]);
|
||||||
@@ -189,6 +207,11 @@ const remove = (row: any) => {
|
|||||||
useRemove(removeUrl, row.id, "_message.warehouse.stocktransferorder.delete_message");
|
useRemove(removeUrl, row.id, "_message.warehouse.stocktransferorder.delete_message");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showItem = (row: any) => {
|
||||||
|
itemParentId.value = row.id;
|
||||||
|
itemVisible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
const approve = (row: any) => {
|
const approve = (row: any) => {
|
||||||
useApprove(approveUrl, row.id, "_message.warehouse.stocktransferorder.approve_confirm");
|
useApprove(approveUrl, row.id, "_message.warehouse.stocktransferorder.approve_confirm");
|
||||||
};
|
};
|
||||||
@@ -226,6 +249,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
|||||||
case "remove":
|
case "remove":
|
||||||
remove(row);
|
remove(row);
|
||||||
break;
|
break;
|
||||||
|
case "showItem":
|
||||||
|
showItem(row);
|
||||||
|
break;
|
||||||
case "approve":
|
case "approve":
|
||||||
approve(row);
|
approve(row);
|
||||||
break;
|
break;
|
||||||
@@ -261,7 +287,11 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.outStoreName')" prop="outStoreName" />
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.outStoreName')" prop="outStoreName" />
|
||||||
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
@@ -368,4 +398,18 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</template>
|
</template>
|
||||||
</BaseFormWithTable>
|
</BaseFormWithTable>
|
||||||
|
<BaseItemDialog
|
||||||
|
:title="$t('_title.warehouse.stocktransferorder.showItem')"
|
||||||
|
v-model:visible="itemVisible"
|
||||||
|
:url="getItemUrl"
|
||||||
|
parent-param-name="orderId"
|
||||||
|
v-model:parent-param-value="itemParentId"
|
||||||
|
>
|
||||||
|
<template #columns>
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.partNumber')" prop="partNumber" width="150" />
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.productSpecs')" prop="productSpecs" width="200" />
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.productCount')" prop="productCount" width="200" />
|
||||||
|
<el-table-column :label="$t('_prop.warehouse.stocktransferorder.demandCount')" prop="demandCount" width="200" />
|
||||||
|
</template>
|
||||||
|
</BaseItemDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -162,6 +162,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 表单状态标签类型映射
|
||||||
|
const getFormStatusTagType = (code: number | null): string => {
|
||||||
|
const tagTypeMap: Record<number, string> = {
|
||||||
|
0: "info", // 未审核
|
||||||
|
1: "success", // 已审核
|
||||||
|
2: "danger", // 已驳回
|
||||||
|
3: "warning", // 未完成
|
||||||
|
4: "success", // 已完成
|
||||||
|
5: "primary", // 入库中
|
||||||
|
6: "info", // 已导入
|
||||||
|
7: "warning", // 审核中
|
||||||
|
8: "danger", // 已退回
|
||||||
|
};
|
||||||
|
return tagTypeMap[code ?? -1] || "info";
|
||||||
|
};
|
||||||
|
|
||||||
const submit = (form: any, formRef: FormInstance | undefined) => {
|
const submit = (form: any, formRef: FormInstance | undefined) => {
|
||||||
const targetRef = formRef || (baseFormWithTableRef.value as any)?.baseFormRef;
|
const targetRef = formRef || (baseFormWithTableRef.value as any)?.baseFormRef;
|
||||||
if (!targetRef) return;
|
if (!targetRef) return;
|
||||||
@@ -199,7 +215,11 @@ const submit = (form: any, formRef: FormInstance | undefined) => {
|
|||||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formName')" prop="formName" />
|
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formName')" prop="formName" />
|
||||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formMark')" prop="formMark" />
|
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.formMark')" prop="formMark" />
|
||||||
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
<el-table-column :label="$t('_prop.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||||
<DefaultStatusSwitchColumn status-param-name="formStatus" :status-label-mapping="getFormStatusLabel" />
|
<DefaultStatusSwitchColumn
|
||||||
|
status-param-name="formStatus"
|
||||||
|
:status-label-mapping="getFormStatusLabel"
|
||||||
|
:tag-type-mapping="getFormStatusTagType"
|
||||||
|
/>
|
||||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||||
</template>
|
</template>
|
||||||
<template #item-content="{ itemData }">
|
<template #item-content="{ itemData }">
|
||||||
@@ -331,9 +351,24 @@ const submit = (form: any, formRef: FormInstance | undefined) => {
|
|||||||
v-model:parent-param-value="itemParentId"
|
v-model:parent-param-value="itemParentId"
|
||||||
>
|
>
|
||||||
<template #columns>
|
<template #columns>
|
||||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.partNumber')" prop="partNumber" />
|
<el-table-column
|
||||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.productSpec')" prop="productSpec" />
|
:label="$t('_prop.warehouse.warehousereceipt.partNumber')"
|
||||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.productCount')" prop="productCount" />
|
prop="partNumber"
|
||||||
|
min-width="180"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('_prop.warehouse.warehousereceipt.productSpec')"
|
||||||
|
prop="productSpec"
|
||||||
|
min-width="200"
|
||||||
|
show-overflow-tooltip
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
:label="$t('_prop.warehouse.warehousereceipt.productCount')"
|
||||||
|
prop="productCount"
|
||||||
|
min-width="120"
|
||||||
|
align="right"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</BaseItemDialog>
|
</BaseItemDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user