Browse Source

架位/设备

master
xuhuajiao 7 months ago
parent
commit
3a35ead8b6
  1. 1
      package.json
  2. 147
      src/api/device/index.js
  3. 173
      src/assets/styles/manage.scss
  4. 10
      src/assets/styles/mixin.scss
  5. 12
      src/router/routers.js
  6. 3
      src/views/visualCheck/venueDevice/bookshelf/index.vue
  7. 373
      src/views/visualCheck/venueDevice/bookshelfPosition/index.vue
  8. 417
      src/views/visualCheck/venueDevice/device/index.vue

1
package.json

@ -82,6 +82,7 @@
"v-viewer": "^1.6.4",
"vkbeautify": "^0.99.3",
"vue": "^2.6.14",
"vue-awesome-swiper": "^3.1.3",
"vue-count-to": "^1.0.13",
"vue-cropper": "0.4.9",
"vue-demi": "^0.14.7",

147
src/api/device/index.js

@ -0,0 +1,147 @@
import request from '@/utils/request'
export function getSupplier() {
return request({
url: 'api/supplier/dropdown-list',
method: 'get'
})
}
export function add(data) {
const url = getUrl(data, 'add')
return request({
url: url,
method: 'post',
data
})
}
export function del(data) {
return request({
url: '/api/device/delete',
method: 'delete',
data
})
}
export function edit(data) {
const url = getUrl(data, 'edit')
return request({
url: url,
method: 'put',
data
})
}
export function getDeviceType() {
return request({
url: 'api/device/type',
method: 'get'
})
}
export function getDeviceById(params) {
return request({
url: 'api/device/state',
method: 'get',
params
})
}
export function getDesecabinetById(params) {
return request({
url: 'api/desecabinet/query',
method: 'get',
params
})
}
export function getRotarycabinetById(params) {
return request({
url: 'api/rotarycabinet/query',
method: 'get',
params
})
}
function getUrl(data, optTYpe) {
let url = 'api/desecabinet/'
if (data.deviceTypeId.name === '密集架') {
url = 'api/desecabinet/'
} else if (data.deviceTypeId.name === '回转柜') {
url = 'api/rotarycabinet/'
} else if (data.deviceTypeId.name === '摄像头') {
url = 'api/camera/'
} else if (data.deviceTypeId.name === '空调' || data.deviceTypeId.name === '桌面式RFID读写器' || data.deviceTypeId.name === '盘点机' || data.deviceTypeId.name === '恒湿机' || data.deviceTypeId.name === '漏水传感器' || data.deviceTypeId.name === '温湿度感应器' || data.deviceTypeId.name === '空气质量检测设备' || data.deviceTypeId.name === '漏水传感器') {
url = 'api/insidedevices/'
} else if (data.deviceTypeId.name === '通道门' || data.deviceTypeId.name === '手持式RFID读写器') {
url = 'api/outsidedevices/'
}
if (optTYpe === 'add') {
url += 'create'
} else if (optTYpe === 'edit') {
url += 'update'
}
return url
}
export function getDeviceList(params) {
return request({
url: 'api/device/list',
method: 'get',
params
})
}
// 根据区列获取在库已借数
export function FetchInBorrowByQuCol(params) {
return request({
url: 'api/tag/getInBorrowByQuCol',
method: 'get',
params
})
}
export function unbind(data) {
return request({
url: 'api/displayconfig/unbind',
method: 'post',
data
})
}
// 打开架体具体某一列
export function FetchCallExternalOpenCol(params) {
return request({
url: 'api/callExternal/openCol',
method: 'get',
params
})
}
// 密集架合架
export function FetchCallExternalResetCol(params) {
return request({
url: 'api/callExternal/reset',
method: 'get',
params
})
}
// 密集架通风
export function FetchCallExternalVent(params) {
return request({
url: 'api/callExternal/vent',
method: 'get',
params
})
}
// 停止移动
export function FetchCallExternalStopMove(params) {
return request({
url: 'api/callExternal/stopMove',
method: 'get',
params
})
}
export default { add, edit, del, getSupplier, getDeviceType, getDeviceById, getDesecabinetById, getRotarycabinetById, getDeviceList, FetchInBorrowByQuCol, unbind, FetchCallExternalOpenCol, FetchCallExternalResetCol, FetchCallExternalVent, FetchCallExternalStopMove }

173
src/assets/styles/manage.scss

@ -8,6 +8,7 @@
padding: 16px 30px 10px 20px;
color: #0C0E1E;
background-color: #fff;
border-bottom: 1px solid #EDEFF3;
h4{
font-size: 18px;
i{
@ -173,4 +174,176 @@
border-color: #0348F3;
}
}
}
.bookshelf-main{
height: calc(100% - 80px);
padding: 20px;
background-color: #fff;
}
.bookshelf-top{
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.bookshelf-info{
flex: 1;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
li{
width: calc(100% / 3);
line-height: 40px;
color: #545B65;
p{
display: inline-block;
color: #0C0E1E;
}
}
}
.bookshelf-layer-info{
display: flex;
justify-content: space-between;
}
.bookshelf-left{
flex: 1;
}
.bookshelf-right-info{
width: 260px;
padding: 20px;
margin: 52px 0 0 0;
border: 1px solid #EDEFF3;
.layer-status{
display: flex;
justify-content: space-between;
.row-state{
margin: 0 5px;
padding: 0;
width: 50%;
height: 34px;
line-height: 34px;
font-size: 14px;
}
}
.layer-name{
font-size: 20px;
font-weight: bold;
text-align: center;
color: #0C0E1E;
padding: 40px 0;
}
.layer-code-sort{
display: flex;
justify-content: space-between;
align-items: stretch;
ul {
flex: 1;
li {
margin-bottom: 10px;
p {
font-weight: bold;
color: #0C0E1E;
margin-bottom: 5px;
}
&:last-child{
margin-bottom: 0;
}
// span{
// display: block;
// height: 26px;
// line-height: 26px;
// }
}
}
.edit-callNumber{
width: 90px;
font-size: 24px;
i{
display: block;
font-style: normal;
text-align: justify;
&:first-child{
padding-bottom: 4px;
}
}
}
}
.layer-handle{
padding-top: 30px;
margin-top: 30px;
border-top: 1px solid #EDEFF3;
li{
display: flex;
justify-content: flex-start;
margin-bottom: 20px;
p{
padding-right: 20px;
font-weight: bold;
color: #0C0E1E;
}
}
}
}
.cabinet-row{
display: flex;
flex: 1;
flex-wrap: wrap;
text-align: center;
height: 100%;
.cabinet-cell{
position: relative;
font-size: 20px;
border: 1px solid #A6ADB6;
overflow: hidden;
// &:nth-last-of-type(-n+4) {
// margin-bottom: 0;
// }
// &:nth-child(4n){
// margin-right: 0;
// }
span{
display: block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
z-index: 9;
}
&.active{
color: #fff;
background-color: #A6ADB6;
}
}
.in-all, .out-all, .out-part, .in-part{
position: relative;
width: 100%;
span{
display: block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
z-index: 9;
}
}
.in-all, .out-all{
height: 100%;
}
.out-part, .in-part{
height: 50%;
}
.out-all, .out-part{
background-color: #F65163;
}
.in-all, .in-part{
background-color: #1AAE93;
}
}

10
src/assets/styles/mixin.scss

@ -1060,6 +1060,11 @@
border: 1px solid #FEBD98;
opacity: 0.6;
}
&.other-state{
color: #8B43F0;
border: 1px solid #CAA4FF;
opacity: 0.6;
}
}
[data-theme="light"] & {
&.ing-state{
@ -1082,5 +1087,10 @@
background-color: #FFF3E5;
border: 1px solid #FEBD98
}
&.other-state{
color: #8B43F0;
background-color: #F4EDFF;
border: 1px solid #CAA4FF;
}
}
}

12
src/router/routers.js

@ -65,7 +65,7 @@ export const constantRouterMap = [
]
},
{
path: '/bookshelfPosition',
path: '/bookshelf',
component: Layout,
hidden: true,
redirect: 'noredirect',
@ -73,20 +73,12 @@ export const constantRouterMap = [
{
path: 'bookshelfPosition',
component: (resolve) => require(['@/views/visualCheck/venueDevice/bookshelfPosition/index'], resolve),
name: '/check/venueDevice/bookshelf/bookshelfPosition',
name: '架位列表',
meta: { title: '架位列表', noCache: true, activeMenu: '/check/venueDevice/bookshelf' }
}
]
}
// {
// path: '/check/venueDevice/bookshelf/bookshelfPosition', // 路径及携带参数
// component: () => import('@/views/visualCheck/venueDevice/bookshelfPosition/index'),
// name: '架位列表',
// // meta.activeMunu 激活时的菜单,新开的页面需要挂在那个菜单下
// meta: { title: '架位列表', noCache: true, activeMenu: '/check/venueDevice/bookshelf' },
// hidden: true // 是否显示在菜单
// }
// {
// path: '/preview',
// component: (resolve) => require(['@/views/preview/index'], resolve),
// hidden: true

3
src/views/visualCheck/venueDevice/bookshelf/index.vue

@ -335,8 +335,7 @@ export default {
console.log(value)
},
clickRowHandler(row) {
this.$router.push({ path: '/bookshelfPosition', query: { }})
// this.$router.push({ path: '/check/venueDevice/bookshelf/bookshelfPosition', query: { }})
this.$router.push({ path: '/bookshelf/bookshelfPosition', query: { }})
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
// http://192.168.99.67:12010/api/fileRelevant/getImg?imgId=f6d3ecea-0456-4429-ba77-1a4921d5c806

373
src/views/visualCheck/venueDevice/bookshelfPosition/index.vue

@ -1,16 +1,385 @@
<template>
<div class="app-container">
架位管理
<div class="venue-header">
<h4><i class="iconfont icon-shujia" />架位列表</h4>
<span class="bookshelf-area">一楼-A区</span>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="bookshelf-main">
<div class="bookshelf-top">
<ul class="bookshelf-info">
<li><p>书架名称</p><span>001排A面</span></li>
<li><p>书架规格</p><span>6 x 8</span></li>
<li><p>/双面</p><span>单面</span></li>
<li><p>倒架规则</p><span>无序0</span></li>
<li><p>错误判断</p><span>书架</span></li>
</ul>
<div class="bookshelf-button">
<el-button size="mini" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出层位编码
</el-button>
<el-button size="mini" :disabled="!isBindCarme">
<i class="iconfont icon-yulan" />
{{ isBindCarme ? '摄像头预览' : '未绑定摄像头' }}
</el-button>
</div>
</div>
<div class="bookshelf-layer-info">
<div class="bookshelf-left">
<swiper
ref="swiperTitle"
class="swiper-title"
:options="swiperOptionTitle"
:auto-update="true"
:auto-destroy="true"
:delete-instance-on-destroy="true"
:cleanup-styles-on-destroy="true"
>
<swiper-slide
v-for="(item, index) of tabListData"
ref="swiperSlideItem"
:key="'name' + index"
:iname="item.name"
class="swiper-slide-title"
>
<div
class="tab-name"
:class="{ active: index === swiperActiveIndex }"
@click="handleSlidClickFun(index)"
>
{{ item.name }}
</div>
</swiper-slide>
</swiper>
<swiper
ref="swiperContent"
class="swiper-content"
:options="swiperOptionContent"
:auto-update="true"
:auto-destroy="true"
:delete-instance-on-destroy="true"
:cleanup-styles-on-destroy="true"
>
<swiper-slide
v-for="(item, index) of tabListData"
:key="'content' + index"
class="swiper-slide-content"
>
<ul class="cabinet-row">
<!-- layerNum*rackNum -->
<li v-for="(item,index) in layerNum*rackNum" :key="index" class="cabinet-cell" :style="cellStyle" :class="{ active: index === cellIndex }" @click="handleCellCurrent(index)">
<span>{{ index+1 }}</span>
</li>
</ul>
</swiper-slide>
</swiper>
</div>
<div class="bookshelf-right-info">
<div class="layer-status">
<span class="row-state end-state">正常盘点</span>
<!-- <span class="row-state soon-state">待初始化</span>
<span class="row-state cancel-state">停止盘点</span> -->
<!-- <span class="row-state other-state">无序倒架</span> -->
<span class="row-state ing-state">有序倒架</span>
</div>
<h5 class="layer-name">001排A面01架1层</h5>
<div class="layer-code-sort">
<ul>
<!-- I247.58/586 -->
<li><p>起始索书号</p><span>-</span></li>
<li><p>结束索书号</p><span>I247.58/592:3</span></li>
</ul>
<el-button size="mini" class="edit-callNumber" @click="callNumVisible = true">
<!-- <i class="iconfont icon-yulan" /> -->
<i>&nbsp;&nbsp;&nbsp;</i>
<i>索书号</i>
</el-button>
</div>
<ul class="layer-handle">
<li>
<p>层位盘点开关</p>
<el-switch
v-model="checkValue"
active-color="#13ce66"
inactive-color="#ff4949"
active-value="true"
inactive-value="false"
@change="changeCheckSwitch"
/>
</li>
<li>
<p>图书有序检查</p>
<el-switch
v-model="bookSortValue"
active-color="#13ce66"
inactive-color="#ff4949"
active-value="true"
inactive-value="false"
@change="changeBookSortSwitch"
/>
</li>
</ul>
</div>
</div>
</div>
<!-- 编辑索书号 -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :visible="callNumVisible" title="编辑索书号范围" :before-close="handleClose">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :rules="rules" :model="form" size="small" label-width="100px">
<el-form-item label="所属架位" prop="floorName">
<el-input v-model="form.floorName" disabled style="width: 580px;" />
</el-form-item>
<el-form-item label="起始索书号" prop="startNum">
<el-input v-model="form.startNum" style="width: 580px;" />
</el-form-item>
<el-form-item label="结束索书号" prop="endNum">
<el-input v-model="form.endNum" style="width: 580px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click.native="handleClose">取消</el-button>
<el-button type="primary" @click.native="handleSaveCallNum">保存</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
// https://blog.csdn.net/qq_37236395/article/details/119737898
import crudFloor from '@/api/floor/index'
import CRUD, { presenter, header, crud } from '@crud/crud'
import { mapGetters } from 'vuex'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
export default {
name: 'BookshelfPosition',
components: { swiper, swiperSlide },
cruds() {
return CRUD({ title: '架位', url: 'api/libraryFloor/initLibraryFloorList', crudMethod: { ...crudFloor }, sort: [], optShow: {
add: true,
edit: true,
del: false,
download: false,
group: false,
reset: false
}})
},
mixins: [presenter(), header(), crud()],
data() {
const _this = this
return {
isBindCarme: false,
callNumVisible: false,
layerNum: 6,
rackNum: 8,
checkValue: 'true',
bookSortValue: 'true',
swiperActiveIndex: 0,
cellIndex: null,
titleActive: '',
swiperOptionContent: {
slidesPerView: 'auto',
on: {
slideChangeTransitionStart: function() {
_this.cellIndex = null
_this.swiperActiveIndex = this.activeIndex
_this.swiperTitle.slideTo(this.activeIndex, 500, false)
}
}
},
swiperOptionTitle: {
slidesPerView: 'auto',
freeMode: true
},
tabListData: [
{
name: 'A面'
},
{
name: 'B面'
}
],
form: {
'floorName': null,
'startNum': null,
'endNum': null
},
rules: {
floorName: [
{ required: true, message: '所属架位不可为空', trigger: 'blur' }
],
startNum: [
{ required: true, message: '起始索书号不可为空', trigger: 'blur' }
],
endNum: [
{ required: true, message: '结束索书号不可为空', trigger: 'blur' }
]
}
}
},
computed: {
...mapGetters([
'user',
'baseApi'
]),
swiperContent() {
return this.$refs.swiperContent.$el.swiper
},
swiperTitle() {
return this.$refs.swiperTitle.$el.swiper
},
cellStyle: function() {
const h = '100%/' + this.layerNum
// if (this.cabinetNum > 8) {
// h = '100%/' + (this.deviceData.rowNo - 1)
// } else {
// h = '100%/' + this.deviceData.rowNo
// }
// const h = '100%/' + this.deviceData.rowNo
const w = '100%/' + this.rackNum
return { width: `calc(${w} - 4px )`, height: `calc(${h} - 2px)` }
}
// heightStyle: function() {
// let h
// if (this.cabinetNum > 8) {
// h = '100%/' + (this.deviceData.rowNo - 1)
// } else {
// h = '100%/' + this.deviceData.rowNo
// }
// // const h = '100%/' + this.deviceData.rowNo
// return { height: `calc(${h})` }
// },
// widhtStyle: function() {
// const w = '100%/' + this.deviceData.partNo
// return { width: `calc(${w} - 10px)` }
// }
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
},
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
return true
},
handleSlideToFun(index) {
this.swiperActiveIndex = index
this.swiperContent.slideTo(index, 500, false)
this.swiperTitle.slideTo(index, 500, false)
},
handleSlidClickFun(index) {
this.cellIndex = null
this.handleSlideToFun(index)
},
handleCellCurrent(index) {
this.cellIndex = index
},
changeCheckSwitch(data) {
console.log(data)
this.$confirm('此操作将开启/关闭该架位的盘点功能' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
}).catch(() => {
this.checkValue = data === 'true' ? 'false' : 'true'
})
},
changeBookSortSwitch(data) {
console.log(data)
this.$confirm('此操作将开启/关闭该架位的图书顺序检查' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
}).catch(() => {
this.bookSortValue = data === 'true' ? 'false' : 'true'
})
},
handleClose() {
this.$refs['form'].resetFields()
this.callNumVisible = false
},
handleSaveCallNum() {
if (this.$refs['form']) {
this.$refs['form'].validate((valid) => {
if (valid) {
this.callNumVisible = false
}
})
}
},
doExport(data) {
console.log(data)
// this.crud.downloadLoading = true
this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// const ids = []
// data.forEach(val => {
// ids.push(val.deptsId)
// })
// const params = {
// 'deptsIds': ids
// }
// console.log(params)
// exportFile(this.baseApi + '/api/depts/download?' + qs.stringify(params, { indices: false }))
}).catch(() => {
})
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.venue-header{
h4{
flex: 1;
}
.bookshelf-area{
padding-right: 30px;
font-weight: bold;
color: #0348F3;
}
}
.swiper-title{
::v-deep .swiper-wrapper{
margin: 10px 0;
border-bottom: 1px solid #EDEFF3;
}
}
.swiper-slide-title {
width: auto !important;
margin-right: 20px;
cursor: pointer;
.tab-name {
padding: 10px;
&.active {
color: #0348F3;
border-bottom: 3px solid #0348F3;
}
}
}
.swiper-content{
height: 544px;
}
.swiper-slide-content {
// padding: 0 10px;
// margin: 0 10px 0 0;
}
</style>

417
src/views/visualCheck/venueDevice/device/index.vue

@ -1,16 +1,429 @@
<template>
<div class="app-container">
设备管理
<div class="container-main" style="justify-content: flex-start;">
<div class="elect-cont-left">
<el-tree ref="tree" v-loading="crud.loading" :data="fondsDatas" :props="defaultProps" :expand-on-click-node="false" :default-expanded-keys="defaultExpandedKeys" node-key="id" highlight-current @node-click="handleNodeClick">
<template
slot-scope="{node,data}"
class="custom-tree-node"
>
<el-tooltip
v-if="data.fondsName"
effect="dark"
:content="data.fondsName"
:enterable="false"
placement="left"
>
<span class="tree-text"> {{ data.fondsName }}</span>
</el-tooltip>
<span v-else class="tree-text"> {{ data.deptsName }}</span>
</template>
</el-tree>
</div>
<!--用户数据-->
<div class="elect-cont-right">
<!--工具栏-->
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-input v-model="query.blurry" clearable size="small" placeholder="输入设备编号或名称搜索" prefix-icon="el-icon-search" style="width: 225px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="crud.toQuery">搜索</el-button>
<el-button v-if="crud.optShow.reset" class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery()">重置</el-button>
</div>
<crudOperation :permission="permission">
<template v-slot:left>
<el-button v-permission="permission.add" size="mini" @click="deviceSelectVisible = true">
<i class="iconfont icon-xinzeng" />
新增
</el-button>
</template>
<template v-slot:middle>
<el-button slot="reference" size="mini" :loading="crud.delAllLoading" :disabled="crud.selections.length === 0" @click="toDelete(crud.selections)">
<i class="iconfont icon-shanchu" />
删除
</el-button>
</template>
<template v-slot:right>
<!-- :disabled="selections.length !== 1 || selections[0].bindState" -->
<el-button type="primary" size="mini" :disabled="crud.selections.length !== 1"><i class="iconfont icon-bangding" />书架绑定</el-button>
</template>
</crudOperation>
</div>
<div class="container-right">
<span class="right-top-line" />
<span class="left-bottom-line" />
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @row-click="clickRowHandler" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="deviceTypeId.name" label="设备类型" />
<el-table-column prop="deviceName" label="设备名称" />
<el-table-column prop="deviceCode" label="设备编号" />
<el-table-column prop="deviceIp" label="接口IP" />
<el-table-column label="接口IP" prop="deviceIp" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceIp"> {{ scope.row.deviceIp }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="端口" prop="devicePort">
<template slot-scope="scope">
<span v-if="scope.row.devicePort"> {{ scope.row.devicePort }} </span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="状态" prop="categoryName" align="center">
<template slot-scope="scope">
<span :class="{ 'spk-a': scope.row.deviceState === 1, 'off-line': scope.row.deviceState !== 1 }" />
</template>
</el-table-column>
<el-table-column prop="bindShelfNum" label="已绑架位" />
<el-table-column prop="fondsId" label="所属机构" />
<el-table-column prop="floorName" label="所属楼层" />
<el-table-column prop="areaName" label="所属区域" />
<el-table-column :show-overflow-tooltip="true" prop="createTime" label="创建日期">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
<el-dialog
:close-on-click-modal="false"
:modal-append-to-body="false"
append-to-body
:before-close="handleCloseDialog"
:visible.sync="deviceSelectVisible"
title="新增设备-选择设备类型"
>
<div class="setting-dialog">
<el-form ref="deviceForm" inline :model="deviceForm" size="small" label-width="90px">
<el-form-item label="设备类型" prop="deviceType" :rules="[{ required:true, message:'请选择设备类型', trigger:'change'}]">
<el-select v-model="deviceForm.deviceType" class="filter-item" value-key="id" placeholder="设备类型" style="width: 550px;">
<el-option v-for="item in deviceTypeOptions" :key="item.id" :label="item.name" :value="item" />
</el-select>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="handleCloseDialog">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="handleComfirmDevice">确定</el-button>
</div>
</div>
</el-dialog>
<el-dialog
:close-on-click-modal="false"
:modal-append-to-body="false"
append-to-body
:before-close="crud.cancelCU"
:visible.sync="crud.status.cu > 0"
:title="addDeviceTitle"
>
<div class="setting-dialog">
<el-form ref="form" inline :model="form" :rules="rules" size="small" label-width="90px">
<el-form-item label="设备名称" prop="name">
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="设备编号" prop="code">
<el-input v-model="form.code" />
</el-form-item>
<el-row>
<el-form-item label="品牌厂商" prop="supplier">
<el-select v-model="form.supplier" class="filter-item" placeholder="请选择" style="width: 225px;">
<el-option v-for="item in supplierOptions" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
</el-row>
<el-form-item label="IPv4地址" prop="deviceIp">
<el-input v-model="form.deviceIp" />
</el-form-item>
<el-form-item label="RTSP端口" prop="port" style="margin-right: 0; margin-left: 30px;">
<el-input v-model="form.port" placeholder="RTSP端口一般均为554" />
</el-form-item>
<el-form-item label="账号" prop="deviceAccount">
<el-input v-model="form.deviceAccount" />
</el-form-item>
<el-form-item label="密码" prop="devicePassword" style="margin-right: 0; margin-left: 30px;">
<el-input v-model="form.devicePassword" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="4" style="width: 585px;" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</div>
</div>
</template>
<script>
import crudDevice from '@/api/device/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
// import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
const typeJson = {
'code': 200,
'message': '操作成功',
'data': [
{
'id': '7305DE3D273B0CAC079538',
'name': '球型摄像机'
},
{
'id': 'C09A1946216E496BB3FA88',
'name': '盘点机器人'
}
]
}
const defaultForm = {
id: null,
name: null,
code: null,
deviceIp: null,
port: null,
remark: null,
supplier: null,
deviceAccount: null,
devicePassword: null
}
export default {
name: 'Device',
components: { crudOperation, pagination },
cruds() {
return CRUD({ title: '设备', url: 'api/device/list', sort: [], crudMethod: { ...crudDevice }, optShow: {
add: false,
edit: true,
del: false,
reset: true,
download: false,
group: false
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
fondsDatas: [],
deviceType: null,
deviceTypeOptions: [],
deviceSelectVisible: false,
deviceForm: {
deviceType: null
},
addDeviceTitle: '',
supplierOptions: [],
selectedDeviceType: '球型摄像机',
defaultExpandedKeys: [],
defaultProps: { children: 'children', label: 'fondsName' },
levelNumber: 0,
permission: {
add: ['admin', 'device:add'],
edit: ['admin', 'device:edit'],
del: ['admin', 'device:del']
}
}
},
computed: {
rules() {
// const checkDeviceIp = (rule, value, callback) => {
// const reg = /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/
// if (reg.test(value)) {
// callback()
// } else {
// callback(new Error('IP'))
// }
// }
const checkDevicePort = (rule, value, callback) => {
const reg = /^([0-9]|[1-9]\d{1,3}|[1-5]\d{4}|6[0-4]\d{4}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/
if (reg.test(value)) {
callback()
} else {
callback(new Error('端口号输入错误'))
}
}
const validateRule = {
code: [{ required: true, message: '设备编号不可为空', trigger: 'blur' }],
name: [{ required: true, message: '设备名称不可为空', trigger: 'blur' }]
}
this.$set(validateRule, 'deviceIp', [
{ required: true, message: '请输入接口IP', trigger: 'blur' }
// { validator: checkDeviceIp, trigger: 'blur' }
])
this.$set(validateRule, 'port', [
{ required: true, message: '请输入端口号', trigger: 'blur' },
{ validator: checkDevicePort, trigger: 'blur' }
])
this.$set(validateRule, 'deviceAccount', [
{ required: true, message: '请输入账号', trigger: 'blur' }
])
this.$set(validateRule, 'devicePassword', [
{ required: true, message: '请输入密码', trigger: 'blur' }
])
return validateRule
}
},
watch: {
},
created() {
this.deviceTypeOptions = typeJson.data
// this.crud.data = [
// { id: '7305DE3D273B0CAC079538', deviceTypeId: { name: 'NVR' }},
// { id: 'C09A1946216E496BB3FA88', deviceTypeId: { name: '' }},
// { id: 'DD656054BE3D1DF1E2F1FC', deviceTypeId: { name: '' }},
// { id: '65D1886B0F864291766421', deviceTypeId: { name: '' }},
// { id: 'E2767FEACA9CE0E3B16B89', deviceTypeId: { name: 'RFID' }},
// { id: '3B85FA21FDAFBB618B5D40', deviceTypeId: { name: 'RFID' }}
// ]
},
mounted: () => {
},
methods: {
resetQuery() {
this.crud.query.blurry = ''
this.crud.toQuery()
},
//
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
// this.crud.data = [
// { id: 1, deviceTypeId: { name: 'NVR' }},
// { id: 2, deviceTypeId: { name: '' }},
// { id: 3, deviceTypeId: { name: '' }},
// { id: 4, deviceTypeId: { name: '' }},
// { id: 5, deviceTypeId: { name: 'RFID' }},
// { id: 6, deviceTypeId: { name: 'RFID' }}
// ]
},
[CRUD.HOOK.beforeToEdit](crud, form, btn) {
// form.deviceTypeId.name
this.selectedDeviceType = '球形摄像机'
this.addDeviceTitle = '编辑设备 - ' + '球形摄像机'
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return false
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
//
handleNodeClick(data) {
console.log(data)
const selectedKey = this.$refs.tree.getCurrentNode()
if (data.pid === 0) {
this.query.deptsId = null
this.query.deptsName = null
this.leftFondsId = null
this.leftDeptsId = null
} else {
if (data.hasOwnProperty('fondsNo')) {
const selectedParentVal = this.$refs.tree.getNode(selectedKey).data.id
this.query.fondsId = data.id
this.query.deptsId = null
this.query.deptsName = null
this.leftFondsId = selectedParentVal
} else {
const selectedParentVal = this.$refs.tree.getNode(selectedKey).parent.data.id
this.query.fondsId = null
this.query.deptsId = data.id
this.query.deptsName = data.deptsName
this.leftFondsId = selectedParentVal
}
}
this.crud.toQuery()
},
//
toDelete(datas) {
this.$confirm('此操作将删除当前所选' + this.crud.title + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.crud.delAllLoading = true
const ids = []
datas.forEach(val => {
ids.push(val.id)
})
// crudDevice.del(ids).then(() => {
// this.crud.notify('', CRUD.NOTIFICATION_TYPE.SUCCESS)
// this.crud.delAllLoading = false
// this.crud.refresh()
// }).catch(err => {
// this.crud.delAllLoading = false
// console.log(err)
// })
}).catch(() => {
})
},
handleComfirmDevice() {
this.$refs.deviceForm.validate((valid) => {
console.log('valid', valid)
if (valid) {
this.deviceSelectVisible = false
this.selectedDeviceType = this.deviceForm.deviceType.name
this.addDeviceTitle = '新增设备 - ' + this.selectedDeviceType
this.crud.toAdd()
} else {
console.log('error submit!!')
return false
}
})
},
handleCloseDialog(done) {
//
if (this.$refs.deviceForm) {
this.deviceSelectVisible = false
this.$refs.deviceForm.resetFields()
}
if (this.$refs.form) {
this.crud.cancelCU()
this.$refs.form.resetFields()
}
//
// done()
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
::v-deep .el-tree{
.el-tree-node__content{
font-size: 14px;
color: #545B65;
.tree-text{
font-size: 16px;
font-weight: 600;
color: #0C0E1E;
}
}
.el-tree-node__children{
.tree-text {
font-size: 14px !important;
font-weight: normal;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: inline-block;
min-width: 170px;
color: #545B65;
}
}
}
</style>
Loading…
Cancel
Save