From 61fee49d8ca4e3024c6e3f575bf88e99cde53931 Mon Sep 17 00:00:00 2001
From: buhuazhen <hua100783@gmail.com>
Date: 星期四, 28 八月 2025 14:03:37 +0800
Subject: [PATCH] Merge branch 'feature/0827' into dev_JLMY
---
/dev/null | 213 ---------------------
src/api/personnelManagement/employeeRecord.js | 10
src/views/salesOutbound/index.vue | 13 +
src/components/FileUpload/SimpleMultiFileUpload.vue | 118 +++++++++++
src/views/personnelManagement/contractManagement/components/filesDia.vue | 76 +++++++
src/components/PIMTable/PIMTable.vue | 76 +++---
src/plugins/download.js | 11 +
src/views/personnelManagement/contractManagement/index.vue | 25 +-
src/views/accountReceivableLedger/index.vue | 8
src/views/payable/components/PayableDialog.vue | 4
10 files changed, 291 insertions(+), 263 deletions(-)
diff --git a/src/api/personnelManagement/employeeRecord.js b/src/api/personnelManagement/employeeRecord.js
index 378756a..c5ad362 100644
--- a/src/api/personnelManagement/employeeRecord.js
+++ b/src/api/personnelManagement/employeeRecord.js
@@ -15,4 +15,12 @@
method: 'get',
params: query,
})
-}
\ No newline at end of file
+}
+
+export function save(data){
+ return request({
+ url: '/staff/staffOnJob/save',
+ method: 'post',
+ data: data
+ })
+}
diff --git a/src/components/FileUpload/SimpleMultiFileUpload.vue b/src/components/FileUpload/SimpleMultiFileUpload.vue
new file mode 100644
index 0000000..f02a1d3
--- /dev/null
+++ b/src/components/FileUpload/SimpleMultiFileUpload.vue
@@ -0,0 +1,118 @@
+<script setup>
+import {computed, ref, reactive, defineEmits,watch} from "vue";
+import {getToken} from "@/utils/auth.js";
+import axios from "axios";
+import {ElMessage} from "element-plus";
+
+const emit = defineEmits(['update:fileList', 'onUpload',"update:ids"]);
+
+const props = defineProps({
+ action: {type: String, default: "/common/minioUploads"},
+ fileList: {type: Array, default: () => []},
+ statusType: {type: Number, default: 0}
+})
+
+const localFileList = ref([...props.fileList])
+
+
+const headers = computed(() => ({Authorization: "Bearer " + getToken()}));
+const uploadFileUrl = computed(() => import.meta.env.VITE_APP_BASE_API + props.action);
+
+const handleChange = () => {
+ emit('update:ids', localFileList.value.map(item => item.id))
+ emit('update:fileList', localFileList.value)
+ emit('onUpload', localFileList.value)
+}
+const handleUploadSuccess = (res, file) => {
+ // console.log(res)
+ localFileList.value.push(...res.data.map((it) => {
+ return {
+ id: it.id,
+ url: it.downloadUrl,
+ name: it.originalFilename,
+ status: "success",
+ uid: file.uid
+ }
+ }))
+ handleChange()
+}
+
+const handleUploadPreview = (it) => {
+ const link = document.createElement("a");
+ if (it.url) {
+ link.href = it.url
+ } else {
+ link.href = localFileList.value.find(fl => fl.uid === it.uid).url;
+ }
+ link.download = it.name;
+ link.click();
+}
+
+const handleUploadRemove = (it) => {
+ localFileList.value = localFileList.value.filter(f => f.uid !== it.uid);
+ handleChange()
+}
+
+watch(
+ () => props.fileList,
+ (val) => {
+ localFileList.value = [...val]
+ },
+ { immediate: true, deep: true }
+)
+
+// 鏂囦欢涓婁紶澶勭悊
+const UploadImage = (param) => {
+ const formData = new FormData();
+ formData.append("files", param.file);
+ formData.append("type", props.statusType);
+ axios.post(uploadFileUrl.value, formData, {
+ headers: {
+ "Content-Type": "multipart/form-data",
+ ...headers.value,
+ },
+ onUploadProgress: (progressEvent) => {
+ const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
+ param.onProgress({percent});
+ },
+ })
+ .then((response) => {
+ if (response.data.code === 200) {
+ handleUploadSuccess(response.data, param.file);
+ ElMessage.success("涓婁紶鎴愬姛");
+ } else {
+ param.onError(new Error(response.data.msg));
+ ElMessage.error(response.data.msg);
+ }
+ })
+ .catch((error) => {
+ param.onError(error);
+ });
+};
+
+</script>
+
+<template>
+ <div class="upload-file">
+ <el-upload
+ class="upload-demo"
+ drag
+ :fileList="localFileList"
+ :action="props.action"
+ :headers="headers"
+ :http-request="UploadImage"
+ :on-success="handleUploadSuccess"
+ :on-remove="handleUploadRemove"
+ :on-preview="handleUploadPreview"
+ multiple>
+ <i class="el-icon-upload"></i>
+ <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+ </el-upload>
+ </div>
+</template>
+
+<style scoped lang="scss">
+
+
+
+</style>
\ No newline at end of file
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 955173d..985ab54 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -40,7 +40,7 @@
:fixed="item.fixed"
:label="item.label"
:prop="item.prop"
- show-overflow-tooltip
+ :show-overflow-tooltip="item.dataType !== 'multiTagLink'"
:align="item.align"
:sortable="!!item.sortable"
:type="item.type"
@@ -80,43 +80,22 @@
style="width: 40px; height: 40px; margin-top: 10px"
/>
</div>
-
- <!-- tag -->
- <div v-else-if="item.dataType == 'tag'">
- <el-tag
- v-if="
- typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
- 'string'
- "
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(scope.row[item.prop], item.formatType)"
+ <div v-else-if="item.dataType === 'multiTagLink'">
+ <el-tooltip
+ v-for="(file, index) in dataTypeFnArray(scope.row[item.prop], item.formatData)"
+ :key="index"
+ :content="file.name"
+ effect="dark"
+ placement="top"
>
- {{ formatters(scope.row[item.prop], item.formatData) }}
- </el-tag>
-
- <el-tag
- v-for="(tag, index) in dataTypeFn(
- scope.row[item.prop],
- item.formatData
- )"
- v-else-if="
- typeof dataTypeFn(scope.row[item.prop], item.formatData) ===
- 'object'
- "
- :key="index"
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(tag, item.formatType)"
- >
- {{ item.tagGroup ? tag[item.tagGroup.label] ?? tag : tag }}
- </el-tag>
-
- <el-tag
- v-else
- :title="formatters(scope.row[item.prop], item.formatData)"
- :type="formatType(scope.row[item.prop], item.formatType)"
- >
- {{ formatters(scope.row[item.prop], item.formatData) }}
- </el-tag>
+ <el-tag
+ type="info"
+ style="margin-right: 4px;margin-top: 4px; cursor: pointer;"
+ @click="downloadFile(file)"
+ >
+ {{ truncateName(file.name, 5) }}
+ </el-tag>
+ </el-tooltip>
</div>
<!-- 鎸夐挳 -->
@@ -351,6 +330,29 @@
return format(val);
} else return val;
};
+const dataTypeFnArray = (val, format) => {
+ if (!val) return [];
+ if (typeof format === "function") {
+ return format(val);
+ }
+ // 淇濊瘉杩斿洖鐨勬槸鏁扮粍
+ return Array.isArray(val) ? val : [];
+};
+
+const truncateName = (name, length = 5) => {
+ if (!name) return '';
+ return name.length > length ? name.slice(0, length) + '...' : name;
+};
+
+
+const downloadFile = (file) => {
+ const link = document.createElement("a");
+ link.href = file.url;
+ // 璁剧疆涓嬭浇鏂囦欢鍚嶄负 file.name
+ link.download = file.name;
+ link.click();
+};
+
const formatType = (val, format) => {
if (typeof format === "function") {
diff --git a/src/plugins/download.js b/src/plugins/download.js
index e83e43c..b5cf650 100644
--- a/src/plugins/download.js
+++ b/src/plugins/download.js
@@ -3,6 +3,7 @@
import { saveAs } from 'file-saver'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
+import request from '@/utils/request'
import { blobValidate } from '@/utils/ruoyi'
const baseURL = import.meta.env.VITE_APP_BASE_API
@@ -77,3 +78,13 @@
}
}
+
+export function findFileListByIds(data){
+ return request({
+ url: "/common/findFileListByIds",
+ method: "post",
+ data: data
+ })
+}
+
+
diff --git a/src/views/accountReceivableLedger/index.vue b/src/views/accountReceivableLedger/index.vue
index 0dc1a0a..a97ff20 100644
--- a/src/views/accountReceivableLedger/index.vue
+++ b/src/views/accountReceivableLedger/index.vue
@@ -131,6 +131,13 @@
width:200
},
{
+ label: "闄勪欢",
+ prop: "attachFileList",
+ width:220,
+ dataType: "multiTagLink"
+ }
+ ,
+ {
label: "鐧昏鏃ユ湡",
prop: "createTime",
width:300
@@ -180,6 +187,7 @@
tableData.value = res.records;
page.total = res.total;
});
+ tableLoading.value = false;
};
// 瀛愯〃鍚堣鏂规硶
const summarizeMainTable1 = (param) => {
diff --git a/src/views/payable/components/PayableDialog.vue b/src/views/payable/components/PayableDialog.vue
index f78af79..8f5c99f 100644
--- a/src/views/payable/components/PayableDialog.vue
+++ b/src/views/payable/components/PayableDialog.vue
@@ -150,8 +150,8 @@
form.value.fileList.push(...res.data.map((it,index)=>{
return {
id:it.id,
- url:it.downloadUrl,
- name:it.originalFilename,
+ url:it.url,
+ name:it.name,
status:"success",
uid:file.uid
}
diff --git a/src/views/personnelManagement/contractManagement/components/filesDia.vue b/src/views/personnelManagement/contractManagement/components/filesDia.vue
new file mode 100644
index 0000000..8c6a49d
--- /dev/null
+++ b/src/views/personnelManagement/contractManagement/components/filesDia.vue
@@ -0,0 +1,76 @@
+<script setup>
+import SimpleMultiFileUpload from "@/components/FileUpload/SimpleMultiFileUpload.vue"
+import {ref, defineExpose} from "vue"
+import {ElMessage, ElMessageBox} from "element-plus";
+import {findFileListByIds} from "@/plugins/download.js"
+import {save} from "@/api/personnelManagement/employeeRecord.js"
+
+const ids = ref([])
+const fileList = ref([])
+const contract = ref({})
+const openDialog = (row, type) => {
+ dialogFormVisible.value = true;
+ contract.value = row
+ //鏌ヨ鍑洪檮浠朵俊鎭繘琛屾樉绀� row.attachUpload
+ fileList.value = []
+ if(row.attachUpload){
+ findFileListByIds(row.attachUpload.split(",")).then(res => {
+ fileList.value = res.data
+ ids.value = fileList.value.map(it => it.id)
+ })
+ }
+}
+
+
+
+const closeDia = () => {
+ emit('close')
+ dialogFormVisible.value = false
+};
+
+const saveDia = async () => {
+ // 鎻愪氦淇濆瓨
+ await save({
+ id: contract.value.id,
+ attachUpload: ids.value.join(',')
+ }).then(res => {
+ if (res.code === 200){
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ }
+ })
+ closeDia()
+}
+
+const emit = defineEmits(['close'])
+const dialogFormVisible = ref(false)
+defineExpose({
+ openDialog
+})
+</script>
+
+<template>
+ <div>
+ <el-dialog
+ v-model="dialogFormVisible"
+ title="涓婁紶闄勪欢"
+ width="50%"
+ @close="closeDia"
+ >
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="closeDia">鍙栨秷</el-button>
+ <el-button @click="saveDia">淇濆瓨</el-button>
+ </div>
+ </template>
+ <SimpleMultiFileUpload
+ :key="contract.id"
+ v-model:ids="ids"
+ v-model:file-list="fileList"
+ />
+ </el-dialog>
+ </div>
+</template>
+
+<style scoped lang="scss">
+
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
deleted file mode 100644
index 4734717..0000000
--- a/src/views/personnelManagement/contractManagement/filesDia.vue
+++ /dev/null
@@ -1,213 +0,0 @@
-<template>
- <div>
- <el-dialog
- v-model="dialogFormVisible"
- title="涓婁紶闄勪欢"
- width="50%"
- @close="closeDia"
- >
- <!-- <div style="margin-bottom: 10px;text-align: right">
- <el-upload
- v-model:file-list="fileList"
- class="upload-demo"
- :action="uploadUrl"
- :on-success="handleUploadSuccess"
- :on-error="handleUploadError"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: inline;margin-right: 10px"
- >
- <el-button type="primary">涓婁紶闄勪欢</el-button>
- </el-upload>
-
- <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
- </div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :tableLoading="tableLoading"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- height="500"
- >
- </PIMTable>
- <pagination
- style="margin: 10px 0"
- v-show="total > 0"
- @pagination="paginationSearch"
- :total="total"
- :page="page.current"
- :limit="page.size"
- /> -->
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="closeDia">鍙栨秷</el-button>
- </div>
- </template>
- <fileUpload
- ref="fileUploadRef"
- :fileSize="1024"
- :fileType="['pdf', 'docx', 'txt', 'xlsx', 'pptx....']"
- :limit="10"
- :drag="false"
- v-model:modelValue="modelValue"
- />
- </el-dialog>
- <filePreview ref="filePreviewRef" />
- </div>
-</template>
-
-<script setup>
-import {ref} from "vue";
-import {ElMessageBox} from "element-plus";
-import {getToken} from "@/utils/auth.js";
-import filePreview from '@/components/filePreview/index.vue';
-import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import {
- fileAdd,
- fileDel,
- fileListPage
-} from "@/api/financialManagement/revenueManagement.js";
-import Pagination from "@/components/PIMTable/Pagination.vue";
-import fileUpload from "@/components/FileUpload/index.vue";
-const { proxy } = getCurrentInstance()
-const emit = defineEmits(['close'])
-
-const dialogFormVisible = ref(false);
-const currentId = ref('')
-const selectedRows = ref([]);
-const filePreviewRef = ref()
-const tableColumn = ref([
- {
- label: "鏂囦欢鍚嶇О",
- prop: "name",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "涓嬭浇",
- type: "text",
- clickFun: (row) => {
- downLoadFile(row);
- },
- },
- {
- name: "棰勮",
- type: "text",
- clickFun: (row) => {
- lookFile(row);
- },
- }
- ],
- },
-]);
-const page = reactive({
- current: 1,
- size: 100,
-});
-const total = ref(0);
-const tableData = ref([]);
-const fileList = ref([]);
-const tableLoading = ref(false);
-const accountType = ref('')
-const headers = ref({
- Authorization: "Bearer " + getToken(),
-});
-// const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
-
-// 鎵撳紑寮规
-const openDialog = (row,type) => {
- accountType.value = type;
- dialogFormVisible.value = true;
- currentId.value = row.id;
- getList()
-}
-const paginationSearch = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getList();
-};
-const getList = () => {
- fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
- tableData.value = res.data.records;
- total.value = res.data.total;
- })
-}
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鍏抽棴寮规
-const closeDia = () => {
- dialogFormVisible.value = false;
- emit('close')
-};
-// 涓婁紶鎴愬姛澶勭悊
-function handleUploadSuccess(res, file) {
- // 濡傛灉涓婁紶鎴愬姛
- if (res.code == 200) {
- const fileRow = {}
- fileRow.name = res.data.originalName
- fileRow.url = res.data.tempPath
- uploadFile(fileRow)
- } else {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
- }
-}
-function uploadFile(file) {
- file.accountId = currentId.value;
- file.accountType = accountType.value;
- fileAdd(file).then(res => {
- proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
- getList()
- })
-}
-// 涓婁紶澶辫触澶勭悊
-function handleUploadError() {
- proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
-}
-// 涓嬭浇闄勪欢
-const downLoadFile = (row) => {
- proxy.$download.name(row.url);
-}
-// 鍒犻櫎
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- }).then(() => {
- fileDel(ids).then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getList();
- });
- }).catch(() => {
- proxy.$modal.msg("宸插彇娑�");
- });
-};
-// 棰勮闄勪欢
-const lookFile = (row) => {
- filePreviewRef.value.open(row.url)
-}
-
-defineExpose({
- openDialog,
-});
-</script>
-
-<style scoped>
-
-</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index ece00db..073fed2 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -65,7 +65,7 @@
</div>
</template>
</el-dialog>
- <files-dia ref="filesDia"></files-dia>
+ <files-dia ref="filesDia" @close="filesClose"></files-dia>
</div>
</template>
@@ -78,7 +78,7 @@
import dayjs from "dayjs";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import { getToken } from "@/utils/auth.js";
-import FilesDia from "./filesDia.vue";
+import FilesDia from "./components/filesDia.vue";
const data = reactive({
searchForm: {
staffName: "",
@@ -250,18 +250,23 @@
page.size = obj.limit;
getList();
};
-const getList = () => {
+
+const getList = async () => {
tableLoading.value = true;
const params = { ...searchForm.value, ...page };
params.entryDate = undefined
- staffOnJobListPage(params).then(res => {
- tableLoading.value = false;
- tableData.value = res.data.records
- page.total = res.data.total;
- }).catch(err => {
- tableLoading.value = false;
- })
+ let res = await staffOnJobListPage(params)
+ tableData.value = res.data.records
+ page.total = res.data.total;
+ tableLoading.value = false;
+
};
+
+
+const filesClose = ()=>{
+ getList()
+}
+
// 琛ㄦ牸閫夋嫨鏁版嵁
const handleSelectionChange = (selection) => {
selectedRows.value = selection;
diff --git a/src/views/salesOutbound/index.vue b/src/views/salesOutbound/index.vue
index 8f06840..69c3153 100644
--- a/src/views/salesOutbound/index.vue
+++ b/src/views/salesOutbound/index.vue
@@ -166,6 +166,15 @@
/>
</el-form-item>
</el-col>
+ <el-col :span="12">
+ <el-form-item label="闄勪欢涓婁紶锛�" prop="receiptPaymentDate">
+ <SimpleMultiFileUpload
+ style="width: 100%"
+ v-model:ids="ids"
+ v-model:file-list="fileList"
+ />
+ </el-form-item>
+ </el-col>
</el-row>
</el-form>
<template #footer>
@@ -180,6 +189,7 @@
<script setup>
import {ref, reactive, onMounted, nextTick} from "vue";
+import SimpleMultiFileUpload from "@/components/FileUpload/SimpleMultiFileUpload.vue"
const { proxy } = getCurrentInstance()
const { receipt_payment_type } = proxy.useDict("receipt_payment_type");
import {Delete, Download, Plus} from "@element-plus/icons-vue";
@@ -199,6 +209,8 @@
const formDia = ref()
const activeTab = ref("out");
+const ids = ref([])
+const fileList = ref([])
// 鏍囩椤垫暟鎹�
const tabs = reactive([
{ name: "out", label: "閿�鍞嚭搴�" },
@@ -342,6 +354,7 @@
const submitForm = () => {
proxy.$refs["formRef"].validate((valid) => {
if (valid) {
+ former.value.attachUpload = ids.value.join(",")
receiptPaymentSaveOrUpdate(former.value).then((res) => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
closeDia();
--
Gitblit v1.9.3