新疆——新聚lims
1.标准库层级需要修改层级,行业-标准,总共两级;实验室换成行业
2.每个标准下的检验项列表加一个搜索查询功能
已添加1个文件
已修改4个文件
806 ■■■■■ 文件已修改
src/utils/standardTree.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/business/productOrder/components/addOrder.vue 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/standard/standardLibrary/components/BatchCopy.vue 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/standard/standardLibrary/index.vue 503 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/standardTree.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,77 @@
/**
 * æ ‡å‡†åº“树通用工具
 *
 * å±‚级不固定:children ä¸º null / undefined / ç©ºæ•°ç»„的节点即为「标准」叶子。
 * æ ‘路径统一由 " - " è¿žæŽ¥ï¼Œæ ¼å¼ä¸ŽåŽ†å²å®žçŽ°é€å­—èŠ‚ä¿æŒä¸€è‡´ï¼š
 * é¡¶å±‚真实节点的 parent æ˜¯ Element UI çš„虚拟根,因此根节点会进入路径。
 */
// æ˜¯å¦å¶å­ï¼ˆæ ‡å‡†ï¼‰
export function isLeaf(data) {
  if (!data) return true;
  const children = data.children;
  return children === null || children === undefined || children.length === 0;
}
// ç¥–å…ˆ label åˆ—表:含根,顺序为 æ ¹ -> å¶
export function getAncestorLabels(node) {
  const labels = [];
  let cur = node;
  while (cur && cur.parent) {
    labels.push(cur.label);
    cur = cur.parent;
  }
  labels.reverse();
  return labels;
}
// å¤åˆ»åŽŸ getNodeParent çš„路径格式
// leafMarker:标准库传 'null',下单侧传 ''
// å¶å­åˆ¤å®šå¿…须与 isLeaf ä¸€è‡´ï¼Œå¦åˆ™ children ä¸º undefined / ç©ºæ•°ç»„的叶子会丢失标记段
export function buildSelectTree(node, leafMarker = '') {
  const tokens = [];
  let cur = node;
  while (cur && cur.parent) {
    if (isLeaf(cur.data)) {
      tokens.push(cur.label, leafMarker);
    } else {
      tokens.push(cur.label);
    }
    cur = cur.parent;
  }
  tokens.reverse();
  return tokens.join(' - ');
}
// è·¯å¾„末段是否为叶子(标准):buildSelectTree ä¼šåœ¨å¶å­å‰æ’入标记段
// ç”¨å®ƒåˆ¤æ–­æ— éœ€ä¾èµ– el-tree èŠ‚ç‚¹å¯¹è±¡ï¼Œæ¨¡æ¿å›žå¡«è·¯å¾„åŽåŒæ ·é€‚ç”¨
export function isLeafPath(path) {
  if (!path) return false;
  const tokens = path.split(' - ');
  if (tokens.length < 2) return false;
  const marker = tokens[tokens.length - 2];
  return marker === '' || marker === 'null';
}
// æŒ‰ç¥–先位置映射订单实体字段
// ç¼ºå¤±çš„非叶子层级填空串,model å–叶子 label(叶子即标准)
export function deriveTreeFields(node) {
  const labels = getAncestorLabels(node);
  const n = labels.length;
  const at = (i) => (i < n - 1 ? labels[i] : '');
  return {
    labels,
    factory: at(0),
    laboratory: at(1),
    sampleType: at(2),
    sample: at(3),
    model: n ? labels[n - 1] : '',
  };
}
// åŽ»æŽ‰è·¯å¾„æœ«æ®µï¼Œç”¨äºŽã€Œå½“å‰æ˜¯å¶å­ä½†æŸ¥ä¸åˆ°æ ‡å‡†ã€æ—¶å›žé€€åˆ°çˆ¶çº§æŸ¥è¯¢
export function dropLastLabel(path) {
  if (!path) return '';
  const idx = path.lastIndexOf(' - ');
  return idx === -1 ? '' : path.slice(0, idx);
}
src/views/business/productOrder/components/addOrder.vue
@@ -612,6 +612,12 @@
import {mapGetters} from "vuex";
import { bigEval } from "@/utils/bigEval";
import {addQuarter, updateQuarterOnOrder} from "@/api/business/finishedProductSampling";
import {
  isLeafPath,
  buildSelectTree,
  deriveTreeFields,
  dropLastLabel,
} from "@/utils/standardTree";
export default {
  name: 'AddOrder',
@@ -744,6 +750,8 @@
      list: [],
      selectStandardTreeLoading: false,
      selectTree: null,
      // å½“前选中的树节点(用于按层级推导字段)
      selectTreeNode: null,
      sampleViewEn: null,
      expandedKeys: [],
      sampleList: [],
@@ -1470,9 +1478,9 @@
      },
      nodeOpen(data, node, el) {
        $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder-opened')
        if (node.data.code === '[3]') {
        if (data.sampleTypeEn !== undefined && data.sampleTypeEn !== null) {
          this.sampleViewEn = data.sampleTypeEn
        } else if (node.data.code === '[4]') {
        } else if (data.sampleEn !== undefined && data.sampleEn !== null) {
          this.sampleViewEn = data.sampleEn
        }
      },
@@ -1480,47 +1488,13 @@
        $($(el.$el).find('.node_i')[0]).attr('class', 'node_i el-icon-folder')
      },
      handleNodeClick(val, node, el) {
        this.selectTree = ''
        this.models = val.children
        this.getNodeParent(node)
        let flag = false
        if (node.level == 3) {
          if(node.data.children.length>0){
            node.data.children.forEach(a => {
              let key = Object.keys(a)
              if(!key.includes('level')) {
                flag = true
              }
            })
          }
        }
        if (node.data.code === '[3]') {
        this.selectTreeNode = node
        this.models = val.children || []
        this.selectTree = buildSelectTree(node, '')
        if (val.sampleTypeEn !== undefined && val.sampleTypeEn !== null) {
          this.sampleViewEn = val.sampleTypeEn
        } else if (node.data.code === '[4]') {
          if (node.data.children!==null && node.data.children.length>0) {
            this.sampleViewEn = val.sampleEn
          }
        }
        this.selectTree = this.selectTree.replace(' - ', '')
        if(flag) {
          this.selectTree =  ' -  - ' + this.selectTree
        }
        let data = this.selectTree.split(' - ')
        let data2 = ''
        for (let index = data.length - 1; index >= 0; index--) {
          data2 += " - " + data[index]
        }
        this.selectTree = data2.replace(' - ', '')
      },
      getNodeParent(val) {
        if (val.parent != null) {
          if (val.data.children === null) {
            this.selectTree += ' - ' + val.label + ' - ' + ''
          } else {
            this.selectTree += ' - ' + val.label
          }
          this.getNodeParent(val.parent)
        } else if (val.sampleEn !== undefined && val.sampleEn !== null) {
          this.sampleViewEn = val.sampleEn
        }
      },
      selectStandardTreeList() {
@@ -1538,22 +1512,18 @@
        return data.label.indexOf(value) !== -1;
      },
      activeStandardTree() {
        let trees = this.selectTree.split(" - ")
        if (trees.length < 3) {
        const fields = deriveTreeFields(this.selectTreeNode)
        if (fields.labels.length < 2) {
          this.$message.error('未选择对象')
          return
        }
        this.addObj.factory = trees[0]
        this.addObj.laboratory = trees[1]
        this.addObj.sampleType = trees[2]
        if (trees[3] === undefined || trees[3] === '' || trees[3] === '- ') {
          this.addObj.sample = trees[2]
        } else {
          this.addObj.sample = trees[3]
        }
        this.addObj.factory = fields.factory
        this.addObj.laboratory = fields.laboratory
        this.addObj.sampleType = fields.sampleType
        this.addObj.sample = fields.sample || fields.sampleType
        this.addObj.sampleView = this.addObj.sample
        this.addObj.sampleViewEn = this.sampleViewEn
        this.addObj.model = (trees[4] == undefined ? null : trees[4])
        this.addObj.model = fields.model
        this.selectStandardTree = false
        this.sampleList = []
        for (var i = 0; i < this.addObj.sampleNum; i++) {
@@ -1575,26 +1545,35 @@
        this.$refs.sampleTable.doLayout()
        // this.selectsStandardMethodByFLSSM()
      },
      // ç”¨æŒ‡å®šåž‹å·æ›¿æ¢æ ‘路径末段(末段即标准/型号)
      buildFactoryPath(model) {
        const tree = this.selectTree || ''
        if (!tree || !model) return tree
        const tokens = tree.split(' - ')
        tokens[tokens.length - 1] = model
        return tokens.join(' - ')
      },
      selectsStandardMethodByFLSSMList() {
        this.methodLoad = true
        selectsStandardMethodByFLSSM({
          tree: this.selectTree
        }).then(res => {
          this.methodLoad = false
          try {
            if (res.data.standardMethodList.length == 0 && this.selectTree.split('-').length == 5) {
              let arr = this.selectTree.split('-')
              let arr0 = arr.slice(0, arr.length - 1)
              let selectTree = arr0.join('-').substring(0, arr0.join('-').length - 1)
          const list = (res.data && res.data.standardMethodList) || []
          // å½“前是叶子(标准)却查不到标准时,回退到父级再查一次
          // ç”¨è·¯å¾„判定叶子:模板回填时 selectTreeNode ä¸ºç©ºï¼ŒèŠ‚ç‚¹å¯¹è±¡åˆ¤å®šä¼šå¤±æ•ˆ
          if (list.length === 0 && isLeafPath(this.selectTree)) {
            const parentTree = dropLastLabel(this.selectTree)
            if (parentTree) {
              selectsStandardMethodByFLSSM({
                tree: selectTree
                tree: parentTree
              }).then(ress => {
                this.methods = ress.data.standardMethodList
                this.methods = (ress.data && ress.data.standardMethodList) || []
              })
            } else {
              this.methods = res.data.standardMethodList
              return
            }
          } catch (e) {}
          }
          this.methods = list
        })
      },
      addStandardTree() {
@@ -1833,13 +1812,11 @@
          }
        }
        this.getProductLoad = true
        let selectTreeList = this.selectTree.split(" - ")
        this.addObj.model&&(selectTreeList[selectTreeList.length - 1] = this.addObj.model)
        selectStandardProductList({
          model: this.addObj.model?this.addObj.model:row.model,
          modelNum: row.modelNum,
          standardMethodListId: val,
          factory: selectTreeList.join(" - "),
          factory: this.buildFactoryPath(this.addObj.model),
          cores: row.cores,
          conductorMaterial: row.conductorMaterial,
          conductorType: row.conductorType,
@@ -1900,14 +1877,12 @@
          this.isAskOnlyRead = false
        }
        this.getProductLoad = true
        let selectTreeList = this.selectTree.split(" - ")
        this.addObj.model&&(selectTreeList[selectTreeList.length - 1] = this.addObj.model)
        selectStandardProductList({
          model: this.addObj.model?this.addObj.model:row.model,
          modelNum: row.modelNum,
          standardMethodListId: val,
          cores: row.cores,
          factory: selectTreeList.join(" - "),
          factory: this.buildFactoryPath(this.addObj.model),
        }).then(res => {
          res.data.forEach(a => {
            a.state = this.inspectionScope === 'all' ? 1 : 0
@@ -1949,13 +1924,13 @@
      },
      handleChangeModel(e) {
        this.productList = []
        let num = this.selectTree.split('-').length;
        if (num != 5) {
          this.selectTree = this.selectTree + ' - ' + e
        const tree = this.selectTree || ''
        // è·¯å¾„末段已是标准(叶子):替换末段;否则追加
        // ç”¨è·¯å¾„判定:模板回填(obj.selectTree)时没有可用的树节点对象
        if (isLeafPath(tree)) {
          this.selectTree = this.buildFactoryPath(e)
        } else {
          let arr = this.selectTree.split('-')
          let arr0 = arr.slice(0, arr.length - 1)
          this.selectTree = arr0.join('-') + '- ' + e
          this.selectTree = tree ? tree + ' - ' + e : e
        }
      },
      // è¦æ±‚值变化时
@@ -2091,13 +2066,7 @@
        const selectedProducts = sample.insProduct || []
        if (!sample.standardMethodListId) return Promise.resolve(sample)
        const product = selectedProducts[0] || {}
        const factory = [
          product.factory || this.addObj.factory,
          product.laboratory || this.addObj.laboratory,
          product.sampleType || this.addObj.sampleType,
          product.sample || sample.sample,
          product.model || sample.model
        ].join(' - ')
        const factory = this.buildFactoryPath(product.model || sample.model)
        return selectStandardProductList({
          model: sample.model,
          modelNum: sample.modelNum,
src/views/standard/standardLibrary/components/BatchCopy.vue
@@ -229,11 +229,11 @@
                <span
                  ><i
                    :class="`node_i ${
                      data.children != undefined
                        ? data.code === '[1]'
                      isLeaf(data)
                        ? 'el-icon-tickets'
                        : data.code === '[1]'
                          ? 'el-icon-folder-opened'
                          : 'el-icon-folder'
                        : 'el-icon-tickets'
                    }`"
                  ></i>
                  {{ data.code }} {{ data.label }}</span
@@ -467,6 +467,12 @@
  selectStandardTreeList2,
  selectsStandardMethodByFLSSM,
} from "@/api/standard/standardLibrary";
import {
  isLeaf,
  buildSelectTree,
  deriveTreeFields,
  dropLastLabel,
} from "@/utils/standardTree";
export default {
  name: "BatchCopy",
  // import å¼•入的组件需要注入到对象中才能使用
@@ -498,6 +504,8 @@
      search: null,
      expandedKeys: [],
      selectTree: null,
      // å½“前选中的树节点,用于按层级推导字段
      treeNode: null,
      standardMethodListId: null,
      methodLoad: false,
      methods: [],
@@ -516,6 +524,8 @@
  },
  // æ–¹æ³•集合
  methods: {
    // ä¾›æ¨¡æ¿åˆ¤æ–­å¶å­(标准)节点
    isLeaf,
    // èŽ·å–å·¦è¾¹è¡¨æ ¼æ•°æ®
    getList() {
      this.batchCopyDia = true;
@@ -685,7 +695,8 @@
    selectStandardTreeList() {
      this.selectStandardTreeLoading = true;
      selectStandardTreeList2().then((res) => {
        this.list = res.data;
        this.list = res.data || [];
        this.expandedKeys = [];
        this.list.forEach((a) => {
          this.expandedKeys.push(a.label);
        });
@@ -694,39 +705,8 @@
    },
    // é€‰æ‹©æ ·å“åç§°çš„回调
    handleNodeClick(val, node, el) {
      this.selectTree = "";
      this.getNodeParent(node);
      let flag = false;
      if (node.level == 3) {
        if (node.data.children.length > 0) {
          node.data.children.forEach((a) => {
            let key = Object.keys(a);
            if (!key.includes("level")) {
              flag = true;
            }
          });
        }
      }
      this.selectTree = this.selectTree.replace(" - ", "");
      if (flag) {
        this.selectTree = " -  - " + this.selectTree;
      }
      let data = this.selectTree.split(" - ");
      let data2 = "";
      for (let index = data.length - 1; index >= 0; index--) {
        data2 += " - " + data[index];
      }
      this.selectTree = data2.replace(" - ", "");
    },
    getNodeParent(val) {
      if (val.parent != null) {
        if (val.data.children === null) {
          this.selectTree += " - " + val.label + " - " + "null";
        } else {
          this.selectTree += " - " + val.label;
        }
        this.getNodeParent(val.parent);
      }
      this.treeNode = node;
      this.selectTree = buildSelectTree(node, "null");
    },
    changeStandardMethodListId() {
      // æ ¹æ®æ£€éªŒæ ‡å‡†æŸ¥å³è¾¹table数据
@@ -753,38 +733,29 @@
        tree: this.selectTree,
      }).then((res) => {
        this.methodLoad = false;
        try {
          if (
            res.data.standardMethodList.length == 0 &&
            this.selectTree.split("-").length == 5
          ) {
            let arr = this.selectTree.split("-");
            let arr0 = arr.slice(0, arr.length - 1);
            let selectTree = arr0
              .join("-")
              .substring(0, arr0.join("-").length - 1);
        const list = (res.data && res.data.standardMethodList) || [];
        // å½“前是叶子(标准)却查不到标准时,回退到父级再查一次
        if (list.length === 0 && this.treeNode && isLeaf(this.treeNode.data)) {
          const parentTree = dropLastLabel(this.selectTree);
          if (parentTree) {
            selectsStandardMethodByFLSSM({
              tree: selectTree,
              tree: parentTree,
            }).then((ress) => {
              this.methods = ress.data.standardMethodList;
              this.methods = (ress.data && ress.data.standardMethodList) || [];
            });
          } else {
            this.methods = res.data.standardMethodList;
            return;
          }
        } catch (e) {}
        }
        this.methods = list;
      });
    },
    activeStandardTree() {
      let trees = this.selectTree.split(" - ");
      if (trees.length < 3) {
      const { labels, sample, sampleType } = deriveTreeFields(this.treeNode);
      if (labels.length < 2) {
        this.$message.error("未选择对象");
        return;
      }
      if (trees[3] === undefined || trees[3] === "" || trees[3] === "- ") {
        this.sample = trees[2];
      } else {
        this.sample = trees[3];
      }
      this.sample = sample || sampleType;
      this.selectStandardTree = false;
    },
    handleSelectionChange0(val) {
src/views/standard/standardLibrary/index.vue
@@ -8,44 +8,41 @@
            <div class="head-container addButton">
              <el-input v-model="search" clearable placeholder="输入关键字进行搜索" size="small" style="margin-bottom: 5px"
                        suffix-icon="el-icon-search" @keydown.enter.native="searchFilter" @blur="searchFilter" @clear="searchFilter"></el-input>
              <el-button circle icon="el-icon-plus" size="mini" type="primary" @click="addDia = true"></el-button>
              <el-button circle icon="el-icon-plus" size="mini" type="primary" @click="openAddDia"></el-button>
            </div>
            <div class="head-container">
              <el-tree ref="tree" v-loading="treeLoad" :allow-drop="allowDrop" :data="list"
                       :default-expanded-keys="expandedKeys" :draggable="true" :filter-node-method="filterNode"
              <el-tree ref="tree" v-loading="treeLoad" :data="list"
                       :default-expanded-keys="expandedKeys" :filter-node-method="filterNode"
                       :props="{ children: 'children', label: 'label' }" highlight-current node-key="label"
                       style="
                        height: calc(100vh - 173px);
                        overflow-y: scroll;
                        scrollbar-width: none;"
                       @node-click="handleNodeClick"
                       @node-drop="handleDrop">
                       @node-click="handleNodeClick">
                <div slot-scope="{ node, data }" class="custom-tree-node">
                  <el-row style="width: 100%">
                    <el-col :class="{ sort: node.level > 3 }" :span="19" :title="data.label" style="text-align: left">
                    <el-col :span="19" :title="data.label" style="text-align: left">
              <span>
                <i :class="`node_i ${data.children != undefined
                  ? data.code === '[1]'
                <i :class="`node_i ${isLeaf(data)
                  ? 'el-icon-tickets'
                  : node.level === 1
                    ? 'el-icon-folder-opened'
                    : 'el-icon-folder'
                  : 'el-icon-tickets'
                  }`"></i>
                {{ data.label }}
              </span>
                    </el-col>
                    <el-col v-if="
              checkPermi(['standard:standardLibrary:delStandardTree']) &&
              (node.data.children === null ||
                node.data.children === undefined)
              isLeaf(node.data)
            " :span="2" style="text-align: right">
                      <el-button size="mini" type="text" @click.stop="editTreeName(node.data)">
                      <el-button size="mini" type="text" @click.stop="editTreeName(node)">
                        <i class="el-icon-edit"></i>
                      </el-button>
                    </el-col>
                    <el-col v-if="
              checkPermi(['standard:standardLibrary:delStandardTree']) &&
              (node.data.children === null ||
                node.data.children === undefined)
              isLeaf(node.data)
            " :span="2" style="text-align: right">
                      <el-button size="mini" type="text" @click.stop="remove(node, data)">
                        <i class="el-icon-delete"></i>
@@ -64,6 +61,9 @@
              <p style="font-size: 14px; color: #999;margin-left: 10px">{{ selectTree }}</p>
            </div>
            <div class="options_button">
              <el-input v-model="productKeyword" :disabled="!selected.isLeaf" clearable placeholder="搜索检验项/检验项子项"
                        size="small" style="width: 240px" suffix-icon="el-icon-search"
                        @keyup.enter.native="searchProduct" @clear="searchProduct"></el-input>
              <el-button v-if="isShowCopy" size="small" style="position: absolute; right: 20px; top: 1px" type="primary"
                         @click="openCopyDia">批量复制</el-button>
            </div>
@@ -198,12 +198,17 @@
    <el-dialog :visible.sync="addDia" title="分类添加" width="400px">
      <div class="body">
        <el-row style="line-height: 30px">
          <el-col :span="24" style="color: #999; font-size: 13px">
            æ–°å¢žåˆ°ï¼š{{ selected.tree || '根目录' }}
          </el-col>
        </el-row>
        <el-row style="line-height: 50px">
          <el-col :span="6" style="text-align: right">
            <span class="required-span">* </span>型号:
            <span class="required-span">* </span>名称:
          </el-col>
          <el-col :offset="1" :span="16">
            <el-input v-model="addOb.model" clearable placeholder="请输入型号" size="small"
            <el-input v-model="addOb.name" clearable placeholder="请输入名称" size="small"
                      @keyup.enter.native="addStandardTree"></el-input>
          </el-col>
        </el-row>
@@ -217,10 +222,10 @@
      <div class="body">
        <el-row style="line-height: 50px">
          <el-col :span="6" style="text-align: right">
            <span class="required-span">* </span>型号:
            <span class="required-span">* </span>名称:
          </el-col>
          <el-col :offset="1" :span="16">
            <el-input v-model="addOb.model" clearable placeholder="请输入型号" size="small"
            <el-input v-model="addOb.name" clearable placeholder="请输入名称" size="small"
                      @keyup.enter.native="updateStandardTree"></el-input>
          </el-col>
        </el-row>
@@ -302,9 +307,7 @@
<script>
import Sortable from "sortablejs";
import draggable from "vuedraggable";
import {
  updateTreeSort,
  resetTreeDragBatch,
  delStandardTree,
  selectStandardTreeList,
@@ -317,13 +320,16 @@
  upStandardProductList,
  selectStandardProductListByMethodId,
  updateSection,
  upStandardProducts,
  getStandardTemplate,
  selectStandardProductByMethodId,
  selectStandardProductEnumByMethodId,
} from "@/api/standard/standardLibrary";
import bindSupplierDensityDialogAsk from "./components/bindSupplierDensityDialogAsk.vue";
import BatchCopy from "./components/BatchCopy.vue";
import {
  isLeaf,
  buildSelectTree,
  getAncestorLabels,
  dropLastLabel,
} from "@/utils/standardTree";
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
@@ -332,7 +338,6 @@
  components: {
    BatchCopy,
    bindSupplierDensityDialogAsk,
    draggable,
    Splitpanes,
    Pane
  },
@@ -346,13 +351,18 @@
      factory: [],
      addDia: false,
      updateDia: false, // ä¿®æ”¹æ ‘名字弹框
      oldModel: "",
      oldLabel: "",
      editTree: "",
      // å½“前选中的节点:label / å®Œæ•´è·¯å¾„ / æ˜¯å¦å¶å­(标准)
      selected: {
        label: "",
        tree: "",
        isLeaf: false,
      },
      // æ£€éªŒé¡¹æœç´¢å…³é”®å­—,走后端过滤(检验项 + æ£€éªŒé¡¹å­é¡¹ï¼‰
      productKeyword: "",
      addOb: {
        factory: null,
        laboratory: null,
        sampleType: null,
        sample: null,
        model: null,
        name: "",
      },
      laboratory: [],
      addLoad: false,
@@ -384,29 +394,17 @@
      total: 0,
      currentPage: 1,
      standardId: 0,
      total0: 0,
      currentPage0: 1,
      productList0: [],
      methodList: [],
      productTableLoading0: false,
      filters0: [],
      filters1: [],
      pages: 1,
      inspectionItem: null,
      inspectionItemSubclass: null,
      sonLaboratory: null,
      token: null,
      fileList: [],
      uploading: false,
      isEquipment: true,
      isHaveChildren: {},
      sortTable: null,
      currentSupplierDensityRow: {}, // é€‰æ‹©é›¶ä»¶ç»‘定本条数据的信息
      bindSupplierDensityDialog: false,
      isShowCopy: false,
      batchCopyDia: false,
      VUE_APP_BASE_API: process.env.VUE_APP_BASE_API,
      moreSelects: [],
    };
  },
  mounted() {
@@ -424,40 +422,18 @@
    };
  },
  methods: {
    // ä¿®æ”¹æœ€å­çº§åå­—
    editTreeName(info) {
    isLeaf,
    // æ‰“开新增弹框:在当前选中节点下新增子级(未选中则新增根级)
    openAddDia() {
      this.addOb.name = "";
      this.addDia = true;
    },
    // ä¿®æ”¹èŠ‚ç‚¹åå­—
    editTreeName(node) {
      this.updateDia = true;
      this.oldModel = info.label;
    },
    // æ‹–拽时判定目标节点能否被放置
    // 'prev'、'inner' å’Œ 'next',前、插入、后
    allowDrop(draggingNode, dropNode, type) {
      if (draggingNode.level !== 3) return;
      if (draggingNode.data.level === dropNode.data.level) {
        if (draggingNode.data.parentId === dropNode.data.parentId) {
          return type === "prev" || type === "next";
        } else {
          return false;
        }
      } else {
        // ä¸åŒçº§è¿›è¡Œå¤„理
        return false;
      }
    },
    // tree拖拽成功完成时触发的事件
    handleDrop(draggingNode, dropNode, dropType, ev) {
      try {
        this.treeLoad = true;
        updateTreeSort(this.list).then((res) => {
          if (res.code === 200) {
            this.$message.success("操作成功");
          }
          this.treeLoad = false;
        });
      } catch (e) {
        this.treeLoad = false;
        console.log("e----", e);
      }
      this.oldLabel = node.label;
      this.editTree = buildSelectTree(node, "null");
      this.addOb.name = node.label;
    },
    rowDrop(methodId) {
      const that = this;
@@ -497,54 +473,12 @@
        });
      }
    },
    hasChildWithId(nodes, name) {
      for (let node of nodes) {
        const comName = node.label + node.code;
        if (comName == name) {
          //判断递归结束条件
          this.isHaveChildren = node;
          return node;
        } else if (node.children && node.children.length > 0) {
          //判断children是否有数据
          this.hasChildWithId(node.children, name); //递归调用
        }
      }
    },
    // è°ƒç”¨tree过滤方法 ä¸­æ–‡è‹±è¿‡æ»¤
    filterNode (value, data, node) {
      if (!value) {    //如果数据为空,则返回true,显示所有的数据项
        return true
      }
      return data.label.indexOf(value) !== -1;
      // æŸ¥è¯¢åˆ—表是否有匹配数据,将值小写,匹配英文数据
      // let val = value.toLowerCase()
      // return this.chooseNode(val, data, node) // è°ƒç”¨è¿‡æ»¤äºŒå±‚方法
    },
    // è¿‡æ»¤çˆ¶èŠ‚ç‚¹ / å­èŠ‚ç‚¹ (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
    chooseNode (value, data, node) {
      if (data.label.indexOf(value) !== -1) {
        return true
      }
      const level = node.level
      // å¦‚果传入的节点本身就是一级节点就不用校验了
      if (level === 1) {
        return false
      }
      // å…ˆå–当前节点的父节点
      let parentData = node.parent
      // éåŽ†å½“å‰èŠ‚ç‚¹çš„çˆ¶èŠ‚ç‚¹
      let index = 0
      while (index < level - 1) {
        // å¦‚果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
        if (parentData.data.label.indexOf(value) !== -1) {
          return true
        }
        // å¦åˆ™çš„话再往上一层做匹配
        parentData = parentData.parent
        index++
      }
      // æ²¡åŒ¹é…åˆ°è¿”回false
      return false
    },
    searchFilter() {
@@ -554,40 +488,26 @@
      this.upIndex++;
    },
    handleNodeClick(val, node, el) {
      //树的值
      if (node.childNodes.length === 0) {
        this.isShowCopy = true;
      } else {
        this.isShowCopy = false;
      }
      const leaf = isLeaf(val);
      // å¶å­èŠ‚ç‚¹å³æ ‡å‡†ï¼Œæ‰æ˜¾ç¤ºæ‰¹é‡å¤åˆ¶ã€æ‰æŸ¥è¯¢æ£€éªŒé¡¹
      this.isShowCopy = leaf;
      this.total = 0;
      this.currentPage = 1;
      this.selectTree = "";
      this.getNodeParent(node);
      this.selectTree = this.selectTree.replace(" - ", "");
      let data = this.selectTree.split(" - ");
      let data2 = "";
      for (let index = data.length - 1; index >= 0; index--) {
        data2 += " - " + data[index];
      }
      this.selectTree = data2.replace(" - ", "");
      if (node.childNodes.length === 0) {
      this.selectTree = buildSelectTree(node, "null");
      this.selected = {
        label: val.label,
        tree: this.selectTree,
        isLeaf: leaf,
      };
      // åˆ‡æ¢èŠ‚ç‚¹æ—¶æ¸…ç©ºæœç´¢ä¸Žåˆ—è¡¨ï¼›éžæ ‡å‡†èŠ‚ç‚¹è¿˜è¦æ¸…ç©º standardId,避免搜索查到上一个标准
      this.productKeyword = "";
      this.standardList = [];
      this.productList = [];
      if (leaf) {
        this.selectsStandardMethodByFLSSM();
      }
      let trees = this.selectTree.split(" - ");
      this.addOb.factory = trees[0];
      this.addOb.laboratory = trees[1];
      this.addOb.sampleType = trees[2];
      this.addOb.sample = trees[3];
    },
    getNodeParent(val) {
      if (val.parent != null) {
        if (val.data.children === null) {
          this.selectTree += " - " + val.label + " - " + "null";
        } else {
          this.selectTree += " - " + val.label;
        }
        this.getNodeParent(val.parent);
      } else {
        this.standardId = 0;
        this.syncSortable();
      }
    },
    remove(node, data) {
@@ -595,23 +515,20 @@
        type: "error",
      })
        .then(() => {
          // this.treeLoad = true
          this.selectTree = "";
          this.getNodeParent(node);
          this.selectTree = this.selectTree.replace(" - ", "");
          let data = this.selectTree.split(" - ");
          let data2 = "";
          for (let index = data.length - 1; index >= 0; index--) {
            data2 += " - " + data[index];
          }
          this.selectTree = data2.replace(" - ", "");
          delStandardTree({ tree: this.selectTree }).then((res) => {
          const tree = buildSelectTree(node, "null");
          delStandardTree({ tree }).then((res) => {
            this.$message.success("已删除");
            let arr = this.selectTree.split(" - ");
            this.deleteStandard(this.list, arr[arr.length - 1]);
            const labels = getAncestorLabels(node);
            this.deleteStandard(this.list, labels[labels.length - 1]);
            this.selectTree = "";
            this.selected = { label: "", tree: "", isLeaf: false };
            this.standardList = [];
            this.productList = [];
            this.standardId = 0;
            this.isShowCopy = false;
            this.productKeyword = "";
            this.total = 0;
            this.syncSortable();
          });
        })
        .catch((e) => { });
@@ -651,6 +568,7 @@
      this.treeLoad = true;
      selectStandardTreeList().then((res) => {
        this.list = res.data;
        this.expandedKeys = [];
        this.list.forEach((a) => {
          this.expandedKeys.push(a.label);
        });
@@ -693,31 +611,23 @@
        this.standardEnum = data;
      });
    },
    // æäº¤åˆ†ç±»æ·»åŠ 
    // æäº¤åˆ†ç±»æ·»åŠ ï¼šåœ¨é€‰ä¸­èŠ‚ç‚¹ä¸‹æ–°å¢žå­çº§ï¼Œæœªé€‰ä¸­åˆ™æ–°å¢žæ ¹çº§
    addStandardTree() {
      if (this.addOb.sampleType == null || this.addOb.sampleType == "") {
        this.$message.error("对象不存在");
        return;
      }
      if (this.addOb.model == null || this.addOb.model == "") {
        this.$message.error("请填写型号");
      const name = (this.addOb.name || "").trim();
      if (!name) {
        this.$message.error("请填写名称");
        return;
      }
      this.addLoad = true;
      addStandardTree(this.addOb)
      addStandardTree({
        parentTree: this.selected.tree || "",
        name,
      })
        .then((res) => {
          this.$message.success("添加成功");
          this.addDia = false;
          this.list
            .find((a) => a.label == this.addOb.factory)
            .children.find((a) => a.label == this.addOb.laboratory)
            .children.find((a) => a.label == this.addOb.sampleType)
            .children.find((a) => a.label == this.addOb.sample)
            .children.push({
            code: "[5]",
            label: this.addOb.model,
            value: this.addOb.model,
          });
          this.addOb.name = "";
          this.selectStandardTreeList();
          this.addLoad = false;
        })
        .catch((e) => {
@@ -725,24 +635,24 @@
          this.addLoad = false;
        });
    },
    // ä¿®æ”¹åž‹å·
    // ä¿®æ”¹èŠ‚ç‚¹åå­—
    updateStandardTree() {
      if (this.addOb.sampleType == null || this.addOb.sampleType == "") {
        this.$message.error("对象不存在");
      const name = (this.addOb.name || "").trim();
      if (!name) {
        this.$message.error("请填写名称");
        return;
      }
      if (this.addOb.model == null || this.addOb.model == "") {
        this.$message.error("请填写型号");
        return;
      }
      this.addOb.oldModel = this.oldModel;
      this.updateLoad = true;
      updateStandardTree(this.addOb)
      updateStandardTree({
        parentTree: dropLastLabel(this.editTree),
        oldLabel: this.oldLabel,
        name,
      })
        .then((res) => {
          this.$message.success("添加成功");
          this.$tab.refreshPage();
          // this.selectStandardTreeList();
          this.$message.success("修改成功");
          this.updateDia = false;
          this.addOb.name = "";
          this.selectStandardTreeList();
          this.updateLoad = false;
        })
        .catch((e) => {
@@ -756,12 +666,14 @@
        tree: this.selectTree,
      }).then((res) => {
        this.tableLoad = false;
        this.standardList = res.data.standardMethodList;
        if (this.standardList && this.standardList.length > 0) {
        const data = res.data || {};
        this.standardList = data.standardMethodList || [];
        if (this.standardList.length > 0) {
          this.$refs.standard.setCurrentRow(this.standardList[0]);
          this.rowClick(this.standardList[0]);
        } else {
          this.productList = [];
          this.syncSortable();
        }
      });
    },
@@ -853,6 +765,22 @@
        this.rowClick(this.standardList[index]);
      }
    },
    // æ£€éªŒé¡¹æœç´¢ï¼šèµ°åŽç«¯è¿‡æ»¤ï¼ˆåŒ¹é…æ£€éªŒé¡¹ + æ£€éªŒé¡¹å­é¡¹ï¼‰
    searchProduct() {
      if (!this.selected.isLeaf || !this.standardId) return;
      this.rowClick({ id: this.standardId });
    },
    // åªæœ‰é€‰ä¸­çš„æ˜¯æ ‡å‡†(叶子)、未在搜索过滤状态、且列表非空时,才允许拖拽排序
    syncSortable() {
      if (this.sortTable) {
        this.sortTable.destroy();
        this.sortTable = null;
      }
      if (!this.selected.isLeaf || this.productKeyword || this.productList.length === 0) return;
      this.$nextTick(() => {
        this.rowDrop(this.standardId);
      });
    },
    rowClick(row, column, event) {
      this.currentPage = 1;
      this.tableLoad2 = true;
@@ -861,40 +789,18 @@
        id: row.id,
        tree: this.selectTree,
        page: this.currentPage,
        keyword: this.productKeyword,
      }).then((res) => {
        this.productList = res.data.productList;
        this.total = res.data.total;
        const data = res.data || {};
        this.productList = data.productList || [];
        this.total = data.total || 0;
        setTimeout(() => {
          this.productList.forEach((a) => {
            if (a.state == 1) this.toggleSelection(a);
          });
        }, 300);
        this.tableLoad2 = false;
        const tree = this.selectTree.split(" - ");
        // é€‰æ‹©æœ€åŽä¸€å±‚树才可以拖拽排序
        if (tree.length === 4) {
          const name = tree[3] + "[4]";
          this.hasChildWithId(this.list, name);
          if (
            this.isHaveChildren.children &&
            this.isHaveChildren.children.length > 0
          ) {
            if (this.sortTable) {
              this.sortTable.destroy();
              this.sortTable = null;
            }
            return;
          }
        } else if (tree.length < 4) {
          if (this.sortTable) {
            this.sortTable.destroy();
            this.sortTable = null;
          }
          return;
        }
        this.$nextTick(() => {
          this.rowDrop(row.id);
        });
        this.syncSortable();
      });
    },
    toggleSelection(row) {
@@ -916,28 +822,6 @@
      }).then((res) => {
        this.$message.success('已保存')
      });
    },
    filterHandler(value) {
      for (let column in value) {
        if (value[column].length === 0) {
          if (column === "inspectionItem") {
            this.inspectionItem = null;
          } else if (column === "inspectionItemSubclass") {
            this.inspectionItemSubclass = null;
          } else if (column === "sonLaboratory") {
            this.sonLaboratory = null;
          }
        } else {
          if (column === "inspectionItem") {
            this.inspectionItem = value[column][0];
          } else if (column === "inspectionItemSubclass") {
            this.inspectionItemSubclass = value[column][0];
          } else if (column === "sonLaboratory") {
            this.sonLaboratory = value[column][0];
          }
        }
        this.getList();
      }
    },
    handleAll(e) {
      if (e.length > 0) {
@@ -1049,48 +933,21 @@
        this.sectionRow.conductorType = JSON.stringify(conductorTypeList);
      }
      this.sectionLoad = true;
      if (this.moreSelects.length === 0) {
        updateSection({
          str: JSON.stringify({
            id: this.sectionRow.id,
            section: this.sectionRow.section,
            ask: this.sectionRow.ask,
            tell: this.sectionRow.tell,
            // price: this.sectionRow.price,
            // manHour: this.sectionRow.manHour,
            cores: this.sectionRow.cores,
            conductorMaterial: this.sectionRow.conductorMaterial,
            conductorType: this.sectionRow.conductorType,
          }),
        }).then((res) => {
          this.sectionLoad = false;
          this.$message.success("已保存");
          this.sectionUpDia = false;
        });
      } else {
        upStandardProducts({
          ids: JSON.stringify(this.moreSelects.map((a) => a.id)),
          standardProductList: {
            section: this.sectionRow.section,
            ask: this.sectionRow.ask,
            tell: this.sectionRow.tell,
            // price: this.sectionRow.price,
            // manHour: this.sectionRow.manHour,
            cores: this.sectionRow.cores,
            conductorMaterial: this.sectionRow.conductorMaterial,
            conductorType: this.sectionRow.conductorType,
          },
        }).then((res) => {
          this.sectionLoad = false;
          this.$message.success("已保存");
          this.sectionUpDia = false;
          this.currentPage0 = 1;
          this.getList();
          this.rowClick({
            id: this.standardId,
          });
        });
      }
      updateSection({
        str: JSON.stringify({
          id: this.sectionRow.id,
          section: this.sectionRow.section,
          ask: this.sectionRow.ask,
          tell: this.sectionRow.tell,
          cores: this.sectionRow.cores,
          conductorMaterial: this.sectionRow.conductorMaterial,
          conductorType: this.sectionRow.conductorType,
        }),
      }).then((res) => {
        this.sectionLoad = false;
        this.$message.success("已保存");
        this.sectionUpDia = false;
      });
    },
    bindSupplierDensitySecond(row) {
      this.bindSupplierDensity(row);
@@ -1143,81 +1000,6 @@
        this.methodList = data;
      });
    },
    handleSelectAll0(rows) {
      if (rows.length) {
        rows.forEach((a) => {
          if (!this.moreSelects.find((b) => a.id === b.id)) {
            this.moreSelects.push(a);
          }
        });
      } else {
        this.productList0.forEach((a) => {
          this.moreSelects = this.moreSelects.filter((b) => b.id != a.id);
        });
      }
    },
    handleSelectionChange0(val, row) {
      if (this.moreSelects.find((a) => a.id === row.id)) {
        this.moreSelects = this.moreSelects.filter((a) => a.id != row.id);
      } else {
        this.moreSelects.push(row);
      }
    },
    getList() {
      this.productTableLoading0 = true;
      this.getItemEnum();
      selectStandardProductByMethodId({
        id: this.standardId,
        tree: this.selectTree,
        page: this.currentPage0,
        laboratory: this.sonLaboratory,
        items: this.inspectionItemSubclass,
        item: this.inspectionItem,
      }).then((res) => {
        this.productList0 = res.data.records;
        this.total0 = res.data.total;
        this.productTableLoading0 = false;
        this.page = res.data.pages;
        this.$nextTick(() => {
          this.productList0.forEach((a, i) => {
            if (this.moreSelects.find((b) => a.id == b.id)) {
              this.$refs.productTable0.toggleRowSelection(
                this.productList0[i],
                true
              );
            }
          });
        });
      });
    },
    handleCurrentChange0(e) {
      this.currentPage0 = e;
      this.getList();
    },
    getItemEnum() {
      selectStandardProductEnumByMethodId({
        id: this.standardId,
        tree: this.selectTree,
        item: this.inspectionItem,
      }).then((res) => {
        this.filters0 = [];
        this.filters1 = [];
        res.data.item.forEach((a) => {
          this.filters0.push({
            text: a.inspectionItem,
            value: a.inspectionItem,
          });
        });
        res.data.items.forEach((a) => {
          if (a != null) {
            this.filters1.push({
              text: a.inspectionItemSubclass,
              value: a.inspectionItemSubclass,
            });
          }
        });
      });
    },
  },
};
</script>
@@ -1229,6 +1011,9 @@
  .options_button {
    margin-top: 3px;
    margin-right: 120px;
    display: flex;
    align-items: center;
  }
}
vue.config.js
@@ -27,7 +27,7 @@
  lintOnSave: process.env.NODE_ENV === "development",
  // å¦‚果你不需要生产环境的 source map,可以将其设置为 false ä»¥åŠ é€Ÿç”Ÿäº§çŽ¯å¢ƒæž„å»ºã€‚
  productionSourceMap: false,
  transpileDependencies: ["quill"],
  transpileDependencies: ["quill", "fast-png", "iobuffer"],
  // webpack-dev-server ç›¸å…³é…ç½®
  devServer: {
    host: "0.0.0.0",
@@ -37,7 +37,7 @@
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
        // target: `http://36.213.90.123:9015/lims`,
        target: `http://127.0.0.1:9509/lims`,
        target: `http://192.168.0.24:8001/lims`,
        changeOrigin: true,
        pathRewrite: {
          ["^" + process.env.VUE_APP_BASE_API]: "",