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 = {
|
||||
layout: {
|
||||
name: "Teek Design Vue3",
|
||||
name: "牛安管理系统",
|
||||
avatar: "/avatar.png",
|
||||
titleMode: TitleModeEnum.ProjectPage,
|
||||
layoutMode: LayoutModeEnum.Vertical,
|
||||
@@ -36,15 +36,15 @@ export const defaultServiceConfig: ServiceConfig = {
|
||||
env: [],
|
||||
},
|
||||
themePanelTriggerPosition: ThemePanelTriggerPositionEnum.Header,
|
||||
globalAlert: {
|
||||
enabled: false,
|
||||
text: "Teek Design Vue3 祝您圣诞快乐,愿节日的欢乐与祝福如雪花般纷至沓来!",
|
||||
startDate: "2025-12-25",
|
||||
endDate: "2025-12-25",
|
||||
type: "primary",
|
||||
closable: true,
|
||||
showIcon: false,
|
||||
},
|
||||
// globalAlert: {
|
||||
// enabled: false,
|
||||
// text: "Teek Design Vue3 祝您圣诞快乐,愿节日的欢乐与祝福如雪花般纷至沓来!",
|
||||
// startDate: "2025-12-25",
|
||||
// endDate: "2025-12-25",
|
||||
// type: "primary",
|
||||
// closable: true,
|
||||
// showIcon: false,
|
||||
// },
|
||||
},
|
||||
theme: {
|
||||
// 默认与 css var 一致,在这里配置一份,方便生成 1 - 9 的基础色
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -898,6 +898,7 @@ export default {
|
||||
input_iconName: "请输入图标名称",
|
||||
input_sort: "请输入排序值",
|
||||
input_parentId: "请输入父级权限ID,0表示根节点",
|
||||
select_parentId: "请选择父级权限",
|
||||
delete_message: "删除权限",
|
||||
},
|
||||
},
|
||||
@@ -948,6 +949,7 @@ export default {
|
||||
},
|
||||
production_issue: {
|
||||
returnDialog: "退料编辑",
|
||||
showItem: "发料明细",
|
||||
},
|
||||
finishedproductreceipt: {
|
||||
add: "添加成品入库单",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<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 { ElMessage, type UploadInstance, type UploadUserFile } from "element-plus";
|
||||
import * as XLSX from "xlsx";
|
||||
@@ -15,6 +15,7 @@ const props = defineProps({
|
||||
uploadDesc: String,
|
||||
itemArrayName: { type: String, required: true },
|
||||
mappingConfig: { type: Object, required: true },
|
||||
templateFileName: { type: String, default: "模板" },
|
||||
});
|
||||
const emit = defineEmits<Emits>();
|
||||
const form = defineModel<any>("form");
|
||||
@@ -104,16 +105,13 @@ const handleFileChange = (file: any) => {
|
||||
const maxSize = 10 * 1024 * 1024; // 10MB
|
||||
if (file.size > maxSize) {
|
||||
ElMessage.error("文件大小不能超过 10MB");
|
||||
clearAllData();
|
||||
return;
|
||||
}
|
||||
|
||||
clearAllData();
|
||||
|
||||
// 更新当前文件显示
|
||||
currentFile.value = file;
|
||||
|
||||
// 解析 Excel
|
||||
// 解析 Excel(追加模式,不清空原有数据)
|
||||
parseExcel(file.raw);
|
||||
};
|
||||
const parseExcel = (file: any) => {
|
||||
@@ -149,11 +147,15 @@ const parseExcel = (file: any) => {
|
||||
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) {
|
||||
console.error(error);
|
||||
ElMessage.error("文件解析失败,请检查文件格式");
|
||||
@@ -165,32 +167,36 @@ const parseExcel = (file: any) => {
|
||||
// 【新增】存储当前上传的文件信息,用于显示和移除
|
||||
const currentFile = ref<UploadUserFile | null>(null);
|
||||
|
||||
// 【新增】深度清理函数
|
||||
const resetFormData = () => {
|
||||
// 1. 清空表单验证
|
||||
// 【新增】只清理表格数据(保留基本表单数据)
|
||||
const clearTableData = () => {
|
||||
// 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) {
|
||||
// 方式 A: 调用暴露的 clearValidate 方法
|
||||
baseFormComponentRef.value.clearValidate();
|
||||
// 方式 B: 或者访问内部 formRef (如果暴露了)
|
||||
// baseFormComponentRef.value.formRef?.clearValidate();
|
||||
}
|
||||
|
||||
// 2. 重置 form 对象 (保留非表格字段?通常重置是全部清空或设为初始值,这里设为空对象)
|
||||
if (form.value) {
|
||||
// 只清空表格数据,保留其他表单字段?还是全部重置?
|
||||
// 根据需求“数据清理不干净”,通常指表格和文件。
|
||||
// 这里我们清空表格数组和文件,其他字段由 BaseForm 的 reset 逻辑处理或手动置空
|
||||
if (Array.isArray(form.value[props.itemArrayName])) {
|
||||
form.value[props.itemArrayName].splice(0, form.value[props.itemArrayName].length);
|
||||
}
|
||||
ElMessage.success("表格数据已清空");
|
||||
};
|
||||
|
||||
// 【新增】深度清理函数(清理表格+文件,保留基本表单数据)
|
||||
const resetFormData = () => {
|
||||
// 1. 清空表格数据
|
||||
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;
|
||||
uploadRef.value?.clearFiles();
|
||||
|
||||
// 4. 如果需要完全重置 form 为初始空对象,取消下面注释
|
||||
form.value = {};
|
||||
// 3. 清空表单验证
|
||||
if (baseFormComponentRef.value) {
|
||||
baseFormComponentRef.value.clearValidate();
|
||||
}
|
||||
};
|
||||
|
||||
// 【新增】增加一行
|
||||
@@ -220,6 +226,43 @@ const removeFile = () => {
|
||||
clearAllData();
|
||||
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 事件
|
||||
const handleBaseFormReset = () => {
|
||||
resetFormData();
|
||||
@@ -229,6 +272,8 @@ defineExpose({
|
||||
resetFormData,
|
||||
addRow,
|
||||
deleteRow,
|
||||
clearTableData,
|
||||
downloadTemplate,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
@@ -266,6 +311,10 @@ defineExpose({
|
||||
<span class="tip-desc" v-if="props.uploadDesc">{{ uploadDesc }}</span>
|
||||
</span>
|
||||
</el-upload>
|
||||
<el-button type="success" @click="downloadTemplate">
|
||||
<el-icon><Download /></el-icon>
|
||||
下载模板文件
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
@@ -288,7 +337,7 @@ defineExpose({
|
||||
<el-icon><Plus /></el-icon>
|
||||
增加一行
|
||||
</el-button>
|
||||
<el-button type="warning" link @click="resetFormData">
|
||||
<el-button type="warning" link @click="clearTableData">
|
||||
<el-icon><Delete /></el-icon>
|
||||
清空表格
|
||||
</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) {
|
||||
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 = () => {
|
||||
@@ -35,7 +42,8 @@ const defaultProps = {
|
||||
};
|
||||
|
||||
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) => {
|
||||
@@ -43,11 +51,13 @@ const clickHandle = (clickNode: any, nodeAttr: any, treeNode: any, event: any) =
|
||||
};
|
||||
|
||||
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) => {
|
||||
if (newV === undefined) return;
|
||||
if (newV === undefined || newV.length === 0) return;
|
||||
initSelect(newV);
|
||||
});
|
||||
|
||||
@@ -64,11 +74,12 @@ defineExpose({
|
||||
ref="treeRef"
|
||||
:props="defaultProps"
|
||||
:data="treeData"
|
||||
v-model="treeCheck"
|
||||
node-key="id"
|
||||
default-expand-all
|
||||
highlight-current
|
||||
:show-checkbox="showCheckbox"
|
||||
:default-checked-keys="treeCheck"
|
||||
check-strictly
|
||||
@check="checkHandle"
|
||||
@node-click="clickHandle"
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { $t } from "@/common/languages";
|
||||
import { computed } from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
authShowFunc: Function,
|
||||
@@ -9,6 +10,16 @@ const emit = defineEmits<{ "operate-button-click": [eventName: string, row: any]
|
||||
|
||||
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) => {
|
||||
if (props.authShowFunc !== undefined) {
|
||||
return props.authShowFunc(row, button);
|
||||
@@ -17,18 +28,49 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
};
|
||||
</script>
|
||||
<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 v-for="button of buttonList" :key="button.buttonName">
|
||||
<el-button
|
||||
v-if="authShowFunc(row, button)"
|
||||
:type="button.colorType || 'primary'"
|
||||
@click="emit('operate-button-click', button.eventName, row)"
|
||||
link
|
||||
>
|
||||
{{ $t("_button." + button.eventName) }}
|
||||
</el-button>
|
||||
</template>
|
||||
<div class="operate-buttons">
|
||||
<template v-for="button of buttonList" :key="button.buttonName">
|
||||
<el-button
|
||||
v-if="authShowFunc(row, button)"
|
||||
:type="button.colorType || 'primary'"
|
||||
@click="emit('operate-button-click', button.eventName, row)"
|
||||
link
|
||||
size="small"
|
||||
class="operate-btn"
|
||||
>
|
||||
{{ $t("_button." + button.eventName) }}
|
||||
</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</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>
|
||||
<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">
|
||||
<!-- 没有权限按钮时,显示带框标签 -->
|
||||
<span v-if="buttonList.length === 0">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { ref, reactive, nextTick, computed } from "vue";
|
||||
import type { PropType } from "vue";
|
||||
import BasePageableTable from "../base-pageable-table/BasePageableTable.vue";
|
||||
import type { SearcherProp } from "../search-bar/SearchBarType";
|
||||
@@ -19,6 +19,14 @@ const props = defineProps({
|
||||
itemIdName: String,
|
||||
itemFieldName: String,
|
||||
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 {
|
||||
@@ -209,7 +217,7 @@ defineExpose({
|
||||
</template>
|
||||
|
||||
<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 }">
|
||||
<div :class="['item-container', { 'is-expanded': expanded }]">
|
||||
<div v-if="loadingItems[getRowKey(row)]" class="loading-state">
|
||||
|
||||
@@ -19,6 +19,7 @@ const props = defineProps({
|
||||
treeSideNodeName: String,
|
||||
treeSideTitle: String,
|
||||
});
|
||||
const emit = defineEmits(["update:current-node"]);
|
||||
const page = ref(1);
|
||||
const pageSize = ref(20);
|
||||
const total = ref(0);
|
||||
@@ -32,6 +33,10 @@ const resetClick = () => {
|
||||
loadData();
|
||||
};
|
||||
|
||||
watch(treeSelect, newVal => {
|
||||
emit("update:current-node", newVal);
|
||||
});
|
||||
|
||||
const loadData = async () => {
|
||||
if (props.data !== undefined) {
|
||||
total.value = props.data.length;
|
||||
|
||||
@@ -181,6 +181,8 @@ export const useRouteFn = () => {
|
||||
// 这两个顺序不能互换,因为 translateTitle 函数需要 route.meta.useI18n
|
||||
if (useI18n === undefined && routeUseI18n !== undefined) route.meta.useI18n = routeUseI18n;
|
||||
if (!isFunction(title)) {
|
||||
// 保留原始 title,用于语言切换时重新翻译
|
||||
route.meta._rawTitle = String(title);
|
||||
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) => {
|
||||
// 取消 meta 响应式
|
||||
const meta: MetaProps = { ...route.meta };
|
||||
const { title: routeTitle, useI18n } = meta;
|
||||
const { title: routeTitle, useI18n, _rawTitle } = meta;
|
||||
const name = route.name as string;
|
||||
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 (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;
|
||||
/**
|
||||
* 原始的 title(i18n key),用于语言切换时重新翻译
|
||||
*/
|
||||
_rawTitle?: string;
|
||||
/**
|
||||
* 可访问该页面的权限数组,当前路由设置的权限会影响子路由
|
||||
*/
|
||||
|
||||
@@ -175,6 +175,16 @@ const remove = (row: any) => {
|
||||
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) => {
|
||||
// 检查单据状态,只有待出货和出货中状态才能出货
|
||||
if (row.formStatus !== 1 && row.formStatus !== 3) {
|
||||
@@ -320,6 +330,7 @@ const handleReset = () => {
|
||||
<DefaultStatusSwitchColumn
|
||||
status-param-name="formStatus"
|
||||
:status-label-mapping="getFinishedProductReceiptStatusLabel"
|
||||
:tag-type-mapping="getFinishedProductReceiptStatusTagType"
|
||||
/>
|
||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" :auth-show-func="authShowFunc" />
|
||||
</template>
|
||||
|
||||
@@ -146,6 +146,22 @@ const remove = (row: any) => {
|
||||
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) => {
|
||||
ElMessageBox.confirm($t("_message.production.finishedproductshipment.approve_confirm"), $t("_level.warning"), {
|
||||
confirmButtonText: $t("_button.confirm"),
|
||||
@@ -265,7 +281,11 @@ const handleReset = () => {
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('_prop.production.finishedproductshipment.formMark')" prop="formMark" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
|
||||
@@ -13,6 +13,7 @@ import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { ref } from "vue";
|
||||
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
||||
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 { getFormStatusLabel } = useStatus();
|
||||
const { useApprove, useReject } = usePage(tableRef);
|
||||
const { useApprove, useReject, useGeneralPageRef } = usePage(tableRef);
|
||||
const { itemVisible, itemParentId } = useGeneralPageRef();
|
||||
const productionReturnRef = ref<InstanceType<typeof BaseTableForm>>();
|
||||
const productionReturnVisible = ref(false);
|
||||
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) => {
|
||||
switch (eventName) {
|
||||
case "approve":
|
||||
@@ -79,6 +86,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
||||
case "productionReturn":
|
||||
productionReturn(row);
|
||||
break;
|
||||
case "showItem":
|
||||
showItem(row);
|
||||
break;
|
||||
}
|
||||
};
|
||||
const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
@@ -92,6 +102,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
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 () => {
|
||||
if (!productionReturnTableData.value || productionReturnTableData.value.length === 0) {
|
||||
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.formMark')" prop="formMark" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
@@ -201,4 +231,18 @@ const generateProductionReturn = async () => {
|
||||
</el-button>
|
||||
</template>
|
||||
</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>
|
||||
|
||||
@@ -152,6 +152,17 @@ const viewMaterialShortage = async () => {
|
||||
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[]) => {
|
||||
ElMessageBox.confirm($t("_message.production.production_plan.generate_purchase_plan_confirm"), $t("_level.warning"), {
|
||||
confirmButtonText: $t("_button.confirm"),
|
||||
@@ -408,6 +419,7 @@ const handleReset = () => {
|
||||
<DefaultStatusSwitchColumn
|
||||
status-param-name="productionStatus"
|
||||
:status-label-mapping="getProductionPlanStatusLabel"
|
||||
:tag-type-mapping="getProductionPlanStatusTagType"
|
||||
/>
|
||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||
</template>
|
||||
|
||||
@@ -8,6 +8,7 @@ import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultS
|
||||
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
||||
import { usePage } from "@/composables/use-page";
|
||||
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 { 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) => {
|
||||
useReject(rejectUrl, row.id);
|
||||
};
|
||||
const showItem = (row: any) => {
|
||||
itemParentId.value = row.id;
|
||||
itemVisible.value = true;
|
||||
};
|
||||
|
||||
const operateButtonClick = (eventName: string, row: any) => {
|
||||
switch (eventName) {
|
||||
case "approve":
|
||||
@@ -41,6 +48,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
||||
case "reject":
|
||||
reject(row);
|
||||
break;
|
||||
case "showItem":
|
||||
showItem(row);
|
||||
break;
|
||||
}
|
||||
};
|
||||
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;
|
||||
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>
|
||||
<template>
|
||||
<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.formMark')" prop="formMark" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
@@ -77,4 +107,17 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
</el-table>
|
||||
</template>
|
||||
</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>
|
||||
|
||||
@@ -343,6 +343,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
}
|
||||
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>
|
||||
<template>
|
||||
<ExpandablePageableTable
|
||||
@@ -366,7 +382,11 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
</el-table-column>
|
||||
<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" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
|
||||
@@ -111,6 +111,16 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
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) => {
|
||||
switch (eventName) {
|
||||
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.planName')" prop="planName" />
|
||||
<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.common.createDate')" prop="createDate" :formatter="formatDate" />
|
||||
<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));
|
||||
}
|
||||
};
|
||||
|
||||
// 表单状态标签类型映射
|
||||
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>
|
||||
<template>
|
||||
<ExpandablePageableTable
|
||||
@@ -264,6 +280,7 @@ const calculateTotalPrice = (row: any) => {
|
||||
<DefaultStatusSwitchColumn
|
||||
status-param-name="formStatus"
|
||||
:status-label-mapping="getFormStatusLabel"
|
||||
:tag-type-mapping="getFormStatusTagType"
|
||||
:switch-on-value="1"
|
||||
:switch-off-value="0"
|
||||
/>
|
||||
|
||||
@@ -85,6 +85,15 @@ const handleSuccess = () => {
|
||||
};
|
||||
|
||||
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>
|
||||
<template>
|
||||
<BasePageableTable ref="tableRef" :url="url" :searchers="searchers">
|
||||
@@ -106,7 +115,7 @@ const getDialogTitle = computed(() => (isEdit.value ? "编辑用户" : "新建
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createDate" min-width="160" />
|
||||
<DefaultStatusSwitchColumn />
|
||||
<DefaultStatusSwitchColumn :tag-type-mapping="getCommonStatusTagType" />
|
||||
<DefaultOperateButtonColumn />
|
||||
</template>
|
||||
</BasePageableTable>
|
||||
|
||||
@@ -9,6 +9,7 @@ import { formatDate } from "@/common/utils/format-utils";
|
||||
import TreeSidePageableTable from "@/components/base/treeside-pageable-table/TreeSidePageableTable.vue";
|
||||
import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultStatusSwitchColumn.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 { title, visible, formType, form } = useGeneralPageRef();
|
||||
|
||||
/**
|
||||
* 左侧树当前选中的节点
|
||||
*/
|
||||
const currentTreeNode = ref<any>(null);
|
||||
|
||||
/**
|
||||
* 可以自定义的变量
|
||||
*/
|
||||
|
||||
const add = () => {
|
||||
form.value = {};
|
||||
// 如果左侧树有选中节点,自动设置父级权限
|
||||
if (currentTreeNode.value && currentTreeNode.value.id !== undefined) {
|
||||
form.value.parentId = currentTreeNode.value.id;
|
||||
}
|
||||
title.value = "_title.systemset.permission.add";
|
||||
visible.value = true;
|
||||
formType.value = false;
|
||||
@@ -122,6 +132,15 @@ const formatPermissionType = (row: any) => {
|
||||
const type = permissionTypeOptions.find(item => item.code === row.permissionType);
|
||||
return type?.description || "";
|
||||
};
|
||||
|
||||
// 通用状态标签类型映射(启用/禁用)
|
||||
const getCommonStatusTagType = (code: number | null): string => {
|
||||
const tagTypeMap: Record<number, string> = {
|
||||
0: "success", // 启用
|
||||
1: "info", // 禁用
|
||||
};
|
||||
return tagTypeMap[code ?? -1] || "info";
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -132,6 +151,7 @@ const formatPermissionType = (row: any) => {
|
||||
:tree-side-url="treeSideUrl"
|
||||
tree-side-param-name="parentId"
|
||||
tree-side-node-name="id"
|
||||
@update:current-node="currentTreeNode = $event"
|
||||
>
|
||||
<template #tool-button>
|
||||
<DefaultToolButton @top-button-click="topButtonClick" />
|
||||
@@ -158,7 +178,7 @@ const formatPermissionType = (row: any) => {
|
||||
</el-tag>
|
||||
</template>
|
||||
</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" />
|
||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||
</template>
|
||||
@@ -274,11 +294,10 @@ const formatPermissionType = (row: any) => {
|
||||
</el-row>
|
||||
|
||||
<el-form-item :label="$t('_prop.systemset.permission.parentId')" prop="parentId">
|
||||
<el-input-number
|
||||
<BaseTreeSelect
|
||||
v-model="form.parentId"
|
||||
:min="0"
|
||||
:placeholder="$t('_message.systemset.permission.input_parentId')"
|
||||
style="width: 100%"
|
||||
:url="treeSideUrl"
|
||||
:placeholder="$t('_message.systemset.permission.select_parentId')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -87,6 +87,15 @@ const operateButtonClick = (eventName: string, row: any) => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// 通用状态标签类型映射(启用/禁用)
|
||||
const getCommonStatusTagType = (code: number | null): string => {
|
||||
const tagTypeMap: Record<number, string> = {
|
||||
0: "success", // 启用
|
||||
1: "info", // 禁用
|
||||
};
|
||||
return tagTypeMap[code ?? -1] || "info";
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<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.sort')" prop="sort" />
|
||||
<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" />
|
||||
<DefaultOperateButtonColumn @operate-button-click="operateButtonClick" />
|
||||
</template>
|
||||
|
||||
@@ -82,6 +82,15 @@ const operateButtonClick = (eventName: string, row: any) => {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// 通用状态标签类型映射(启用/禁用)
|
||||
const getCommonStatusTagType = (code: number | null): string => {
|
||||
const tagTypeMap: Record<number, string> = {
|
||||
0: "success", // 启用
|
||||
1: "info", // 禁用
|
||||
};
|
||||
return tagTypeMap[code ?? -1] || "info";
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<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.common.remark')" prop="remark" />
|
||||
<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" />
|
||||
</template>
|
||||
</BasePageableTable>
|
||||
|
||||
@@ -175,6 +175,15 @@ const getUserTypeLabel = (type: number) => {
|
||||
const option = userTypeOptions.find(item => item.code === type);
|
||||
return option?.description || "-";
|
||||
};
|
||||
|
||||
// 通用状态标签类型映射(启用/禁用)
|
||||
const getCommonStatusTagType = (code: number | null): string => {
|
||||
const tagTypeMap: Record<number, string> = {
|
||||
0: "success", // 启用
|
||||
1: "info", // 禁用
|
||||
};
|
||||
return tagTypeMap[code ?? -1] || "info";
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<BasePageableTable :url="getPageUrl" :searchers="searchers" ref="tableRef">
|
||||
@@ -191,7 +200,7 @@ const getUserTypeLabel = (type: number) => {
|
||||
:formatter="(row: any) => getUserTypeLabel(row.userType)"
|
||||
/>
|
||||
<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" />
|
||||
</template>
|
||||
</BasePageableTable>
|
||||
|
||||
@@ -13,6 +13,7 @@ import DefaultStatusSwitchColumn from "@/components/base/default-column/DefaultS
|
||||
import { useStatus } from "@/common/languages/mapping/base-info-mapping";
|
||||
import { generateDucumentNo } from "@/common/utils/document-no-generator/document-no-generator";
|
||||
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 { 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 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 warehouseOptions = ref<Array<{ label: string; value: number }>>([]);
|
||||
@@ -189,6 +207,11 @@ const remove = (row: any) => {
|
||||
useRemove(removeUrl, row.id, "_message.warehouse.stocktransferorder.delete_message");
|
||||
};
|
||||
|
||||
const showItem = (row: any) => {
|
||||
itemParentId.value = row.id;
|
||||
itemVisible.value = true;
|
||||
};
|
||||
|
||||
const approve = (row: any) => {
|
||||
useApprove(approveUrl, row.id, "_message.warehouse.stocktransferorder.approve_confirm");
|
||||
};
|
||||
@@ -226,6 +249,9 @@ const operateButtonClick = (eventName: string, row: any) => {
|
||||
case "remove":
|
||||
remove(row);
|
||||
break;
|
||||
case "showItem":
|
||||
showItem(row);
|
||||
break;
|
||||
case "approve":
|
||||
approve(row);
|
||||
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.formMark')" prop="formMark" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
@@ -368,4 +398,18 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
</el-table-column>
|
||||
</template>
|
||||
</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>
|
||||
|
||||
@@ -162,6 +162,22 @@ const authShowFunc = (row: any, button: globalThis.ButtonProp) => {
|
||||
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 targetRef = formRef || (baseFormWithTableRef.value as any)?.baseFormRef;
|
||||
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.formMark')" prop="formMark" />
|
||||
<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" />
|
||||
</template>
|
||||
<template #item-content="{ itemData }">
|
||||
@@ -331,9 +351,24 @@ const submit = (form: any, formRef: FormInstance | undefined) => {
|
||||
v-model:parent-param-value="itemParentId"
|
||||
>
|
||||
<template #columns>
|
||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.partNumber')" prop="partNumber" />
|
||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.productSpec')" prop="productSpec" />
|
||||
<el-table-column :label="$t('_prop.warehouse.warehousereceipt.productCount')" prop="productCount" />
|
||||
<el-table-column
|
||||
:label="$t('_prop.warehouse.warehousereceipt.partNumber')"
|
||||
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>
|
||||
</BaseItemDialog>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user