From af7fa041da9f063ca49f1f1126ec01616f14cd85 Mon Sep 17 00:00:00 2001 From: spring <2396852758@qq.com> Date: 星期四, 28 八月 2025 14:04:17 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev_JLMY' into dev_JLMY --- src/views/warehouseManagement/index.vue | 7 /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/views/production/productionReporting/components/ProductionDialog.vue | 6 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 12 files changed, 301 insertions(+), 266 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/production/productionReporting/components/ProductionDialog.vue b/src/views/production/productionReporting/components/ProductionDialog.vue index 4d6bf8c..0cc62e1 100644 --- a/src/views/production/productionReporting/components/ProductionDialog.vue +++ b/src/views/production/productionReporting/components/ProductionDialog.vue @@ -30,7 +30,7 @@ <el-row :gutter="30"> <el-col :span="12"> <el-form-item label="寰呯敓浜ф暟閲忥細"> - <el-input v-model="pendingNum" placeholder="璇疯緭鍏�" clearable disabled/> + <el-input v-model="pendingNumTemp" placeholder="璇疯緭鍏�" clearable disabled/> </el-form-item> </el-col> <el-col :span="12"> @@ -85,12 +85,14 @@ }, }); const { form, rules } = toRefs(data); +const pendingNumTemp = ref(0) const changeNum = (value) => { + console.log(value) if (value > pendingNum.value) { form.value.finishedNum = pendingNum.value ElMessage.warning("鏈鐢熶骇鏁伴噺涓嶅彲澶т簬鎺掍骇鏁伴噺"); } - pendingNum.value = pendingNum.value - form.value.finishedNum; + pendingNumTemp.value = pendingNum.value - value; } // Props 鍜� Emits const props = defineProps({ 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(); diff --git a/src/views/warehouseManagement/index.vue b/src/views/warehouseManagement/index.vue index a7d612c..6183677 100644 --- a/src/views/warehouseManagement/index.vue +++ b/src/views/warehouseManagement/index.vue @@ -77,6 +77,11 @@ align="center" /> <el-table-column + prop="code" + label="缂栧彿" + width="180" + /> + <el-table-column prop="supplierName" label="渚涜揣鍟嗗悕绉�" width="180" @@ -84,7 +89,7 @@ /> <el-table-column prop="type" label="鐓ゆ枡绫诲瀷"> <template #default="scope"> - {{scope.row.type === 1 ? '鎴愬搧' : '鍘熸枡'}} + {{scope.row.type == 1 ? '鎴愬搧' : '鍘熸枡'}} </template> </el-table-column> <el-table-column prop="coal" label="鐓ょ" sortable /> -- Gitblit v1.9.3