feat(cnas-search): 1.标准查新模块
2.印章使用记录
| | |
| | | # æä»¶è®¿é®ä¸æ®éæ¥å£ç»ä¸èµ°æ¬å°å¼å代ç |
| | | VITE_APP_BASE_URL = '/dev-api' |
| | | |
| | | # OnlyOffice ææ¡£æå¡å°åï¼é¢è§ pdf ç¨ï¼æ²¡æ http:// åç¼ä¼å½æç¸å¯¹è·¯å¾ï¼ |
| | | # OnlyOffice ææ¡£æå¡å°åï¼Word çææ¡£çå¨çº¿é¢è§ä¸ç¼è¾ï¼PDF ä½¿ç¨æµè§å¨åçé¢è§ï¼ |
| | | VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001' |
| | | |
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli |
| | |
| | | # ç产ç¯å¢ip+ç«¯å£ |
| | | VITE_APP_BASE_URL = 'http://192.168.21.53:8001/lims' |
| | | |
| | | # OnlyOffice ææ¡£æå¡å°åï¼é¢è§ pdf ç¨ï¼æ²¡æ http:// åç¼ä¼å½æç¸å¯¹è·¯å¾ï¼ |
| | | # OnlyOffice ææ¡£æå¡å°åï¼Word çææ¡£çå¨çº¿é¢è§ä¸ç¼è¾ï¼PDF ä½¿ç¨æµè§å¨åçé¢è§ï¼ |
| | | VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001' |
| | | |
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli |
| | |
| | | # æµè¯ç¯å¢ip+ç«¯å£ |
| | | VITE_APP_BASE_URL = '/stage-api' |
| | | |
| | | # OnlyOffice ææ¡£æå¡å°åï¼é¢è§ pdf ç¨ï¼æ²¡æ http:// åç¼ä¼å½æç¸å¯¹è·¯å¾ï¼ |
| | | # OnlyOffice ææ¡£æå¡å°åï¼Word çææ¡£çå¨çº¿é¢è§ä¸ç¼è¾ï¼PDF ä½¿ç¨æµè§å¨åçé¢è§ï¼ |
| | | VITE_APP_ONLYOFFICE_API = 'http://192.168.21.53:9001' |
| | | |
| | | # æ¯å¦å¨æå
æ¶å¼å¯åç¼©ï¼æ¯æ gzip å brotli |
| | |
| | | }); |
| | | } |
| | | |
| | | // æ¥è¯¢ç±æ åç»´æ¤èªå¨å½æ¡£çè®°å½ |
| | | 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, |
| | | }); |
| | |
| | | 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>æ£å¨è¿æ¥ææ¡£æå¡å¹¶å è½½æ¥å...</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; |
| | |
| | | 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); |
| | | }); |
| | | // å 载失败åå
è®¸ä¸æ¬¡éè¯ |
| | |
| | | export default { |
| | | name: "VabOnlyOffice", |
| | | props: ['options'], |
| | | emits: ['ready', 'error'], |
| | | data() { |
| | | return { |
| | | editorId: `onlyoffice-${this._uid || Math.random().toString(36).slice(2)}`, |
| | | doctype: "", |
| | | docEditor: null, |
| | | //åèvabOnlyOfficeç»ä»¶åæ°é
ç½® |
| | | 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: { |
| | |
| | | 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() { |
| | |
| | | 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: { |
| | | //åç¼ |
| | |
| | | //å®å¶ |
| | | customization: { |
| | | autosave: true, //æ¯å¦èªå¨ä¿å |
| | | forcesave: true, //ç¹å»ä¿åæ¶ç«å³åè°ä¸å¡æå¡ |
| | | chat: true, |
| | | comments: false, |
| | | help: false, |
| | |
| | | }, |
| | | 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}` : 'æ¥åå 载失败ï¼è¯·æ£æ¥ææ¡£æå¡', 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('æ¥åå è½½è¶
æ¶ï¼è¯·æ£æ¥ææ¡£æå¡ä¸æ¥åå°å', 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) { |
| | |
| | | <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; |
| | |
| | | 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' |
| | | |
| | |
| | | }), |
| | | documentMode: 'editing', |
| | | role: 'editor', |
| | | workerUrls: { document: documentWorkerUrl }, |
| | | telemetry: { enabled: false }, |
| | | ui: { toolbar: { container: toolbar.value, strings: superdocToolbarZh }, ruler: true, comments: false }, |
| | | onReady: async ({ superdoc }) => { |
| | |
| | | import { installCryptoRandomUUID } from './cryptoRandomUUID' |
| | | |
| | | let modulePromise |
| | | |
| | | // å®¡æ ¸å¼å§æ¶é¢å è½½ï¼ç¼è¾å¨å¤ç¨å䏿¬¡å è½½ï¼å¤±è´¥åä»å
许éè¯ã |
| | | export function loadSuperDoc() { |
| | | if (!modulePromise) { |
| | | installCryptoRandomUUID() |
| | | modulePromise = import('superdoc').catch(error => { |
| | | modulePromise = null |
| | | throw error |
| | |
| | | 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) { |
| | | // æ§æ£éªæ¥åæé¡µç æ¾å¨æµ®å¨ææ¬æ¡ä¸ï¼SuperDoc éæ°å页æ¶ä¼ä¸¢å¤± Word çæ¨ªåéç¹ã |
| | |
| | | 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) |
| | |
| | | <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> |
| | |
| | | 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', |
| | |
| | | // è¿éåæ¾æ°æ® |
| | | return { |
| | | formDia: false, |
| | | searchResultOptions, |
| | | searchSourceOptions, |
| | | form: { |
| | | methodName: '', |
| | | standardNo: '', |
| | |
| | | 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'}], |
| | | }, |
| | |
| | | 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) => { |
| | |
| | | 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 => { |
| | |
| | | </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"> |
| | |
| | | <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> |
| | |
| | | <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', |
| | |
| | | // è¿éåæ¾æ°æ® |
| | | return { |
| | | formDia: false, |
| | | searchResultOptions, |
| | | searchSourceOptions, |
| | | form: { |
| | | taskRel: [ |
| | | { |
| | | newMethodName: '', |
| | | newStandardNo: '', |
| | | methodName: '', |
| | | standardNo: '', |
| | | fileNo: '', |
| | | searchNewTime: '', |
| | | nextSearchDate: '', |
| | | searchNewResult: '', |
| | | searchNewWebsite: '', |
| | | searchNewSource: '', |
| | | remark: '', |
| | | newMethodName: '', |
| | | newStandardNo: '', |
| | | } |
| | | ] |
| | | }, |
| | |
| | | }, |
| | | // æ¹æ³éå |
| | | 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) { |
| | |
| | | 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 |
| | |
| | | </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> |
| | |
| | | </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="导å
¥æ 忥æ°" |
| | |
| | | template-name="æ 忥æ°å¯¼å
¥æ¨¡æ¿.xlsx" |
| | | :tips="[ |
| | | '表头为两è¡ï¼è¯·ä»ç¬¬ 3 è¡å¼å§å¡«åæ°æ®', |
| | | 'æ ååç§°ãæ åå·è¯·å¡«åç°è¡æ åçåç§°åç¼å·', |
| | | 'æ¥æ°æ¥æºæâæ åç½ â å§ææ
æ¥æ â æ åä¹¦åº â å
¶ä»âç顺åºå第ä¸ä¸ªé空项', |
| | | '夿³¨ååªè½å¡«åâæ¿æ¢âæâä½åºâï¼ç空表示æ 夿³¨' |
| | | 'æ ååç§°ãæ åå·è¯·å¡«åæ¬æ¬¡æ¥æ°çæ åä¿¡æ¯', |
| | | 'æ¥æ°æ¥ææ ¼å¼ä¸º YYYY-MM-DDï¼æ¥æ°ç»æå¡«åç°è¡ææã已修订/ææ°çæ¬æ¿ä»£ãåºæ¢ï¼æ æ¿ä»£ï¼æå³å°å®æ½', |
| | | 'å
ä¸ªæ¥æ°æ¥æºåä¸åªè½å¡«åä¸ä¸ªï¼å¡«åâââ表示éä¸' |
| | | ]" |
| | | @success="searchList" |
| | | /> |
| | |
| | | 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' |
| | | |
| | |
| | | data() { |
| | | // è¿éåæ¾æ°æ® |
| | | return { |
| | | historyDialog: false, |
| | | historyLoading: false, |
| | | historyRecords: [], |
| | | historyStandard: '', |
| | | historyScopeId: null, |
| | | historySearchNo: '', |
| | | historyPage: { current: 1, size: 10, total: 0 }, |
| | | searchForm: { |
| | | standardNo: '' |
| | | }, |
| | |
| | | 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: 'æ¥æ°äºº', |
| | |
| | | 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', |
| | |
| | | label: 'æä½', |
| | | operation: [ |
| | | { |
| | | name: 'ç¼è¾', |
| | | name: 'æ¥æ°', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.openEditFormDia(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | name: 'æ¬æ åè®°å½', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.handleDelete(row); |
| | | this.openHistory(row); |
| | | }, |
| | | }, |
| | | ] |
| | |
| | | }, |
| | | // æ¹æ³éå |
| | | 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 |
| | |
| | | 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(); |
| | | }, |
| | | }, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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) : '' |
| | | } |
| | |
| | | <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"> |
| | |
| | | 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), |
| | |
| | | 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 |
| | |
| | | tableData: [], |
| | | selection: [], |
| | | tableLoading: false, |
| | | selectedExportLoading: false, |
| | | filteredExportLoading: false, |
| | | exportLoading: false, |
| | | copiesDialogVisible: false, |
| | | submitLoading: false, |
| | | copiesForm: { id: null, reportCode: '', copies: 1, version: 0 }, |
| | |
| | | { label: '份æ°', prop: 'copies', dataType: 'slot', slot: 'copies', width: '120px' }, |
| | | { label: 'ç¨å°äººç¾å', prop: 'useUserName', width: '140px' } |
| | | ] |
| | | } |
| | | }, |
| | | computed: { |
| | | exportLoading() { |
| | | return this.selectedExportLoading || this.filteredExportLoading |
| | | } |
| | | }, |
| | | mounted() { |
| | |
| | | }) |
| | | }) |
| | | }, |
| | | 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 => { |
| | |
| | | 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)) |