Bladeren bron

设备管理优化

wyh 1 jaar geleden
bovenliggende
commit
482ca4e48a

+ 265 - 0
src/views/module_tpm/Equipment/EquipmentList.vue

@@ -0,0 +1,265 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备名称">
+              <a-input placeholder="请输入设备名称" v-model="queryParam.equipmentname"></a-input>
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备分类">
+              <!-- <j-category-select placeholder="请选择设备分类" v-model="queryParam.equipmenttreeid" pcode="id"/> -->
+              <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择设备分类"
+                v-model="queryParam.equipmenttreeid"
+                dict="ems_tpm_equipment_tree,name,id"
+                pidField="parentid"
+                pidValue="0"
+                hasChildField="has_child"
+                >
+              </j-tree-select>
+            </a-form-item>
+          </a-col>
+          <template v-if="toggleSearchStatus">
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="设备编号">
+                <a-input placeholder="请输入设备编号" v-model="queryParam.equipmentcode"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="规格型号">
+                <a-input placeholder="请输入规格型号" v-model="queryParam.spec"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="安装地点">
+                <a-input placeholder="请输入安装地点" v-model="queryParam.address"></a-input>
+              </a-form-item>
+            </a-col>
+            <a-col :xl="6" :lg="7" :md="8" :sm="24">
+              <a-form-item label="区域">
+                <!-- <a-input placeholder="请输入区域" v-model="queryParam.spaceid"></a-input> -->
+                <j-tree-select
+                  ref="treeSelect"
+                  placeholder="请选择区域"
+                  v-model="queryParam.spaceid"
+                  dict="ems_space,name,id"
+                  pidField="parentid"
+                  pidValue="0"
+                  hasChildField="has_child"
+                  >
+                </j-tree-select>
+              </a-form-item>
+            </a-col>
+          </template>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+              <a @click="handleToggleSearch" style="margin-left: 8px">
+                {{ toggleSearchStatus ? '收起' : '展开' }}
+                <a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
+              </a>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('设备档案')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query> -->
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+
+    <tpm-equipment-modal ref="modalForm" @ok="modalFormOk"></tpm-equipment-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import TpmEquipmentModal from './modules/TpmEquipmentModal'
+  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
+
+  export default {
+    name: 'TpmEquipmentList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      TpmEquipmentModal
+    },
+    data () {
+      return {
+        description: '设备档案管理页面',
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'设备名称',
+            align:"center",
+            dataIndex: 'equipmentname'
+          },
+          {
+            title:'设备分类',
+            align:"center",
+            dataIndex: 'equipmenttreeid_dictText',
+            // customRender: (text, record) => (text ? record['name'] : '')
+          },
+          {
+            title:'设备编号',
+            align:"center",
+            dataIndex: 'equipmentcode'
+          },
+          {
+            title:'规格型号',
+            align:"center",
+            dataIndex: 'spec'
+          },
+          {
+            title:'安装地点',
+            align:"center",
+            dataIndex: 'address'
+          },
+          {
+            title:'区域',
+            align:"center",
+            dataIndex: 'spaceid_dictText'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: "/tpmEquipment/tpmEquipment/list",
+          delete: "/tpmEquipment/tpmEquipment/delete",
+          deleteBatch: "/tpmEquipment/tpmEquipment/deleteBatch",
+          exportXlsUrl: "/tpmEquipment/tpmEquipment/exportXls",
+          importExcelUrl: "tpmEquipment/tpmEquipment/importExcel",
+
+        },
+        dictOptions:{},
+        superFieldList:[],
+      }
+    },
+    created() {
+    this.getSuperFieldList();
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    methods: {
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'equipmentname',text:'设备名称',dictCode:''})
+        fieldList.push({type:'string',value:'equipmenttreeid',text:'设备分类ID(分类id)'})
+        fieldList.push({type:'string',value:'equipmentcode',text:'设备编号',dictCode:''})
+        fieldList.push({type:'string',value:'spec',text:'规格型号',dictCode:''})
+        fieldList.push({type:'string',value:'address',text:'安装地点',dictCode:''})
+        fieldList.push({type:'string',value:'spaceid',text:'区域',dictCode:''})
+        this.superFieldList = fieldList
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 164 - 0
src/views/module_tpm/Equipment/modules/EquipmentForm.vue

@@ -0,0 +1,164 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="24">
+            <a-form-model-item label="设备名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentname">
+              <a-input v-model="model.equipmentname" placeholder="请输入设备名称"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="设备分类" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmenttreeid">
+              <!-- <j-category-select v-model="model.equipmenttreeid" pcode="id" placeholder="请选择设备分类" back="name" @change="handleCategoryChange" /> -->
+              <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择设备分类"
+                v-model="model.equipmenttreeid"
+                dict="ems_tpm_equipment_tree,name,id"
+                pidField="parentid"
+                pidValue="0"
+                hasChildField="has_child"
+                >
+              </j-tree-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentcode">
+              <span slot="label">
+                设备编号&nbsp;
+                <a-tooltip title="若未填写设备编号 则自动生成">
+                  <a-icon type="exclamation-circle" theme="filled" />
+                </a-tooltip>
+              </span>
+              <a-input v-model="model.equipmentcode" placeholder="请输入设备编号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="规格型号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="spec">
+              <a-input v-model="model.spec" placeholder="请输入规格型号"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="安装地点" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="address">
+              <a-input v-model="model.address" placeholder="请输入安装地点"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="24">
+            <a-form-model-item label="区域" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="spaceid">
+              <!-- <a-input v-model="model.spaceid" placeholder="请输入区域"  ></a-input> -->
+              <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择区域"
+                v-model="model.spaceid"
+                dict="ems_space,name,id"
+                pidField="parentid"
+                pidValue="0"
+                hasChildField="has_child"
+                >
+              </j-tree-select>
+            </a-form-model-item>
+          </a-col>
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'TpmEquipmentForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+          equipmentname: [
+            { required: true, message: '请输入设备名称!'},
+          ],
+          equipmenttreeid: [
+            { required: true, message: '请选择设备分类!'},
+          ],
+        },
+        url: {
+          add: "/tpmEquipment/tpmEquipment/add",
+          edit: "/tpmEquipment/tpmEquipment/edit",
+          queryById: "/tpmEquipment/tpmEquipment/queryById"
+        }
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      submitForm () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+
+        })
+      },
+      handleCategoryChange(value,backObj){
+         this.model = Object.assign(this.model, backObj);
+      }
+    }
+  }
+</script>

+ 84 - 0
src/views/module_tpm/Equipment/modules/EquipmentModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <tpm-equipment-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></tpm-equipment-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import TpmEquipmentForm from './TpmEquipmentForm'
+
+  export default {
+    name: 'TpmEquipmentModal',
+    components: {
+      TpmEquipmentForm
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        });
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/module_tpm/Equipment/modules/EquipmentModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <tpm-equipment-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></tpm-equipment-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import TpmEquipmentForm from './TpmEquipmentForm'
+  export default {
+    name: 'TpmEquipmentModal',
+    components: {
+      TpmEquipmentForm
+    },
+    data () {
+      return {
+        title:'',
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 383 - 0
src/views/module_tpm/EquipmentTree/EquipmentTreeList.vue

@@ -0,0 +1,383 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备分类名称">
+              <a-input placeholder="请输入设备分类名称" v-model="queryParam.name"></a-input>
+              <!-- <j-tree-select
+                ref="treeSelect"
+                placeholder="请选择设备分类"
+                v-model="queryParam.id"
+                dict="ems_tpm_equipment_tree,name,id"
+                pidField="parentid"
+                pidValue="0"
+                hasChildField="has_child"
+                >
+              </j-tree-select> -->
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button @click="expandClose" type="primary">{{tableTreeStatus == 1 ? '一键展开':'一键折叠'}}</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('设备树定义')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query> -->
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        rowKey="id"
+        class="j-table-force-nowrap"
+        :scroll="{x:true}"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="false"
+        :loading="loading"
+        :expandedRowKeys="expandedRowKeys"
+        @change="handleTableChange"
+        @expand="handleExpand"
+        v-bind="tableProps">
+
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleAddChild(record)">添加下级</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDeleteNode(record.id)" placement="topLeft">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+
+    <tpmEquipmentTree-modal ref="modalForm" @ok="modalFormOk"></tpmEquipmentTree-modal>
+  </a-card>
+</template>
+
+<script>
+
+  import { getAction, deleteAction } from '@/api/manage'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import TpmEquipmentTreeModal from './modules/TpmEquipmentTreeModal'
+  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
+  import { filterObj } from '@/utils/util';
+
+  export default {
+    name: "TpmEquipmentTreeList",
+    mixins:[JeecgListMixin],
+    components: {
+      TpmEquipmentTreeModal
+    },
+    data () {
+      return {
+        description: '设备树定义管理页面',
+        // 表头
+        columns: [
+          {
+            title:'设备分类名称',
+            align:"left",
+            dataIndex: 'name'
+          },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' },
+          }
+        ],
+        url: {
+          // list: "/tpmEquipmentTree/tpmEquipmentTree/rootList",
+          list: "/tpmEquipmentTree/tpmEquipmentTree/treeList",
+          childList: "/tpmEquipmentTree/tpmEquipmentTree/childList",
+          getChildListBatch: "/tpmEquipmentTree/tpmEquipmentTree/getChildListBatch",
+          delete: "/tpmEquipmentTree/tpmEquipmentTree/delete",
+          deleteBatch: "/tpmEquipmentTree/tpmEquipmentTree/deleteBatch",
+          exportXlsUrl: "/tpmEquipmentTree/tpmEquipmentTree/exportXls",
+          importExcelUrl: "tpmEquipmentTree/tpmEquipmentTree/importExcel",
+        },
+        expandedRowKeys:[],
+        hasChildrenField:"hasChild",
+        pidField:"parentid",
+        dictOptions: {},
+        loadParent: false,
+        superFieldList:[],
+        // 展开/折叠
+        tableTreeStatus: 1,
+      }
+    },
+    created() {
+      this.getSuperFieldList();
+    },
+    computed: {
+      importExcelUrl(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+      tableProps() {
+        let _this = this
+        return {
+          // 列表项是否可选择
+          rowSelection: {
+            selectedRowKeys: _this.selectedRowKeys,
+            onChange: (selectedRowKeys) => _this.selectedRowKeys = selectedRowKeys
+          }
+        }
+      }
+    },
+    methods: {
+      loadData(arg){
+        if(arg==1){
+          this.ipagination.current=1
+        }
+        this.loading = true
+        let params = this.getQueryParams()
+        params.hasQuery = 'true'
+        getAction(this.url.list,params).then(res=>{
+          if(res.success){
+            this.dataSource = res.result;
+            // let result = res.result
+            // if(Number(result.total)>0){
+            //   this.ipagination.total = Number(result.total)
+            //   this.dataSource = this.getDataByResult(res.result.records)
+            //   return this.loadDataByExpandedRows(this.dataSource)
+            // }else{
+            //   this.ipagination.total=0
+            //   this.dataSource=[]
+            // }
+          }else{
+            this.$message.warning(res.message)
+          }
+        }).finally(()=>{
+          this.loading = false
+        })
+      },
+      // 根据已展开的行查询数据(用于保存后刷新时异步加载子级的数据)
+      loadDataByExpandedRows(dataList) {
+        if (this.expandedRowKeys.length > 0) {
+          return getAction(this.url.getChildListBatch,{ parentIds: this.expandedRowKeys.join(',') }).then(res=>{
+            if (res.success && res.result.records.length>0) {
+              //已展开的数据批量子节点
+              let records = res.result.records
+              const listMap = new Map();
+              for (let item of records) {
+                let pid = item[this.pidField];
+                if (this.expandedRowKeys.join(',').includes(pid)) {
+                 let mapList = listMap.get(pid);
+                  if (mapList == null) {
+                    mapList = [];
+                  }
+                  mapList.push(item);
+                  listMap.set(pid, mapList);
+                }
+              }
+              let childrenMap = listMap;
+              let fn = (list) => {
+                if(list) {
+                  list.forEach(data => {
+                    if (this.expandedRowKeys.includes(data.id)) {
+                      data.children = this.getDataByResult(childrenMap.get(data.id))
+                      fn(data.children)
+                    }
+                  })
+                }
+              }
+              fn(dataList)
+            }
+          })
+        } else {
+          return Promise.resolve()
+        }
+      },
+      getQueryParams(arg) {
+        //获取查询条件
+        let sqp = {}
+        let param = {}
+        if(this.superQueryParams){
+          sqp['superQueryParams']=encodeURI(this.superQueryParams)
+          sqp['superQueryMatchType'] = this.superQueryMatchType
+        }
+        if(arg){
+          param = Object.assign(sqp, this.isorter ,this.filters);
+        }else{
+          param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
+        }
+        if(JSON.stringify(this.queryParam) === "{}" || arg){
+          param.hasQuery = 'false'
+        }else{
+          param.hasQuery = 'true'
+        }
+        param.field = this.getQueryField();
+        param.pageNo = this.ipagination.current;
+        param.pageSize = this.ipagination.pageSize;
+        return filterObj(param);
+      },
+      searchReset() {
+        //重置
+        this.expandedRowKeys = []
+        this.queryParam = {}
+        this.loadData(1);
+      },
+      getDataByResult(result){
+        if(result){
+          return result.map(item=>{
+            //判断是否标记了带有子节点
+            if(item[this.hasChildrenField]=='1'){
+              let loadChild = { id: item.id+'_loadChild', name: 'loading...', isLoading: true }
+              item.children = [loadChild]
+            }
+            return item
+          })
+        }
+      },
+      handleExpand(expanded, record){
+        // 判断是否是展开状态
+        if (expanded) {
+          this.expandedRowKeys.push(record.id)
+          if (record.children.length>0 && record.children[0].isLoading === true) {
+            let params = this.getQueryParams(1);//查询条件
+            params[this.pidField] = record.id
+            params.hasQuery = 'false'
+            params.superQueryParams=""
+            getAction(this.url.childList,params).then((res)=>{
+              if(res.success){
+                if(res.result.records){
+                  record.children = this.getDataByResult(res.result.records)
+                  this.dataSource = [...this.dataSource]
+                }else{
+                  record.children=''
+                  record.hasChildrenField='0'
+                }
+              }else{
+                this.$message.warning(res.message)
+              }
+            })
+          }
+        }else{
+          let keyIndex = this.expandedRowKeys.indexOf(record.id)
+          if(keyIndex>=0){
+            this.expandedRowKeys.splice(keyIndex, 1);
+          }
+        }
+      },
+      handleAddChild(record){
+        this.loadParent = true
+        let obj = {}
+        obj[this.pidField] = record['id']
+        this.$refs.modalForm.add(obj);
+      },
+      handleDeleteNode(id) {
+        if(!this.url.delete){
+          this.$message.error("请设置url.delete属性!")
+          return
+        }
+        var that = this;
+        deleteAction(that.url.delete, {id: id}).then((res) => {
+          if (res.success) {
+             that.loadData(1)
+          } else {
+            that.$message.warning(res.message);
+          }
+        });
+      },
+      batchDel(){
+        if(this.selectedRowKeys.length<=0){
+          this.$message.warning('请选择一条记录!');
+          return false;
+        }else{
+          let ids = "";
+          let that = this;
+          that.selectedRowKeys.forEach(function(val) {
+            ids+=val+",";
+          });
+          that.$confirm({
+            title:"确认删除",
+            content:"是否删除选中数据?",
+            onOk: function(){
+              that.handleDeleteNode(ids)
+              that.onClearSelected();
+            }
+          });
+        }
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'name',text:'设备分类名称',dictCode:''})
+        fieldList.push({type:'string',value:'parentid',text:'上级ID',dictCode:"ems_tpm_equipment_tree,name,id"})
+        this.superFieldList = fieldList
+      },
+      expandClose(){
+        this.tableTreeStatus = - this.tableTreeStatus
+        if (this.tableTreeStatus == 1) {
+          this.expandedRowKeys = []
+        } else {
+          this.expandedRowKeys = this.dataSource.map(item =>{
+            return item.id
+          })
+        }
+      }
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 177 - 0
src/views/module_tpm/EquipmentTree/modules/EquipmentTreeModal.vue

@@ -0,0 +1,177 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    switchFullscreen
+    @ok="handleOk"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <a-spin :spinning="confirmLoading">
+      <a-form-model ref="form" :model="model" :rules="validatorRules">
+        <a-form-model-item label="设备分类名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="name">
+          <a-input v-model="model.name" placeholder="请输入设备分类名称" ></a-input>
+        </a-form-model-item>
+        <a-form-model-item label="选择上级" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="parentid">
+          <j-tree-select
+            ref="treeSelect"
+            placeholder="请选择上级"
+            v-model="model.parentid"
+            dict="ems_tpm_equipment_tree,name,id"
+            pidField="parentid"
+            pidValue="0"
+            hasChildField="has_child"
+            >
+          </j-tree-select>
+        </a-form-model-item>
+
+      </a-form-model>
+    </a-spin>
+  </j-modal>
+</template>
+
+<script>
+
+  import { httpAction } from '@/api/manage'
+  import { duplicateCheck } from '@/api/api'
+  import { validateDuplicateValue } from '@/utils/util'
+  export default {
+    name: "TpmEquipmentTreeModal",
+    components: {
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+
+        confirmLoading: false,
+        validatorRules: {
+          name: [
+            { required: true, message: '请输入设备分类名称!'},
+            { validator: this.validateTemplateCode}
+          ],
+          // parentid: [
+          //   { required: true, message: '请选择上级!'},
+          // ],
+        },
+        url: {
+          add: "/tpmEquipmentTree/tpmEquipmentTree/add",
+          edit: "/tpmEquipmentTree/tpmEquipmentTree/edit",
+        },
+        expandedRowKeys:[],
+        pidField:"parentid"
+
+      }
+    },
+    created () {
+       //备份model原始值
+       this.modelDefault = JSON.parse(JSON.stringify(this.model));
+    },
+    methods: {
+      validateTemplateCode(rule, value, callback){
+        var params = {
+          tableName: "ems_tpm_equipment_tree",
+          fieldName: "name",
+          fieldVal: value,
+          dataId: this.model.name
+        }
+        duplicateCheck(params).then((res)=>{
+          if(res.success){
+            callback();
+          }else{
+            callback("设备分类名称已存在,请重新输入");
+          }
+        })
+
+      },
+      add (obj) {
+        this.modelDefault.parentid=''
+        this.edit(Object.assign(this.modelDefault , obj));
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+        this.$refs.form.clearValidate()
+      },
+      handleOk () {
+        const that = this;
+        // 触发表单验证
+       this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+             if(this.model.id && this.model.id === this.model[this.pidField]){
+              that.$message.warning("父级节点不能选择自己");
+              that.confirmLoading = false;
+              return;
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                this.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+              that.close();
+            })
+          }else{
+             return false
+          }
+        })
+      },
+      handleCancel () {
+        this.close()
+      },
+      submitSuccess(formData,flag){
+        if(!formData.id){
+          let treeData = this.$refs.treeSelect.getCurrTreeData()
+          this.expandedRowKeys=[]
+          this.getExpandKeysByPid(formData[this.pidField],treeData,treeData)
+          this.$emit('ok',formData,this.expandedRowKeys.reverse());
+        }else{
+          this.$emit('ok',formData,flag);
+        }
+      },
+      getExpandKeysByPid(pid,arr,all){
+        if(pid && arr && arr.length>0){
+          for(let i=0;i<arr.length;i++){
+            if(arr[i].key==pid){
+              this.expandedRowKeys.push(arr[i].key)
+              this.getExpandKeysByPid(arr[i]['parentId'],all,all)
+            }else{
+              this.getExpandKeysByPid(pid,arr[i].children,all)
+            }
+          }
+        }
+      }
+
+
+    }
+  }
+</script>

+ 139 - 0
src/views/module_tpm/Tag/DeviceList.vue

@@ -0,0 +1,139 @@
+<template>
+  <a-card :bordered="false">
+    <!-- <div class="tree">
+    </div> -->
+    <div>
+      <a-input-search style="margin-bottom: 8px" placeholder="Search" @change="onChange" />
+      <a-tree
+        :expanded-keys="expandedKeys"
+        auto-expand-parent
+        :tree-data="tpmTreeData"
+        @expand="onExpand"
+        :replace-fields="replaceFields"
+        :filter-tree-node="filterTreeNode"
+        >
+        <!-- <template slot="title" slot-scope="{ title }">
+          <span v-if="name.indexOf(searchValue) > -1">
+          {{ name.substr(0, name.indexOf(searchValue)) }}
+          <span style="color: #f50">{{ searchValue }}</span>
+          {{ name.substr(name.indexOf(searchValue) + searchValue.length) }}
+          </span>
+          <span v-else>{{ title }}</span>
+        </template> -->
+      </a-tree>
+    </div>
+  </a-card>
+</template>
+
+<script>
+  import { getAction } from '@api/manage'
+  export default({
+    components: {
+    },
+    data () {
+      return {
+        expandedKeys: [],
+        searchValue: '',
+        autoExpandParent: true,
+        tpmListData: [], // 原始数据
+        tpmTreeData: [], // 树形列表使用数据
+        replaceFields: {
+          children: 'children',
+          title: 'name',
+        },
+      }
+    },
+    created() {
+      this.getTpmTreeData()
+    },
+    methods: {
+      getTpmTreeData(){
+        getAction(`/tpmEquipmentTree/tpmEquipmentTree/listtreeandequip`).then(res=>{
+          if (res.success) {
+            // 防止res.result对tpmListData造成地址赋值的问题
+            this.tpmListData = JSON.parse(JSON.stringify(res.result))
+            this.tpmTreeData = this.handleTree(res.result, "id", "parentid")
+            console.log(this.tpmTreeData)
+          } else {
+            
+          }
+        })
+      },
+      filterTreeNode(node) {
+        console.log(node)
+        // if (!inputValue) return true;
+        return node.title.indexOf('设备') !== -1;
+      },
+      onExpand(expandedKeys) {
+        this.expandedKeys = expandedKeys;
+        this.autoExpandParent = false;
+      },
+      onChange(e) {
+        const value = e.target.value;
+        // 筛选后数据
+        var filterData = []
+        // 筛选符合条件的数据:包含当前搜索的项
+        console.log(this.tpmListData)
+        filterData = this.tpmListData.filter(item => (item.name.indexOf(value) !== -1))
+        // var data = []
+        // filterData.forEach(item => {
+        //   var arr = this.tpmListData.filter(data => item.parentid === data.id)
+        //   console.log('父级', arr)
+        //   // filterData = [...filterData, ...arr]
+        // })
+        // 循环寻找父级
+        // console.log(this.findParents(this.tpmTreeData, '287813167808513'))
+
+        
+
+        
+        this.tpmTreeData = this.handleTree(filterData, "id", "parentid")
+        // const expandedKeys = dataList.map(item => {
+        //   if (item.name.indexOf(value) > -1) {
+        //       // return getParentKey(item.key, gData);
+        //       return this.filterNode(item.key, gData);
+        //   }
+        //   return null;
+        // }).filter((item, i, self) => item && self.indexOf(item) === i);
+        // Object.assign(this, {
+        //   expandedKeys,
+        //   searchValue: value,
+        //   autoExpandParent: true,
+        // });
+      },
+      // findParents(treeData,id){
+      //   let allparents = []
+      //   if(treeData.length==0){
+      //     return 
+      //   }
+
+      //   let findele = (data,id) => {
+      //     if(!id) return
+      //     data.forEach((item,index) => {
+      //       if(item.id == id){
+      //         allparents.unshift(item.id)
+      //         findele(treeData,item.parentid)
+
+      //       }else{
+      //         if(!!item.children){
+      //             findele(item.children,id)
+      //         }
+              
+      //       }
+      //     })
+      //   }
+
+      //   findele(treeData,id)
+      //   return allparents
+
+      // },
+    },
+  })
+</script>
+
+<style scoped>
+.tree{
+  height: calc(100vh - 185px);
+  width: 100%;
+}
+</style>

+ 296 - 0
src/views/module_tpm/Tag/TagList.vue

@@ -0,0 +1,296 @@
+<template>
+  <a-card :bordered="false">
+    <!-- 查询区域 -->
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline" @keyup.enter.native="searchQuery">
+        <a-row :gutter="24">
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="设备名称">
+              <j-search-select-tag v-model="queryParam.equipmentid" placeholder="请选择设备" dict="ems_tpm_equipment,equipmentname,id"  />
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <a-form-item label="点位名">
+              <j-search-select-tag v-model="queryParam.tagname" placeholder="请选择点位" dict="ems_tpm_tag,tagname,tagname"  />
+              <!-- <a-select
+              v-model="queryParam.tagname"
+              placeholder="请选择点位"
+              show-search
+              allowClear
+              :options="pointOptions">
+              </a-select> -->
+            </a-form-item>
+          </a-col>
+          <a-col :xl="6" :lg="7" :md="8" :sm="24">
+            <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
+              <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
+              <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+    <!-- 查询区域-END -->
+
+    <!-- 操作按钮区域 -->
+    <div class="table-operator">
+      <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
+      <a-button @click="handleAddPL" type="primary" icon="plus">批量引入</a-button>
+      <!-- <a-button type="primary" icon="download" @click="handleExportXls('设备点位表')">导出</a-button>
+      <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
+        <a-button type="primary" icon="import">导入</a-button>
+      </a-upload> -->
+      <!-- 高级查询区域 -->
+      <!-- <j-super-query :fieldList="superFieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query> -->
+      <a-dropdown v-if="selectedRowKeys.length > 0">
+        <a-menu slot="overlay">
+          <a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
+        </a-menu>
+        <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
+      </a-dropdown>
+    </div>
+
+    <!-- table区域-begin -->
+    <div>
+      <div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
+        <i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>项
+        <a style="margin-left: 24px" @click="onClearSelected">清空</a>
+      </div>
+
+      <a-table
+        ref="table"
+        size="middle"
+        :scroll="{x:true}"
+        bordered
+        rowKey="id"
+        :columns="columns"
+        :dataSource="dataSource"
+        :pagination="ipagination"
+        :loading="loading"
+        :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+        class="j-table-force-nowrap"
+        @change="handleTableChange">
+
+        <template slot="htmlSlot" slot-scope="text">
+          <div v-html="text"></div>
+        </template>
+        <template slot="imgSlot" slot-scope="text,record">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
+          <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
+        </template>
+        <template slot="fileSlot" slot-scope="text">
+          <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
+          <a-button
+            v-else
+            :ghost="true"
+            type="primary"
+            icon="download"
+            size="small"
+            @click="downloadFile(text)">
+            下载
+          </a-button>
+        </template>
+
+        <span slot="action" slot-scope="text, record">
+          <a @click="handleEdit(record)">编辑</a>
+
+          <a-divider type="vertical" />
+          <a-dropdown>
+            <a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
+            <a-menu slot="overlay">
+              <a-menu-item>
+                <a @click="handleDetail(record)">详情</a>
+              </a-menu-item>
+              <a-menu-item>
+                <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
+                  <a>删除</a>
+                </a-popconfirm>
+              </a-menu-item>
+            </a-menu>
+          </a-dropdown>
+        </span>
+
+      </a-table>
+    </div>
+
+    <tpm-tag-modal ref="modalForm" @ok="modalFormOk"></tpm-tag-modal>
+    <TpmTagModalPL ref="modalFormPL" @ok="modalFormOk"></TpmTagModalPL>
+  </a-card>
+</template>
+
+<script>
+  import { httpAction, getAction } from '@/api/manage'
+  import '@/assets/less/TableExpand.less'
+  import { mixinDevice } from '@/utils/mixin'
+  import { JeecgListMixin } from '@/mixins/JeecgListMixin'
+  import TpmTagModal from './modules/TpmTagModal'
+  import {filterMultiDictText} from '@/components/dict/JDictSelectUtil'
+import TpmTagModalPL from './modulesPL/TpmTagModalPL.vue'
+
+  export default {
+    name: 'TpmTagList',
+    mixins:[JeecgListMixin, mixinDevice],
+    components: {
+      TpmTagModal,
+      TpmTagModalPL
+    },
+    data () {
+      return {
+        description: '设备点位表管理页面',
+        // 表头
+        columns: [
+          {
+            title: '#',
+            dataIndex: '',
+            key:'rowIndex',
+            width:60,
+            align:"center",
+            customRender:function (t,r,index) {
+              return parseInt(index)+1;
+            }
+          },
+          {
+            title:'设备',
+            align:"center",
+            dataIndex: 'equipmentid_dictText'
+          },
+          {
+            title:'点位名',
+            align:"center",
+            dataIndex: 'tagname'
+          },
+          {
+            title:'点位地址',
+            align:"center",
+            dataIndex: 'tagaddress'
+          },
+          {
+            title:'点位类型',
+            align:"center",
+            dataIndex: 'tagtype'
+          },
+          {
+            title:'能源分类',
+            align:"center",
+            dataIndex: 'energytypeid'
+          },
+          {
+            title:'能源分项',
+            align:"center",
+            dataIndex: 'energyitemid'
+          },
+          {
+            title:'下限',
+            align:"center",
+            dataIndex: 'min'
+          },
+          {
+            title:'上限',
+            align:"center",
+            dataIndex: 'max'
+          },
+          {
+            title:'报警延时(分钟)',
+            align:"center",
+            dataIndex: 'delay'
+          },
+          {
+            title:'其他值1',
+            align:"center",
+            dataIndex: 'param1'
+          },
+          {
+            title:'其他值2',
+            align:"center",
+            dataIndex: 'param2'
+          },
+          {
+            title:'当前点位值获得时间',
+            align:"center",
+            dataIndex: 'logtime'
+          },
+          {
+            title:'当前点位值',
+            align:"center",
+            dataIndex: 'tagvalue'
+          },
+          // {
+          //   title:'最后一次报警时间',
+          //   align:"center",
+          //   dataIndex: 'lastalarmtime'
+          // },
+          {
+            title: '操作',
+            dataIndex: 'action',
+            align:"center",
+            fixed:"right",
+            width:147,
+            scopedSlots: { customRender: 'action' }
+          }
+        ],
+        url: {
+          list: "/tpmTag/tpmTag/list",
+          delete: "/tpmTag/tpmTag/delete",
+          deleteBatch: "/tpmTag/tpmTag/deleteBatch",
+          exportXlsUrl: "/tpmTag/tpmTag/exportXls",
+          importExcelUrl: "tpmTag/tpmTag/importExcel",
+          getPoint: "/tpmIoserverTag/tpmIoserverTag/tagList"
+        },
+        dictOptions:{},
+        superFieldList:[],
+        // 点位名下拉列表
+        pointOptions: [],
+      }
+    },
+    created() {
+      this.getSuperFieldList();
+      // 获取点位数据
+      this.getPointOptions()
+    },
+    computed: {
+      importExcelUrl: function(){
+        return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
+      },
+    },
+    methods: {
+      initDictConfig(){
+      },
+      getSuperFieldList(){
+        let fieldList=[];
+        fieldList.push({type:'string',value:'equipmentid',text:'设备ID',dictCode:"ems_tpm_equipment,id,equipmentname"})
+        fieldList.push({type:'string',value:'tagname',text:'点位名',dictCode:''})
+        fieldList.push({type:'string',value:'tagaddress',text:'点位地址',dictCode:'tagaddress'})
+        fieldList.push({type:'string',value:'tagtype',text:'点位类型:温度、湿度、噪声、氧浓度、需量、电流、电压、电量、冷热模式、开关机、设定温度、运行状态、故障状态、环境温度等',dictCode:''})
+        fieldList.push({type:'string',value:'energytypeid',text:'能源分类ID',dictCode:''})
+        fieldList.push({type:'string',value:'energyitemid',text:'能源分项ID',dictCode:''})
+        fieldList.push({type:'BigDecimal',value:'min',text:'下限',dictCode:''})
+        fieldList.push({type:'BigDecimal',value:'max',text:'上限',dictCode:''})
+        fieldList.push({type:'int',value:'delay',text:'报警延时(分钟)',dictCode:''})
+        fieldList.push({type:'string',value:'param1',text:'其他值1',dictCode:''})
+        fieldList.push({type:'string',value:'param2',text:'其他值2',dictCode:''})
+        fieldList.push({type:'datetime',value:'logtime',text:'当前点位值获得时间'})
+        fieldList.push({type:'BigDecimal',value:'tagvalue',text:'当前点位值',dictCode:''})
+        fieldList.push({type:'datetime',value:'lastalarmtime',text:'最后一次报警时间'})
+        this.superFieldList = fieldList
+      },
+      handleAddPL(){
+        this.$refs.modalFormPL.title = "批量引入点位";
+        this.$refs.modalFormPL.disableSubmit = false;
+        this.$refs.modalFormPL.visible = true;
+      },
+      getPointOptions() {
+            getAction(this.url.getPoint, this.queryParam).then((res) => {
+                this.pointOptions = res.result.map(item => {
+                    return {
+                      value: item.tagname,
+                      label: item.tagname
+                    }
+                })
+            })
+        },
+    }
+  }
+</script>
+<style scoped>
+  @import '~@assets/less/common.less';
+</style>

+ 47 - 0
src/views/module_tpm/Tag/index.vue

@@ -0,0 +1,47 @@
+<template>
+    <div class="all">
+        <div class="left">
+            <tpm-device-list></tpm-device-list>
+        </div>
+        <div class="right">
+            <tpm-tag-list></tpm-tag-list>
+        </div>
+    </div>
+</template>
+
+<script>
+import TpmTagList from './TpmTagList.vue';
+import TpmDeviceList from './TpmDeviceList.vue';
+
+    export default({
+        components: {
+            TpmTagList,
+            TpmDeviceList
+        },
+        data () {
+            return {
+                
+            }
+        }
+    })
+</script>
+
+<style scoped>
+.all{
+    height: calc(100vh - 135px);
+    width: 100%;
+    display: flex;
+}
+.left{
+    height: 100%;
+    width: 20%;
+    /* border: 2px solid red; */
+    margin-right: 10px;
+    margin-left: 5px;
+}
+.right{
+    height: 100%;
+    width: 80%;
+    /* border: 2px solid red; */
+}
+</style>

+ 200 - 0
src/views/module_tpm/Tag/modules/TagForm.vue

@@ -0,0 +1,200 @@
+<template>
+  <a-spin :spinning="confirmLoading">
+    <j-form-container :disabled="formDisabled">
+      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+        <a-row>
+          <a-col :span="12">
+            <a-form-model-item label="设备" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentid">
+              <!-- <a-input v-model="model.equipmentid" placeholder="请输入设备ID"  ></a-input> -->
+              <j-search-select-tag v-model="model.equipmentid" placeholder="请选择设备" dict="ems_tpm_equipment,equipmentname,id"  />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="点位名" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="tagname">
+              <!-- <a-input v-model="model.tagname" placeholder="请输入点位名"  ></a-input> -->
+              <a-select
+                v-model="model.tagname"
+                placeholder="请选择点位"
+                show-search
+                allowClear
+                :options="pointOptions">
+                </a-select>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="点位地址" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="tagaddress">
+              <a-input v-model="model.tagaddress" placeholder="请输入点位地址"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="点位类型" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="tagtype">
+              <a-input v-model="model.tagtype" placeholder="请输入点位类型"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="能源分类" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="energytypeid">
+              <a-input v-model="model.energytypeid" placeholder="请输入能源分类"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="能源分项" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="energyitemid">
+              <a-input v-model="model.energyitemid" placeholder="请输入能源分项"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="下限" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="min">
+              <a-input-number v-model="model.min" placeholder="请输入下限" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="上限" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="max">
+              <a-input-number v-model="model.max" placeholder="请输入上限" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="报警延时(分钟)" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="delay">
+              <a-input-number v-model="model.delay" placeholder="请输入报警延时(分钟)" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="其他值1" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="param1">
+              <a-input v-model="model.param1" placeholder="请输入其他值1"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="其他值2" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="param2">
+              <a-input v-model="model.param2" placeholder="请输入其他值2"  ></a-input>
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="当前点位值" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="tagvalue">
+              <a-input-number v-model="model.tagvalue" placeholder="请输入当前点位值" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <a-col :span="12">
+            <a-form-model-item label="获得时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="logtime">
+              <j-date placeholder="请选择当前点位值获得时间"  v-model="model.logtime" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
+            </a-form-model-item>
+          </a-col>
+          <!-- <a-col :span="12">
+            <a-form-model-item label="最后一次报警时间" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="lastalarmtime">
+              <j-date placeholder="请选择最后一次报警时间"  v-model="model.lastalarmtime" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%" />
+            </a-form-model-item>
+          </a-col> -->
+        </a-row>
+      </a-form-model>
+    </j-form-container>
+  </a-spin>
+</template>
+
+<script>
+
+  import { httpAction, getAction } from '@/api/manage'
+  import { validateDuplicateValue } from '@/utils/util'
+
+  export default {
+    name: 'TpmTagForm',
+    components: {
+    },
+    props: {
+      //表单禁用
+      disabled: {
+        type: Boolean,
+        default: false,
+        required: false
+      }
+    },
+    data () {
+      return {
+        model:{
+         },
+        labelCol: {
+          xs: { span: 24 },
+          sm: { span: 5 },
+        },
+        wrapperCol: {
+          xs: { span: 24 },
+          sm: { span: 16 },
+        },
+        confirmLoading: false,
+        validatorRules: {
+          equipmentid: [
+            { required: true, message: '请选择设备!'},
+          ],
+          tagname: [
+            { required: true, message: '请选择点位!'},
+          ],
+        },
+        url: {
+          add: "/tpmTag/tpmTag/add",
+          edit: "/tpmTag/tpmTag/edit",
+          queryById: "/tpmTag/tpmTag/queryById",
+          getPoint: "/tpmIoserverTag/tpmIoserverTag/tagList"
+        },
+        // 点位数据
+        pointOptions: []
+      }
+    },
+    computed: {
+      formDisabled(){
+        return this.disabled
+      },
+    },
+    created () {
+       //备份model原始值
+      this.modelDefault = JSON.parse(JSON.stringify(this.model));
+      // 获取点位下拉列表
+      this.getPointOptions()
+    },
+    methods: {
+      add () {
+        this.edit(this.modelDefault);
+      },
+      edit (record) {
+        this.model = Object.assign({}, record);
+        this.visible = true;
+      },
+      submitForm () {
+        const that = this;
+        // 触发表单验证
+        this.$refs.form.validate(valid => {
+          if (valid) {
+            that.confirmLoading = true;
+            let httpurl = '';
+            let method = '';
+            if(!this.model.id){
+              httpurl+=this.url.add;
+              method = 'post';
+            }else{
+              httpurl+=this.url.edit;
+               method = 'put';
+            }
+            httpAction(httpurl,this.model,method).then((res)=>{
+              if(res.success){
+                that.$message.success(res.message);
+                that.$emit('ok');
+              }else{
+                that.$message.warning(res.message);
+              }
+            }).finally(() => {
+              that.confirmLoading = false;
+            })
+          }
+         
+        })
+      },
+      getPointOptions() {
+        getAction(this.url.getPoint).then((res) => {
+          console.log(1111,res.result)
+          this.pointOptions = res.result.map(item => {
+            return {
+              // value: item.id,
+              value: item.tagname,
+              label: item.tagname
+            }
+          })
+        })
+      }
+    }
+  }
+</script>

+ 84 - 0
src/views/module_tpm/Tag/modules/TagModal.Style#Drawer.vue

@@ -0,0 +1,84 @@
+<template>
+  <a-drawer
+    :title="title"
+    :width="width"
+    placement="right"
+    :closable="false"
+    @close="close"
+    destroyOnClose
+    :visible="visible">
+    <tpm-tag-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></tpm-tag-form>
+    <div class="drawer-footer">
+      <a-button @click="handleCancel" style="margin-bottom: 0;">关闭</a-button>
+      <a-button v-if="!disableSubmit"  @click="handleOk" type="primary" style="margin-bottom: 0;">提交</a-button>
+    </div>
+  </a-drawer>
+</template>
+
+<script>
+
+  import TpmTagForm from './TpmTagForm'
+
+  export default {
+    name: 'TpmTagModal',
+    components: {
+      TpmTagForm
+    },
+    data () {
+      return {
+        title:"操作",
+        width:800,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        });
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>
+
+<style lang="less" scoped>
+/** Button按钮间距 */
+  .ant-btn {
+    margin-left: 30px;
+    margin-bottom: 30px;
+    float: right;
+  }
+  .drawer-footer{
+    position: absolute;
+    bottom: -8px;
+    width: 100%;
+    border-top: 1px solid #e8e8e8;
+    padding: 10px 16px;
+    text-align: right;
+    left: 0;
+    background: #fff;
+    border-radius: 0 0 2px 2px;
+  }
+</style>

+ 60 - 0
src/views/module_tpm/Tag/modules/TagModal.vue

@@ -0,0 +1,60 @@
+<template>
+  <j-modal
+    :title="title"
+    :width="width"
+    :visible="visible"
+    switchFullscreen
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <tpm-tag-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit"></tpm-tag-form>
+  </j-modal>
+</template>
+
+<script>
+
+  import TpmTagForm from './TpmTagForm'
+  export default {
+    name: 'TpmTagModal',
+    components: {
+      TpmTagForm
+    },
+    data () {
+      return {
+        title:'',
+        width:1200,
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      add () {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.add();
+        })
+      },
+      edit (record) {
+        this.visible=true
+        this.$nextTick(()=>{
+          this.$refs.realForm.edit(record);
+        })
+      },
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>

+ 358 - 0
src/views/module_tpm/Tag/modulesPL/TagFormPL1.vue

@@ -0,0 +1,358 @@
+<template>
+    <div class="center">
+        <div class="left">
+            <a-card size="small" title="选择点位" style="width: 100%;">
+                <a slot="extra" @click="handleQR">确认</a>
+                <a-form layout="inline" @keyup.enter.native="getPointOptions">
+                    <a-form-item>
+                        <a-input v-model="queryParam.tagname" placeholder="输入点位名,回车查询"/>
+                    </a-form-item>
+                </a-form>
+                <a-table
+                ref="table"
+                size="small"
+                :scroll="{x:true}"
+                bordered
+                rowKey="id"
+                :columns="columns"
+                :dataSource="dataPoint"
+                :pagination="false"
+                :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
+                class="j-table-force-nowrap">
+                </a-table>
+            </a-card>
+        </div>
+        <div class="right">
+            <j-form-container>
+                <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
+                    <div class="top">
+                        <a-card size="small" title="选择设备" style="width: 100%;">
+                            <div style="height: 100%;width:100%;display: flex;">
+                                <div style="height: 100%;width:95%;">
+                                    <!-- <j-form-container>
+                                        <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail"> -->
+                                                <a-form-model-item label="设备名称" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="equipmentid">
+                                                    <!-- bug:不能搜索 (解决:a-form-model加上slot="detail")-->
+                                                    <j-search-select-tag v-model="model.equipmentid" placeholder="请选择设备" dict="ems_tpm_equipment,equipmentname,id"  />
+                                                </a-form-model-item>
+                                        <!-- </a-form-model>
+                                    </j-form-container> -->
+                                </div>
+                                <div style="height: 100%;width:5%;padding-top:0.3%;">
+                                    <a-button type="primary" icon="search" />
+                                </div>
+                            </div>
+                        </a-card>
+                    </div>
+                    <div class="bottom">
+                        <a-card size="small" title="设置点位信息" style="width: 100%;">
+                            <a-table
+                            size="small"
+                            :columns="columnsR"
+                            :dataSource="model.data"
+                            :pagination="false"
+                            :rowKey="(record, index) => { return index }"
+                            bordered
+                            class="j-table-force-nowrap"
+                            >
+                                <template slot="tagname" slot-scope="text, record,index">
+                                    <!--  -->
+                                    <a-form-model-item :prop="'data.'+index+'.tagname'" :rules="validatorRules.tagname" style="margin-bottom: 0px;">
+                                        <!-- <a-input v-model="record.tagname"></a-input> -->
+                                        {{ record.tagname }}
+                                    </a-form-model-item>
+                                </template>
+                                <template slot="tagaddress" slot-scope="text, record,index">
+                                    <a-form-model-item :prop="'data.'+index+'.tagaddress'" :rules="validatorRules.tagaddress" style="margin-bottom: 0px;">
+                                        <a-input v-model="record.tagaddress"></a-input>
+                                    </a-form-model-item>
+                                </template>
+                                <!-- <template slot="tagtype" slot-scope="text, record,index">
+                                    <a-form-model-item :prop="'data.'+index+'.tagtype'" :rules="validatorRules.tagtype" style="margin-bottom: 0px;">
+                                        <a-input v-model="record.tagtype"></a-input>
+                                    </a-form-model-item>
+                                </template> -->
+                                <template slot="operation" slot-scope="text, record">
+                                    <span>
+                                        <a-popconfirm title="是否要删除此行?" @confirm="remove(record.key)">
+                                            <a>删除</a>
+                                        </a-popconfirm>
+                                        </span>
+                                </template>
+                            </a-table>
+                        </a-card>
+                    </div>
+                </a-form-model>
+            </j-form-container>
+        </div>
+    </div>
+</template>
+
+<script>
+import { httpAction, getAction } from '@/api/manage'
+
+export default {
+    name: 'TpmTagFormPL1',
+    components: {
+    },
+    data () {
+        return {
+            queryParam: {},
+            // 左侧表格表头
+            columns: [
+                {
+                    title:'点位名',
+                    align:"center",
+                    dataIndex: 'tagname'
+                },
+            ],
+            // 右侧表格表头
+            columnsR: [
+                // {
+                // title: '样品名称',
+                // dataIndex: 'sampleName',
+                // key: 'sampleName',
+                // align: 'center',
+                // scopedSlots: { customRender: 'sampleName' }
+                // },
+                {
+                title: '点位名称',
+                dataIndex: 'tagname',
+                key: 'tagname',
+                align: 'center',
+                scopedSlots: { customRender: 'tagname' }
+                },
+                {
+                title: '点位地址',
+                dataIndex: 'tagaddress',
+                key: 'tagaddress',
+                align: 'center',
+                scopedSlots: { customRender: 'tagaddress' }
+                },
+                {
+                title: '点位类型',
+                dataIndex: 'tagtype',
+                key: 'tagtype',
+                align: 'center',
+                scopedSlots: { customRender: 'tagtype' }
+                },
+                {
+                title: '能源分类',
+                dataIndex: 'energytypeid',
+                key: 'energytypeid',
+                align: 'center',
+                scopedSlots: { customRender: 'energytypeid' }
+                },
+                {
+                title: '能源分项',
+                dataIndex: 'energyitemid',
+                key: 'energyitemid',
+                align: 'center',
+                scopedSlots: { customRender: 'energyitemid' }
+                },
+                {
+                title: '下限',
+                dataIndex: 'min',
+                key: 'min',
+                align: 'center',
+                scopedSlots: { customRender: 'min' }
+                },
+                {
+                title: '上限',
+                dataIndex: 'max',
+                key: 'max',
+                align: 'center',
+                scopedSlots: { customRender: 'max' }
+                },
+                {
+                title: '报警延时(分钟)',
+                dataIndex: 'delay',
+                key: 'delay',
+                align: 'center',
+                scopedSlots: { customRender: 'delay' }
+                },
+                {
+                title: '其他值1',
+                dataIndex: 'param1',
+                key: 'param1',
+                align: 'center',
+                scopedSlots: { customRender: 'param1' }
+                },
+                {
+                title: '其他值2',
+                dataIndex: 'param2',
+                key: 'param2',
+                align: 'center',
+                scopedSlots: { customRender: 'param2' }
+                },
+                {
+                title: '当前点位值',
+                dataIndex: 'tagvalue',
+                key: 'tagvalue',
+                align: 'center',
+                scopedSlots: { customRender: 'tagvalue' }
+                },
+                {
+                title: '获得时间',
+                dataIndex: 'logtime',
+                key: 'logtime',
+                align: 'center',
+                scopedSlots: { customRender: 'logtime' }
+                },
+                {
+                title: '操作',
+                key: 'action',
+                align: 'center',
+                scopedSlots: { customRender: 'operation' }
+                }
+            ],
+            /* table选中keys*/
+            selectedRowKeys: [],
+            /* table选中records*/
+            selectionRows: [],
+            url: {
+                add: "/tpmTag/tpmTag/saveBatch",
+                getPoint: "/tpmIoserverTag/tpmIoserverTag/tagList"
+            },
+            // 点位数据
+            dataPoint: [],
+            count: 1,
+            model:{
+                data: []
+            },
+            labelCol: {
+                xs: { span: 24 },
+                sm: { span: 2 },
+            },
+            wrapperCol: {
+                xs: { span: 24 },
+                sm: { span: 22 },
+            },
+            validatorRules: {
+                equipmentid: [
+                    { required: true, message: '请选择设备!'},
+                ],
+            },
+        }
+    },
+    created () {
+      // 获取点位数据
+      this.getPointOptions()
+    },
+    methods: {
+        getPointOptions() {
+            getAction(this.url.getPoint, this.queryParam).then((res) => {
+                this.dataPoint = res.result.map(item => {
+                    return {
+                    id: item.id,
+                    tagname: item.tagname
+                    }
+                })
+            })
+        },
+        onSelectChange(selectedRowKeys, selectionRows) {
+            console.log(selectedRowKeys, selectionRows)
+            this.selectedRowKeys = selectedRowKeys;
+            this.selectionRows = selectionRows;
+        },
+        onClearSelected() {
+            this.selectedRowKeys = [];
+            this.selectionRows = [];
+        },
+        handleQR() {
+            console.log(77,this.selectionRows)
+            this.model.data = []
+            for (let i = 0; i < this.selectionRows.length; i++) {
+                const element = this.selectionRows[i];
+                console.log(88,element)
+                this.model.data.push({
+                    key: this.count + '',
+                    tagname: element.tagname,
+                })
+                this.count++
+            }
+            console.log(99,this.model.data)
+        },
+        remove(key) {
+            console.log(key)
+            const newData = this.model.data.filter(item => item.key !== key)
+            this.model.data = newData
+        },
+        submitForm () {
+            const that = this;
+            // 触发表单验证
+            this.$refs.form.validate(valid => {
+            if (valid) {
+                console.log(this.model)
+                let httpurl = '';
+                let method = '';
+                const a = this.model.data.map(item=>{
+                    var obj = item
+                    obj.equipmentid = this.model.equipmentid
+                    return obj
+                    // return {
+                    //     tagname: item.tagname,
+                    //     tagaddress: item.tagaddress,
+                    //     equipmentid: this.model.equipmentid
+                    // }
+                })
+                console.log(a)
+                httpurl+=this.url.add;
+                method = 'post';
+                httpAction(httpurl,a,method).then((res)=>{
+                    if(res.success){
+                        that.$message.success(res.message);
+                        that.$emit('ok');
+                    }else{
+                        that.$message.warning(res.message);
+                    }
+                })
+            }
+            
+            })
+        },
+    }
+}
+</script>
+
+<style scoped>
+.center{
+    height: 100%;
+    width: 100%;
+    display: flex;
+}
+.left{
+    height: 100%;
+    width: 25%;
+    /* border: 2px solid red; */
+}
+.right{
+    height: 100%;
+    width: 75%;
+    padding-left: 1%;
+    /* border: 2px solid red; */
+}
+.top{
+    height: 18%;
+    width: 100%;
+    display: flex;
+    padding-bottom: 1%;
+    /* border: 2px solid red; */
+}
+.bottom{
+    height: 80%;
+    width: 100%;
+    display: flex;
+    /* border: 2px solid red; */
+}
+/* 更改a-input样式 */
+::v-deep .a-input .ant-form-inline .ant-form-item{
+    width: 100% !important;
+}
+::v-deep .ant-row{
+    width: 100% !important;
+}
+::v-deep .ant-form-inline .ant-form-item > .ant-form-item-control-wrapper, .ant-form-inline .ant-form-item > .ant-form-item-label{
+    width: 100% !important;
+}
+</style>

+ 47 - 0
src/views/module_tpm/Tag/modulesPL/TagModalPL.vue

@@ -0,0 +1,47 @@
+<template>
+  <u-modal
+    :title="title"
+    :visible.sync="visible"
+    contentFull
+    @ok="handleOk"
+    :okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
+    @cancel="handleCancel"
+    cancelText="关闭">
+    <TpmTagFormPL1 ref="realForm" @ok="submitCallback"></TpmTagFormPL1>
+  </u-modal>
+</template>
+
+<script>
+import UModal from '../../../../components/module_ems/UModal/UModal.vue';
+  import TpmTagFormPL1 from './TpmTagFormPL1'
+  export default {
+    name: 'TpmTagModalPL',
+    components: {
+      TpmTagFormPL1,
+        UModal
+    },
+    data () {
+      return {
+        title:'',
+        visible: false,
+        disableSubmit: false
+      }
+    },
+    methods: {
+      close () {
+        this.$emit('close');
+        this.visible = false;
+      },
+      handleOk () {
+        this.$refs.realForm.submitForm();
+      },
+      submitCallback(){
+        this.$emit('ok');
+        this.visible = false;
+      },
+      handleCancel () {
+        this.close()
+      }
+    }
+  }
+</script>