From 4518a41e3fce438fcf861317a603c6c17c1a047a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 13 二月 2025 17:52:32 +0800
Subject: [PATCH] 实验室资质、能力范围、场所或设施页面迁移
---
src/api/structural/laboratory.js | 26 ++
src/assets/styles/index.scss | 3
src/views/structural/premises/index.vue | 13 +
src/views/structural/laboratory/index.vue | 462 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/views/structural/capability/index.vue | 13 +
src/api/system/customer.js | 1
6 files changed, 517 insertions(+), 1 deletions(-)
diff --git a/src/api/structural/laboratory.js b/src/api/structural/laboratory.js
new file mode 100644
index 0000000..bf318db
--- /dev/null
+++ b/src/api/structural/laboratory.js
@@ -0,0 +1,26 @@
+import request from '@/utils/request'
+
+// 鏌ヨ璧勮川鏄庣粏鍒楄〃
+export function getCertificationDetail(query) {
+ return request({
+ url: '/certification/getCertificationDetail',
+ method: 'post',
+ params: query
+ })
+}
+// 娣诲姞璧勮川鏄庣粏鍒楄〃
+export function addCertificationDetail(query) {
+ return request({
+ url: '/certification/addCertificationDetail',
+ method: 'post',
+ params: query
+ })
+}
+// 鍒犻櫎璧勮川鏄庣粏鍒楄〃
+export function delCertificationDetail(query) {
+ return request({
+ url: '/certification/delCertificationDetail',
+ method: 'post',
+ params: query
+ })
+}
diff --git a/src/api/system/customer.js b/src/api/system/customer.js
index f64f3e2..a218cfb 100644
--- a/src/api/system/customer.js
+++ b/src/api/system/customer.js
@@ -1,5 +1,4 @@
import request from '@/utils/request'
-import { parseStrEmpty } from "@/utils/ruoyi";
// 鏌ヨ瀹㈡埛鍒楄〃
export function selectCustomPageList(query) {
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index 2f3b9ef..cacf353 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -123,6 +123,9 @@
.app-container {
padding: 20px;
}
+.capacity-scope {
+ padding: 20px;
+}
.components-container {
margin: 30px 50px;
diff --git a/src/views/structural/capability/index.vue b/src/views/structural/capability/index.vue
new file mode 100644
index 0000000..2ebcd51
--- /dev/null
+++ b/src/views/structural/capability/index.vue
@@ -0,0 +1,13 @@
+<script>
+export default {
+name: "index"
+}
+</script>
+
+<template>
+
+</template>
+
+<style scoped lang="scss">
+
+</style>
diff --git a/src/views/structural/laboratory/index.vue b/src/views/structural/laboratory/index.vue
new file mode 100644
index 0000000..00da998
--- /dev/null
+++ b/src/views/structural/laboratory/index.vue
@@ -0,0 +1,462 @@
+<template>
+ <div class="capacity-scope">
+ <div>
+ <el-form :model="queryParams" ref="queryForm" size="small" :inline="true">
+ <el-form-item label="璧勮川鍚嶇О" prop="nickName">
+ <el-select v-model="queryParams.name" placeholder="閫夋嫨璧勮川鍚嶇О" size="small" @change="refreshTable()">
+ <el-option v-for="dict in dict.type.qualification_name" :key="dict.value" :label="dict.label" :value="dict.value">
+ {{ dict.label }}
+ </el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" icon="el-icon-search" size="mini" @click="refreshTable">鏌� 璇�</el-button>
+ <el-button icon="el-icon-refresh" size="mini" @click="refresh">閲� 缃�</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div>
+ <el-row class="title">
+ <el-col :span="12" style="text-align: left">
+ <el-radio-group v-model="radio" @input="selectorSwitch" size="medium" fill="#409EFF">
+ <el-radio-button :label="0">璧勮川鏄庣粏</el-radio-button>
+ <el-radio-button :label="1">璧勮川鎬昏</el-radio-button>
+ </el-radio-group>
+ </el-col>
+ <el-col :span="12" style="text-align: right;" v-if="radio===0">
+ <el-button size="small" type="primary" @click="openAdd">璧勮川鏇存柊</el-button>
+ <el-button size="small" icon="el-icon-delete" @click="handleDel">鍒犻櫎</el-button>
+ </el-col>
+ </el-row>
+ </div>
+ <div v-if="radio===0">
+ <lims-table :tableData="tableData" :column="column"
+ :isSelection="true" :handleSelectionChange="handleSelectionChange"
+ :page="page" :tableLoading="tableLoading"></lims-table>
+ </div>
+ <div class="table" v-if="radio===1" v-loading="pageLoading" @scroll="scrollFn">
+ <el-row :gutter="16">
+ <el-col :span="6" v-for="(m,i) in list" :key="i" :xs="24" :sm="12" :md="8" :lg="6" :xl="6" style="margin-bottom: 16px;">
+ <div class="table-item">
+ <el-image style="width: 102px;height: 102px;margin-right: 20px;border-radius: 16px;" :src="process.env.VUE_APP_BASE_API+'/img/'+m.imageUrl">
+ <div slot="error" class="image-error" style="width: 100px;
+ height: 100px;
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #EEEEEE;">
+ <i class="el-icon-picture-outline" style="font-size:30px;color:#666666;"></i>
+ </div>
+ </el-image>
+ <div class="table-item-right" style="flex: 1;font-size: 12px;color: #666666;">
+ <p style="line-height: 26px;">璧勮川鍚嶇О锛�<span style="color: #3A7BFA;">{{ m.name }}</span></p>
+ <p style="line-height: 26px;">棰佸彂鏃堕棿锛歿{m.recentlyTime}}</p>
+ <p style="line-height: 26px;">鍒版湡鏃堕棿锛歿{m.expireTime}}</p>
+ <p>
+ <span>鐘舵�侊細</span>
+ <el-tag :type="m.state===0?'danger':'success'" size="small">{{ m.state===0?'澶辨晥':'鏈夋晥' }}</el-tag>
+ </p>
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+ <div v-if="list.length<1&&!pageLoading&&!isLoding" style="color:#909399;font-size:14px;text-align: center;margin-top:200px" >鏆傛棤鏁版嵁</div>
+ <div v-if="list.length>0">
+ <el-button v-if="isLoding" type="text" style="display: flex; margin: 0 auto; color: #909399">
+ <i class="el-icon-loading" style="font-size:20px"></i>
+ </el-button>
+ <el-button type="text" v-if="finishLoding" style="display: flex; margin: 0 auto; color: #909399">宸茬粡娌℃湁鏇村鍟</el-button>
+ </div>
+ </div>
+ <el-dialog title="璧勮川鏇存柊" :visible.sync="qualificationsConnectVisible" width="400px">
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px"><span class="required-span">* </span>璧勮川鍚嶇О锛�</div>
+ <div class="search_input">
+ <el-select v-model="formData.name" placeholder="璇烽�夋嫨" style="width: 100%;" size="small" clearable>
+ <el-option
+ v-for="item in qualificationsList"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value">
+ </el-option>
+ </el-select>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px"><span class="required-span">* </span>璧勮川缂栫爜锛�</div>
+ <div class="search_input">
+ <el-input
+ size="small"
+ placeholder="璇疯緭鍏�"
+ clearable
+ v-model="formData.code"></el-input>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px"><span class="required-span">* </span>棰佸彂鏈烘瀯锛�</div>
+ <div class="search_input">
+ <el-input
+ size="small"
+ placeholder="璇疯緭鍏�"
+ clearable
+ v-model="formData.organization"></el-input>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px">璧勮川璇存槑锛�</div>
+ <div class="search_input">
+ <el-input
+ size="small"
+ placeholder="璇疯緭鍏�"
+ clearable
+ v-model="formData.explanation"></el-input>
+ </div>
+ </div>
+
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px"><span class="required-span">* </span>棰佸彂鏃堕棿锛�</div>
+ <div class="search_input">
+ <el-date-picker style="width:100%" v-model="formData.dateOfIssuance"
+ type="datetime"
+ size="small"
+ format="yyyy-MM-dd HH:mm:ss"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ clearable
+ placeholder="閫夋嫨鏃ユ湡">
+ </el-date-picker>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px"><span class="required-span">* </span>鍒版湡鏃堕棿锛�</div>
+ <div class="search_input">
+ <el-date-picker style="width:100%" v-model="formData.expireTime"
+ type="datetime"
+ size="small"
+ format="yyyy-MM-dd HH:mm:ss"
+ value-format="yyyy-MM-dd HH:mm:ss"
+ clearable
+ placeholder="閫夋嫨鏃ユ湡">
+ </el-date-picker>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px">璧勮川鍥剧墖锛�</div>
+ <div class="search_input">
+ <el-upload
+ ref="upload"
+ :action="action"
+ :on-success="m=>handleSuccessUpImg(m,'imageUrl')"
+ accept='image/jpg,image/jpeg,image/png'
+ :multiple="false"
+ :limit="1"
+ :headers="headers" :on-change="beforeUpload"
+ :on-error="onError">
+ <el-button slot="trigger" size="small" type="primary">閫夊彇鍥剧墖</el-button>
+ </el-upload>
+ </div>
+ </div>
+ <div class="search_thing" style="margin-bottom: 16px;">
+ <div class="search_label" style="width:120px">璧勮川闄勪欢锛�</div>
+ <div class="search_input">
+ <el-upload
+ ref="upload1"
+ :action="action"
+ :on-success="m=>handleSuccessUpImg(m,'fileUrl')"
+ accept='image/jpg,image/jpeg,image/png,application/pdf,.doc,.docx' :headers="headers" :multiple="false" :limit="1" :on-change="beforeUpload1"
+ :on-error="onError1">
+ <el-button slot="trigger" size="small" type="primary">閫夊彇鏂囦欢</el-button>
+ </el-upload>
+ </div>
+ </div>
+ <span slot="footer" class="dialog-footer">
+ <el-button @click="qualificationsConnectVisible = false">鍙� 娑�</el-button>
+ <el-button type="primary" @click="confirmQualifications" :loading="loading">纭� 瀹�</el-button>
+ </span>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import limsTable from "@/components/Table/lims-table.vue";
+import {addCertificationDetail, delCertificationDetail, getCertificationDetail} from "@/api/structural/laboratory";
+
+export default {
+ components: {
+ limsTable
+ },
+ dicts: ['qualification_name'],
+ data() {
+ return {
+ radio: 0,
+ queryParams: {
+ name: ''
+ },
+ tableData: [],
+ selection: [],
+ column: [
+ {label: '璧勮川鍚嶇О', prop: 'name'},
+ {label: '璧勮川缂栫爜', prop: 'code'},
+ {label: '棰佸彂鏈烘瀯', prop: 'organization'},
+ {label: '璧勮川璇存槑', prop: 'explanation'},
+ {label: '棣栨棰佸彂鏃堕棿', prop: 'firstIssuanceDate'},
+ {label: '鏈�杩戦鍙戞椂闂�', prop: 'latestIssuanceDate'},
+ {label: '鍒版湡棰佸彂鏃堕棿', prop: 'expireTime'},
+ {
+ dataType: 'action',
+ fixed: 'right',
+ label: '鎿嶄綔',
+ operation: [
+ {
+ name: '闄勪欢涓嬭浇',
+ type: 'text',
+ clickFun: (row) => {
+ this.handleDownLoad(row);
+ },
+ },
+ ]
+ }
+ ],
+ page: {
+ total:0,
+ size:10,
+ current:0
+ },
+ tableLoading: false,
+ qualificationsList:[],
+ qualificationsConnectVisible:false,
+ formData:{},
+ loading:false,
+ pageLoading:false,
+ isLoding: false, // 鍔犺浇涓紝loading鍥炬爣,榛樿涓簍rue
+ finishLoding: false, // 鍔犺浇瀹屾垚锛屾樉绀哄凡缁忔病鏈夋洿澶氫簡
+ currentPage: 1, // 褰撳墠椤�
+ pageSize: 16, // 涓�椤�16鏉�
+ total: '',
+ list:[],
+ }
+ },
+ computed: {
+ headers() {
+ return {
+ 'token': sessionStorage.getItem('token')
+ }
+ },
+ action() {
+ return ''
+ }
+ },
+ mounted() {
+ this.refreshTable()
+ },
+ methods: {
+ selectorSwitch(radio) {
+ if(radio === '1'){
+ this.list = [];
+ this.refreshTable();
+ }
+ },
+ refreshTable() {
+ if (this.radio === '0') {
+ getCertificationDetail({...this.page,...this.queryParams,}).then(res => {
+ this.tableLoading = false
+ if (res.code === 200) {
+ this.tableData = res.data
+ this.page.total = res.total
+ }
+ }).catch(err => {
+ this.tableLoading = false
+ })
+ } else {
+ if(this.currentPage>1){
+ this.isLoding = true
+ }else{
+ this.pageLoading = true
+ }
+ if(this.list.length===0){
+ window.addEventListener("scroll", this.throttle(this.scrollFn, 20000));
+ }
+ getCertificationDetail({
+ page: {
+ current: this.currentPage,
+ size: this.pageSize
+ },
+ entity: this.queryParams
+ }).then(res => {
+ if(res.code===200){
+ this.total = res.data.body.total
+ let list = res.data.body.records;
+ if(list.length===0){
+ this.finishLoding = true;
+ }else{
+ if(list.length<this.pageSize){
+ this.finishLoding = true;
+ }
+ this.list = this.list.concat(list)
+ if(this.total===this.list.length){
+ this.finishLoding = true;
+ }
+ }
+ }
+ this.pageLoading = false
+ this.isLoding = false;
+ }).catch(err => {
+ this.pageLoading = false
+ this.isLoding = false;
+ })
+ }
+ },
+ // 閲嶇疆
+ refresh() {
+ this.queryParams.name = ''
+ this.page.size = 10
+ this.page.current = 1
+ this.refreshTable()
+ },
+ // 琛ㄦ牸澶氶��
+ handleSelectionChange (selection) {
+ this.selection = selection;
+ },
+ // 璧勮川鏄庣粏鎵归噺鍒犻櫎
+ handleDel(){
+ if (this.selection.length===0) {
+ this.$message.warning('璇烽�夋嫨鑷冲皯涓�鏉℃暟鎹�')
+ return
+ }
+ const delIds = []
+ this.selection.forEach(item => {
+ delIds.push(item.id)
+ })
+ delCertificationDetail(delIds).then(res => {
+ if (res.code !== 200) return
+ this.refreshTable();
+ this.$message.success('鍒犻櫎鎴愬姛')
+ })
+ },
+ // 璧勮川鏄庣粏闄勪欢涓嬭浇
+ handleDownLoad(row){
+ // let url = row.fileUrl;
+ // const link = document.createElement('a');
+ // link.href = this.javaApi + '/img/'+ url;
+ // document.body.appendChild(link);
+ // link.target = '_blank';
+ // link.click();
+ const url = process.env.VUE_APP_BASE_API + '/img/'+ row.fileUrl
+ this.$download.saveAs(url, row.fileUrl);
+ },
+ openAdd() {
+ this.qualificationsConnectVisible = true;
+ this.$nextTick(()=>{
+ this.$refs.upload.clearFiles()
+ this.$refs.upload1.clearFiles()
+ })
+ this.formData = {};
+ },
+ handleSuccessUpImg(response,name) {
+ if (response.code === 200) {
+ this.formData[name] = response.data.url;
+ }
+ },
+ beforeUpload(file) {
+ if (file.size > 1024 * 1024 * 10) {
+ this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+ this.$refs.upload.clearFiles()
+ return false;
+ } else {
+ return true;
+ }
+ },
+ onError(err, file, fileList) {
+ this.$message.error('涓婁紶澶辫触')
+ this.$refs.upload.clearFiles()
+ },
+ beforeUpload1(file) {
+ if (file.size > 1024 * 1024 * 10) {
+ this.$message.error('涓婁紶鏂囦欢涓嶈秴杩�10M');
+ this.$refs.upload1.clearFiles()
+ return false;
+ } else {
+ return true;
+ }
+ },
+ onError1(err, file, fileList) {
+ this.$message.error('涓婁紶澶辫触')
+ this.$refs.upload1.clearFiles()
+ },
+ confirmQualifications(){
+ if(!this.formData.name){
+ this.$message.error('鏈~鍐欒祫璐ㄥ悕绉�');
+ return
+ }
+ if(!this.formData.code){
+ this.$message.error('鏈~鍐欒祫璐ㄧ紪鐮�');
+ return
+ }
+ if(!this.formData.organization){
+ this.$message.error('鏈~鍐欓鍙戞満鏋�');
+ return
+ }
+ if(!this.formData.expireTime){
+ this.$message.error('鏈~鍐欏埌鏈熼鍙戞椂闂�');
+ return
+ }
+ if(!this.formData.imageUrl){
+ this.$message.error('鏈笂浼犺祫璐ㄥ浘鐗�');
+ return
+ }
+ if(!this.formData.fileUrl){
+ this.$message.error('鏈笂浼犺祫璐ㄩ檮浠�');
+ return
+ }
+ this.loading = true;
+ addCertificationDetail({...this.formData}).then(res => {
+ this.loading = false
+ if (res.code === 201) return
+ this.$message.success('宸叉彁浜�')
+ this.refreshTable('page')
+ this.qualificationsConnectVisible = false
+ })
+ },
+ // 婊氬姩瑙﹀簳鍔犺浇
+ scrollFn() {
+ let clientHeight = document.documentElement.clientHeight - 18; //鍙鍖哄煙
+ let scrollHeight = document.body.scrollHeight; // 婊氬姩鏂囨。楂樺害
+ let scrollTop = parseInt(document.documentElement.scrollTop); // 宸叉粴鍔ㄧ殑楂樺害
+ let height = 300;
+ if (scrollTop + clientHeight >= scrollHeight - height && scrollHeight !== 0) {
+ if (!this.finishLoding&&this.currentPage*this.pageSize<this.total) {
+ this.currentPage = this.currentPage + 1;
+ this.refreshTable();
+ }
+ } else {
+ return false;
+ }
+ },
+ throttle(fn, wait) {
+ // 灏佽鍑芥暟杩涜鑺傛祦
+ var timer = null;
+ return function () {
+ var context = this;
+ var args = arguments;
+ if (!timer) {
+ timer = setTimeout(function () {
+ fn.apply(context, args);
+ timer = null;
+ }, wait);
+ }
+ };
+ },
+ },
+ destroyed() {
+ window.removeEventListener("scroll", this.throttle(), false);
+ },
+}
+</script>
+
+<style scoped>
+.title {
+ height: 40px;
+ line-height: 40px;
+ margin-bottom: 10px;
+}
+</style>
diff --git a/src/views/structural/premises/index.vue b/src/views/structural/premises/index.vue
new file mode 100644
index 0000000..65bfbb8
--- /dev/null
+++ b/src/views/structural/premises/index.vue
@@ -0,0 +1,13 @@
+<script>
+export default {
+ name: "index"
+}
+</script>
+
+<template>
+
+</template>
+
+<style scoped lang="scss">
+
+</style>
--
Gitblit v1.9.3