From 1021003321fe54f3f45d77457db86105d206551a Mon Sep 17 00:00:00 2001
From: yaowanxin <3588231647@qq.com>
Date: 星期五, 26 九月 2025 14:04:34 +0800
Subject: [PATCH] 档案管理-书籍二维码生成,借阅-归还扫瞄
---
src/views/fileManagement/document/index.vue | 164 ++++++++++++++++++++++++++
src/views/fileManagement/return/index.vue | 110 ++++++++++++++++--
src/views/fileManagement/borrow/index.vue | 61 ++++++++-
src/api/fileManagement/return.js | 7 +
4 files changed, 317 insertions(+), 25 deletions(-)
diff --git a/src/api/fileManagement/return.js b/src/api/fileManagement/return.js
index 2e0c0e7..9021ac9 100644
--- a/src/api/fileManagement/return.js
+++ b/src/api/fileManagement/return.js
@@ -26,6 +26,13 @@
data: ids,
});
}
+//鏍规嵁涔︾睄id鏌ヨ鍊熼槄璁板綍
+export function getBorrowListByDocumentationId(id) {
+ return request({
+ url: "/documentationBorrowManagement/getByDocumentationId/"+id,
+ method: "get"
+ });
+}
// 鏇存柊鍊熼槄璁板綍
export function updateBorrow(data) {
diff --git a/src/views/fileManagement/borrow/index.vue b/src/views/fileManagement/borrow/index.vue
index 6875571..531feb6 100644
--- a/src/views/fileManagement/borrow/index.vue
+++ b/src/views/fileManagement/borrow/index.vue
@@ -90,10 +90,6 @@
ref="borrowFormRef"
>
<el-row :gutter="20">
-
- </el-row>
-
- <el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鍊熼槄浜猴細" prop="borrower">
<el-input v-model="borrowForm.borrower" placeholder="璇疯緭鍏ュ�熼槄浜�" />
@@ -101,14 +97,31 @@
</el-col>
<el-col :span="12">
<el-form-item label="鍊熼槄涔︾睄锛�" prop="documentationId">
- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="width: 100%">
+ <!-- <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="width: 100%" @change="handleScanContent">
<el-option
v-for="item in documentList"
:key="item.id"
:label="item.docName || item.name"
:value="item.id"
/>
- </el-select>
+ </el-select> -->
+ <div style="display: flex; gap: 10px;">
+ <el-select v-model="borrowForm.documentationId" placeholder="璇烽�夋嫨鍊熼槄涔︾睄" style="flex: 1;width: 100px;" @change="handleSelectChange">
+ <el-option
+ v-for="item in documentList"
+ :key="item.id"
+ :label="item.docName || item.name"
+ :value="item.id"
+ />
+ </el-select>
+ <el-input
+ v-model="scanContent"
+ placeholder="鎵爜杈撳叆"
+ style="width: 100px;"
+ @input="handleScanContent"
+ clearable
+ />
+ </div>
</el-form-item>
</el-col>
</el-row>
@@ -188,7 +201,7 @@
const borrowList = ref([]);
const selectedRows = ref([]);
const documentList = ref([]); // 鏂囨。鍒楄〃锛岀敤浜庡�熼槄涔︾睄閫夋嫨
-
+const scanContent = ref('') // 鎵爜鍐呭
// 鍒嗛〉鐩稿叧
const pagination = reactive({
currentPage: 1,
@@ -368,6 +381,36 @@
ElMessage.success("鏌ヨ鏉′欢宸查噸缃�");
};
+// 澶勭悊涓嬫媺閫夋嫨鍙樺寲
+const handleSelectChange = (value) => {
+ // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
+ scanContent.value = '';
+};
+
+// 澶勭悊鎵爜鍐呭
+const handleScanContent = async (value) => {
+if (!value) return;
+
+ try {
+ // 鏌ユ壘鎵弿鍐呭瀵瑰簲鐨勬枃妗�
+ // 鍋囪浜岀淮鐮佸寘鍚殑鏄枃妗D鎴栨枃妗e悕绉�
+ const matchedDoc = documentList.value.find(item =>
+ item.documentationId === value
+ );
+
+ if (matchedDoc) {
+ // 鎵惧埌鍖归厤鐨勬枃妗o紝璁剧疆琛ㄥ崟鍊�
+ borrowForm.documentationId = matchedDoc.documentationId;
+ ElMessage.success(`宸查�夋嫨: ${matchedDoc.docName || matchedDoc.name}`);
+ } else {
+ // 鏈壘鍒板尮閰嶇殑鏂囨。锛屾彁绀虹敤鎴�
+ ElMessage.warning('鏈壘鍒板搴旂殑涔︾睄锛岃妫�鏌ユ壂鐮佸唴瀹规垨鎵嬪姩閫夋嫨');
+ }
+ } catch (error) {
+ ElMessage.error('鎵爜澶勭悊澶辫触锛岃閲嶈瘯');
+ console.error('鎵爜澶勭悊閿欒:', error);
+ }
+}
// 鎵撳紑鍊熼槄寮规
const openBorrowDia = async (type, data) => {
// 鍏堝埛鏂版枃妗e垪琛�
@@ -375,7 +418,8 @@
borrowOperationType.value = type;
borrowDia.value = true;
-
+ scanContent.value = ''; // 娓呯┖鎵爜鍐呭
+
if (type === "edit") {
// 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
Object.assign(borrowForm, data);
@@ -395,6 +439,7 @@
const closeBorrowDia = () => {
proxy.$refs.borrowFormRef.resetFields();
borrowDia.value = false;
+ scanContent.value = ''; // 娓呯┖鎵爜鍐呭
};
// 鎻愪氦鍊熼槄琛ㄥ崟
diff --git a/src/views/fileManagement/document/index.vue b/src/views/fileManagement/document/index.vue
index 7cf352c..a0d824a 100644
--- a/src/views/fileManagement/document/index.vue
+++ b/src/views/fileManagement/document/index.vue
@@ -153,7 +153,39 @@
</div>
</template>
</el-dialog>
-
+<el-dialog
+ v-model="qrCodeDialogVisible"
+ title="鏂囨。浜岀淮鐮�"
+ width="400px"
+ @close="closeQrCodeDialog"
+ >
+ <div class="qr-code-container">
+ <div v-if="qrCodeUrl" class="qr-code-image">
+ <img :src="qrCodeUrl" alt="鏂囨。浜岀淮鐮�" class="qr-image" />
+ <div class="qr-info">
+ <p><strong>鏂囨。鍚嶇О锛�</strong>{{ currentDocument.docName }}</p>
+ <p><strong>鏂囨。缂栧彿锛�</strong>{{ currentDocument.docNumber }}</p>
+ </div>
+ </div>
+ <div v-else class="qr-loading">
+ <el-icon class="is-loading"><Loading /></el-icon>
+ <p>姝e湪鐢熸垚浜岀淮鐮�...</p>
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="closeQrCodeDialog">鍏抽棴</el-button>
+ <el-button
+ v-if="qrCodeUrl"
+ type="primary"
+ @click="downloadQRCode"
+ icon="Download"
+ >
+ 涓嬭浇浜岀淮鐮�
+ </el-button>
+ </div>
+ </template>
+ </el-dialog>
<!-- 鏂囨。鏂板/淇敼瀵硅瘽妗� -->
<el-dialog
v-model="documentDia"
@@ -352,8 +384,8 @@
<el-button @click="closeDocumentDia">鍙栨秷</el-button>
</div>
</template>
- </el-dialog>
- <AttachmentManager ref="attachmentManagerRef" />
+ </el-dialog>
+ <AttachmentManager ref="attachmentManagerRef" />
</div>
</template>
@@ -371,7 +403,9 @@
const { proxy } = getCurrentInstance();
const tree = ref(null);
const containerRef = ref(null);
-
+// 瀵煎叆qrcode搴�
+import QRCode from 'qrcode'
+import { Loading, Download } from '@element-plus/icons-vue'
// 浣跨敤瀛楀吀鏁版嵁
const { confidentiality_level, document_urgency, document_status, document_type, document_categories, retention_period } = useDict('confidentiality_level', 'document_urgency', 'document_status', 'document_type', 'document_categories', 'retention_period')
@@ -407,6 +441,10 @@
// 浣嶇疆鏍戞暟鎹�
const locationTree = ref([]);
+// 浜岀淮鐮佺浉鍏冲彉閲�
+const qrCodeDialogVisible = ref(false)
+const qrCodeUrl = ref('')
+const currentDocument = ref({})
// 琛ㄦ牸鍒楅厤缃�
const tableColumns = ref([
{ label: '鏂囨。鍚嶇О', prop: 'docName', width: '200' },
@@ -568,7 +606,7 @@
label: "鎿嶄綔",
align: "center",
fixed: 'right',
- width: '150',
+ width: '200',
operation: [
{
name: "缂栬緫",
@@ -584,10 +622,74 @@
openAttachment(row)
},
},
+ {
+ name: "鐢熸垚浜岀淮鐮�",
+ type: "text",
+ clickFun: (row) => {
+ generateQRCode(row)
+ },
+ },
],
}
]);
+// 鐢熸垚浜岀淮鐮�
+const generateQRCode = async (row) => {
+ try {
+ // 妫�鏌ュ繀瑕佸瓧娈�
+ if (!row.docName || !row.docNumber) {
+ ElMessage.warning('鏂囨。淇℃伅涓嶅畬鏁达紝鏃犳硶鐢熸垚浜岀淮鐮�')
+ return
+ }
+
+ currentDocument.value = row
+ qrCodeUrl.value = ''
+ qrCodeDialogVisible.value = true
+
+ // 鏋勫缓浜岀淮鐮佸唴瀹�
+ // const qrContent = `${row.id}|${row.docName}|${row.docNumber}`
+ const qrContent = `${row.id}`
+ // 鐢熸垚浜岀淮鐮�
+ qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+ width: 256,
+ margin: 2,
+ color: {
+ dark: '#000000',
+ light: '#FFFFFF'
+ },
+ errorCorrectionLevel: 'M'
+ })
+
+ // ElMessage.success('浜岀淮鐮佺敓鎴愭垚鍔燂紒')
+
+ } catch (error) {
+ console.error('鐢熸垚浜岀淮鐮佸け璐�:', error)
+ ElMessage.error('鐢熸垚浜岀淮鐮佸け璐ワ細' + error.message)
+ qrCodeDialogVisible.value = false
+ }
+}
+// 涓嬭浇浜岀淮鐮�
+const downloadQRCode = () => {
+ if (!qrCodeUrl.value) {
+ ElMessage.warning('璇峰厛鐢熸垚浜岀淮鐮�')
+ return
+ }
+
+ const a = document.createElement('a')
+ a.href = qrCodeUrl.value
+ a.download = `${currentDocument.value.docName}_浜岀淮鐮乢${new Date().getTime()}.png`
+ document.body.appendChild(a)
+ a.click()
+ document.body.removeChild(a)
+ ElMessage.success('涓嬭浇鎴愬姛锛�')
+}
+
+// 鍏抽棴浜岀淮鐮佸脊绐�
+const closeQrCodeDialog = () => {
+ qrCodeDialogVisible.value = false
+ qrCodeUrl.value = ''
+ currentDocument.value = {}
+}
// 鍒嗙被琛ㄥ崟
const categoryForm = reactive({
category: "",
@@ -1259,4 +1361,56 @@
color: #606266;
font-size: 14px;
}
+/* 浜岀淮鐮侀瑙堟牱寮� */
+.qr-code-container {
+ text-align: center;
+ padding: 20px;
+}
+
+.qr-code-image {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 20px;
+}
+
+.qr-image {
+ max-width: 100%;
+ height: auto;
+ border: 2px solid #e0e0e0;
+ border-radius: 8px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.qr-info {
+ text-align: left;
+ background: #f8f9fa;
+ padding: 15px;
+ border-radius: 8px;
+ min-width: 300px;
+}
+
+.qr-info p {
+ margin: 8px 0;
+ color: #666;
+ font-size: 14px;
+}
+
+.qr-loading {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 15px;
+ padding: 40px 0;
+}
+
+.qr-loading .el-icon {
+ font-size: 32px;
+ color: #409EFF;
+}
+
+.qr-loading p {
+ color: #666;
+ margin: 0;
+}
</style>
diff --git a/src/views/fileManagement/return/index.vue b/src/views/fileManagement/return/index.vue
index a95c8af..3c14dc5 100644
--- a/src/views/fileManagement/return/index.vue
+++ b/src/views/fileManagement/return/index.vue
@@ -100,14 +100,31 @@
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="鏂囨。锛�" prop="borrowId">
- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="width: 100%" @change="handleDocumentChange">
+ <!-- <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="flex: 1;" @change="handleDocumentChange">
<el-option
v-for="item in documentList"
:key="item.id"
:label="item.docName || item.name"
:value="item.id"
/>
- </el-select>
+ </el-select> -->
+ <div style="display: flex; gap: 10px;">
+ <el-select v-model="returnForm.borrowId" placeholder="璇烽�夋嫨鏂囨。" style="width: 120px;" @change="handleDocumentChange">
+ <el-option
+ v-for="item in documentList"
+ :key="item.id"
+ :label="item.docName || item.name"
+ :value="item.id"
+ />
+ </el-select>
+ <el-input
+ v-model="scanContent"
+ placeholder="鎵爜杈撳叆"
+ style="flex: 1;"
+ @input="handleScanContent"
+ clearable
+ />
+ </div>
</el-form-item>
</el-col>
<el-col :span="12">
@@ -182,7 +199,7 @@
import { ElMessageBox, ElMessage } from "element-plus";
import { Search, Refresh, Plus, Delete } from '@element-plus/icons-vue';
import PIMTable from '@/components/PIMTable/PIMTable.vue';
-import { getReturnListPage, returnDocument, deleteReturn, getDocumentList, updateBorrow, reventUpdate } from '@/api/fileManagement/return';
+import { getReturnListPage, returnDocument, deleteReturn, getDocumentList, updateBorrow, reventUpdate,getBorrowListByDocumentationId } from '@/api/fileManagement/return';
const { proxy } = getCurrentInstance();
@@ -193,6 +210,8 @@
const returnList = ref([]);
const selectedRows = ref([]);
const documentList = ref([]); // 鏂囨。鍒楄〃
+const borrowInfoList = ref([]); // 鍊熼槄淇℃伅鍒楄〃
+const scanContent = ref(''); // 鎵爜鍐呭
// 鍒嗛〉鐩稿叧
const pagination = reactive({
@@ -368,7 +387,9 @@
const openReturnDia = (type, data) => {
returnOperationType.value = type;
returnDia.value = true;
-
+ scanContent.value = ''; // 娓呯┖鎵爜鍐呭
+ borrowInfoList.value = []; // 娓呯┖鍊熼槄淇℃伅鍒楄〃
+
if (type === "edit") {
// 缂栬緫妯″紡锛屽姞杞界幇鏈夋暟鎹�
Object.assign(returnForm, data);
@@ -392,6 +413,8 @@
const closeReturnDia = () => {
proxy.$refs.returnFormRef.resetFields();
returnDia.value = false;
+ scanContent.value = ''; // 娓呯┖鎵爜鍐呭
+ borrowInfoList.value = []; // 娓呯┖鍊熼槄淇℃伅鍒楄〃
};
// 鎻愪氦褰掕繕琛ㄥ崟
@@ -517,16 +540,62 @@
pagination.pageSize = size;
loadReturnList();
};
-
+// 澶勭悊鎵爜鍐呭
+const handleScanContent = async (value) => {
+ if (!value) return;
+
+ try {
+ // 璋冪敤API鏍规嵁涔︾睄ID鑾峰彇鍊熼槄淇℃伅
+ const res = await getBorrowListByDocumentationId(value);
+
+ if (res.code === 200 && res.data && res.data.length > 0) {
+ // 淇濆瓨鑾峰彇鍒扮殑鍊熼槄淇℃伅鍒楄〃
+ borrowInfoList.value = res.data;
+
+ // 濡傛灉鍙湁涓�鏉¤褰曪紝鐩存帴閫夋嫨
+ if (res.data.length === 1) {
+ const borrowInfo = res.data[0];
+ returnForm.borrowId = borrowInfo.id;
+ returnForm.borrower = borrowInfo.borrower || borrowInfo.borrowerName || '';
+ returnForm.dueReturnDate = borrowInfo.dueReturnDate || borrowInfo.expectedReturnDate || '';
+ ElMessage.success(`宸查�夋嫨: ${borrowInfo.docName || borrowInfo.name}`);
+ } else {
+ // 濡傛灉鏈夊鏉¤褰曪紝鏄剧ず閫夋嫨鎻愮ず
+ ElMessage.success(`鎵惧埌 ${res.data.length} 鏉$浉鍏冲�熼槄璁板綍锛岃浠庝笅鎷夊垪琛ㄤ腑閫夋嫨`);
+ // 閲嶆柊鍔犺浇鏂囨。鍒楄〃锛屽寘鍚渶鏂扮殑鍊熼槄淇℃伅
+ await loadDocumentList();
+ }
+ } else {
+ // 鏈壘鍒板尮閰嶇殑鍊熼槄璁板綍
+ ElMessage.warning('鏈壘鍒板搴旂殑鍊熼槄璁板綍锛岃妫�鏌ユ壂鐮佸唴瀹规垨鎵嬪姩閫夋嫨');
+ }
+ } catch (error) {
+ ElMessage.error('鎵爜澶勭悊澶辫触锛岃閲嶈瘯');
+ console.error('鎵爜澶勭悊閿欒:', error);
+ }
+};
// 澶勭悊鏂囨。閫夋嫨鍙樺寲
-const handleDocumentChange = (documentId) => {
- if (documentId) {
- // 鏍规嵁閫夋嫨鐨勬枃妗D锛屼粠鏂囨。鍒楄〃涓煡鎵惧搴旂殑鏂囨。淇℃伅
- const selectedDoc = documentList.value.find(doc => doc.id === documentId);
- if (selectedDoc) {
+// 澶勭悊鏂囨。閫夋嫨鍙樺寲
+const handleDocumentChange = (borrowId) => {
+ // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
+ scanContent.value = '';
+
+ if (borrowId) {
+ // 浼樺厛浠庡�熼槄淇℃伅鍒楄〃涓煡鎵�
+ let selectedInfo;
+ if (borrowInfoList.value.length > 0) {
+ selectedInfo = borrowInfoList.value.find(info => info.id === borrowId);
+ }
+
+ // 濡傛灉鍊熼槄淇℃伅鍒楄〃涓病鏈夋壘鍒帮紝浠庢枃妗e垪琛ㄤ腑鏌ユ壘
+ if (!selectedInfo) {
+ selectedInfo = documentList.value.find(doc => doc.id === borrowId);
+ }
+
+ if (selectedInfo) {
// 鑷姩濉厖鍊熼槄浜哄拰搴斿綊杩樻棩鏈�
- returnForm.borrower = selectedDoc.borrower || selectedDoc.borrowerName || '';
- returnForm.dueReturnDate = selectedDoc.dueReturnDate || selectedDoc.expectedReturnDate || '';
+ returnForm.borrower = selectedInfo.borrower || selectedInfo.borrowerName || '';
+ returnForm.dueReturnDate = selectedInfo.dueReturnDate || selectedInfo.expectedReturnDate || '';
}
} else {
// 娓呯┖鐩稿叧瀛楁
@@ -534,6 +603,23 @@
returnForm.dueReturnDate = '';
}
};
+// const handleDocumentChange = (documentId) => {
+// // 褰撲笅鎷夋閫夋嫨鏃讹紝娓呯┖鎵爜杈撳叆妗�
+// scanContent.value = '';
+// if (documentId) {
+// // 鏍规嵁閫夋嫨鐨勬枃妗D锛屼粠鏂囨。鍒楄〃涓煡鎵惧搴旂殑鏂囨。淇℃伅
+// const selectedDoc = documentList.value.find(doc => doc.id === documentId);
+// if (selectedDoc) {
+// // 鑷姩濉厖鍊熼槄浜哄拰搴斿綊杩樻棩鏈�
+// returnForm.borrower = selectedDoc.borrower || selectedDoc.borrowerName || '';
+// returnForm.dueReturnDate = selectedDoc.dueReturnDate || selectedDoc.expectedReturnDate || '';
+// }
+// } else {
+// // 娓呯┖鐩稿叧瀛楁
+// returnForm.borrower = '';
+// returnForm.dueReturnDate = '';
+// }
+// };
// 鐢熷懡鍛ㄦ湡
onMounted(() => {
--
Gitblit v1.9.3