Переглянути джерело

dcs车间单独一个表,不和设备位置公用

hfxc226 1 рік тому
батько
коміт
11956405c7

+ 174 - 0
src/api/remote/remote-position.js

@@ -0,0 +1,174 @@
+import { axios } from '@/utils/request'
+import { stringify } from 'qs'
+
+/**
+ * page func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function getSbPositionPage (parameter) {
+  return axios({
+    url: '/remote/positions/page?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}
+
+/**
+ * add func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function addSbPosition (parameter) {
+  return axios({
+    url: '/remote/positions',
+    method: 'POST',
+    headers: {
+      'Accept': 'application/json',
+      'Content-Type': 'application/json;charset=UTF-8'
+    },
+    data: parameter
+  })
+}
+
+/**
+ * update func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function updateSbPosition (parameter) {
+  return axios({
+    url: '/remote/positions/' + parameter.id,
+    method: 'PUT',
+    data: parameter
+  })
+}
+
+/**
+ * fetch single func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function fetchSbPosition (parameter) {
+  return axios({
+    url: '/remote/positions/' + parameter.id,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}
+
+/**
+ * query list func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function querySbPosition (parameter) {
+  return axios({
+    url: '/remote/positions?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}
+
+/**
+ * delete batch func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function deleteSbPositions (parameter) {
+  return axios({
+    url: '/remote/positions',
+    method: 'DELETE',
+    data: parameter
+  })
+}
+
+/**
+ * delete single func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function deleteSbPosition (parameter) {
+  return axios({
+    url: '/remote/positions/' + parameter.id,
+    method: 'DELETE',
+    data: parameter
+  })
+}
+
+/**
+ * export file
+ * parameter: { }
+ * @param parameter :
+ * @returns {*}
+ */
+export function exportSbPosition (parameter) {
+  return axios({
+    url: '/remote/positions/export?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    },
+    responseType: 'blob'
+  })
+}
+/**
+ * 获取设备位置树
+ * parameter: { }
+ * @param parameter :
+ * @returns {*}
+ */
+export function getSbPositionTree (parameter) {
+  return axios({
+    url: '/remote/positions/tree?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}
+
+/**
+ * 获取设备位置树
+ * parameter: { }
+ * @param parameter :
+  * @returns {*}
+ */
+export function getSbPositionSbTree (parameter) {
+  return axios({
+    url: '/remote/positions/remote/tree?' + stringify(parameter),
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}
+
+/**
+ * fetch single func
+ * parameter: { }
+ * @param parameter
+ * @returns {*}
+ */
+export function selectCountByPosition (parameter) {
+  return axios({
+    url: '/remote/positions/num/code/' + parameter.code,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8'
+    }
+  })
+}

+ 1 - 0
src/router/generator-platform-routers.js

@@ -381,6 +381,7 @@ const constantRouterComponents = {
   'OpcPosition': () => import('@/views/remote/opc/OpcPosition'), // opc车间
   'OpcPositionNot': () => import('@/views/remote/opc/OpcPositionNot'), // opc车间未配置
   'OpcPositionForProducer': () => import('@/views/remote/opc/OpcPositionForProducer'), // opc车间生产入口
+  'RemotePosition': () => import('@/views/remote/position/RemotePosition'), // opc车间配置
   // 初始化导入
   'ImportExcel': () => import('@/views/excel/ImportExcel'),
 

+ 2 - 2
src/views/opc/Opc.vue

@@ -163,7 +163,7 @@
 <script>
 import VueDragResize from 'vue-drag-resize'
 import LiquidLevel from '@/components/LiquidLevel'
-import { getSbPositionTree, fetchSbPosition, querySbPosition } from '@/api/sb/position'
+import { getSbPositionTree, fetchSbPosition, querySbPosition } from '@/api/remote/remote-position'
 import { queryRemoteOpc, updateRemoteOpc } from '@/api/remote/opc'
 import BaseChartInfo from './modules/BaseChartInfo.vue'
 import BaseForm from '@/views/remote/opc/modules/BaseForm.vue'
@@ -272,7 +272,7 @@ export default {
       querySbPosition({ parentId: this.parentId }).then(res => {
         this.list = res.data
       })
-      getSbPositionTree({ opcFlag: 1 }).then(res => {
+      getSbPositionTree().then(res => {
         this.treeData = res.data
       })
     },

+ 2 - 2
src/views/opc/OpcInfo.vue

@@ -202,7 +202,7 @@
 import VueDragResize from 'vue-drag-resize'
 import LiquidLevel from '@/components/LiquidLevel'
 
-import { getSbPositionTree, fetchSbPosition, querySbPosition } from '@/api/sb/position'
+import { getSbPositionTree, fetchSbPosition, querySbPosition } from '@/api/remote/remote-position'
 import {
   updateRemoteOpc,
   fetchRemoteOpc, queryRemoteOpc, queryRemoteOpcFromRedis
@@ -255,7 +255,7 @@ export default {
       this.getOpcInfoFromRedis(this.positionId)
     })
     this.getImg()
-    getSbPositionTree({ opcFlag: 1 }).then(res => {
+    getSbPositionTree().then(res => {
       this.treeData = res.data
     })
     this.timer = setInterval(() => {

+ 1 - 1
src/views/remote/opc/OpcPosition.vue

@@ -11,7 +11,7 @@
 
 <script>
 
-import { getSbPositionTree } from '@/api/sb/position'
+import { getSbPositionTree } from '@/api/remote/remote-position'
 
 export default {
   name: 'OpcPosition',

+ 1 - 1
src/views/remote/opc/OpcPositionForProducer.vue

@@ -11,7 +11,7 @@
 
 <script>
 
-import { getSbPositionTree } from '@/api/sb/position'
+import { getSbPositionTree } from '@/api/remote/remote-position'
 
 export default {
   name: 'OpcPosition',

+ 3 - 3
src/views/remote/opc/OpcPositionNot.vue

@@ -1,13 +1,13 @@
 <template>
-  <SbPosition :opc-flag="0"/>
+  <RemotePosition/>
 </template>
 
 <script>
-import SbPosition from '@/views/sb/position/SbPosition'
+import RemotePosition from '@/views/remote/position/RemotePosition'
 export default {
   name: 'OpcPositionNot',
   components: {
-    SbPosition
+    RemotePosition
   }
 }
 </script>

+ 308 - 0
src/views/remote/position/RemotePosition.vue

@@ -0,0 +1,308 @@
+<template>
+  <a-card :bordered="false">
+    <div class="table-page-search-wrapper">
+      <a-form layout="inline">
+        <a-row :gutter="48">
+          <a-col :md="8" :sm="24">
+            <a-form-item label="关键字">
+              <a-input v-model.trim="queryParam.keyword" placeholder="请输入名称/编码"/>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8" :sm="24">
+            <a-form-item label="上层位置类型">
+              <a-tree-select
+                style="width: 100%"
+                :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
+                :treeData="treeData"
+                :treeNodeFilterProp="'title'"
+                :showSearch="true"
+                v-model="queryParam.parentId"
+                placeholder="请选择"
+              >
+              </a-tree-select>
+            </a-form-item>
+          </a-col>
+          <a-col :md="8 || 24" :sm="24">
+            <span class="table-page-search-submitButtons">
+              <a-button type="primary" @click="$refs.table.refresh(true)">查询</a-button>
+              <a-button style="margin-left: 8px" @click="resetSearchForm">重置</a-button>
+            </span>
+          </a-col>
+        </a-row>
+      </a-form>
+    </div>
+
+    <div class="table-operator" style="margin-bottom: 8px;">
+      <a-button v-if="$auth('remote-positions-add')" type="primary" icon="plus" @click="$refs.baseModal.base()">新增</a-button>
+      <a-button style="margin-left: 8px" v-if="$auth('remote-positions-export')" type="primary" icon="download" @click="doExport">导出</a-button>
+      <a-dropdown v-action:edit v-if="selectedRowKeys.length > 0 && $auth('remote-positions-del')">
+        <a-menu slot="overlay">
+          <a-popconfirm title="是否要删除所选数据?" @confirm="batchDelete()">
+            <a-menu-item key="1"><a-icon type="delete" /><a>删除</a></a-menu-item>
+          </a-popconfirm>
+        </a-menu>
+        <a-button style="margin-left: 8px">
+          批量操作 <a-icon type="down" />
+        </a-button>
+      </a-dropdown>
+    </div>
+
+    <s-table
+      ref="table"
+      size="default"
+      rowKey="id"
+      :columns="columns"
+      :data="loadData"
+      :alert="options.alert"
+      :rowSelection="options.rowSelection"
+      showPagination="auto"
+    >
+      <span slot="action" slot-scope="record">
+        <template>
+          <a @click="handleView(record)">查看</a>
+          <a-divider type="vertical" />
+          <a v-if="$auth('remote-positions-edit')" @click="handleEdit(record)">修改</a>
+          <!--<a-divider type="vertical" />
+          <a-popconfirm v-if="$auth('remote-positions-del')" title="是否要删除该条数据?" @confirm="batchDelete(record.id)">
+            <a>删除</a>
+          </a-popconfirm>-->
+          <a-divider type="vertical" />
+          <a @click="handleCopy(record)">复制</a>
+          <a-divider type="vertical" />
+          <a v-if="record.opcFlag==1" @click="handleSetting(record)">点位配置</a>
+        </template>
+      </span>
+      <span slot="delFlag" slot-scope="text">
+        <badge
+          :status="DictCache.COLOR.DELFLAG[text]"
+          :text="delFlagMap[text]" />
+      </span>
+    </s-table>
+    <base-form ref="baseModal" @ok="handleOk"/>
+    <detail ref="detailModal"/>
+  </a-card>
+</template>
+
+<script>
+import { STable, Ellipsis } from '@/components'
+import BaseForm from './modules/BaseForm'
+import Detail from './modules/Detail'
+import { getSbPositionPage, deleteSbPositions, fetchSbPosition, exportSbPosition, getSbPositionTree } from '@/api/remote/remote-position'
+
+export default {
+  name: 'RemotePositionList',
+  components: {
+    STable,
+    Ellipsis,
+    BaseForm,
+    Detail
+  },
+  data () {
+    return {
+      // 查询参数
+      yesNoMap: {},
+      queryParam: {
+        opcFlag: this.opcFlag,
+        lightFlag: this.lightFlag
+      },
+      positionTypeMap: {},
+      delFlagMap: {},
+      treeData: [],
+      // 表头
+      columns: [
+        {
+          title: '序号',
+          dataIndex: 'index',
+          customRender: (text, record, index) => {
+            return `${(this.$refs.table.localPagination.current - 1) * this.$refs.table.localPagination.pageSize + index + 1}`
+          }
+        },
+        {
+          title: '编码',
+          dataIndex: 'no'
+        },
+        {
+          title: '名称',
+          dataIndex: 'name'
+        },
+        {
+          title: '类型',
+          dataIndex: 'type',
+          customRender: (text, record, index) => {
+            return this.BaseTool.Object.getField(this.positionTypeMap, text)
+          }
+        },
+        /*      {
+          title: '父子关联编码',
+          dataIndex: 'code'
+        }, */
+        {
+          title: '排序',
+          dataIndex: 'sort'
+        },
+        {
+          title: '上层位置',
+          dataIndex: 'parentId',
+          customRender: (text, record, index) => {
+            return record.parentName
+          }
+        },
+        {
+          title: '备注',
+          dataIndex: 'remark'
+        },
+        {
+          title: '创建日期',
+          dataIndex: 'createdTime'
+        },
+        {
+          title: '是否删除',
+          dataIndex: 'delFlag',
+          scopedSlots: { customRender: 'delFlag' }
+        },
+        {
+          title: '操作',
+          key: 'action',
+          width: '200px',
+          align: 'center',
+          scopedSlots: { customRender: 'action' }
+        }
+      ],
+      // 加载数据方法 必须为 Promise 对象
+      loadData: parameter => {
+        parameter = {
+          ...parameter,
+          ...this.queryParam,
+          dataScope: {
+            sortBy: 'asc',
+            sortName: 'sort'
+          }
+        }
+        return getSbPositionPage(Object.assign(parameter, this.queryParam))
+          .then(res => {
+            return res.data
+          })
+      },
+      selectedRowKeys: [],
+      selectedRows: [],
+
+      options: {
+        alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+        rowSelection: {
+          selectedRowKeys: this.selectedRowKeys,
+          onChange: this.onSelectChange
+        }
+      },
+      optionAlertShow: false
+    }
+  },
+  created () {
+    this.tableOption()
+    this.delFlagMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.DELFLAG)
+    this.yesNoMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.YES_NO)
+    this.positionTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.SBPOSITION_TYPE)
+  },
+  methods: {
+    tableOption () {
+      this.setTree()
+      if (!this.optionAlertShow) {
+        this.options = {
+          alert: { show: true, clear: () => { this.selectedRowKeys = [] } },
+          rowSelection: {
+            selectedRowKeys: this.selectedRowKeys,
+            onChange: this.onSelectChange,
+            getCheckboxProps: record => ({
+              props: {
+                disabled: false,
+                name: record.id
+              }
+            })
+          }
+        }
+        this.optionAlertShow = true
+      } else {
+        this.options = {
+          alert: false,
+          rowSelection: null
+        }
+        this.optionAlertShow = false
+      }
+    },
+    batchDelete (id) {
+      let ids = []
+      if (this.BaseTool.String.isBlank(id)) {
+        const length = this.selectedRows.length
+        if (length === 0) {
+          this.$message.info('请选择要删除的记录')
+          return
+        }
+        ids = this.selectedRows.map(item => item.id)
+      } else {
+        ids = [id]
+      }
+      deleteSbPositions(ids).then(res => {
+        this.$message.info('删除成功')
+        this.handleOk()
+        this.$refs.table.clearSelected()
+      })
+    },
+    handleEdit (record) {
+      fetchSbPosition({ id: record.id }).then(res => {
+        const modal = this.$refs.baseModal
+        modal.base(res.data)
+      })
+    },
+    handleView (record) {
+      fetchSbPosition({ id: record.id }).then(res => {
+        const modal = this.$refs.detailModal
+        modal.base(res.data)
+      })
+    },
+    handleOk () {
+      this.setTree()
+      this.$refs.table.refresh()
+    },
+    onSelectChange (selectedRowKeys, selectedRows) {
+      this.selectedRowKeys = selectedRowKeys
+      this.selectedRows = selectedRows
+    },
+    resetSearchForm () {
+      this.queryParam = {
+        opcFlag: this.opcFlag,
+        lightFlag: this.lightFlag
+      }
+      this.$refs.table.refresh(true)
+    },
+    doExport () {
+      const parameter = {
+        ...this.queryParam
+      }
+      exportSbPosition(parameter).then(file => {
+        this.BaseTool.UPLOAD.downLoadExportExcel(file)
+      })
+    },
+    handleCopy (record) {
+      fetchSbPosition({ id: record.id }).then(res => {
+        const modal = this.$refs.baseModal
+        res.data.id = null
+        modal.base(res.data)
+      })
+    },
+    handleSetting (position) {
+      const a = document.createElement('a')
+      a.href = '/opc?line=' + position.id
+      a.target = '_blank'
+      a.click()
+    },
+    /**
+     * 设置位置树
+     */
+    setTree () {
+      getSbPositionTree({}).then(res => {
+        console.log(res.data)
+        this.treeData = res.data
+      })
+    }
+  }
+}
+</script>

+ 266 - 0
src/views/remote/position/modules/BaseForm.vue

@@ -0,0 +1,266 @@
+<template>
+  <a-modal
+    :title="modalTitle"
+    :width="800"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @cancel="handleCancel"
+  >
+    <a-form :form="form">
+
+      <a-form-item v-show="false" >
+        <a-input v-decorator="['id']" type="hidden"/>
+      </a-form-item>
+
+      <a-form-item
+        label="位号"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-input
+          v-decorator="['no', {rules: [{required: true, message: '位号不能为空'}]}]" />
+      </a-form-item>
+      <a-form-item
+        label="名称"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-input
+          v-decorator="['name', {rules: [{required: true, message: '名称不能为空'}]}]" />
+      </a-form-item>
+      <a-form-item
+        label="类型"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-select v-decorator="['type', {rules: [{required: true, message: '类型不能为空'}]}]" placeholder="请选择">
+          <a-select-option
+            v-for="(label,value) in positionTypeMap"
+            :key="value"
+            :label="label"
+            :value="parseInt(value)">{{ label }}
+          </a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item
+        label="上层位置"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-tree-select
+          style="width: 100%"
+          :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
+          :treeData="treeData"
+          :treeNodeFilterProp="'title'"
+          :showSearch="true"
+          v-decorator="['parentId', {rules: [{required: false, message: '上层位置不能为空'}]}]"
+          placeholder="请选择"
+        >
+        </a-tree-select>
+      </a-form-item>
+      <!--      <a-form-item
+        label="父子关联编码"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-input
+          v-decorator="['code', {rules: [{required: true, message: '父子关联编码不能为空'}]}]" />
+      </a-form-item>-->
+      <a-form-item
+        label="排序"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-input-number
+          style="width: 100%"
+          :min="1"
+          v-decorator="['sort', {initialValue:1,rules: [{required: true, message: '排序不能为空'}]}]" />
+      </a-form-item>
+      <a-form-item
+        label="OPC背景图片"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <upload-position-img
+          ref="imageUpload"
+          @catchImage="catchImage"
+        ></upload-position-img>
+      </a-form-item>
+      <a-form-item
+        label="是否删除"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-select v-decorator="['delFlag', {initialValue:DictCache.VALUE.DELFLAG.NORMAL, rules: [{required: true, message: '是否删除不能为空'}]}]" placeholder="请选择">
+          <a-select-option
+            v-for="(label,value) in delFlagMap"
+            :key="value"
+            :label="label"
+            :value="parseInt(value)">{{ label }}
+          </a-select-option>
+        </a-select>
+      </a-form-item>
+      <a-form-item
+        label="备注"
+        :labelCol="BaseTool.Constant.labelCol"
+        :wrapperCol="BaseTool.Constant.wrapperCol"
+      >
+        <a-input
+          v-decorator="['remark', {rules: [{required: false, message: '备注不能为空'}]}]" />
+      </a-form-item>
+    </a-form>
+    <template slot="footer">
+      <a-button :loading="confirmLoading" type="primary" @click="save()">保存</a-button>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+import pick from 'lodash.pick'
+import { addSbPosition, updateSbPosition, getSbPositionTree } from '@/api/remote/remote-position'
+import { queryRepairUser } from '@/api/upms/user-dept'
+import UploadPositionImg from '@/components/Upload/UploadPositionImg'
+import UploadPositionLightImg from '@/components/Upload/UploadPositionLightImg'
+export default {
+  name: 'BaseRemotePosition',
+  components: { UploadPositionImg, UploadPositionLightImg },
+  data () {
+    return {
+      confirmLoading: false,
+      modalTitle: null,
+      form: this.$form.createForm(this),
+      visible: false,
+      opcImg: '',
+      lightImg: '',
+      positionTypeMap: {},
+      delFlagMap: {},
+      userList: {},
+      yesNoMap: {},
+      treeData: []
+    }
+  },
+  props: {
+  },
+  created () {
+    this.delFlagMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.DELFLAG)
+    this.yesNoMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.YES_NO)
+    this.positionTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.SBPOSITION_TYPE)
+    const params = { roleType: 3, deptId: null, queryType: 1 }
+    queryRepairUser(params).then(res => {
+      this.userList = res.data
+    })
+  },
+  methods: {
+    base (record) {
+      this.setTree(record)
+      this.visible = true
+      // 如果是空标识添加
+      if (this.BaseTool.Object.isBlank(record)) {
+        this.modalTitle = '添加'
+        return
+      }
+      this.modalTitle = '编辑'
+      if (this.BaseTool.Object.isBlank(record.id)) {
+        this.modalTitle = '复制'
+      }
+      const { form: { setFieldsValue } } = this
+      this.$nextTick(() => {
+        setFieldsValue(Object.assign(pick(record, [
+          'id',
+          'no',
+          'name',
+          'type',
+          'code',
+          'sort',
+          'opcFlag',
+          'lightFlag',
+          'delFlag',
+          'parentId',
+          'userId',
+          'remark'
+        ])))
+      })
+      this.opcImg = record.opcImg
+      this.lightImg = record.lightImg
+      const fileList = []
+      if (record.opcImg) {
+        fileList.push({
+          uid: '-1',
+          name: record.name,
+          status: 'done',
+          url: this.BaseTool.Constant.FILE_URL + record.opcImg,
+          originUrl: record.opcImg
+        })
+      }
+      this.$refs.imageUpload.base(1, fileList)
+
+      const fileListLight = []
+      if (record.lightImg) {
+        fileListLight.push({
+          uid: '-1',
+          name: record.name,
+          status: 'done',
+          url: this.BaseTool.Constant.FILE_URL + record.lightImg,
+          originUrl: record.lightImg
+        })
+      }
+      this.$refs.imageUploadLight.base(1, fileListLight)
+    },
+    catchImage (fileList) {
+      if (fileList.length !== 0) {
+        this.opcImg = fileList[0].url
+      }
+    },
+    catchImageLight (fileList) {
+      if (fileList.length !== 0) {
+        this.lightImg = fileList[0].url
+      }
+    },
+    save () {
+      const { form: { validateFieldsAndScroll } } = this
+      this.confirmLoading = true
+      validateFieldsAndScroll((errors, values) => {
+        if (errors) {
+          this.confirmLoading = false
+          return
+        }
+        values.opcImg = this.opcImg
+        values.lightImg = this.lightImg
+        if (this.BaseTool.String.isBlank(values.id)) {
+          addSbPosition(values)
+            .then(() => {
+              this.handleCancel(values)
+            }).catch(() => {
+              this.confirmLoading = false
+            })
+        } else {
+          updateSbPosition(values)
+            .then(() => {
+              this.handleCancel(values)
+            }).catch(() => {
+              this.confirmLoading = false
+            })
+        }
+      })
+    },
+    handleCancel (values) {
+      this.visible = false
+      this.confirmLoading = false
+      this.form.resetFields()
+      if (this.BaseTool.Object.isNotBlank(values)) {
+        this.$emit('ok', values)
+      }
+    },
+    /**
+     * 设置位置树
+     */
+    setTree (record = {}) {
+      getSbPositionTree({ id: record.id }).then(res => {
+        console.log(res.data)
+        this.treeData = res.data
+      })
+    }
+
+  }
+}
+</script>

+ 85 - 0
src/views/remote/position/modules/Detail.vue

@@ -0,0 +1,85 @@
+<template>
+  <a-modal
+    :title="modalTitle"
+    :width="850"
+    :visible="visible"
+    :confirmLoading="confirmLoading"
+    @cancel="handleCancel"
+  >
+    <detail-list title="" :col="2">
+      <detail-list-item term="编号">{{ model.id }}</detail-list-item>
+      <detail-list-item term="编码">{{ model.no }}</detail-list-item>
+      <detail-list-item term="名称">{{ model.name }}</detail-list-item>
+      <detail-list-item term="类型">{{ BaseTool.Object.getField(positionTypeMap,model.type) }}</detail-list-item>
+      <detail-list-item term="排序">{{ model.sort }}</detail-list-item>
+      <detail-list-item term="上层位置">{{ model.parentName }}</detail-list-item>
+      <detail-list-item term="备注">{{ model.remark }}</detail-list-item>
+      <detail-list-item term="图片"><img :src="BaseTool.Constant.FILE_URL + model.opcImg" width="200px" height="200px"/></detail-list-item>
+      <detail-list-item term="创建人">{{ model.createdUserName }}</detail-list-item>
+      <detail-list-item term="是否OPC展示"><badge :status="DictCache.COLOR.DELFLAG[model.opcFlag]" :text="yesNoMap[model.opcFlag]"></badge></detail-list-item>
+      <detail-list-item term="是否删除"><badge :status="DictCache.COLOR.DELFLAG[model.delFlag]" :text="delFlagMap[model.delFlag]"></badge></detail-list-item>
+      <detail-list-item term="更新日期">{{ model.updateTime }}</detail-list-item>
+    </detail-list>
+
+    <template slot="footer">
+      <a-button :loading="confirmLoading" type="primary" @click="handleCancel()">返回</a-button>
+    </template>
+  </a-modal>
+</template>
+
+<script>
+import DetailList from '@/components/tools/DetailList'
+const DetailListItem = DetailList.Item
+
+export default {
+  name: 'RemotePositionDetail',
+  components: {
+    DetailList,
+    DetailListItem
+  },
+  data () {
+    return {
+      confirmLoading: false,
+      mdl: {},
+      modalTitle: null,
+      visible: false,
+      model: {
+        'id': null,
+        'no': null,
+        'name': null,
+        'opcFlag': null,
+        'opcImg': null,
+        'type': null,
+        'sort': null,
+        'delFlag': null,
+        'parentId': null,
+        'remark': null,
+        'createdUserId': null,
+        'updateTime': null,
+        'parentName': null,
+        'createdUserName': null
+      },
+      positionTypeMap: {},
+      yesNoMap: {},
+      delFlagMap: {}
+    }
+  },
+  created () {
+    this.delFlagMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.DELFLAG)
+    this.yesNoMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.YES_NO)
+    this.positionTypeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.SBPOSITION_TYPE)
+  },
+  methods: {
+    base (record) {
+      this.visible = true
+      this.modalTitle = '详情'
+      this.model = record
+    },
+    handleCancel () {
+      this.visible = false
+      this.confirmLoading = false
+    }
+
+  }
+}
+</script>