8 changed files with 1120 additions and 16 deletions
-
1package.json
-
147src/api/device/index.js
-
173src/assets/styles/manage.scss
-
10src/assets/styles/mixin.scss
-
12src/router/routers.js
-
3src/views/visualCheck/venueDevice/bookshelf/index.vue
-
373src/views/visualCheck/venueDevice/bookshelfPosition/index.vue
-
417src/views/visualCheck/venueDevice/device/index.vue
@ -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 } |
@ -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>编 辑</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> |
@ -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> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue