From 49cdc0884a9a4381cd968cffff65e2a332bc675a Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期六, 24 十月 2026 21:05:29 +0800
Subject: [PATCH] feat(cnas-search): 1.标准查新模块 2.印章使用记录
---
outputs/standard-search-new/标准查新导入模板.xlsx | 0
src/views/structural/sealManage/usageLedger/index.vue | 44 +--
public/import-templates/标准查新导入模板.xlsx | 0
src/views/business/reportPreparation/index.vue | 5
src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue | 205 +++++++--------
src/utils/reportDocxLayout.js | 36 ++
src/api/cnas/process/method/standardNoveltyRetrieval.js | 15
.env.staging | 2
.env.development | 2
vite/plugins/index.js | 3
src/utils/loadSuperDoc.js | 3
src/views/CNAS/process/method/standardNoveltyRetrieval/options.js | 36 ++
src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue | 118 +++++---
src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue | 95 +++++--
.env.production | 2
src/components/Onlyoffice/onlyoffice.vue | 185 ++++++++++---
src/components/ReportWordEditor/index.vue | 2
17 files changed, 479 insertions(+), 274 deletions(-)
diff --git a/.env.development b/.env.development
index 4c4455e..435c7ee 100644
--- a/.env.development
+++ b/.env.development
@@ -10,7 +10,7 @@
# 鏂囦欢璁块棶涓庢櫘閫氭帴鍙g粺涓�璧版湰鍦板紑鍙戜唬鐞�
VITE_APP_BASE_URL = '/dev-api'
-# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛圵ord 绛夋枃妗g殑鍦ㄧ嚎棰勮涓庣紪杈戯紱PDF 浣跨敤娴忚鍣ㄥ師鐢熼瑙堬級
VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
# 鏄惁鍦ㄦ墦鍖呮椂寮�鍚帇缂╋紝鏀寔 gzip 鍜� brotli
diff --git a/.env.production b/.env.production
index 4168280..190570e 100644
--- a/.env.production
+++ b/.env.production
@@ -10,7 +10,7 @@
# 鐢熶骇鐜ip+绔彛
VITE_APP_BASE_URL = 'http://192.168.21.53:8001/lims'
-# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛圵ord 绛夋枃妗g殑鍦ㄧ嚎棰勮涓庣紪杈戯紱PDF 浣跨敤娴忚鍣ㄥ師鐢熼瑙堬級
VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
# 鏄惁鍦ㄦ墦鍖呮椂寮�鍚帇缂╋紝鏀寔 gzip 鍜� brotli
diff --git a/.env.staging b/.env.staging
index 854fc1b..b3a15eb 100644
--- a/.env.staging
+++ b/.env.staging
@@ -10,7 +10,7 @@
# 娴嬭瘯鐜ip+绔彛
VITE_APP_BASE_URL = '/stage-api'
-# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛堥瑙� pdf 鐢紝娌℃湁 http:// 鍓嶇紑浼氬綋鎴愮浉瀵硅矾寰勶級
+# OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛圵ord 绛夋枃妗g殑鍦ㄧ嚎棰勮涓庣紪杈戯紱PDF 浣跨敤娴忚鍣ㄥ師鐢熼瑙堬級
VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001'
# 鏄惁鍦ㄦ墦鍖呮椂寮�鍚帇缂╋紝鏀寔 gzip 鍜� brotli
diff --git "a/outputs/standard-search-new/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" "b/outputs/standard-search-new/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
new file mode 100644
index 0000000..1e9a5bd
--- /dev/null
+++ "b/outputs/standard-search-new/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
Binary files differ
diff --git "a/public/import-templates/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx" "b/public/import-templates/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
index 4d545ee..00f55c5 100644
--- "a/public/import-templates/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
+++ "b/public/import-templates/\346\240\207\345\207\206\346\237\245\346\226\260\345\257\274\345\205\245\346\250\241\346\235\277.xlsx"
Binary files differ
diff --git a/src/api/cnas/process/method/standardNoveltyRetrieval.js b/src/api/cnas/process/method/standardNoveltyRetrieval.js
index cec5582..3df73a0 100644
--- a/src/api/cnas/process/method/standardNoveltyRetrieval.js
+++ b/src/api/cnas/process/method/standardNoveltyRetrieval.js
@@ -19,10 +19,19 @@
});
}
-// 鏌ヨ鐢辨爣鍑嗙淮鎶よ嚜鍔ㄥ綊妗g殑璁板綍
-export function pageAutoArchived(query) {
+// 鏌ヨ鏌愪釜鏍囧噯鐨勫巻娆℃煡鏂拌褰�
+export function listSearchNewHistory(query) {
return request({
- url: "/processMethodSearchNew/pageAutoArchived",
+ url: "/processMethodSearchNew/listSearchNewHistory",
+ method: "get",
+ params: query,
+ });
+}
+
+// 鍒嗛〉鏌ヨ鍏ㄩ儴鏌ユ柊璁板綍锛屽寘鍚凡搴熸鍜岃鏂扮増鏇夸唬鐨勬爣鍑�
+export function pageSearchNewHistory(query) {
+ return request({
+ url: "/processMethodSearchNew/pageSearchNewHistory",
method: "get",
params: query,
});
diff --git a/src/components/Onlyoffice/onlyoffice.vue b/src/components/Onlyoffice/onlyoffice.vue
index 00db4a5..eb69148 100644
--- a/src/components/Onlyoffice/onlyoffice.vue
+++ b/src/components/Onlyoffice/onlyoffice.vue
@@ -8,13 +8,39 @@
class="native-pdf-preview"
title="PDF棰勮"
></iframe>
- <div v-else id="vabOnlyOffice"></div>
+ <template v-else>
+ <div :id="editorId"></div>
+ <div v-if="editorWarning" class="editor-warning">{{ editorWarning }}</div>
+ <div v-if="editorState !== 'ready'" class="editor-status">
+ <template v-if="editorState === 'failed'">
+ <p>{{ editorError }}</p>
+ <el-button type="primary" @click="setEditor(option)">閲嶆柊鍔犺浇</el-button>
+ </template>
+ <span v-else>姝e湪杩炴帴鏂囨。鏈嶅姟骞跺姞杞芥姤鍛�...</span>
+ </div>
+ </template>
</div>
</template>
<script>
// OnlyOffice 鏂囨。鏈嶅姟鍦板潃锛屾寜鐜閰嶇疆锛涜剼鏈湪鐪熸闇�瑕侀瑙堟椂鎵嶅姞杞�
const OFFICE_API_BASE = import.meta.env.VITE_APP_ONLYOFFICE_API || "http://192.168.21.53:9001";
+
+function normalizeOptions(source = {}) {
+ return {
+ url: source.url || "",
+ isEdit: source.isEdit === true || source.isEdit === "true",
+ fileType: source.fileType || "",
+ title: source.title || "",
+ lang: source.lang || "zh-CN",
+ isPrint: source.isPrint !== false,
+ user: { id: source.user_id, name: source.user_name },
+ editUrl: source.editUrl || "",
+ key: source.key || "",
+ model: source.model,
+ token: source.token
+ };
+}
// 澶氫釜椤甸潰鍏辩敤缂栬緫鍣紝api.js 鍙姞杞戒竴娆�
let docsApiPromise = null;
@@ -26,14 +52,23 @@
docsApiPromise = new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = OFFICE_API_BASE.replace(/\/$/, "") + "/web-apps/apps/api/documents/api.js";
+ const timeout = window.setTimeout(() => {
+ script.remove();
+ reject(new Error("OnlyOffice 鏂囨。鏈嶅姟杩炴帴瓒呮椂"));
+ }, 15000);
script.onload = () => {
+ window.clearTimeout(timeout);
if (window.DocsAPI) {
resolve(window.DocsAPI);
} else {
reject(new Error("api.js 鍔犺浇瀹屾垚浣嗘湭娉ㄥ唽 DocsAPI"));
}
};
- script.onerror = () => reject(new Error("OnlyOffice 鏂囨。鏈嶅姟鑴氭湰鍔犺浇澶辫触锛�" + script.src));
+ script.onerror = () => {
+ window.clearTimeout(timeout);
+ script.remove();
+ reject(new Error("OnlyOffice 鏂囨。鏈嶅姟鑴氭湰鍔犺浇澶辫触"));
+ };
document.head.appendChild(script);
});
// 鍔犺浇澶辫触鍚庡厑璁镐笅娆¢噸璇�
@@ -47,21 +82,18 @@
export default {
name: "VabOnlyOffice",
props: ['options'],
+ emits: ['ready', 'error'],
data() {
return {
+ editorId: `onlyoffice-${this._uid || Math.random().toString(36).slice(2)}`,
doctype: "",
docEditor: null,
- //鍙傝�僾abOnlyOffice缁勪欢鍙傛暟閰嶇疆
- option: {
- url: "",
- isEdit: false,
- fileType: "",
- title: "",
- lang: "zh-CN",
- isPrint: true,
- user: {},
- editUrl: ""
- }
+ editorGeneration: 0,
+ editorState: 'loading',
+ editorError: '',
+ editorWarning: '',
+ readyTimer: null,
+ option: normalizeOptions(this.options || this.$route.query)
};
},
computed: {
@@ -69,41 +101,24 @@
return this.isPdfFile(this.option);
}
},
- created() {
- if(this.options){
- const option = this.options
- this.option.url = option.url
- this.option.isEdit = option.isEdit === "true" ? true : false
- this.option.fileType = option.fileType
- this.option.title = option.title
- this.option.lang = option.lang
- this.option.isPrint = option.isPrint
- this.option.user.id = option.user_id
- this.option.user.name = option.user_name
- this.option.editUrl = option.editUrl
- }else{
- const option = this.$route.query
- this.option.url = option.url
- this.option.isEdit = option.isEdit === "true" ? true : false
- this.option.fileType = option.fileType
- this.option.title = option.title
- this.option.lang = option.lang
- this.option.isPrint = option.isPrint
- this.option.user.id = option.user_id
- this.option.user.name = option.user_name
- this.option.editUrl = option.editUrl
- }
- },
beforeUnmount() {
+ this.editorGeneration++;
+ window.clearTimeout(this.readyTimer);
this.destroyEditor();
},
watch: {
- option: {
- handler: function(n) {
- this.setEditor(n);
- this.doctype = this.getFileType(n.fileType);
+ options: {
+ handler(newOptions) {
+ this.option = normalizeOptions(newOptions || this.$route.query);
+ this.setEditor(this.option);
},
deep: true
+ },
+ '$route.query'(query) {
+ if (!this.options) {
+ this.option = normalizeOptions(query);
+ this.setEditor(this.option);
+ }
}
},
mounted() {
@@ -114,19 +129,32 @@
methods: {
destroyEditor() {
if (this.docEditor !== null) {
- this.docEditor.destroyEditor();
+ try {
+ this.docEditor.destroyEditor();
+ } catch (error) {
+ console.error('閿�姣� OnlyOffice 缂栬緫鍣ㄥけ璐�', error);
+ }
this.docEditor = null;
}
},
async setEditor(option) {
+ const generation = ++this.editorGeneration;
+ window.clearTimeout(this.readyTimer);
this.destroyEditor();
// PDF 浣跨敤娴忚鍣ㄥ師鐢熼瑙堬紱鍏朵粬鏂囨。鎵嶅垵濮嬪寲 OnlyOffice銆�
if (!option || !option.url || this.isPdfFile(option)) {
return;
}
+ this.editorState = 'loading';
+ this.editorError = '';
+ this.editorWarning = '';
// 绛夊緟 v-else 涓殑 OnlyOffice 瀹瑰櫒瀹屾垚娓叉煋銆�
await this.$nextTick();
this.doctype = this.getFileType(option.fileType);
+ if (!this.doctype) {
+ this.failEditor('鎶ュ憡鏂囦欢鏍煎紡涓嶅彈鏀寔', generation);
+ return;
+ }
let config = {
document: {
//鍚庣紑
@@ -149,6 +177,7 @@
//瀹氬埗
customization: {
autosave: true, //鏄惁鑷姩淇濆瓨
+ forcesave: true, //鐐瑰嚮淇濆瓨鏃剁珛鍗冲洖璋冧笟鍔℃湇鍔�
chat: true,
comments: false,
help: false,
@@ -164,20 +193,54 @@
},
width: "100%",
height: "100%",
- token: option.token || ""
+ token: option.token || "",
+ events: {
+ onDocumentReady: () => {
+ if (generation === this.editorGeneration) {
+ window.clearTimeout(this.readyTimer);
+ this.editorState = 'ready';
+ this.$emit('ready');
+ }
+ },
+ onError: (event) => {
+ const detail = event && event.data && (event.data.errorDescription || event.data.errorCode);
+ this.failEditor(detail ? `鎶ュ憡鍔犺浇澶辫触锛�${detail}` : '鎶ュ憡鍔犺浇澶辫触锛岃妫�鏌ユ枃妗f湇鍔�', generation);
+ }
+ }
};
try {
await loadDocsApi();
} catch (error) {
console.error(error);
- this.$message.error("鏂囨。鏈嶅姟鏆傛椂涓嶅彲鐢紝鏃犳硶棰勮");
+ this.failEditor(error.message || '鏂囨。鏈嶅姟鏆傛椂涓嶅彲鐢�', generation);
return;
}
- if (this._isDestroyed) {
+ if (generation !== this.editorGeneration || !this.$el?.isConnected) {
return;
}
- this.docEditor = new window.DocsAPI.DocEditor("vabOnlyOffice", config);
+ try {
+ this.readyTimer = window.setTimeout(() => {
+ this.failEditor('鎶ュ憡鍔犺浇瓒呮椂锛岃妫�鏌ユ枃妗f湇鍔′笌鎶ュ憡鍦板潃', generation);
+ }, 30000);
+ this.docEditor = new window.DocsAPI.DocEditor(this.editorId, config);
+ } catch (error) {
+ window.clearTimeout(this.readyTimer);
+ console.error(error);
+ this.failEditor('鏂囨。缂栬緫鍣ㄥ垵濮嬪寲澶辫触锛岃閲嶈瘯', generation);
+ }
+ },
+ failEditor(message, generation) {
+ if (generation !== this.editorGeneration) return;
+ window.clearTimeout(this.readyTimer);
+ if (this.editorState === 'ready') {
+ this.editorWarning = String(message);
+ this.$emit('error', this.editorWarning);
+ return;
+ }
+ this.editorError = String(message);
+ this.editorState = 'failed';
+ this.$emit('error', this.editorError);
},
isPdfFile(option) {
if (!option) {
@@ -253,10 +316,36 @@
<style scoped>
.document-preview,
.native-pdf-preview,
-#vabOnlyOffice {
+.document-preview > div {
width: 100%;
height: 100%;
}
+.document-preview {
+ position: relative;
+}
+.editor-status {
+ position: absolute;
+ inset: 0;
+ z-index: 2;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ gap: 12px;
+ background: #fff;
+ color: #606266;
+}
+.editor-warning {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 2;
+ height: auto !important;
+ padding: 8px 12px;
+ background: #fff3e0;
+ color: #a35d00;
+}
.native-pdf-preview {
display: block;
border: 0;
diff --git a/src/components/ReportWordEditor/index.vue b/src/components/ReportWordEditor/index.vue
index 58d2010..c84b0ef 100644
--- a/src/components/ReportWordEditor/index.vue
+++ b/src/components/ReportWordEditor/index.vue
@@ -25,6 +25,7 @@
import { ElMessage } from 'element-plus'
import { normalizeReportDocxForEditor } from '@/utils/reportDocxLayout'
import { loadSuperDoc } from '@/utils/loadSuperDoc'
+import documentWorkerUrl from 'virtual:superdoc-http-worker-url'
import { superdocToolbarZh } from '@/utils/superdocToolbarZh'
import 'superdoc/style.css'
@@ -114,6 +115,7 @@
}),
documentMode: 'editing',
role: 'editor',
+ workerUrls: { document: documentWorkerUrl },
telemetry: { enabled: false },
ui: { toolbar: { container: toolbar.value, strings: superdocToolbarZh }, ruler: true, comments: false },
onReady: async ({ superdoc }) => {
diff --git a/src/utils/loadSuperDoc.js b/src/utils/loadSuperDoc.js
index a01ee88..49b6c94 100644
--- a/src/utils/loadSuperDoc.js
+++ b/src/utils/loadSuperDoc.js
@@ -1,8 +1,11 @@
+import { installCryptoRandomUUID } from './cryptoRandomUUID'
+
let modulePromise
// 瀹℃牳寮�濮嬫椂棰勫姞杞斤紱缂栬緫鍣ㄥ鐢ㄥ悓涓�娆″姞杞斤紝澶辫触鍚庝粛鍏佽閲嶈瘯銆�
export function loadSuperDoc() {
if (!modulePromise) {
+ installCryptoRandomUUID()
modulePromise = import('superdoc').catch(error => {
modulePromise = null
throw error
diff --git a/src/utils/reportDocxLayout.js b/src/utils/reportDocxLayout.js
index 98ad551..ff2ae3f 100644
--- a/src/utils/reportDocxLayout.js
+++ b/src/utils/reportDocxLayout.js
@@ -4,6 +4,41 @@
const floatingPositionPattern = /<w:tblpPr\b[^>]*\/>/
const tableIndentPattern = /<w:tblInd\b[^>]*\/>/
const runFontsPattern = /<w:rFonts\b[^>]*\/>/g
+const tableRowPattern = /<w:tr(?:\s[^>]*)?>[\s\S]*?<\/w:tr>/g
+const tableCellPattern = /<w:tc(?:\s[^>]*)?>[\s\S]*?<\/w:tc>/g
+
+function fitCoverCustomer(xml) {
+ let changed = false
+ const normalized = xml.replace(tableRowPattern, row => {
+ if (changed) return row
+ const cells = [...row.matchAll(tableCellPattern)]
+ if (cells.length !== 2) return row
+ const cellText = cell => [...cell.matchAll(/<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g)]
+ .map(match => match[1]).join('')
+ if (cellText(cells[0][0]).replace(/[\s:锛歖/g, '') !== '濮旀墭鍗曚綅') return row
+
+ const valueCell = cells[1][0]
+ const customer = cellText(valueCell)
+ const widthTag = valueCell.match(/<w:tcW\b[^>]*>/)?.[0]
+ const widthTwips = Number(widthTag?.match(/\bw:w="(\d+)"/)?.[1])
+ const fontHalfPoints = Number(valueCell.match(/<w:sz\b[^>]*\bw:val="(\d+)"/)?.[1])
+ if (!customer || customer.includes('{{') || !widthTwips || fontHalfPoints !== 32) return row
+
+ // 灏侀潰涓嬪垝绾挎槸鍗曞厓鏍煎簳杈规銆�16 纾呯殑闀垮崟浣嶅悕绉板垰濂藉崰婊″垪瀹芥椂锛�
+ // PDF 鎺掔増鍣ㄥ彲鑳藉皢娈佃惤缁撴潫绗︽尋鍒扮浜岃锛屽鑷磋〃鏍艰鍜屼笅鍒掔嚎涓嬬Щ銆�
+ const units = [...customer].reduce((sum, char) => sum +
+ (/\s/.test(char) ? 0.35 : char.codePointAt(0) > 0x2e80 ? 1 : 0.6), 0)
+ const availablePoints = widthTwips / 20 - 10
+ if (units * fontHalfPoints / 2 <= availablePoints) return row
+ const fittedHalfPoints = Math.max(24, Math.floor(availablePoints / units * 2))
+ const fittedCell = valueCell.replace(/<w:sz(?:Cs)?\b[^>]*\/>/g, tag =>
+ tag.replace(/\bw:val="32"/, `w:val="${fittedHalfPoints}"`))
+ if (fittedCell === valueCell) return row
+ changed = true
+ return row.replace(valueCell, fittedCell)
+ })
+ return changed ? normalized : null
+}
function alignReportHeader(xml, reportCode) {
// 鏃ф楠屾姤鍛婃妸椤电爜鏀惧湪娴姩鏂囨湰妗嗕腑锛汼uperDoc 閲嶆柊鍒嗛〉鏃朵細涓㈠け Word 鐨勬í鍚戦敋鐐广��
@@ -138,6 +173,7 @@
const themeXml = themePart ? await themePart.async('string') : ''
const themeFonts = { major: chineseThemeFont(themeXml, 'major'), minor: chineseThemeFont(themeXml, 'minor') }
let normalizedXml = alignResultTable(documentXml) || documentXml
+ normalizedXml = fitCoverCustomer(normalizedXml) || normalizedXml
normalizedXml = materializeChineseThemeFonts(normalizedXml, themeFonts) || normalizedXml
let changed = normalizedXml !== documentXml
if (changed) zip.file('word/document.xml', normalizedXml)
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
index 591109d..279ddb8 100644
--- a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/EditFormDia.vue
@@ -1,75 +1,63 @@
<template>
<div>
- <el-dialog v-model="formDia" title="缂栬緫" width="80%" @close="closeDia">
+ <el-dialog v-model="formDia" title="鏂板鏌ユ柊" width="820px" @close="closeDia">
<el-form ref="form" :model="form" :rules="formRules" label-width="auto">
<el-col :span="8">
<el-form-item label="鏍囧噯鍚嶇О锛�" prop="methodName">
- <el-input v-model="form.methodName" size="small"></el-input>
+ <el-input v-model="form.methodName" size="small" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="鏍囧噯鍙凤細" prop="standardNo">
- <el-input v-model="form.standardNo" size="small"></el-input>
+ <el-input v-model="form.standardNo" size="small" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
- <el-form-item label="鏂囦欢缂栧彿锛�" prop="fileNo">
- <el-input v-model="form.fileNo" size="small"></el-input>
+ <el-form-item label="鏌ユ柊鏃ユ湡锛�" prop="searchNewTime">
+ <el-date-picker v-model="form.searchNewTime" type="date" value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD" placeholder="璇烽�夋嫨鏃ユ湡" size="small"
+ style="width: 100%;" @change="refreshDefaultNextSearchDate"></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
- <el-form-item label="鏌ユ柊鏃堕棿锛�" prop="searchNewTime">
- <el-date-picker v-model="form.searchNewTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
- format="YYYY-MM-DD HH:mm:ss" placeholder="璇烽�夋嫨" size="small"
- style="width: 100%;"></el-date-picker>
+ <el-form-item label="涓嬫鏌ユ柊鏃ユ湡锛�">
+ <el-input v-if="isSearchRetired" model-value="涓嶉�傜敤" size="small" disabled />
+ <el-date-picker v-else v-model="form.nextSearchDate" type="date" value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD" placeholder="榛樿涓変釜鏈堝悗锛屽彲淇敼" size="small"
+ style="width: 100%;" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="鏌ユ柊浜猴細">
- <el-input :model-value="form.searchNewUserName" size="small" disabled></el-input>
+ <el-input :model-value="currentUserName" size="small" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="鏌ユ柊缁撴灉锛�" prop="searchNewResult">
- <el-input v-model="form.searchNewResult" size="small"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鏄惁鏄柊鏍囧噯锛�">
- <el-tag type="success">鏄�</el-tag>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="鏌ユ柊璁板綍鏉ユ簮锛�" prop="searchNewSource">
- <el-radio-group v-model="form.searchNewSource">
- <el-radio :value="0">鏍囧噯缃�</el-radio>
- <el-radio :value="1">濮旀墭鎯呮姤</el-radio>
- <el-radio :value="2">鏍囧噯鏁�</el-radio>
- <el-radio :value="3">鍏朵粬</el-radio>
- </el-radio-group>
- </el-form-item>
- </el-col>
- <el-col v-if="form.searchNewSource === 3" :span="8">
- <el-form-item label="鏉ユ簮缃戝潃/缃戠珯鍚嶇О锛�" prop="searchNewWebsite"
- :rules="[{required: true, message: '璇峰~鍐欏叿浣撶綉鍧�鎴栫綉绔欏悕绉�', trigger: 'blur'}]">
- <el-input v-model="form.searchNewWebsite" size="small"></el-input>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="澶囨敞锛�" prop="remark">
- <el-select v-model="form.remark"
- clearable size="small">
- <el-option :value="0" label="浣滃簾"></el-option>
- <el-option :value="1" label="鏇挎崲"></el-option>
+ <el-select v-model="form.searchNewResult" placeholder="璇烽�夋嫨" style="width: 100%"
+ @change="handleSearchResultChange">
+ <el-option v-for="item in searchResultOptions" :key="item" :label="item" :value="item" />
</el-select>
</el-form-item>
</el-col>
- <el-col v-if="form.isNewStandard == 1" :span="8">
+ <el-col :span="24">
+ <el-form-item label="鏌ユ柊璁板綍鏉ユ簮锛�" prop="searchNewSource">
+ <el-radio-group v-model="form.searchNewSource">
+ <el-radio v-for="item in searchSourceOptions" :key="item.value" :value="item.value">{{ item.label }}</el-radio>
+ </el-radio-group>
+ </el-form-item>
+ </el-col>
+ <el-col v-if="form.searchNewSource === 3" :span="24">
+ <el-form-item label="鍏朵粬鏉ユ簮鍚嶇О锛�" prop="searchNewWebsite">
+ <el-input v-model="form.searchNewWebsite" size="small" placeholder="閫夊~锛屾棤闇�濉啓缃戝潃"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col v-if="form.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬'" :span="12">
<el-form-item label="鏂版爣鍑嗗悕绉帮細" prop="newMethodName">
<el-input v-model="form.newMethodName" size="small"></el-input>
</el-form-item>
</el-col>
- <el-col v-if="form.isNewStandard == 1" :span="8">
+ <el-col v-if="form.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬'" :span="12">
<el-form-item label="鏂版爣鍑嗗彿锛�" prop="newStandardNo">
<el-input v-model="form.newStandardNo" size="small"></el-input>
</el-form-item>
@@ -87,6 +75,8 @@
import {
updateMethodSearchNew
} from '@/api/cnas/process/method/standardNoveltyRetrieval'
+import useUserStore from '@/store/modules/user'
+import { calculateNextSearchDate, isSearchRetired, searchResultOptions, searchSourceOptions } from '../options'
export default {
name: 'FormDialog',
@@ -96,6 +86,8 @@
// 杩欓噷瀛樻斁鏁版嵁
return {
formDia: false,
+ searchResultOptions,
+ searchSourceOptions,
form: {
methodName: '',
standardNo: '',
@@ -103,18 +95,20 @@
newMethodName: '',
newStandardNo: '',
searchNewTime: '',
+ nextSearchDate: '',
searchNewResult: '',
searchNewUserName: '',
searchNewWebsite: '',
searchNewSource: '',
- remark: '',
fileNo: '',
},
formRules: {
methodName: [{required: true, message: '璇峰~鍐欐爣鍑嗗悕绉�',trigger: 'blur'}],
standardNo: [{required: true, message: '璇峰~鍐欐爣鍑嗗彿',trigger: 'blur'}],
- newMethodName: [{required: false, message: '璇峰~鍐欐柊鏍囧噯鍚嶇О',trigger: 'blur'}],
- newStandardNo: [{required: false, message: '璇峰~鍐欐柊鏍囧噯鍙�',trigger: 'blur'}],
+ newMethodName: [{required: true, message: '璇峰~鍐欐柊鏍囧噯鍚嶇О',trigger: 'blur'}],
+ newStandardNo: [{required: true, message: '璇峰~鍐欐柊鏍囧噯鍙�',trigger: 'blur'}],
+ searchNewTime: [{required: true, message: '璇烽�夋嫨鏌ユ柊鏃ユ湡',trigger: 'change'}],
+ searchNewResult: [{required: true, message: '璇烽�夋嫨鏌ユ柊缁撴灉',trigger: 'change'}],
searchNewSource: [{required: true, message: '璇烽�夋嫨鏌ユ柊璁板綍鏉ユ簮',trigger: 'change'}],
fileNo: [{required: true, message: '璇峰~鍐欐枃浠跺彿',trigger: 'blur'}],
},
@@ -122,11 +116,40 @@
info: {},
};
},
+ computed: {
+ isSearchRetired() {
+ return isSearchRetired(this.form.searchNewResult)
+ },
+ currentUserName() {
+ const user = useUserStore()
+ return user.nickName || user.name || user.userName
+ }
+ },
// 鏂规硶闆嗗悎
methods: {
openDia(row) {
this.formDia = true
- this.form = {...row, isNewStandard: 1}
+ this.form = {
+ ...row,
+ searchNewTime: '',
+ nextSearchDate: '',
+ searchNewResult: '',
+ searchNewSource: null,
+ searchNewWebsite: '',
+ newMethodName: '',
+ newStandardNo: ''
+ }
+ },
+ refreshDefaultNextSearchDate() {
+ this.form.nextSearchDate = this.isSearchRetired ? null
+ : calculateNextSearchDate(this.form.searchNewTime)
+ },
+ handleSearchResultChange() {
+ if (this.isSearchRetired) {
+ this.form.nextSearchDate = null
+ } else if (!this.form.nextSearchDate) {
+ this.refreshDefaultNextSearchDate()
+ }
},
handleEdit() {
this.$refs['form'].validate((valid) => {
@@ -134,13 +157,14 @@
this.editLoad = true
const processMethodSearchNews = this.HaveJson(this.form)
delete processMethodSearchNews.createTime
+ processMethodSearchNews.searchNewTime = `${processMethodSearchNews.searchNewTime} 00:00:00`
if (processMethodSearchNews.searchNewSource !== 3) {
processMethodSearchNews.searchNewWebsite = null
}
updateMethodSearchNew(processMethodSearchNews).then(res => {
this.editLoad = false
if (res.code === 200){
- this.$message.success('鎿嶄綔鎴愬姛')
+ this.$message.success('鏌ユ柊璁板綍宸蹭繚瀛�')
this.closeDia()
}
}).catch(err => {
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
index 784cd5f..5f666ba 100644
--- a/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/component/FormDialog.vue
@@ -14,20 +14,33 @@
</div>
<el-row :gutter="20">
<el-col :span="12">
- <el-form-item :prop="`taskRel.${index}.newMethodName`" :rules="{required: true, message: '璇峰~鍐欐爣鍑嗗悕绉�',trigger: 'blur',}" label="鏂版爣鍑嗗悕绉帮細">
- <el-input v-model="items.newMethodName" size="small"></el-input>
+ <el-form-item :prop="`taskRel.${index}.methodName`" :rules="{required: true, message: '璇峰~鍐欐爣鍑嗗悕绉�',trigger: 'blur',}" label="鏍囧噯鍚嶇О锛�">
+ <el-input v-model="items.methodName" size="small"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item :prop="`taskRel.${index}.newStandardNo`" :rules="{required: true,message: '璇峰~鍐欐爣鍑嗗彿',trigger: 'blur',}" label="鏂版爣鍑嗗彿锛�">
- <el-input v-model="items.newStandardNo" size="small"></el-input>
+ <el-form-item :prop="`taskRel.${index}.standardNo`" :rules="{required: true,message: '璇峰~鍐欐爣鍑嗗彿',trigger: 'blur',}" label="鏍囧噯鍙凤細">
+ <el-input v-model="items.standardNo" size="small"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
- <el-form-item :prop="`taskRel.${index}.searchNewTime`" label="鏌ユ柊鏃堕棿锛�">
- <el-date-picker v-model="items.searchNewTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
- format="YYYY-MM-DD HH:mm:ss" placeholder="璇烽�夋嫨" size="small"
- style="width: 100%;"></el-date-picker>
+ <el-form-item :prop="`taskRel.${index}.fileNo`" :rules="{required: true,message: '璇峰~鍐欐枃浠剁紪鍙�',trigger: 'blur',}" label="鏂囦欢缂栧彿锛�">
+ <el-input v-model="items.fileNo" size="small"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item :prop="`taskRel.${index}.searchNewTime`" :rules="{required: true,message: '璇烽�夋嫨鏌ユ柊鏃ユ湡',trigger: 'change',}" label="鏌ユ柊鏃ユ湡锛�">
+ <el-date-picker v-model="items.searchNewTime" type="date" value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD" placeholder="璇烽�夋嫨鏃ユ湡" size="small"
+ style="width: 100%;" @change="refreshDefaultNextSearchDate(items)"></el-date-picker>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="涓嬫鏌ユ柊鏃ユ湡锛�">
+ <el-input v-if="isSearchRetired(items.searchNewResult)" model-value="涓嶉�傜敤" size="small" disabled />
+ <el-date-picker v-else v-model="items.nextSearchDate" type="date" value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD" placeholder="榛樿涓変釜鏈堝悗锛屽彲淇敼" size="small"
+ style="width: 100%;" />
</el-form-item>
</el-col>
<el-col :span="12">
@@ -35,34 +48,35 @@
<el-input :model-value="currentUserName" size="small" disabled></el-input>
</el-form-item>
</el-col>
- <el-col :span="24">
- <el-form-item :prop="`taskRel.${index}.searchNewResult`" label="鏌ユ柊缁撴灉锛�">
- <el-input v-model="items.searchNewResult" type="textarea" :rows="2" size="small"></el-input>
+ <el-col :span="12">
+ <el-form-item :prop="`taskRel.${index}.searchNewResult`" :rules="{required: true,message: '璇烽�夋嫨鏌ユ柊缁撴灉',trigger: 'change',}" label="鏌ユ柊缁撴灉锛�">
+ <el-select v-model="items.searchNewResult" placeholder="璇烽�夋嫨" style="width: 100%"
+ @change="handleSearchResultChange(items)">
+ <el-option v-for="result in searchResultOptions" :key="result" :label="result" :value="result" />
+ </el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item :prop="`taskRel.${index}.searchNewSource`" :rules="{required: true,message: '璇烽�夋嫨鏌ユ柊璁板綍鏉ユ簮',trigger: 'change',}" label="鏌ユ柊璁板綍鏉ユ簮锛�">
<el-radio-group v-model="items.searchNewSource">
- <el-radio :value="0">鏍囧噯缃�</el-radio>
- <el-radio :value="1">濮旀墭鎯呮姤</el-radio>
- <el-radio :value="2">鏍囧噯鏁�</el-radio>
- <el-radio :value="3">鍏朵粬</el-radio>
+ <el-radio v-for="source in searchSourceOptions" :key="source.value" :value="source.value">{{ source.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col v-if="items.searchNewSource === 3" :span="24">
<el-form-item :prop="`taskRel.${index}.searchNewWebsite`"
- :rules="{required: true, message: '璇峰~鍐欏叿浣撶綉鍧�鎴栫綉绔欏悕绉�', trigger: 'blur'}"
- label="鏉ユ簮缃戝潃/缃戠珯鍚嶇О锛�">
- <el-input v-model="items.searchNewWebsite" size="small" placeholder="璇疯緭鍏ュ叿浣撶綉鍧�鎴栫綉绔欏悕绉�"></el-input>
+ label="鍏朵粬鏉ユ簮鍚嶇О锛�">
+ <el-input v-model="items.searchNewWebsite" size="small" placeholder="閫夊~锛屾棤闇�濉啓缃戝潃"></el-input>
</el-form-item>
</el-col>
- <el-col :span="12">
- <el-form-item :prop="`taskRel.${index}.remark`" :rules="{required: false,message: '璇烽�夋嫨澶囨敞',trigger: 'change',}" label="澶囨敞锛�">
- <el-select v-model="items.remark" clearable size="small" style="width: 100%;">
- <el-option :value="0" label="浣滃簾"></el-option>
- <el-option :value="1" label="鏇挎崲"></el-option>
- </el-select>
+ <el-col v-if="items.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬'" :span="12">
+ <el-form-item :prop="`taskRel.${index}.newMethodName`" :rules="{required: true,message: '璇峰~鍐欐柊鏍囧噯鍚嶇О',trigger: 'blur',}" label="鏂版爣鍑嗗悕绉帮細">
+ <el-input v-model="items.newMethodName" size="small"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col v-if="items.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬'" :span="12">
+ <el-form-item :prop="`taskRel.${index}.newStandardNo`" :rules="{required: true,message: '璇峰~鍐欐柊鏍囧噯鍙�',trigger: 'blur',}" label="鏂版爣鍑嗗彿锛�">
+ <el-input v-model="items.newStandardNo" size="small"></el-input>
</el-form-item>
</el-col>
</el-row>
@@ -83,6 +97,7 @@
<script>
import { addMethodSearchNew } from '@/api/cnas/process/method/standardNoveltyRetrieval'
import useUserStore from '@/store/modules/user'
+import { calculateNextSearchDate, isSearchRetired, searchResultOptions, searchSourceOptions } from '../options'
export default {
name: 'FormDialog',
@@ -92,16 +107,21 @@
// 杩欓噷瀛樻斁鏁版嵁
return {
formDia: false,
+ searchResultOptions,
+ searchSourceOptions,
form: {
taskRel: [
{
- newMethodName: '',
- newStandardNo: '',
+ methodName: '',
+ standardNo: '',
+ fileNo: '',
searchNewTime: '',
+ nextSearchDate: '',
searchNewResult: '',
searchNewWebsite: '',
searchNewSource: '',
- remark: '',
+ newMethodName: '',
+ newStandardNo: '',
}
]
},
@@ -118,12 +138,26 @@
},
// 鏂规硶闆嗗悎
methods: {
+ isSearchRetired,
openDia (row) {
this.formDia = true
},
// 娣诲姞涓�鏉�
addBtn() {
- this.form.taskRel.push({ newMethodName: '', newStandardNo:'', searchNewTime: '', searchNewResult: '', searchNewWebsite: '', searchNewSource: '', remark: ''});
+ this.form.taskRel.push({ methodName: '', standardNo: '', fileNo: '', searchNewTime: '',
+ nextSearchDate: '', searchNewResult: '', searchNewWebsite: '', searchNewSource: '',
+ newMethodName: '', newStandardNo: '' });
+ },
+ refreshDefaultNextSearchDate(item) {
+ item.nextSearchDate = isSearchRetired(item.searchNewResult) ? null
+ : calculateNextSearchDate(item.searchNewTime)
+ },
+ handleSearchResultChange(item) {
+ if (isSearchRetired(item.searchNewResult)) {
+ item.nextSearchDate = null
+ } else if (!item.nextSearchDate) {
+ this.refreshDefaultNextSearchDate(item)
+ }
},
// 鍒犻櫎涓�鏉�
deleteHeaderRow (index) {
@@ -135,7 +169,10 @@
this.editLoad = true
const records = this.form.taskRel.map(item => ({
...item,
- searchNewWebsite: item.searchNewSource === 3 ? item.searchNewWebsite : null
+ searchNewTime: `${item.searchNewTime} 00:00:00`,
+ searchNewWebsite: item.searchNewSource === 3 ? item.searchNewWebsite : null,
+ newMethodName: item.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬' ? item.newMethodName : null,
+ newStandardNo: item.searchNewResult === '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬' ? item.newStandardNo : null
}))
addMethodSearchNew(records).then(res => {
this.editLoad = false
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue b/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
index 8ea5d96..03a091b 100644
--- a/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/index.vue
@@ -13,6 +13,7 @@
</div>
</div>
<div style="line-height: 30px;">
+ <el-button size="small" @click="openAllHistory">鏌ユ柊璁板綍</el-button>
<el-button size="small" type="primary" style="margin-left: 10px;"
@click="$refs.importDialog.open()">瀵煎叆</el-button>
<el-button size="small" style="margin-left: 10px;" type="primary" @click="openFormDia">鏂� 澧�</el-button>
@@ -26,6 +27,36 @@
</div>
<FormDialog v-if="formDialog" ref="formDialog" @closeDia="closeDia"></FormDialog>
<EditFormDia v-if="editFormDialog" ref="editFormDialog" @closeEditDia="closeEditDia"></EditFormDia>
+ <el-dialog v-model="historyDialog" :title="`${historyStandard} 路 鏌ユ柊璁板綍`" width="960px">
+ <div v-if="historyScopeId === null" style="display: flex; gap: 8px; margin-bottom: 12px;">
+ <el-input v-model="historySearchNo" clearable placeholder="鎸夋爣鍑嗗彿鏌ヨ" style="width: 260px"
+ @keyup.enter="searchAllHistory" />
+ <el-button type="primary" @click="searchAllHistory">鏌ヨ</el-button>
+ </div>
+ <el-table v-loading="historyLoading" :data="historyRecords" border>
+ <el-table-column prop="methodName" label="鏍囧噯鍚嶇О" min-width="160" />
+ <el-table-column prop="standardNo" label="鏍囧噯鍙�" min-width="135" />
+ <el-table-column prop="fileNo" label="鏂囦欢缂栧彿" min-width="120" />
+ <el-table-column prop="searchNewDate" label="鏌ユ柊鏃ユ湡" width="115" />
+ <el-table-column prop="nextSearchDate" label="涓嬫鏌ユ柊鏃ユ湡" width="125" />
+ <el-table-column prop="searchNewResult" label="鏌ユ柊缁撴灉" width="190" />
+ <el-table-column label="鏌ユ柊鏉ユ簮" min-width="210">
+ <template #default="scope">
+ {{ displaySearchSource(scope.row.searchNewSource) }}
+ <span v-if="scope.row.searchNewWebsite">锛坽{ scope.row.searchNewWebsite }}锛�</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="searchNewUserName" label="鏌ユ柊浜�" width="110" />
+ <el-table-column prop="newMethodName" label="鏂扮増鏍囧噯鍚嶇О" min-width="150" />
+ <el-table-column prop="newStandardNo" label="鏂扮増鏍囧噯鍙�" min-width="135" />
+ <el-table-column prop="createTime" label="鎻愪氦鏃堕棿" width="165" />
+ </el-table>
+ <el-empty v-if="!historyLoading && historyRecords.length === 0" description="鏆傛棤鏌ユ柊璁板綍" />
+ <el-pagination v-if="historyScopeId === null" v-model:current-page="historyPage.current"
+ v-model:page-size="historyPage.size" :total="historyPage.total"
+ layout="total, prev, pager, next" style="margin-top: 12px; justify-content: flex-end;"
+ @current-change="loadHistory" />
+ </el-dialog>
<import-dialog
ref="importDialog"
title="瀵煎叆鏍囧噯鏌ユ柊"
@@ -35,9 +66,9 @@
template-name="鏍囧噯鏌ユ柊瀵煎叆妯℃澘.xlsx"
:tips="[
'琛ㄥご涓轰袱琛岋紝璇蜂粠绗� 3 琛屽紑濮嬪~鍐欐暟鎹�',
- '鏍囧噯鍚嶇О銆佹爣鍑嗗彿璇峰~鍐欑幇琛屾爣鍑嗙殑鍚嶇О鍜岀紪鍙�',
- '鏌ユ柊鏉ユ簮鎸夆�滄爣鍑嗙綉 鈫� 濮旀墭鎯呮姤鎵� 鈫� 鏍囧噯涔﹀簵 鈫� 鍏朵粬鈥濈殑椤哄簭鍙栫涓�涓潪绌洪」',
- '澶囨敞鍒楀彧鑳藉~鍐欌�滄浛鎹⑩�濇垨鈥滀綔搴熲�濓紝鐣欑┖琛ㄧず鏃犲娉�'
+ '鏍囧噯鍚嶇О銆佹爣鍑嗗彿璇峰~鍐欐湰娆℃煡鏂扮殑鏍囧噯淇℃伅',
+ '鏌ユ柊鏃ユ湡鏍煎紡涓� YYYY-MM-DD锛屾煡鏂扮粨鏋滃~鍐欑幇琛屾湁鏁堛�佸凡淇/鏈夋柊鐗堟湰鏇夸唬銆佸簾姝紙鏃犳浛浠o級鎴栧嵆灏嗗疄鏂�',
+ '鍏釜鏌ユ柊鏉ユ簮鍒椾腑鍙兘濉啓涓�涓紝濉啓鈥溾垰鈥濊〃绀洪�変腑'
]"
@success="searchList"
/>
@@ -50,8 +81,10 @@
import ImportDialog from '@/components/ImportDialog/index.vue'
import FormDialog from './component/FormDialog.vue';
import EditFormDia from './component/EditFormDia.vue';
+import { displayDate, displaySearchSource } from './options'
import {
- delMethodSearchNew,
+ listSearchNewHistory,
+ pageSearchNewHistory,
pageMethodSearchNew
} from '@/api/cnas/process/method/standardNoveltyRetrieval'
@@ -67,6 +100,13 @@
data() {
// 杩欓噷瀛樻斁鏁版嵁
return {
+ historyDialog: false,
+ historyLoading: false,
+ historyRecords: [],
+ historyStandard: '',
+ historyScopeId: null,
+ historySearchNo: '',
+ historyPage: { current: 1, size: 10, total: 0 },
searchForm: {
standardNo: ''
},
@@ -87,48 +127,15 @@
minWidth: '100'
},
{
- dataType: 'tag',
- label: '鏄惁鏄柊鏍囧噯',
- prop: 'isNewStandard',
- minWidth: '100',
- formatData: (params) => {
- if (params == 0) {
- return '鍚�';
- } else if (params == 1) {
- return '鏄�';
- } else {
- return null
- }
- },
- formatType: (params) => {
- if (params == 0) {
- return 'danger';
- } else if (params == 1) {
- return 'success';
- } else {
- return null
- }
- }
- },
- {
- label: '鏂版爣鍑嗗悕绉�',
- prop: 'newMethodName',
- minWidth: '100'
- },
- {
- label: '鏂版爣鍑嗗彿',
- prop: 'newStandardNo',
- minWidth: '100'
- },
- {
- label: '鏌ユ柊鏃堕棿',
+ label: '鏈�杩戞煡鏂版棩鏈�',
prop: 'searchNewTime',
- minWidth: '150'
+ minWidth: '125',
+ formatData: displayDate
},
{
label: '鏌ユ柊缁撴灉',
prop: 'searchNewResult',
- minWidth: '140'
+ minWidth: '190'
},
{
label: '鏌ユ柊浜�',
@@ -136,65 +143,20 @@
minWidth: '100'
},
{
- dataType: 'tag',
label: '鏌ユ柊璁板綍鏉ユ簮',
prop: 'searchNewSource',
- minWidth: '100',
- formatData: (params) => {
- if (params == 0) {
- return '鏍囧噯缃�';
- } else if (params == 1) {
- return '濮旀墭鎯呮姤';
- } else if (params == 2) {
- return '鏍囧噯鏁�';
- } else if (params == 3) {
- return '鍏朵粬';
- } else {
- return null
- }
- },
- formatType: (params) => {
- if (params == 0) {
- return 'success';
- } else if (params == 1) {
- return 'danger';
- } else if (params == 2) {
- return 'warning';
- } else if (params == 3) {
- return 'info';
- } else {
- return null
- }
- }
+ minWidth: '180',
+ formatData: displaySearchSource
},
{
- label: '鏉ユ簮缃戝潃/缃戠珯鍚嶇О',
+ label: '鍏朵粬鏉ユ簮鍚嶇О',
prop: 'searchNewWebsite',
minWidth: '150'
},
+ { label: '涓嬫鏌ユ柊鏃ユ湡', prop: 'nextSearchDate', minWidth: '125', formatData: displayDate },
{
- dataType: 'tag',
- label: '澶囨敞',
- prop: 'remark',
- minWidth: '100',
- formatData: (params) => {
- if (params == 0) {
- return '浣滃簾';
- } else if (params == 1) {
- return '鏇挎崲';
- } else {
- return null
- }
- },
- formatType: (params) => {
- if (params == 0) {
- return 'danger';
- } else if (params == 1) {
- return 'success';
- } else {
- return null
- }
- }
+ dataType: 'tag', label: '鏌ユ柊鐘舵��', prop: 'searchDueStatus', minWidth: '100',
+ formatType: value => value === '宸查�炬湡' ? 'danger' : value === '浠婃棩鍒版湡' ? 'warning' : 'success'
},
{
dataType: 'action',
@@ -202,17 +164,17 @@
label: '鎿嶄綔',
operation: [
{
- name: '缂栬緫',
+ name: '鏌ユ柊',
type: 'text',
clickFun: (row) => {
this.openEditFormDia(row);
},
},
{
- name: '鍒犻櫎',
+ name: '鏈爣鍑嗚褰�',
type: 'text',
clickFun: (row) => {
- this.handleDelete(row);
+ this.openHistory(row);
},
},
]
@@ -234,6 +196,43 @@
},
// 鏂规硶闆嗗悎
methods: {
+ displaySearchSource,
+ openAllHistory() {
+ this.historyStandard = '鍏ㄩ儴鏍囧噯'
+ this.historyScopeId = null
+ this.historySearchNo = ''
+ this.historyPage.current = 1
+ this.historyRecords = []
+ this.historyDialog = true
+ this.loadHistory()
+ },
+ searchAllHistory() {
+ this.historyPage.current = 1
+ this.loadHistory()
+ },
+ openHistory(row) {
+ this.historyStandard = row.standardNo || row.methodName
+ this.historyScopeId = row.methodSearchNewId
+ this.historyRecords = []
+ this.historyDialog = true
+ this.loadHistory()
+ },
+ loadHistory() {
+ this.historyLoading = true
+ const request = this.historyScopeId === null
+ ? pageSearchNewHistory({ standardNo: this.historySearchNo,
+ current: this.historyPage.current, size: this.historyPage.size })
+ : listSearchNewHistory({ methodSearchNewId: this.historyScopeId })
+ request.then(res => {
+ if (res.code !== 200) return
+ if (this.historyScopeId === null) {
+ this.historyRecords = res.data?.records || []
+ this.historyPage.total = res.data?.total || 0
+ } else {
+ this.historyRecords = res.data || []
+ }
+ }).finally(() => { this.historyLoading = false })
+ },
// 鏌ヨ鍒楄〃
searchList() {
this.tableLoading = true
@@ -278,24 +277,10 @@
this.editFormDialog = false
this.searchList()
},
- // 鍒犻櫎鏍囧噯鏌ユ柊璁板綍
- handleDelete(row) {
- this.$confirm('鏄惁鍒犻櫎璇ユ潯鏌ユ柊璁板綍?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- delMethodSearchNew({ methodSearchNewId: row.methodSearchNewId }).then(res => {
- if (res.code !== 200) return
- this.$message.success('鍒犻櫎鎴愬姛')
- this.searchList()
- })
- }).catch(() => {
- })
- },
// 鍒嗛〉
pagination(page) {
this.page.size = page.limit
+ this.page.current = page.page
this.searchList();
},
},
diff --git a/src/views/CNAS/process/method/standardNoveltyRetrieval/options.js b/src/views/CNAS/process/method/standardNoveltyRetrieval/options.js
new file mode 100644
index 0000000..e6fc632
--- /dev/null
+++ b/src/views/CNAS/process/method/standardNoveltyRetrieval/options.js
@@ -0,0 +1,36 @@
+import dayjs from 'dayjs'
+
+export const searchResultOptions = ['鐜拌鏈夋晥', '宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬', '搴熸锛堟棤鏇夸唬锛�', '鍗冲皢瀹炴柦']
+
+export function isSearchRetired(searchNewResult) {
+ return ['宸蹭慨璁�/鏈夋柊鐗堟湰鏇夸唬', '搴熸锛堟棤鏇夸唬锛�'].includes(searchNewResult)
+}
+
+export function calculateNextSearchDate(searchNewTime) {
+ if (!searchNewTime) return ''
+ const date = dayjs(searchNewTime)
+ return date.isValid() ? date.add(3, 'month').format('YYYY-MM-DD') : ''
+}
+
+export const searchSourceOptions = [
+ { value: 4, label: '涓浗鏍囧噯鍖栧鍛樹細' },
+ { value: 5, label: '鍥藉甯傚満鐩戠潱绠$悊鎬诲眬' },
+ { value: 6, label: '鍏ㄥ浗鏍囧噯淇℃伅鍏叡鏈嶅姟骞冲彴' },
+ { value: 7, label: '鍥藉鏍囧噯鍏ㄦ枃鍏紑绯荤粺' },
+ { value: 8, label: '宸ユ爣缃�' },
+ { value: 3, label: '鍏朵粬' }
+]
+
+const legacySearchSources = {
+ 0: '鏍囧噯缃戯紙鍘嗗彶鏉ユ簮锛�',
+ 1: '濮旀墭鎯呮姤鎵�锛堝巻鍙叉潵婧愶級',
+ 2: '鏍囧噯涔﹀簵锛堝巻鍙叉潵婧愶級'
+}
+
+export function displaySearchSource(value) {
+ return searchSourceOptions.find(item => item.value === value)?.label || legacySearchSources[value] || ''
+}
+
+export function displayDate(value) {
+ return value ? String(value).slice(0, 10) : ''
+}
diff --git a/src/views/business/reportPreparation/index.vue b/src/views/business/reportPreparation/index.vue
index 495f00f..c0669fc 100644
--- a/src/views/business/reportPreparation/index.vue
+++ b/src/views/business/reportPreparation/index.vue
@@ -165,7 +165,7 @@
<div class="seal-select-block" v-loading="sealLoading">
<div class="seal-select-title">
<span>鎸変綅缃�夋嫨鍗扮珷</span>
- <span class="seal-select-tip">鑷姩鍖归厤 MA绔� / 1鍙风珷 / 楠戠紳绔狅紝姣忛」鍙崟鐙皟鏁存垨娓呯┖</span>
+ <span class="seal-select-tip">鑷姩鍖归厤 MA绔� / 1鍙风珷 / 妫�楠屾娴嬬被鍗扮珷锛屾瘡椤瑰彲鍗曠嫭璋冩暣鎴栨竻绌�</span>
</div>
<div v-if="sealOptions.length" class="seal-position-grid">
<div v-for="position in sealPositions" :key="position.key" class="seal-position-card">
@@ -1290,7 +1290,8 @@
const reportSeal = this.sealOptions.find(item => item.name === '1鍙风珷')
|| this.sealOptions.find(item => !String(item.name).toUpperCase().includes('MA') && !String(item.name).includes('楠戠紳'))
|| this.sealOptions[0]
- const seamSeal = this.sealOptions.find(item => String(item.name).includes('楠戠紳'))
+ const seamSeal = this.sealOptions.find(item => /妫�楠屾娴媩妫�娴嬫楠�/.test(String(item.name || '')))
+ || this.sealOptions.find(item => String(item.name).includes('楠戠紳'))
this.selectedSealPositions = {
maSealId: availableIds.includes(Number(row && row.maSealId))
? Number(row.maSealId) : (maSeal ? Number(maSeal.id) : null),
diff --git a/src/views/structural/sealManage/usageLedger/index.vue b/src/views/structural/sealManage/usageLedger/index.vue
index 665d47c..bbd2bf1 100644
--- a/src/views/structural/sealManage/usageLedger/index.vue
+++ b/src/views/structural/sealManage/usageLedger/index.vue
@@ -35,18 +35,10 @@
v-hasPermi="['structural:sealUsageLedger:export']"
type="primary"
size="small"
- :disabled="selection.length === 0 || exportLoading || submitLoading"
- :loading="selectedExportLoading"
- @click="exportSelected"
- >鍕鹃�夊鍑�</el-button>
- <el-button
- v-hasPermi="['structural:sealUsageLedger:export']"
- type="primary"
- size="small"
:disabled="exportLoading || submitLoading"
- :loading="filteredExportLoading"
- @click="exportFiltered"
- >鎸夋潯浠跺鍑�</el-button>
+ :loading="exportLoading"
+ @click="exportLedger"
+ >瀵煎嚭</el-button>
</div>
<lims-table
@@ -125,8 +117,7 @@
tableData: [],
selection: [],
tableLoading: false,
- selectedExportLoading: false,
- filteredExportLoading: false,
+ exportLoading: false,
copiesDialogVisible: false,
submitLoading: false,
copiesForm: { id: null, reportCode: '', copies: 1, version: 0 },
@@ -144,11 +135,6 @@
{ label: '浠芥暟', prop: 'copies', dataType: 'slot', slot: 'copies', width: '120px' },
{ label: '鐢ㄥ嵃浜虹瀛�', prop: 'useUserName', width: '140px' }
]
- }
- },
- computed: {
- exportLoading() {
- return this.selectedExportLoading || this.filteredExportLoading
}
},
mounted() {
@@ -221,19 +207,15 @@
})
})
},
- exportSelected() {
- if (!this.selection.length) {
- this.$message.warning('璇烽�夋嫨瑕佸鍑虹殑璁板綍')
- return
- }
- this.selectedExportLoading = true
- this.downloadWord({ mode: 'selected', ids: this.selection.map(item => item.id) })
- .finally(() => { this.selectedExportLoading = false })
- },
- exportFiltered() {
- this.filteredExportLoading = true
- this.downloadWord({ mode: 'filtered', query: this.buildQuery() })
- .finally(() => { this.filteredExportLoading = false })
+ exportLedger() {
+ if (this.exportLoading || this.submitLoading) return
+ const payload = this.selection.length
+ ? { mode: 'selected', ids: this.selection.map(item => item.id) }
+ : { mode: 'filtered', query: this.buildQuery() }
+ this.exportLoading = true
+ this.downloadWord(payload)
+ .catch(() => {})
+ .finally(() => { this.exportLoading = false })
},
downloadWord(payload) {
return exportSealUsageLedger(payload).then(async data => {
diff --git a/vite/plugins/index.js b/vite/plugins/index.js
index e12cea1..833d84f 100644
--- a/vite/plugins/index.js
+++ b/vite/plugins/index.js
@@ -4,9 +4,10 @@
import createSvgIcon from './svg-icon'
import createCompression from './compression'
import createSetupExtend from './setup-extend'
+import superdocHttpWorker from './superdoc-http-worker.js'
export default function createVitePlugins(viteEnv, isBuild = false) {
- const vitePlugins = [vue()]
+ const vitePlugins = [vue(), superdocHttpWorker()]
vitePlugins.push(createAutoImport())
vitePlugins.push(createSetupExtend())
vitePlugins.push(createSvgIcon(isBuild))
--
Gitblit v1.9.3