gaoluyang
2025-02-13 4518a41e3fce438fcf861317a603c6c17c1a047a
实验室资质、能力范围、场所或设施页面迁移
已修改2个文件
已添加4个文件
518 ■■■■■ 文件已修改
src/api/structural/laboratory.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/customer.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/styles/index.scss 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/structural/capability/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/structural/laboratory/index.vue 462 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/structural/premises/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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
  })
}
src/api/system/customer.js
@@ -1,5 +1,4 @@
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi";
// æŸ¥è¯¢å®¢æˆ·åˆ—表
export function selectCustomPageList(query) {
src/assets/styles/index.scss
@@ -123,6 +123,9 @@
.app-container {
  padding: 20px;
}
.capacity-scope {
  padding: 20px;
}
.components-container {
  margin: 30px 50px;
src/views/structural/capability/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<script>
export default {
name: "index"
}
</script>
<template>
</template>
<style scoped lang="scss">
</style>
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图标,默认为true
      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>
src/views/structural/premises/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
<script>
export default {
  name: "index"
}
</script>
<template>
</template>
<style scoped lang="scss">
</style>