20260808172946

This commit is contained in:
oneao committed 2026-08-08 17:29:51 +08:00
1 parent 4fbfea82f2
commit d72ca4193d
293 files changed
+37523 -73467

No files matched your search

@@ -35,7 +35,7 @@ import {
import { computed, nextTick, ref, watch } from "vue";
import { useUserStore } from "@/store/user";
import axios from "@/utils/axios";
import { compareAndClassifyData } from "@/utils/dataDiffUtils";
import { compareAndClassifyData, diffData } from "@/utils/dataDiffUtils";
import {
compressImage,
deleteFileApi,
@@ -45,6 +45,7 @@ import {
getFileExtension,
uploadFile,
} from "@/utils/file";
import { loaddataApi } from "@/utils/doSql";
import G3Icon from "@/components/g3-icon/index.vue";
import { VxeTable, VxeColumn } from "vxe-table";
@@ -81,6 +82,34 @@ const displayMode = ref(0);
const userStore = useUserStore();
// 根据 moduleid 查询主表状态,自动判断是否可编辑
const editable = ref(true);
const isReadonly = computed(() => props.readonly || !editable.value);
async function loadEditableStatus() {
try {
const modules = await loaddataApi("s_module", `b_id = '${props.moduleid}'`);
if (!modules?.length) {
editable.value = true;
return;
}
const saveTable = modules[0].b_SaveTable;
if (!saveTable) {
editable.value = true;
return;
}
const records = await loaddataApi(saveTable, `b_id = '${props.father}'`);
if (!records?.length) {
editable.value = true;
return;
}
const state = records[0].b_state;
editable.value = ["草拟", "审核驳回"].includes(state) || !state;
} catch {
editable.value = true;
}
}
const containerRef = ref(null);
const fileInputRef = ref(null);
@@ -234,6 +263,7 @@ watch(
function onOpened() {
loadFiles();
loadEditableStatus();
}
async function loadFiles() {
@@ -291,7 +321,7 @@ function formatTime(date) {
}
// 手动上传
function handleClickUpload() {
if (props.readonly) {
if (isReadonly.value) {
return;
}
fileInputRef.value.click();
@@ -306,7 +336,7 @@ function handleFileInputChange(event) {
}
function handlePaste(e) {
if (props.readonly) {
if (isReadonly.value) {
return;
}
@@ -335,10 +365,9 @@ function handleDrop(e) {
e.preventDefault();
e.stopPropagation();
if (props.readonly) {
if (isReadonly.value) {
return;
}
const files = e.dataTransfer.files;
// 过滤掉文件夹,只处理文件
@@ -570,6 +599,13 @@ function handleBatchDelete() {
}
async function deleteFiles(files) {
await loadEditableStatus();
if (isReadonly.value) {
ElMessage.warning("当前单据已审核,不允许删除附件");
loadFiles();
return;
}
// 收集文件的 mx_filename
const filenames = files.map((file) => file.mx_filename).join(", ");
@@ -608,24 +644,31 @@ async function deleteFiles(files) {
}).then((action) => {
if (action === "confirm") {
loadFiles();
loadEditableStatus();
}
});
}
// 保存
async function handleSave() {
await loadEditableStatus();
if (isReadonly.value) {
ElMessage.warning("当前单据已审核,不允许上传附件");
loadFiles();
return;
}
loading.value = true;
loadingTip.value = "正在保存中 . . .";
const { insertdata, updatedata, deletedata, hasChanges } = compareAndClassifyData(
fileList.value,
oldFileList.value,
"subid",
["_content", "_status", "checked"],
);
const data = compareAndClassifyData(fileList.value, oldFileList.value, "subid", [
"_content",
"_status",
"checked",
]);
// 处理新增的文件
for (const item of insertdata) {
for (const item of data.inserts) {
try {
await uploadFile(
item._content,
@@ -649,6 +692,7 @@ async function handleSave() {
loading.value = false;
loadFiles();
loadEditableStatus();
}
async function handleDownloadZip() {
@@ -709,7 +753,7 @@ function handleTreeNodeClick(data) {
<div class="g3-title">
附件管理({{ fileList.length }})
<template v-if="!props.readonly"> 未上传 ({{ pendingFileList.length }}) </template>
<template v-if="!isReadonly"> 未上传 ({{ pendingFileList.length }}) </template>
</div>
</template>
<input
@@ -753,7 +797,7 @@ function handleTreeNodeClick(data) {
</el-button>
<el-button
v-if="!props.readonly"
v-if="!isReadonly"
size="small"
type="danger"
:disabled="checkedFiles.length === 0 || loading"
@@ -840,7 +884,7 @@ function handleTreeNodeClick(data) {
</div>
<div class="g3-file-actions">
<el-button
v-if="!props.readonly"
v-if="!isReadonly"
type="danger"
:icon="Delete"
size="small"
@@ -854,7 +898,7 @@ function handleTreeNodeClick(data) {
circle
@click.stop="handleDownloadFile(file)"
/>
<el-dropdown v-if="!props.readonly" placement="top" trigger="click">
<el-dropdown v-if="!isReadonly" placement="top" trigger="click">
<el-button
type="info"
:icon="More"
@@ -936,7 +980,7 @@ function handleTreeNodeClick(data) {
<template #default="{ row }">
<div style="display: flex; align-items: center; justify-content: center">
<el-button
v-if="!props.readonly"
v-if="!isReadonly"
type="danger"
link
@click.stop="handleDeleteOne(row)"
@@ -946,7 +990,7 @@ function handleTreeNodeClick(data) {
<el-button type="primary" link @click.stop="handleDownloadFile(row)">
下载
</el-button>
<el-dropdown v-if="!props.readonly" placement="top" trigger="click">
<el-dropdown v-if="!isReadonly" placement="top" trigger="click">
<el-button type="info" link style="margin-left: 12px"> 更多 </el-button>
<el-icon class="el-icon--right">
<ArrowDown />
@@ -969,7 +1013,7 @@ function handleTreeNodeClick(data) {
</div>
</div>
<template v-if="!props.readonly" #footer>
<template v-if="!isReadonly" #footer>
<el-button type="primary" :icon="HelpFilled" :disabled="loading" @click="handleClickUpload">
选择
</el-button>