资源需求(标准物质相关)模块调整;新增统一附件组件并接入供应商管理与客户满意度;客户满意度表单改客户卡片下拉并关联已完成委托单;预览、图表、导航栏等组件调整
| | |
| | | data: query |
| | | }) |
| | | } |
| | | // æ¥è¯¢å·²å®æå§æåï¼å®¢æ·æ»¡æåº¦ä¸æç¨ï¼ä»
å·²æ£éªï¼ |
| | | export function selectCompletedOrders() { |
| | | return request({ |
| | | url: '/insOrder/selectCompletedOrders', |
| | | method: 'get' |
| | | }) |
| | | } |
| | |
| | | }) |
| | | } |
| | | |
| | | //æ åç©è´¨æ¸
åå½è¿ |
| | | export function returnSubstance(query) { |
| | | // æ¥è¯¢æ åç©è´¨å©ä½å¯é¢ç¨æ°é |
| | | export function getRemainingQuantity(substanceId) { |
| | | return request({ |
| | | url: '/feStandardSubstanceRecord/returnSubstance', |
| | | method: 'post', |
| | | data: query |
| | | url: `/feStandardSubstanceRecord/getRemainingQuantity/${substanceId}`, |
| | | method: 'get' |
| | | }) |
| | | } |
| | | |
| | | |
| | | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div> |
| | | <el-dialog :title="dialogTitle" v-model="visible" width="760px"> |
| | | <div class="attachment-header"> |
| | | <div class="el-upload__tip">{{ tip }}</div> |
| | | <el-upload :action="uploadAction" :headers="uploadHeader" multiple :show-file-list="false" |
| | | :on-success="handleUploadSuccess" :on-error="handleUploadError"> |
| | | <el-button size="small" type="primary">ä¸ä¼ éä»¶</el-button> |
| | | </el-upload> |
| | | </div> |
| | | <el-table :data="attachmentList" border size="small" style="margin-top:12px"> |
| | | <el-table-column label="æä»¶åç§°" prop="fileName" min-width="280" show-overflow-tooltip /> |
| | | <el-table-column label="ä¸ä¼ æ¶é´" prop="createTime" width="170" /> |
| | | <el-table-column label="æä½" width="180"> |
| | | <template #default="scope"> |
| | | <el-button link type="primary" @click="previewFile(scope.row)">é¢è§</el-button> |
| | | <el-button link type="primary" @click="downloadFile(scope.row)">ä¸è½½</el-button> |
| | | <el-button link type="danger" @click="removeFile(scope.row)">å é¤</el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <template #footer> |
| | | <el-button @click="visible = false">å
³ é</el-button> |
| | | </template> |
| | | </el-dialog> |
| | | <el-dialog title="é¢è§éä»¶" v-model="previewVisible" fullscreen append-to-body> |
| | | <file-preview v-if="previewVisible" :file-url="previewUrl" :current-file="previewRow" /> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import request from '@/utils/request' |
| | | import filePreview from '@/components/Preview/filePreview.vue' |
| | | |
| | | /** |
| | | * éç¨é件管çç»ä»¶ï¼ä¸ä¼ / é¢è§ / ä¸è½½ / å é¤ï¼ |
| | | * |
| | | * ç¨æ³ï¼é¡µé¢æä½åæ¾ä¸ä¸ªå
¥å£ï¼åå«è°ç¨æ¬ç»ä»¶çæ¹æ³ï¼ |
| | | * ä¸ä¼ éä»¶ -> this.$refs.xxx.open(row) æå¼éä»¶å¼¹çªï¼å¼¹çªå
å¯ä¸ä¼ ï¼ |
| | | * ä¸è½½éä»¶ -> this.$refs.xxx.downloadAttachments(row) åªæä¸ä¸ªéä»¶ç´æ¥ä¸è½½ï¼å¤ä¸ªæå¼å¼¹çª |
| | | * é¢è§éä»¶ -> this.$refs.xxx.previewAttachments(row) åªæä¸ä¸ªéä»¶ç´æ¥é¢è§ï¼å¤ä¸ªæå¼å¼¹çª |
| | | * |
| | | * å端æ¥å£éæç»ä¸çº¦å®æä¾ï¼åç
§ /supplierManagement çéä»¶æ¥å£ï¼ï¼ |
| | | * ä¸ä¼ ï¼POST {uploadUrl}?{idParam}=主表ID 表ååæ° file |
| | | * å表ï¼GET {selectUrl}?{idParam}=主表ID è¿å [{id, fileName, fileUrl, createTime, ...}] |
| | | * å é¤ï¼DELETE {deleteUrl}?id=éä»¶ID |
| | | */ |
| | | export default { |
| | | name: 'LimsAttachment', |
| | | components: { |
| | | filePreview |
| | | }, |
| | | props: { |
| | | // ä¸ä¼ æ¥å£å°åï¼å¦ /supplierManagement/uploadAttachment |
| | | uploadUrl: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | // æ¥è¯¢éä»¶å表æ¥å£å°å |
| | | selectUrl: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | // å é¤éä»¶æ¥å£å°å |
| | | deleteUrl: { |
| | | type: String, |
| | | required: true |
| | | }, |
| | | // å
³è主表ID卿¥å£éçåæ°åï¼å¦ supplierManagementId |
| | | idParam: { |
| | | type: String, |
| | | default: 'id' |
| | | }, |
| | | // å
³è主表IDå¨è¡æ°æ®éçåæ®µåï¼ä¸ä¼ æ¶é»è®¤ä¸ idParam ç¸å |
| | | idField: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // å¼¹çªæ é¢ä¸è¦æ¾ç¤ºåç§°çè¡å段ï¼å¦ supplierName |
| | | nameField: { |
| | | type: String, |
| | | default: '' |
| | | }, |
| | | // å¼¹çªæ é¢åç¼ |
| | | title: { |
| | | type: String, |
| | | default: 'éä»¶' |
| | | }, |
| | | // å¼¹çªå·¦ä¸è§æç¤ºæå |
| | | tip: { |
| | | type: String, |
| | | default: 'æ¯æä»»ææ ¼å¼æä»¶ï¼å个æä»¶ä¸è¶
è¿200MB' |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | visible: false, |
| | | attachmentList: [], |
| | | currentRow: {}, |
| | | previewVisible: false, |
| | | previewRow: {}, |
| | | previewUrl: '' |
| | | } |
| | | }, |
| | | computed: { |
| | | currentId() { |
| | | const field = this.idField || this.idParam |
| | | return this.currentRow ? this.currentRow[field] : undefined |
| | | }, |
| | | dialogTitle() { |
| | | const name = this.nameField && this.currentRow ? this.currentRow[this.nameField] : '' |
| | | return this.title + (name ? ' - ' + name : '') |
| | | }, |
| | | uploadAction() { |
| | | return this.javaApi + this.uploadUrl + '?' + this.idParam + '=' + this.currentId |
| | | } |
| | | }, |
| | | methods: { |
| | | // æå¼é件管çå¼¹çª |
| | | open(row) { |
| | | this.currentRow = row |
| | | this.visible = true |
| | | this.loadList() |
| | | }, |
| | | // é¢è§éä»¶å
¥å£ï¼åªæä¸ä¸ªéä»¶ç´æ¥é¢è§ï¼å¤ä¸ªæå¼å¼¹çª |
| | | previewAttachments(row) { |
| | | this.queryList(row).then(list => { |
| | | if (!list.length) { |
| | | this.$message.warning('ææ éä»¶') |
| | | } else if (list.length === 1) { |
| | | this.previewFile(list[0]) |
| | | } else { |
| | | this.open(row) |
| | | } |
| | | }) |
| | | }, |
| | | // ä¸è½½éä»¶å
¥å£ï¼åªæä¸ä¸ªéä»¶ç´æ¥ä¸è½½ï¼å¤ä¸ªæå¼å¼¹çª |
| | | downloadAttachments(row) { |
| | | this.queryList(row).then(list => { |
| | | if (!list.length) { |
| | | this.$message.warning('ææ éä»¶') |
| | | } else if (list.length === 1) { |
| | | this.downloadFile(list[0]) |
| | | } else { |
| | | this.open(row) |
| | | } |
| | | }) |
| | | }, |
| | | queryList(row) { |
| | | const field = this.idField || this.idParam |
| | | return request({ |
| | | url: this.selectUrl, |
| | | method: 'get', |
| | | params: { [this.idParam]: row[field] } |
| | | }).then(res => (res && res.data) || []) |
| | | }, |
| | | loadList() { |
| | | this.queryList(this.currentRow).then(list => { |
| | | this.attachmentList = list |
| | | }) |
| | | }, |
| | | handleUploadSuccess(res) { |
| | | if (res.code === 200) { |
| | | this.$message.success('ä¸ä¼ æå') |
| | | this.loadList() |
| | | } else { |
| | | this.$message.error(res.msg || 'ä¸ä¼ 失败') |
| | | } |
| | | }, |
| | | handleUploadError() { |
| | | this.$message.error('ä¸ä¼ å¤±è´¥ï¼æä»¶å¯è½è¶
è¿200MB') |
| | | }, |
| | | previewFile(row) { |
| | | this.previewRow = row |
| | | this.previewUrl = this.fullUrl(row.fileUrl) |
| | | this.previewVisible = true |
| | | }, |
| | | downloadFile(row) { |
| | | this.$download.saveAs(this.fullUrl(row.fileUrl), row.fileName) |
| | | }, |
| | | removeFile(row) { |
| | | this.$confirm('æ¯å¦å é¤è¯¥éä»¶ï¼', 'æç¤º', { type: 'warning' }).then(() => { |
| | | request({ |
| | | url: this.deleteUrl, |
| | | method: 'delete', |
| | | params: { id: row.id } |
| | | }).then(() => { |
| | | this.$message.success('å 餿å') |
| | | this.loadList() |
| | | }) |
| | | }).catch(() => {}) |
| | | }, |
| | | // éæå°åæ¼æ¥ï¼ä¸å端ä¸ä¼ ç»ä¸è·¯ç±ä¿æä¸è´ï¼å¾çå¨ /imgï¼å
¶å®é½å¨ /word |
| | | fullUrl(fileUrl) { |
| | | const base = /\.(jpg|jpeg|png|gif)$/i.test(fileUrl) ? '/img/' : '/word/' |
| | | return this.javaApi + base + fileUrl |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .attachment-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div> |
| | | <div v-if="isImage"> |
| | | <img :src="imgUrl" alt="Image Preview" /> |
| | | <!-- å¾ç --> |
| | | <div v-if="isImage" style="text-align: center"> |
| | | <img :src="imgUrl" alt="å¾çé¢è§" /> |
| | | </div> |
| | | <div v-if="isPdf" style="height: 80vh;"> |
| | | <!-- è§é¢ --> |
| | | <div v-else-if="isVideo" style="text-align: center"> |
| | | <video :src="fileUrl" controls style="max-width: 100%; max-height: 85vh"></video> |
| | | </div> |
| | | <!-- é³é¢ --> |
| | | <div v-else-if="isAudio" style="text-align: center; padding-top: 10vh"> |
| | | <audio :src="fileUrl" controls style="width: 60%"></audio> |
| | | </div> |
| | | <!-- PDFï¼ä¼ äº OnlyOffice é
ç½®èµ°ææ¡£æå¡ï¼å¦åç¨æµè§å¨å
ç½®é
è¯»å¨ --> |
| | | <div v-else-if="isPdf" style="height: 80vh;"> |
| | | <onlyoffice v-if="useOnlyOffice" ref="onlyoffice" :options="option" style="width: 100%;height: 100%;" /> |
| | | <iframe v-else-if="pdfUrl" :src="pdfUrl" title="PDF é¢è§" style="width: 100%;height: 100%;border: none;"></iframe> |
| | | <p v-else-if="pdfError">PDF é¢è§å¤±è´¥ï¼<a :href="fileUrl" style="color: var(--el-color-primary);" target="_blank">ç¹æ¤ä¸è½½æ¥ç</a></p> |
| | | <p v-else>æ£å¨å è½½ PDFâ¦</p> |
| | | </div> |
| | | <div v-if="isDoc"> |
| | | <p v-if="!isDocShow">ææ¡£æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <a :href="fileUrl" v-if="!isDocShow">ä¸è½½æä»¶</a> |
| | | <vue-office-docx v-else :src="fileUrl" style="height: 100vh;" @rendered="renderedHandler" @error="errorHandler" /> |
| | | </div> |
| | | <div v-if="isXls"> |
| | | <p v-if="!isDocShow">ææ¡£æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <a :href="fileUrl" v-if="!isDocShow">ä¸è½½æä»¶</a> |
| | | <vue-office-excel v-else :src="fileUrl" :options="excelOptions" style="height: 100vh;" @rendered="renderedHandler" |
| | | <!-- Word --> |
| | | <div v-else-if="isDoc"> |
| | | <vue-office-docx v-if="isDocShow" :key="fileUrl" :src="fileUrl" style="height: 100vh;" @rendered="renderedHandler" |
| | | @error="errorHandler" /> |
| | | <div v-else class="preview-fallback"> |
| | | <p>Word ææ¡£æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <el-button type="primary" @click="downloadFile">ä¸è½½æä»¶</el-button> |
| | | </div> |
| | | <div v-if="isZipOrRar"> |
| | | <p>å缩æä»¶æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <a :href="fileUrl">ä¸è½½æä»¶</a> |
| | | </div> |
| | | <div v-if="isCsv"> |
| | | <p v-if="csvList.length == 0">CSV æä»¶æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <a :href="fileUrl" v-if="csvList.length == 0">ä¸è½½æä»¶</a> |
| | | <el-tabs type="border-card" v-if="csvList.length > 0" tab-position="bottom"> |
| | | <el-tab-pane :label="item.sheetName" v-for="(item, index) in csvList" :key="index"> |
| | | <el-table :data="item.tableData" height="75vh"> |
| | | <el-table-column :label="m.label" :prop="m.prop" v-for="(m, i) in item.column" :key="i" min-width="120px" |
| | | show-overflow-tooltip> |
| | | <template #header="scope"> |
| | | <div> |
| | | <el-tooltip :content="m.label" placement="top"> |
| | | <div class="oneLine"> |
| | | <span>{{ m.label }}</span> |
| | | <!-- Excel --> |
| | | <div v-else-if="isXls"> |
| | | <vue-office-excel v-if="isDocShow" :key="fileUrl" :src="fileUrl" :options="excelOptions" style="height: 100vh;" |
| | | @rendered="renderedHandler" @error="errorHandler" /> |
| | | <div v-else class="preview-fallback"> |
| | | <p>Excel ææ¡£æ æ³ç´æ¥é¢è§ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <el-button type="primary" @click="downloadFile">ä¸è½½æä»¶</el-button> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <!-- CSV è¡¨æ ¼é¢è§ --> |
| | | <div v-else-if="isCsv"> |
| | | <el-table v-if="csvRows.length" :data="csvRows" height="75vh"> |
| | | <el-table-column :label="col" :prop="col" v-for="(col, i) in csvColumns" :key="i" min-width="120px" |
| | | show-overflow-tooltip /> |
| | | </el-table> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <div v-else-if="csvError" class="preview-fallback"> |
| | | <p>CSV æä»¶è§£æå¤±è´¥ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <el-button type="primary" @click="downloadFile">ä¸è½½æä»¶</el-button> |
| | | </div> |
| | | <div v-if="!isSupported"> |
| | | <p>䏿¯æçæä»¶æ ¼å¼</p> |
| | | <p v-else>æ£å¨å è½½â¦</p> |
| | | </div> |
| | | <!-- ææ¬æä»¶ --> |
| | | <div v-else-if="isText"> |
| | | <pre v-if="textLoaded" class="text-preview">{{ textContent }}</pre> |
| | | <div v-else-if="textError" class="preview-fallback"> |
| | | <p>ææ¬æä»¶è¯»å失败ï¼è¯·ä¸è½½æ¥çã</p> |
| | | <el-button type="primary" @click="downloadFile">ä¸è½½æä»¶</el-button> |
| | | </div> |
| | | <p v-else>æ£å¨å è½½â¦</p> |
| | | </div> |
| | | <!-- å
åºï¼å缩å
ãç¨åºæä»¶çæµè§å¨æ æ³ç´æ¥æ¾ç¤ºçæ ¼å¼ï¼ä¿è¯ä¹å¯ä¸è½½ --> |
| | | <div v-else class="preview-fallback"> |
| | | <p>该类åæä»¶ï¼{{ fileExt }}ï¼æµè§å¨æ æ³å¨çº¿æ¾ç¤ºï¼è¯·ä¸è½½åæ¥çã</p> |
| | | <el-button type="primary" @click="downloadFile">ä¸è½½æä»¶</el-button> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | data() { |
| | | return { |
| | | isDocShow: true, |
| | | csvList: [], //csvæä»¶æ°æ® |
| | | csvColumns: [], |
| | | csvRows: [], |
| | | csvError: false, |
| | | textContent: '', |
| | | textLoaded: false, |
| | | textError: false, |
| | | pdfUrl: '', //pdfæ¬å°é¢è§å°å |
| | | pdfError: false |
| | | } |
| | | }, |
| | | computed: { |
| | | // åå®ç°æ isImage / isXls / isCsv åæäºã读æä»¶åç¼ + é¡ºææ¹å«çååºå¼ç¶æãç computedï¼ |
| | | // isImage éå imgUrlãisXls éå options.xlsãisCsv éç´æ¥å请æ±ã |
| | | // computed éåç¶æå±äºå¯ä½ç¨ï¼å¨ Vue3 ä¸ä¼å¨æ¸²ææè§¦åç¶æåæ´ï¼å¾å®¹ææ¼åæé彿´æ°ã |
| | | // è¿éææçº¯è®¡ç®å±æ§ï¼å¯ä½ç¨ç»ä¸äº¤ç»ä¸é¢é£ä¸ª watchã |
| | | isImage() { |
| | | return /\.(jpg|jpeg|png|gif)$/i.test(this.fileUrl) |
| | | }, |
| | | imgUrl() { |
| | | // å isImage æ 论çåé½ä¼å imgUrl = fileUrlï¼å½ä¸å¾çæ¶æ word æ¢æ imgï¼ |
| | | // å¾çåå¨ /img éæè·¯å¾ä¸ï¼è°ç¨æ¹ä¼ çå¯è½æ¯ /word å°åï¼è¿éç»ä¸æ¢æ /img |
| | | return this.isImage ? this.fileUrl.replaceAll('word', 'img') : '' |
| | | }, |
| | | isVideo() { |
| | | return /\.(mp4|webm|ogv|ogg)$/i.test(this.fileUrl) |
| | | }, |
| | | isAudio() { |
| | | return /\.(mp3|wav|m4a|aac|flac|oga)$/i.test(this.fileUrl) |
| | | }, |
| | | isPdf() { |
| | | return /\.pdf$/i.test(this.fileUrl) |
| | |
| | | }, |
| | | isXls() { |
| | | return /\.(xls|xlsx)$/i.test(this.fileUrl) |
| | | }, |
| | | isCsv() { |
| | | return /\.csv$/i.test(this.fileUrl) |
| | | }, |
| | | isText() { |
| | | return /\.(txt|log|json|xml|md|ini|conf|cfg|yml|yaml|sql|properties)$/i.test(this.fileUrl) |
| | | }, |
| | | // vue-office ç excel ç»ä»¶ç¨ xls æ å¿åºå xlsx / xls |
| | | excelOptions() { |
| | |
| | | heightOffset: 10, //å¨é»è®¤æ¸²æçå表é«åº¦ä¸åå Npxé« |
| | | beforeTransformData: workbookData => { |
| | | return workbookData |
| | | }, //åºå±éè¿exceljsè·åexcelæä»¶å
容ï¼éè¿è¯¥é©å彿°ï¼å¯ä»¥å¯¹è·åçexcelæä»¶å
容è¿è¡ä¿®æ¹ï¼æ¯å¦æä¸ªåå
æ ¼çæ°æ®æ¾ç¤ºä¸æ£ç¡®ï¼å¯ä»¥å¨æ¤èªè¡ä¿®æ¹æ¯ä¸ªåå
æ ¼çvalueå¼ã |
| | | }, //åºå±éè¿exceljsè·åexcelæä»¶å
容ï¼éè¿è¯¥é©å彿°ï¼å¯ä»¥å¯¹è·åå°çexcelæä»¶å
容è¿è¡ä¿®æ¹ï¼æ¯å¦æä¸ªåå
æ ¼çæ°æ®æ¾ç¤ºä¸æ£ç¡®ï¼å¯ä»¥å¨æ¤èªè¡ä¿®æ¹æ¯ä¸ªåå
æ ¼çvalueå¼ã |
| | | transformData: workbookData => { |
| | | return workbookData |
| | | } //å°è·åå°çexcelæ°æ®è¿è¡å¤çä¹å䏿¸²æå°é¡µé¢ä¹åï¼å¯éè¿transformData对å³å°æ¸²æçæ°æ®åæ ·å¼è¿è¡ä¿®æ¹ï¼æ¤æ¶æ¯ä¸ªåå
æ ¼çtextå¼å°±æ¯å³å°æ¸²æå°é¡µé¢ä¸çå
容 |
| | | } |
| | | }, |
| | | isZipOrRar() { |
| | | return /\.(zip|rar)$/i.test(this.fileUrl) |
| | | }, |
| | | isCsv() { |
| | | return /\.csv$/i.test(this.fileUrl) |
| | | }, |
| | | isSupported() { |
| | | return this.isImage || this.isPdf || this.isDoc || this.isZipOrRar || this.isCsv || this.isXls |
| | | fileExt() { |
| | | const match = this.fileUrl.match(/\.([a-zA-Z0-9]+)$/) |
| | | return match ? match[1].toUpperCase() : 'æªç¥' |
| | | }, |
| | | // è°ç¨æ¹ä¼ äº OnlyOffice çé
ç½®æèµ°ææ¡£æå¡ï¼å¦åç¨æµè§å¨å
ç½®é
è¯»å¨ |
| | | useOnlyOffice() { |
| | |
| | | watch: { |
| | | fileUrl: { |
| | | handler() { |
| | | this.resetState() |
| | | this.loadPdf() |
| | | if (this.isCsv) { |
| | | this.loadCSVData() |
| | | } |
| | | this.loadTextContent() |
| | | }, |
| | | immediate: true |
| | | } |
| | |
| | | this.releasePdfUrl() |
| | | }, |
| | | methods: { |
| | | // 忢æä»¶æ¶æ¸
æä¸ä¸ä¸ªæä»¶çé¢è§ç¶æï¼é¿å
æ²¿ç¨æ§ç»æï¼æ¯å¦ä¸æ¬¡ Word 渲æå¤±è´¥ï¼è¿æ¬¡è¿è¢«å¡å¨ä¸è½½å
åºé¡µï¼ |
| | | resetState() { |
| | | this.isDocShow = true |
| | | this.csvColumns = [] |
| | | this.csvRows = [] |
| | | this.csvError = false |
| | | this.textContent = '' |
| | | this.textLoaded = false |
| | | this.textError = false |
| | | }, |
| | | releasePdfUrl() { |
| | | if (this.pdfUrl) { |
| | | URL.revokeObjectURL(this.pdfUrl) |
| | |
| | | this.pdfError = true |
| | | } |
| | | }, |
| | | renderedHandler() { |
| | | console.log('渲æå®æ') |
| | | this.isDocShow = true |
| | | this.resetStyle() |
| | | }, |
| | | errorHandler() { |
| | | console.log('渲æå¤±è´¥') |
| | | this.isDocShow = false |
| | | }, |
| | | async loadCSVData() { |
| | | // åå®ç°ä¾èµ this.$axios / this.$apiï¼èè¿ä¸¤ä¸ªå
¨å±åéå¨é¡¹ç®é仿ªæ³¨åè¿ |
| | | // ï¼main.js 没ææè½½ï¼ä¹æ²¡æ api èå对象ï¼ï¼ä¸æ¦è¿å
¥ CSV 忝就æ TypeErrorã |
| | | // 卿¿å°ç宿¥å£ä¹åå
æ¾å¼é级为ãä¸è½½æ¥çãï¼ä¸ç¨æ·å®é
çå°çç»æä¸è´ã |
| | | if (!this.$axios || !this.$api?.insOrderPlan?.preview) { |
| | | console.warn('[filePreview] æªé
ç½® $axios/$apiï¼CSV è½¬è¡¨æ ¼ä¸å¯ç¨ï¼å·²é级为ä¸è½½æ¥ç') |
| | | this.csvList = [] |
| | | // CSV è§£ææè¡¨æ ¼ãææ¬æä»¶ç´æ¥å±ç¤ºï¼å
容常è§ä¸º GBK ç¼ç ï¼UTF-8 è§£åºä¹±ç æ¶æ¢ GBK åè§£ä¸æ¬¡ |
| | | async loadTextContent() { |
| | | if (!this.isCsv && !this.isText) { |
| | | return |
| | | } |
| | | this.$axios |
| | | .post(this.$api.insOrderPlan.preview, { |
| | | id: this.currentFile.id |
| | | }) |
| | | .then(res => { |
| | | let arr = res.data |
| | | arr = arr.map(m => { |
| | | const obj = { |
| | | sheetName: m.sheetName, |
| | | tableData: [], |
| | | column: [] |
| | | try { |
| | | const { data } = await axios.get(this.fileUrl, { responseType: 'arraybuffer' }) |
| | | let text = new TextDecoder('utf-8').decode(data) |
| | | // è§£ç ç»æéåºç° U+FFFD æ¿æ¢ç¬¦ï¼è¯´æåæä¸æ¯ UTF-8ï¼å¸¸è§æ¯ GBK ç¼ç ç䏿æä»¶ |
| | | if (text.indexOf(String.fromCharCode(0xFFFD)) !== -1) { |
| | | try { |
| | | text = new TextDecoder('gbk').decode(data) |
| | | } catch (e) { |
| | | // ä¸ªå«æµè§å¨ä¸æ¯æ gbk è§£ç ï¼ä¿ç UTF-8 ç»æ |
| | | } |
| | | obj.tableData = this.formatCSVToTable(m.content.replaceAll('null', ' ')) |
| | | // .replaceAll('MIN','=MIN').replaceAll('MAX','=MAX').replaceAll('AVERAGE','=AVERAGE') |
| | | for (const item in obj.tableData[0]) { |
| | | obj.column.push({ |
| | | label: item, |
| | | prop: item |
| | | }) |
| | | } |
| | | return obj |
| | | }) |
| | | this.csvList = arr |
| | | }) |
| | | .catch(err => { |
| | | console.log(err) |
| | | }) |
| | | if (this.isCsv) { |
| | | const rows = this.formatCSVToTable(text.replaceAll('\r\n', '\n').replaceAll('\r', '\n')) |
| | | if (rows.length) { |
| | | this.csvColumns = Object.keys(rows[0]) |
| | | this.csvRows = rows.slice(0, 5000) |
| | | } else { |
| | | this.csvError = true |
| | | } |
| | | } else { |
| | | this.textContent = text.length > 1000000 |
| | | ? text.slice(0, 1000000) + '\n\nâ¦â¦ï¼æä»¶è¿å¤§ï¼ä»
é¢è§åä¸ç¾ä¸åï¼å®æ´å
容请ä¸è½½æ¥çï¼' |
| | | : (text || 'ï¼æä»¶å
容为空ï¼') |
| | | this.textLoaded = true |
| | | } |
| | | } catch (error) { |
| | | console.error(error) |
| | | if (this.isCsv) { |
| | | this.csvError = true |
| | | } else { |
| | | this.textError = true |
| | | } |
| | | } |
| | | }, |
| | | formatCSVToTable(str) { |
| | | const result = [] |
| | |
| | | } else { |
| | | const obj = {} |
| | | for (let index = 0; index < arrHeader.length; index++) { |
| | | // ç»è£
è¡¨æ ¼æ°æ® |
| | | const name = String(arrHeader[index]) |
| | | const name = String(arrHeader[index]).trim() |
| | | if (!arrHeader[index]) continue |
| | | if (!obj[name]) { |
| | | try { |
| | | if (kv[index]) { |
| | | obj[name] = String(kv[index]) |
| | | } else { |
| | | obj[name] = '' |
| | | } |
| | | } catch (err) { |
| | | obj[name] = '' |
| | | } |
| | | obj[name] = kv[index] ? String(kv[index]) : '' |
| | | } |
| | | } |
| | | result.push(obj) |
| | |
| | | } |
| | | } |
| | | return result |
| | | }, |
| | | downloadFile() { |
| | | const name = this.currentFile && this.currentFile.fileName |
| | | ? this.currentFile.fileName |
| | | : this.fileUrl.split('/').pop() |
| | | this.$download.saveAs(this.fileUrl, name) |
| | | }, |
| | | renderedHandler() { |
| | | console.log('渲æå®æ') |
| | | this.isDocShow = true |
| | | this.resetStyle() |
| | | }, |
| | | errorHandler() { |
| | | console.log('渲æå¤±è´¥') |
| | | this.isDocShow = false |
| | | }, |
| | | resetStyle() { |
| | | // 注ï¼åå®ç°æ¯ style.replace(/pt/g, 'px')ï¼ä¼ææ ·å¼éä»»æä½ç½®ç pt 齿¢æ |
| | |
| | | max-width: 100%; |
| | | } |
| | | |
| | | .oneLine { |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | | .text-preview { |
| | | white-space: pre-wrap; |
| | | word-break: break-all; |
| | | max-height: 85vh; |
| | | overflow: auto; |
| | | padding: 12px; |
| | | margin: 0; |
| | | background: #f8f9fa; |
| | | font-family: Consolas, Monaco, monospace; |
| | | font-size: 13px; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | .preview-fallback { |
| | | text-align: center; |
| | | padding-top: 15vh; |
| | | color: #606266; |
| | | } |
| | | |
| | | .preview-fallback p { |
| | | margin-bottom: 16px; |
| | | } |
| | | </style> |
| | |
| | | }, |
| | | |
| | | generateChart(option) { |
| | | // é
ç½®æçº¿å¾åæ±ç¶å¾çæ ·å¼ |
| | | // æ ·å¼åªå å¨å¯æ¬ä¸ï¼ä¸è½åå this.seriesï¼series æ¯ç¶é¡µé¢çååºå¼æ°æ®ï¼ |
| | | // ååä¼è§¦åæ¬ç»ä»¶ series ç deep watcher 忬¡ renderChartï¼æ¯æ¬¡çææ°å¯¹è±¡æ°¸ä¸æ¶æï¼é¡µé¢æ»å¾ªç¯å¡æ» |
| | | if (option.series && option.series.length > 0) { |
| | | option.series.forEach((s, index) => { |
| | | option.series = option.series.map((s, index) => { |
| | | if (s.type === 'line') { |
| | | s.itemStyle = { |
| | | color: this.lineColors[index] || this.lineColors[0] |
| | | } |
| | | s.lineStyle = { |
| | | color: this.lineColors[index] || this.lineColors[0] |
| | | } |
| | | const color = this.lineColors[index] || this.lineColors[0] |
| | | return { ...s, itemStyle: { color }, lineStyle: { color } } |
| | | } else if (s.type === 'bar') { |
| | | s.itemStyle = { |
| | | color: this.barColors[index] || this.barColors[0] |
| | | const color = this.barColors[index] || this.barColors[0] |
| | | return { ...s, itemStyle: { color } } |
| | | } |
| | | } |
| | | return s |
| | | }) |
| | | } |
| | | this.chartInstance.clear() |
| | |
| | | <span class="label">LIMSå®éªå®¤ç®¡çç³»ç»</span> |
| | | </div> |
| | | <div class="right-menu"> |
| | | <div class="menu-search"> |
| | | <el-select |
| | | v-model="selectedMenu" |
| | | placeholder="æç´¢èå" |
| | | filterable |
| | | clearable |
| | | :fit-input-width="false" |
| | | :filter-method="filterMenus" |
| | | @change="handleMenuSelect" |
| | | @clear="resetMenuFilter" |
| | | > |
| | | <template #prefix> |
| | | <lims-icon name="el-icon-search" /> |
| | | </template> |
| | | <el-option |
| | | v-for="item in filteredMenus" |
| | | :key="item.path" |
| | | :label="item.breadcrumb" |
| | | :value="item.path" |
| | | /> |
| | | </el-select> |
| | | </div> |
| | | <div class="avatar-wrapper"> |
| | | <el-avatar shape="square" :size="30">{{ avatarText }}</el-avatar> |
| | | <span class="userName">{{ userStore.nickName }}</span> |
| | |
| | | import Hamburger from '@/components/Hamburger' |
| | | import useAppStore from '@/store/modules/app' |
| | | import useUserStore from '@/store/modules/user' |
| | | import usePermissionStore from '@/store/modules/permission' |
| | | import { getNormalPath } from '@/utils/ruoyi' |
| | | |
| | | const appStore = useAppStore() |
| | | const userStore = useUserStore() |
| | | const permissionStore = usePermissionStore() |
| | | const router = useRouter() |
| | | |
| | | const avatarText = computed(() => (userStore.nickName || '').substring(0, 1)) |
| | | |
| | | const selectedMenu = ref(undefined) |
| | | const filteredMenus = ref([]) |
| | | |
| | | // ä¾§è¾¹æ èåæ æå¹³æå¯æç´¢åè¡¨ï¼æ é¢ + 宿´è·¯å¾é¢å
å±ï¼ |
| | | const menuList = computed(() => { |
| | | const list = [] |
| | | const walk = (routes, basePath, parents) => { |
| | | ;(routes || []).forEach(route => { |
| | | if (!route || route.hidden || typeof route.path !== 'string') return |
| | | const fullPath = getNormalPath(`${basePath}/${route.path}`) |
| | | const title = route.meta && route.meta.title |
| | | const children = Array.isArray(route.children) ? route.children : [] |
| | | if (children.length) { |
| | | walk(children, fullPath, title ? parents.concat(title) : parents) |
| | | } else if (title && fullPath) { |
| | | list.push({ title, path: fullPath, breadcrumb: parents.concat(title).join(' / ') }) |
| | | } |
| | | }) |
| | | } |
| | | walk(permissionStore.sidebarRouters, '', []) |
| | | return list |
| | | }) |
| | | |
| | | function filterMenus(query) { |
| | | const q = (query || '').trim().toLowerCase() |
| | | filteredMenus.value = q |
| | | ? menuList.value.filter(item => |
| | | item.title.toLowerCase().includes(q) || item.breadcrumb.toLowerCase().includes(q) |
| | | ) |
| | | : menuList.value |
| | | } |
| | | |
| | | function resetMenuFilter() { |
| | | filteredMenus.value = menuList.value |
| | | } |
| | | |
| | | function handleMenuSelect(path) { |
| | | if (path) { |
| | | router.push(path).catch(() => {}) |
| | | } |
| | | selectedMenu.value = undefined |
| | | resetMenuFilter() |
| | | } |
| | | |
| | | watch(menuList, resetMenuFilter, { immediate: true }) |
| | | |
| | | function toggleSideBar() { |
| | | appStore.toggleSideBar() |
| | |
| | | outline: none; |
| | | } |
| | | |
| | | .menu-search { |
| | | margin-right: 20px; |
| | | |
| | | :deep(.el-select) { |
| | | width: 210px; |
| | | } |
| | | |
| | | :deep(.el-select__wrapper) { |
| | | border-radius: 16px; |
| | | } |
| | | } |
| | | |
| | | .avatar-wrapper { |
| | | display: flex; |
| | | align-items: center; |
| | |
| | | :page="page" :tableLoading="tableLoading"></lims-table> |
| | | </div> |
| | | <form-dia ref="formDia" v-if="formDia" @closeDia="closeDia"></form-dia> |
| | | <lims-attachment ref="attachmentDialog" title="ä¾åºåéä»¶" name-field="supplierName" id-param="supplierManagementId" |
| | | upload-url="/supplierManagement/uploadAttachment" select-url="/supplierManagement/selectAttachments" |
| | | delete-url="/supplierManagement/deleteAttachment" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import FormDia from "../supplierManage/component/formDia.vue"; |
| | | import limsTable from '@/components/Table/lims-table.vue' |
| | | import limsAttachment from '@/components/Attachment/lims-attachment.vue' |
| | | import { |
| | | selectQualifiedSupplierManagementPage, |
| | | exportSupplierManagement, |
| | |
| | | // import å¼å
¥çç»ä»¶éè¦æ³¨å
¥å°å¯¹è±¡ä¸æè½ä½¿ç¨ |
| | | components: { |
| | | limsTable, |
| | | FormDia |
| | | FormDia, |
| | | limsAttachment |
| | | }, |
| | | data() { |
| | | // è¿éåæ¾æ°æ® |
| | |
| | | }, |
| | | }, |
| | | { |
| | | name: 'éä»¶', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.$refs.attachmentDialog.open(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | type: 'text', |
| | | color: 'var(--el-color-danger)', |
| | |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'æ°é', |
| | | prop: 'factoryNum', |
| | | label: 'åå§æ°é', |
| | | prop: 'quantity', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'åä½', |
| | | prop: 'unit', |
| | | minWidth: '80' |
| | | }, |
| | | { |
| | | label: 'æ¬æ¬¡é¢ç¨æ°é', |
| | | prop: 'borrowQuantity', |
| | | minWidth: '110' |
| | | }, |
| | | { |
| | | label: 'ä½é', |
| | | prop: 'remainingQuantity', |
| | | minWidth: '80' |
| | | }, |
| | | { |
| | | label: 'é¢ç¨äºº', |
| | |
| | | { |
| | | label: 'é¢ç¨æ¥æ', |
| | | prop: 'borrowDate', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'å½è¿äºº', |
| | | prop: 'returnIntegrity', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'å½è¿æ¥æ', |
| | | prop: 'returnDate', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'å½è¿æ¶ç¶æ', |
| | | prop: 'returnIntegrity', |
| | | minWidth: '100' |
| | | } |
| | | ], |
| | |
| | | current: 1 |
| | | }, |
| | | total: 0, |
| | | formDia: false, |
| | | borrowDia: false, |
| | | returnDia: false, |
| | | } |
| | | }, |
| | | mounted() { |
| | |
| | | <el-dialog v-loading="diaLoading" :close-on-click-modal="false" |
| | | :close-on-press-escape="false" |
| | | v-model="formDia" |
| | | title="æ åç©è´¨åç¨" |
| | | title="æ åç©è´¨é¢ç¨" |
| | | width="80%" @close="closeBorrowDia"> |
| | | <el-form ref="form" :model="form" :rules="rules" label-position="right" label-width="auto"> |
| | | <el-row :gutter="20"> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å©ä½å¯é¢ç¨"> |
| | | <el-input v-model="remaining" disabled size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="é¢ç¨æ°é" prop="borrowQuantity"> |
| | | <el-input-number v-model="form.borrowQuantity" :min="1" :max="remaining > 0 ? remaining : 1" size="small" style="width: 100%"></el-input-number> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®å¥½æ§" prop="integrity"> |
| | | <el-input v-model="form.integrity" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åç¨äºº" prop="borrowUser"> |
| | | <el-form-item label="é¢ç¨äºº" prop="borrowUser"> |
| | | <el-input v-model="form.borrowUser" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååºæ¥æ" prop="borrowDate"> |
| | | <el-form-item label="é¢ç¨æ¥æ" prop="borrowDate"> |
| | | <el-date-picker |
| | | v-model="form.borrowDate" |
| | | clearable |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="约å®å½è¿æ¥æ" prop="borrowReturnDate"> |
| | | <el-date-picker |
| | | v-model="form.borrowReturnDate" |
| | | clearable |
| | | format="YYYY-MM-DD HH:mm:ss" placeholder="éæ©æ¥æ" |
| | | size="small" style="width: 100%" |
| | | type="datetime" value-format="YYYY-MM-DD HH:mm:ss"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ååºäºº" prop="lender"> |
| | | <el-form-item label="åæ¾äºº" prop="lender"> |
| | | <el-input v-model="form.lender" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | |
| | | |
| | | <script> |
| | | import { |
| | | borrowSubstance |
| | | borrowSubstance, |
| | | getRemainingQuantity |
| | | } from "@/api/cnas/resourceDemand/standardMaterial/standardMaterial"; |
| | | |
| | | export default { |
| | |
| | | borrowUser: '', |
| | | phone: '', |
| | | borrowDate: '', |
| | | borrowReturnDate: '', |
| | | lender: '', |
| | | substanceId: '' |
| | | substanceId: '', |
| | | borrowQuantity: null |
| | | }, |
| | | remaining: 0, |
| | | rules: { |
| | | integrity: [{required: true, message: '请填åå®å¥½æ§',trigger: 'blur'}], |
| | | borrowUser: [{required: true, message: '请填ååç¨äºº',trigger: 'blur'}], |
| | | borrowUser: [{required: true, message: '请填åé¢ç¨äºº',trigger: 'blur'}], |
| | | phone: [{required: true, message: '请填åèç³»æ¹å¼',trigger: 'blur'}], |
| | | borrowDate: [{required: true, message: 'è¯·éæ©ååºæ¥æ',trigger: 'change'}], |
| | | borrowReturnDate: [{required: true, message: 'è¯·éæ©çº¦å®å½è¿æ¥æ',trigger: 'change'}], |
| | | lender: [{required: true, message: 'è¯·éæ©lender',trigger: 'blur'}], |
| | | borrowDate: [{required: true, message: 'è¯·éæ©é¢ç¨æ¥æ',trigger: 'change'}], |
| | | lender: [{required: true, message: '请填ååæ¾äºº',trigger: 'blur'}], |
| | | borrowQuantity: [ |
| | | {required: true, message: '请填åé¢ç¨æ°é', trigger: 'blur'}, |
| | | { |
| | | validator: (rule, value, callback) => { |
| | | if (value === null || value === undefined || value === '') { |
| | | callback(new Error('请填åé¢ç¨æ°é')) |
| | | } else if (Number(value) <= 0) { |
| | | callback(new Error('é¢ç¨æ°éå¿
须大äº0')) |
| | | } else if (Number(value) > this.remaining) { |
| | | callback(new Error('é¢ç¨æ°éä¸è½è¶
è¿å©ä½å¯é¢ç¨æ°é')) |
| | | } else { |
| | | callback() |
| | | } |
| | | }, |
| | | trigger: 'blur' |
| | | }, |
| | | ], |
| | | }, |
| | | }; |
| | | }, |
| | |
| | | this.form.name = row.name |
| | | this.form.model = row.model |
| | | this.form.substanceId = row.id |
| | | this.remaining = 0 |
| | | getRemainingQuantity(row.id).then(res => { |
| | | if (res.code === 200) { |
| | | this.remaining = res.data |
| | | } |
| | | }) |
| | | }, |
| | | // æäº¤å¼¹æ¡æ°æ® |
| | | handleEdit () { |
| | |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºå" prop="supplier"> |
| | | <el-select v-model="form.supplier" clearable filterable placeholder="è¯·éæ©" size="small" style="width: 100%"> |
| | | <el-option v-for="item in supplierOptions" :key="item.value" :label="item.label" :value="item.value"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåç¼å·" prop="factoryNum"> |
| | | <el-input v-model="form.factoryNum" clearable size="small"></el-input> |
| | | </el-form-item> |
| | |
| | | <el-input v-model="form.manageNum" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ä¸ç¡®å®åº¦" prop="uncertainty"> |
| | | <el-input v-model="form.uncertainty" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ°é" prop="quantity"> |
| | | <el-input v-model="form.quantity" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åä½" prop="unit"> |
| | | <el-input v-model="form.unit" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | |
| | | <el-input v-model="form.fileNum" clearable size="small"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åæ¾ä½ç½®" prop="position"> |
| | | <el-input v-model="form.position" clearable size="small"></el-input> |
| | | </el-form-item> |
| | |
| | | import { |
| | | addStandardSubstance |
| | | } from "@/api/cnas/resourceDemand/standardMaterial/standardMaterial"; |
| | | import { selectQualifiedSupplierManagementPage } from "@/api/cnas/externalService/supplierManage/supplierManage"; |
| | | |
| | | export default { |
| | | name: 'formDia', |
| | |
| | | name: '', |
| | | model: '', |
| | | factoryManufacturer: '', |
| | | supplier: '', |
| | | factoryNum: '', |
| | | manageNum: '', |
| | | uncertainty: '', |
| | | quantity: '', |
| | | unit: '', |
| | | acquisitionDate: '', |
| | | effectiveDate: '', |
| | | fileNum: '', |
| | |
| | | rules: { |
| | | name: [{required: true, message: 'è¯·å¡«åæ åç©è´¨åç§°',trigger: 'blur'}], |
| | | model: [{required: true, message: '请填åè§æ ¼åå·',trigger: 'blur'}], |
| | | factoryManufacturer: [{required: true, message: '请填åç产åå®¶',trigger: 'blur'}], |
| | | factoryNum: [{required: true, message: '请填ååºåç¼å·',trigger: 'blur'}], |
| | | manageNum: [{required: true, message: '请填å管çç¼å·',trigger: 'blur'}], |
| | | uncertainty: [{required: true, message: '请填åä¸ç¡®å®åº¦',trigger: 'blur'}], |
| | |
| | | position: [{required: true, message: '请填ååæ¾ä½ç½®',trigger: 'blur'}], |
| | | }, |
| | | operationType: '', |
| | | supplierOptions: [], |
| | | }; |
| | | }, |
| | | mounted() { |
| | |
| | | methods: { |
| | | // æå¼å¼¹æ¡ |
| | | openDia (type, row) { |
| | | this.loadSuppliers() |
| | | this.formDia = true |
| | | this.operationType = type |
| | | if (type !== 'add') { |
| | | this.form = row |
| | | } |
| | | }, |
| | | loadSuppliers () { |
| | | selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => { |
| | | if (res.code === 200) { |
| | | this.supplierOptions = (res.data.records || []).map(item => ({ |
| | | label: item.supplierName, |
| | | value: item.supplierName |
| | | })) |
| | | } |
| | | }) |
| | | }, |
| | | // æäº¤å¼¹æ¡æ°æ® |
| | | handleEdit () { |
| | | this.$refs['form'].validate((valid) => { |
| | |
| | | <div> |
| | | <el-button size="small" @click="exportFun">导 åº</el-button> |
| | | <el-button size="small" type="primary" @click="importVisible = true">导 å
¥</el-button> |
| | | <el-button size="small" type="primary" @click="openFormDia('add')">æ° å¢</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table"> |
| | |
| | | :page="page" :tableLoading="tableLoading"></lims-table> |
| | | </div> |
| | | <form-dia v-if="formDia" ref="formDia" @closeYearDia="closeYearDia"></form-dia> |
| | | <borrow-dia v-if="borrowDia" ref="borrowDia" @closeYearDia="closeBorrowDia"></borrow-dia> |
| | | <return-dia v-if="returnDia" ref="returnDia" @closeYearDia="closeReturnDia"></return-dia> |
| | | <borrow-dia v-if="borrowDia" ref="borrowDia" @closeBorrowDia="closeBorrowDia"></borrow-dia> |
| | | <el-dialog title="æ åç©è´¨å¯¼å
¥" v-model="importVisible" width="500px" @closed="resetImport"> |
| | | <div style="margin-bottom: 12px;"> |
| | | è¯·ä½¿ç¨æ åç©è´¨å¯¼å
¥æ¨¡æ¿å¡«åæ°æ®ï¼å个æä»¶ä¸è¶
è¿10MBã |
| | |
| | | } from '@/api/cnas/resourceDemand/standardMaterial/standardMaterial' |
| | | import FormDia from '../standardMaterial/component/formDia.vue'; |
| | | import BorrowDia from '../standardMaterial/component/borrowDia.vue'; |
| | | import ReturnDia from '../standardMaterial/component/returnDia.vue'; |
| | | export default { |
| | | name: 'StandardMaterial', |
| | | components: { |
| | | limsTable, |
| | | FormDia, |
| | | BorrowDia, |
| | | ReturnDia |
| | | BorrowDia |
| | | }, |
| | | data() { |
| | | return { |
| | |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'ä¾åºå', |
| | | prop: 'supplier', |
| | | minWidth: '120' |
| | | }, |
| | | { |
| | | label: 'åºåç¼å·', |
| | | prop: 'factoryNum', |
| | | minWidth: '100' |
| | |
| | | label: 'æ°é', |
| | | prop: 'quantity', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'åä½', |
| | | prop: 'unit', |
| | | minWidth: '80' |
| | | }, |
| | | { |
| | | label: 'è´ç½®æ¥æ', |
| | |
| | | }, |
| | | }, |
| | | { |
| | | name: 'åç¨', |
| | | name: 'é¢ç¨', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.borrow(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å½è¿', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.return(row); |
| | | } |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | |
| | | total: 0, |
| | | formDia: false, |
| | | borrowDia: false, |
| | | returnDia: false, |
| | | importVisible: false, |
| | | importing: false, |
| | | importFiles: [], |
| | |
| | | }, |
| | | closeBorrowDia() { |
| | | this.borrowDia = false |
| | | this.searchList() |
| | | }, |
| | | // å½è¿ |
| | | return(row) { |
| | | this.returnDia = true |
| | | this.$nextTick(() => { |
| | | this.$refs.returnDia.openDia(row) |
| | | }) |
| | | }, |
| | | closeReturnDia() { |
| | | this.returnDia = false |
| | | this.searchList() |
| | | }, |
| | | // éç½®æ¥è¯¢æ¡ä»¶ |
| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" title="æ åç©è´¨éªæ¶è®°å½" width="72%" v-loading="loading"> |
| | | <el-form :model="acceptance" ref="acceptance" label-width="140px" size="small"> |
| | | <el-form ref="form" :model="form" :rules="rules" label-width="140px" size="small"> |
| | | <div class="section-title">æ åç©è´¨ä¿¡æ¯</div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å家代表" prop="producer"> |
| | | <el-input v-model="acceptance.producer"></el-input> |
| | | <el-form-item label="æ åç©è´¨åç§°" prop="substance.name"> |
| | | <el-input v-model="form.substance.name" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¸å
³éä»¶" prop="file"> |
| | | <el-form-item label="è§æ ¼åå·" prop="substance.model"> |
| | | <el-input v-model="form.substance.model" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç产åå®¶" prop="substance.factoryManufacturer"> |
| | | <el-input v-model="form.substance.factoryManufacturer" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ä¾åºå" prop="substance.supplier"> |
| | | <el-select v-model="form.substance.supplier" clearable filterable placeholder="è¯·éæ©" style="width: 100%" @change="onSupplierChange"> |
| | | <el-option v-for="item in supplierOptions" :key="item.value" :label="item.label" :value="item.value"></el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åºåç¼å·" prop="substance.factoryNum"> |
| | | <el-input v-model="form.substance.factoryNum" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="管çç¼å·" prop="substance.manageNum"> |
| | | <el-input v-model="form.substance.manageNum" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="ä¸ç¡®å®åº¦" prop="substance.uncertainty"> |
| | | <el-input v-model="form.substance.uncertainty" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="æ°é" prop="substance.quantity"> |
| | | <el-input v-model="form.substance.quantity" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <el-form-item label="åä½" prop="substance.unit"> |
| | | <el-input v-model="form.substance.unit" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="è´ç½®æ¥æ" prop="substance.acquisitionDate"> |
| | | <el-date-picker |
| | | v-model="form.substance.acquisitionDate" |
| | | clearable |
| | | type="datetime" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="éæ©æ¥æ" |
| | | style="width: 100%"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æææ" prop="substance.effectiveDate"> |
| | | <el-date-picker |
| | | v-model="form.substance.effectiveDate" |
| | | clearable |
| | | type="datetime" |
| | | format="YYYY-MM-DD HH:mm:ss" |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | placeholder="éæ©æ¥æ" |
| | | style="width: 100%"> |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¡£æ¡ç¼å·" prop="substance.fileNum"> |
| | | <el-input v-model="form.substance.fileNum" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="åæ¾ä½ç½®" prop="substance.position"> |
| | | <el-input v-model="form.substance.position" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="夿³¨" prop="substance.remark"> |
| | | <el-input v-model="form.substance.remark" clearable></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <div class="section-title">éªæ¶ä¿¡æ¯</div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å°è´§æ¥æ" prop="acceptance.arriveDate"> |
| | | <el-date-picker |
| | | v-model="form.acceptance.arriveDate" |
| | | type="date" |
| | | placeholder="éæ©æ¥æ" |
| | | style="width: 100%" |
| | | value-format="YYYY-MM-DD" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å家代表" prop="acceptance.producer"> |
| | | <el-input v-model="form.acceptance.producer"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥æ¶äºº" prop="acceptance.recipient"> |
| | | <el-input v-model="form.acceptance.recipient"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥åç¾å" prop="acceptance.signature"> |
| | | <el-input v-model="form.acceptance.signature"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éªæ¶æ
åµ" prop="acceptance.situation"> |
| | | <el-input v-model="form.acceptance.situation"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®è£
è°è¯æ
åµ" prop="acceptance.installation"> |
| | | <el-input v-model="form.acceptance.installation"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´ä¿®åä½" prop="acceptance.maintenanceUnit"> |
| | | <el-input v-model="form.acceptance.maintenanceUnit"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç¸å
³éä»¶" prop="acceptance.file"> |
| | | <div class="table-between"> |
| | | <el-input v-model="acceptance.file" style="width: 80%;" disabled></el-input> |
| | | <el-input v-model="form.acceptance.file" style="width: 80%;" disabled></el-input> |
| | | <el-upload |
| | | ref="upload" |
| | | style="float: right;" |
| | |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥æ¶äºº" prop="recipient"> |
| | | <el-input v-model="acceptance.recipient"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¥åç¾å" prop="signature"> |
| | | <el-input v-model="acceptance.signature"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="éªæ¶æ
åµ" prop="situation"> |
| | | <el-input v-model="acceptance.situation"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å®è£
è°è¯æ
åµ" prop="installation"> |
| | | <el-input v-model="acceptance.installation"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="æ¸
å" prop="substanceId" |
| | | :rule="[{ required: true, message: 'è¯·éæ©æ¸
å', trigger: 'change' }]"> |
| | | <el-select v-model="acceptance.substanceId" placeholder="è¯·éæ©" style="width: 100%"> |
| | | <el-option |
| | | v-for="item in options" |
| | | :key="item.value" |
| | | :label="item.name" |
| | | :value="item.id"> |
| | | </el-option> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="å°è´§æ¥æ" prop="arriveDate"> |
| | | <el-date-picker |
| | | v-model="acceptance.arriveDate" |
| | | align="right" |
| | | type="date" |
| | | placeholder="éæ©æ¥æ" |
| | | style="width: 100%" |
| | | value-format="YYYY-MM-DD" |
| | | > |
| | | </el-date-picker> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="ç»´ä¿®åä½" prop="maintenanceUnit"> |
| | | <el-input v-model="acceptance.maintenanceUnit"></el-input> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <el-form-item label="å¤ä»¶ç¡®è®¤"> |
| | | <el-button type="primary" style="float: right;" @click="addSpareTable">å¢å è¡</el-button> |
| | | </el-form-item> |
| | | </el-row> |
| | | |
| | | <div class="section-title">å¤ä»¶ç¡®è®¤</div> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="24" class="spare-toolbar"> |
| | | <el-button type="primary" size="small" @click="addSpareTable">å¢å è¡</el-button> |
| | | </el-col> |
| | | <el-col :span="24"> |
| | | <lims-table :tableData="list" :column="spareColumns" height="300"> |
| | |
| | | </template> |
| | | </lims-table> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <template #footer><span class="dialog-footer"> |
| | | <el-button @click="closeDialog">å æ¶</el-button> |
| | |
| | | import limsTable from "@/components/Table/lims-table.vue"; |
| | | import { |
| | | addAcceptance, getAcceptanceDetails, |
| | | getStandardSubstanceAll, |
| | | updateAcceptance |
| | | } from "@/api/cnas/resourceDemand/standardMaterialAccept/standardMaterialAccept"; |
| | | export default { |
| | | components: { |
| | | limsTable, |
| | | }, |
| | | data() { |
| | | import { selectQualifiedSupplierManagementPage } from "@/api/cnas/externalService/supplierManage/supplierManage"; |
| | | |
| | | function defaultSubstance() { |
| | | return { |
| | | dialogVisible: false, |
| | | loading: false, |
| | | submitLoading: false, |
| | | acceptance: { |
| | | id: undefined, |
| | | name: undefined, |
| | | model: undefined, |
| | | factoryManufacturer: undefined, |
| | | supplier: undefined, |
| | | factoryNum: undefined, |
| | | manageNum: undefined, |
| | | uncertainty: undefined, |
| | | quantity: undefined, |
| | | unit: undefined, |
| | | acquisitionDate: undefined, |
| | | effectiveDate: undefined, |
| | | fileNum: undefined, |
| | | position: undefined, |
| | | remark: undefined, |
| | | } |
| | | } |
| | | |
| | | function defaultAcceptance() { |
| | | return { |
| | | id: undefined, |
| | | producer: undefined, // å家代表 |
| | | file: undefined, // ç¸å
³éä»¶ |
| | |
| | | substanceId: undefined, // æ¸
å |
| | | arriveDate: undefined, // å°è´§æ¥æ |
| | | maintenanceUnit: undefined, // ç»´ä¿®åä½ |
| | | list: [], |
| | | } |
| | | } |
| | | |
| | | export default { |
| | | components: { |
| | | limsTable, |
| | | }, |
| | | data() { |
| | | return { |
| | | dialogVisible: false, |
| | | loading: false, |
| | | submitLoading: false, |
| | | form: { |
| | | substance: defaultSubstance(), |
| | | acceptance: defaultAcceptance(), |
| | | }, |
| | | rules: { |
| | | 'substance.name': [{required: true, message: 'è¯·å¡«åæ åç©è´¨åç§°', trigger: 'blur'}], |
| | | 'substance.model': [{required: true, message: '请填åè§æ ¼åå·', trigger: 'blur'}], |
| | | 'substance.factoryNum': [{required: true, message: '请填ååºåç¼å·', trigger: 'blur'}], |
| | | 'substance.manageNum': [{required: true, message: '请填å管çç¼å·', trigger: 'blur'}], |
| | | 'substance.uncertainty': [{required: true, message: '请填åä¸ç¡®å®åº¦', trigger: 'blur'}], |
| | | 'substance.quantity': [{required: true, message: 'è¯·å¡«åæ°é', trigger: 'blur'}], |
| | | 'substance.acquisitionDate': [{required: true, message: 'è¯·éæ©è´ç½®æ¥æ', trigger: 'change'}], |
| | | 'substance.effectiveDate': [{required: true, message: 'è¯·éæ©æææ', trigger: 'change'}], |
| | | 'substance.fileNum': [{required: true, message: 'è¯·å¡«åæ¡£æ¡ç¼å·', trigger: 'blur'}], |
| | | 'substance.position': [{required: true, message: '请填ååæ¾ä½ç½®', trigger: 'blur'}], |
| | | }, |
| | | supplierOptions: [], |
| | | list: [], |
| | | spareColumns: [ |
| | | { |
| | |
| | | width: 150 |
| | | } |
| | | ], |
| | | options: [] |
| | | } |
| | | }, |
| | | mounted() { |
| | | this.getStand() |
| | | }, |
| | | methods: { |
| | | openDialog(id) { |
| | | this.loadSuppliers() |
| | | if(id) { |
| | | this.getDetail(id) |
| | | } else { |
| | |
| | | } |
| | | this.dialogVisible = true |
| | | }, |
| | | loadSuppliers() { |
| | | selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => { |
| | | if (res.code === 200) { |
| | | this.supplierOptions = (res.data.records || []).map(item => ({ |
| | | label: item.supplierName, |
| | | value: item.supplierName |
| | | })) |
| | | } |
| | | }) |
| | | }, |
| | | onSupplierChange(val) { |
| | | this.form.acceptance.producer = val || '' |
| | | }, |
| | | getDetail(id) { |
| | | this.loading = true |
| | | getAcceptanceDetails({id: id}).then(res => { |
| | | this.acceptance = res.data.acceptance |
| | | this.list = res.data.list |
| | | this.form.acceptance = res.data.acceptance || defaultAcceptance() |
| | | this.form.substance = res.data.substance || defaultSubstance() |
| | | this.list = res.data.list || [] |
| | | this.loading = false |
| | | }).catch(err => { |
| | | this.loading = false |
| | | }) |
| | | }, |
| | | getStand() { |
| | | getStandardSubstanceAll().then(res => { |
| | | this.options = res.data |
| | | }) |
| | | }, |
| | | addSpareTable() { |
| | | this.list.push({ |
| | | acceptanceId: this.acceptance.id, |
| | | acceptanceId: this.form.acceptance.id, |
| | | name: '', |
| | | number: '', |
| | | isEdit: true |
| | | }) |
| | | }, |
| | | onSuccess(response) { |
| | | this.acceptance.file = response.data |
| | | this.form.acceptance.file = response.data |
| | | }, |
| | | save(index) { |
| | | this.list[index]['isEdit'] = false |
| | |
| | | this.list[index]['isEdit'] = true |
| | | }, |
| | | clearForm() { |
| | | this.form.substance = defaultSubstance() |
| | | this.form.acceptance = defaultAcceptance() |
| | | this.list = [] |
| | | this.resetForm('acceptance') |
| | | this.$nextTick(() => { |
| | | if (this.$refs.form) { |
| | | this.$refs.form.clearValidate() |
| | | } |
| | | }) |
| | | }, |
| | | closeDialog() { |
| | | this.clearForm() |
| | | this.resetForm('acceptance') |
| | | this.dialogVisible = false |
| | | }, |
| | | submit() { |
| | | if (!this.acceptance.substanceId) { |
| | | this.$message.warning('è¯·éæ©æ¸
å') |
| | | return |
| | | this.$refs.form.validate((valid) => { |
| | | if (!valid) { |
| | | return false |
| | | } |
| | | this.acceptance.list = this.HaveJson(this.list) |
| | | const isEdit = !!this.form.acceptance.id |
| | | this.submitLoading = true |
| | | if(this.acceptance.id) { |
| | | updateAcceptance({acceptance: this.acceptance, list: this.list}).then(res => { |
| | | this.$message.success('ç¼è¾æå') |
| | | this.submitLoading = false |
| | | this.closeDialog() |
| | | this.$emit('submit') |
| | | }).catch((e) => { |
| | | this.submitLoading = false |
| | | }) |
| | | } else { |
| | | addAcceptance({acceptance: this.acceptance, list: this.list}).then(res => { |
| | | this.$message.success('æ°å¢æå') |
| | | this.closeDialog() |
| | | this.$emit('submit') |
| | | }).catch((e) => { |
| | | this.submitLoading = false |
| | | }) |
| | | const payload = { |
| | | acceptance: this.form.acceptance, |
| | | substance: this.form.substance, |
| | | list: this.HaveJson(this.list) |
| | | } |
| | | const request = isEdit ? updateAcceptance : addAcceptance |
| | | request(payload).then(res => { |
| | | this.submitLoading = false |
| | | this.$message.success(isEdit ? 'ç¼è¾æå' : 'æ°å¢æå') |
| | | this.closeDialog() |
| | | this.$emit('submit') |
| | | }).catch((e) => { |
| | | this.submitLoading = false |
| | | }) |
| | | }) |
| | | }, |
| | | }, |
| | | computed: { |
| | |
| | | height: 580px; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .section-title { |
| | | display: flex; |
| | | align-items: center; |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | color: var(--lims-text); |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid var(--lims-divider); |
| | | margin: 8px 0 16px; |
| | | } |
| | | |
| | | .section-title:not(:first-child) { |
| | | margin-top: 24px; |
| | | } |
| | | |
| | | .section-title::before { |
| | | content: ''; |
| | | display: inline-block; |
| | | width: 3px; |
| | | height: 14px; |
| | | border-radius: 2px; |
| | | background: var(--el-color-primary); |
| | | margin-right: 8px; |
| | | } |
| | | |
| | | .spare-toolbar { |
| | | text-align: right; |
| | | margin-bottom: 8px; |
| | | } |
| | | </style> |
| | |
| | | addRecordRef: false, |
| | | columns: [ |
| | | { |
| | | label: "åºåºç¼å·", |
| | | label: "åºåç¼å·", |
| | | prop: "factoryNum" |
| | | }, |
| | | { |
| | |
| | | prop: "factoryManufacturer" |
| | | }, |
| | | { |
| | | label: "ææ¡£ç¼å·", |
| | | label: "æ¡£æ¡ç¼å·", |
| | | prop: "fileNum" |
| | | }, |
| | | { |
| | |
| | | // }, |
| | | { |
| | | label: "æäº¤æ¥æ", |
| | | prop: "acquisitionDate" |
| | | prop: "createTime" |
| | | }, |
| | | { |
| | | label: "æ°é", |
| | | prop: "quantity" |
| | | }, |
| | | { |
| | | label: "åä½", |
| | | prop: "unit" |
| | | }, |
| | | { |
| | | fixed: "right", |
| | | label: "æä½", |
| | | align: "center", |
| | |
| | | </tr> |
| | | <tr> |
| | | <td class="td-title"> |
| | | <p>å§åï¼</p> |
| | | <p>客æ·ï¼</p> |
| | | </td> |
| | | <td class="td-info"> |
| | | <el-input v-model="form.userName" placeholder="请è¾å
¥å
容" size="small"> |
| | | </el-input> |
| | | <el-select v-model="form.orderId" filterable clearable size="small" style="width: 100%" |
| | | popper-class="customer-select-popper" placeholder="è¯·éæ©å®¢æ·ï¼å·²å®æå§æåï¼" @change="onCustomerChange"> |
| | | <el-option v-for="opt in customerOptions" :key="opt.id" :label="opt.company" :value="opt.id"> |
| | | <div class="customer-card"> |
| | | <div>客æ·ï¼{{ opt.company }}</div> |
| | | <div class="customer-card-sub">å§æåç¼å·ï¼{{ opt.entrustCode || '--' }}</div> |
| | | <div class="customer-card-sub">æ ·ååç§°ï¼{{ opt.sampleName || '--' }}</div> |
| | | </div> |
| | | </el-option> |
| | | </el-select> |
| | | </td> |
| | | <td class="td-title"> |
| | | <p>é¨é¨ï¼</p> |
| | |
| | | addClientSatisfaction, |
| | | updateClientSatisfaction |
| | | } from '@/api/cnas/systemManagement/customerSatisfaction.js' |
| | | import { selectCompletedOrders } from '@/api/business/productOrder' |
| | | export default { |
| | | name: 'formDialog', |
| | | // import å¼å
¥çç»ä»¶éè¦æ³¨å
¥å°å¯¹è±¡ä¸æè½ä½¿ç¨ |
| | |
| | | department: '', |
| | | contactNumber: '', |
| | | serviceAttitude: '', |
| | | serviceAttitudeSuggestion: '', |
| | | technicalCompetence: '', |
| | | technicalCompetenceSuggestion: '', |
| | | inspectionWork: '', |
| | |
| | | reasonableFeesSuggestion: '', |
| | | remark: '', |
| | | clientSatisfactionId: '', |
| | | orderId: '', |
| | | entrustCode: '', |
| | | sampleName: '' |
| | | }, |
| | | // 客æ·ä¸æé项ï¼åªå
å«"å·²ä¸è¿å§æåä¸å·²å®æ"çæ°æ® |
| | | customerOptions: [], |
| | | operationType: '', |
| | | editLoad: false, |
| | | |
| | |
| | | }, |
| | | // æ¹æ³éå |
| | | methods: { |
| | | openDia(type, row) { |
| | | async openDia(type, row) { |
| | | this.formDia = true; |
| | | this.operationType = type |
| | | await this.loadCustomerOptions() |
| | | if (this.operationType === 'edit') { |
| | | this.form = { ...row } |
| | | // èæ°æ®æ²¡æå
³èå§æåï¼åæä¸ä¸ªé项æåæ¥çå¼åæ¾åºæ¥ï¼ä¸å¼ºå¶éé |
| | | if (row.orderId == null && row.userName) { |
| | | this.customerOptions.unshift({ |
| | | id: 0, |
| | | company: row.userName, |
| | | entrustCode: row.entrustCode || '--', |
| | | sampleName: row.sampleName || '--' |
| | | }) |
| | | this.form.orderId = 0 |
| | | } else if (row.orderId && !this.customerOptions.some(o => o.id === row.orderId)) { |
| | | // å
³èçå§æå已䏿¯"已宿"ç¶æï¼ç¨è®°å½éçä¿¡æ¯å
åºåæ¾ |
| | | this.customerOptions.unshift({ |
| | | id: row.orderId, |
| | | company: row.userName || 'æªç¥å®¢æ·', |
| | | entrustCode: row.entrustCode || '--', |
| | | sampleName: row.sampleName || '--' |
| | | }) |
| | | } |
| | | } else { |
| | | this.resetForm() |
| | | } |
| | | }, |
| | | resetForm() { |
| | | this.form = { |
| | | unitName: '', |
| | | fillDate: '', |
| | | userName: '', |
| | | department: '', |
| | | contactNumber: '', |
| | | serviceAttitude: '', |
| | | serviceAttitudeSuggestion: '', |
| | | technicalCompetence: '', |
| | | technicalCompetenceSuggestion: '', |
| | | inspectionWork: '', |
| | | inspectionWorkSuggestion: '', |
| | | reasonableFees: '', |
| | | reasonableFeesSuggestion: '', |
| | | remark: '', |
| | | clientSatisfactionId: '', |
| | | orderId: '', |
| | | entrustCode: '', |
| | | sampleName: '' |
| | | } |
| | | }, |
| | | // ä¸ææ°æ®ï¼å端åªè¿å"å·²æ£éª"çå§æåï¼state=4ï¼ |
| | | loadCustomerOptions() { |
| | | this.customerOptions = [] |
| | | return selectCompletedOrders().then(res => { |
| | | if (res.code === 200 && res.data) { |
| | | this.customerOptions = res.data.map(o => ({ |
| | | id: o.id, |
| | | company: o.company, |
| | | entrustCode: o.entrustCode, |
| | | sampleName: o.sampleView |
| | | })) |
| | | } |
| | | }).catch(err => { |
| | | console.log('err---', err) |
| | | }) |
| | | }, |
| | | // éä¸å®¢æ·åï¼å填客æ·åå¹¶èªå¨å¸¦åºåä½åç§°ãå§æåç¼å·ãæ ·ååç§° |
| | | onCustomerChange(val) { |
| | | const opt = this.customerOptions.find(o => o.id === val) |
| | | if (!opt || opt.id === 0) { |
| | | return |
| | | } |
| | | this.form.userName = opt.company |
| | | this.form.entrustCode = opt.entrustCode |
| | | this.form.sampleName = opt.sampleName |
| | | this.form.unitName = opt.company |
| | | }, |
| | | handleEdit() { |
| | | const orderIdEmpty = this.form.orderId === '' || this.form.orderId === null || this.form.orderId === undefined |
| | | if (orderIdEmpty) { |
| | | this.$message.warning('è¯·éæ©å®¢æ·') |
| | | return |
| | | } |
| | | if (!this.form.unitName) { |
| | | this.$message.warning('请填ååä½åç§°') |
| | | return |
| | |
| | | return |
| | | } |
| | | this.editLoad = true |
| | | const payload = { ...this.form } |
| | | // èæ°æ®åæçåæ¾é项ï¼id=0ï¼ä¸ç®çå®å
³èï¼ä¿åæ¶ä»ä¿ææªå
³è |
| | | if (payload.orderId === 0) { |
| | | payload.orderId = null |
| | | } |
| | | if (this.operationType === 'add') { |
| | | addClientSatisfaction(this.form).then(res => { |
| | | addClientSatisfaction(payload).then(res => { |
| | | this.editLoad = false |
| | | this.$message.success('æäº¤æå') |
| | | this.closeFormDia() |
| | |
| | | this.editLoad = false |
| | | }) |
| | | } else { |
| | | updateClientSatisfaction(this.form).then(res => { |
| | | updateClientSatisfaction(payload).then(res => { |
| | | this.editLoad = false |
| | | this.$message.success('æäº¤æå') |
| | | this.closeFormDia() |
| | |
| | | word-wrap: break-word; |
| | | white-space: normal; |
| | | } |
| | | |
| | | .customer-card-sub { |
| | | color: #909399; |
| | | font-size: 12px; |
| | | } |
| | | </style> |
| | | |
| | | <style> |
| | | /* 䏿å¡çä¸è¡éè¦èªéåºé«åº¦ï¼å¼¹å± teleport å° bodyï¼ç¨èªå®ä¹ popper-class å½ä¸ */ |
| | | .customer-select-popper .el-select-dropdown__item { |
| | | height: auto; |
| | | line-height: 1.7; |
| | | padding: 6px 12px; |
| | | } |
| | | </style> |
| | |
| | | style="height: 90vh;overflow-y: auto;" /> |
| | | </el-dialog> |
| | | <FormDialog v-if="formDialog" ref="formDialog" @closeFormDia="closeFormDia"></FormDialog> |
| | | <lims-attachment ref="attachmentDialog" title="满æåº¦éä»¶" name-field="unitName" id-param="clientSatisfactionId" |
| | | upload-url="/clientSatisfaction/uploadAttachment" select-url="/clientSatisfaction/selectAttachments" |
| | | delete-url="/clientSatisfaction/deleteAttachment" /> |
| | | </div> |
| | | </template> |
| | | |
| | |
| | | import limsTable from "@/components/Table/lims-table.vue"; |
| | | import FormDialog from './components/formDialog.vue'; |
| | | import filePreview from '@/components/Preview/filePreview.vue' |
| | | import limsAttachment from '@/components/Attachment/lims-attachment.vue' |
| | | import { |
| | | pageClientSatisfaction, |
| | | pageAnalyseFile, |
| | |
| | | export default { |
| | | name: 'CustomerSatisfaction', |
| | | // import å¼å
¥çç»ä»¶éè¦æ³¨å
¥å°å¯¹è±¡ä¸æè½ä½¿ç¨ |
| | | components: { filePreview, FormDialog, limsTable }, |
| | | components: { filePreview, FormDialog, limsTable, limsAttachment }, |
| | | data() { |
| | | // è¿éåæ¾æ°æ® |
| | | return { |
| | |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'å§å', |
| | | label: '客æ·', |
| | | prop: 'userName', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'å§æåç¼å·', |
| | | prop: 'entrustCode', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | | label: 'æ ·ååç§°', |
| | | prop: 'sampleName', |
| | | minWidth: '100' |
| | | }, |
| | | { |
| | |
| | | }, |
| | | }, |
| | | { |
| | | name: 'éä»¶', |
| | | type: 'text', |
| | | clickFun: (row) => { |
| | | this.$refs.attachmentDialog.open(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: 'å é¤', |
| | | type: 'text', |
| | | color: 'var(--el-color-danger)', |