Browse Source

12-20

master
xuhuajiao 6 months ago
parent
commit
cbb0500543
  1. 72
      src/api/deviceVI/index.js
  2. 10
      src/assets/iconfonts/light/iconfont.css
  3. 2
      src/assets/iconfonts/light/iconfont.js
  4. 7
      src/assets/iconfonts/light/iconfont.json
  5. BIN
      src/assets/iconfonts/light/iconfont.ttf
  6. BIN
      src/assets/iconfonts/light/iconfont.woff
  7. BIN
      src/assets/iconfonts/light/iconfont.woff2
  8. 6
      src/router/routers.js
  9. 264
      src/views/visualCheck/checkManage/checkLog/index.vue
  10. 565
      src/views/visualCheck/checkManage/checkPlan/index.vue
  11. 494
      src/views/visualCheck/checkManage/dataScreening/index.vue
  12. 41
      src/views/visualCheck/checkManage/statistic/index.vue
  13. 145
      src/views/visualCheck/checkManage/statistic/reverseShelf/index.vue
  14. 98
      src/views/visualCheck/checkManage/statistic/search.vue
  15. 100
      src/views/visualCheck/checkManage/statistic/seqShelf/index.vue
  16. 16
      src/views/visualCheck/checkManage/upDownLog/index.vue
  17. 16
      src/views/visualCheck/venueDevice/area/index.vue
  18. 438
      src/views/visualCheck/venueDevice/device/index.vue
  19. 10
      src/views/visualCheck/venueDevice/floor/index.vue

72
src/api/deviceVI/index.js

@ -0,0 +1,72 @@
import request from '@/utils/request'
// 获取区域树
export function FetchRegionTree(params) {
return request({
url: 'api/device/getRegionTree',
method: 'get',
params
})
}
// 设备列表
export function FetchinitDeviceInfoList(params) {
return request({
url: 'api/device/initDeviceInfoList',
method: 'get',
params
})
}
export function add(data) {
return request({
url: 'api/device/editDeviceInfo',
method: 'post',
data
})
}
export function edit(data) {
return request({
url: 'api/device/editDeviceInfo',
method: 'post',
data
})
}
export function del(data) {
return request({
url: 'api/device/delDeviceInfo',
method: 'post',
data
})
}
// 摄像头绑定书架
export function FetchDeviceShelfGridBinding(data) {
return request({
url: 'api/device/deviceShelfGridBinding',
method: 'post',
data
})
}
// 根据设备和条件获取已绑定书架
export function FetchBoundGridByDevice(params) {
return request({
url: 'api/device/getBoundGridByDevice',
method: 'get',
params
})
}
// 根据条件获取未绑定书架
export function FetchUnboundGrid(params) {
return request({
url: 'api/device/getUnboundGrid',
method: 'get',
params
})
}
export default { add, edit, del, FetchRegionTree, FetchinitDeviceInfoList, FetchDeviceShelfGridBinding, FetchBoundGridByDevice, FetchUnboundGrid }

10
src/assets/iconfonts/light/iconfont.css

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1733797195168') format('woff2'),
url('iconfont.woff?t=1733797195168') format('woff'),
url('iconfont.ttf?t=1733797195168') format('truetype');
src: url('iconfont.woff2?t=1734697211726') format('woff2'),
url('iconfont.woff?t=1734697211726') format('woff'),
url('iconfont.ttf?t=1734697211726') format('truetype');
}
.iconfont {
@ -13,6 +13,10 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-shuju:before {
content: "\e68e";
}
.icon-duolouceng:before {
content: "\e87c";
}

2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File

7
src/assets/iconfonts/light/iconfont.json

@ -5,6 +5,13 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "15392667",
"name": "数据",
"font_class": "shuju",
"unicode": "e68e",
"unicode_decimal": 59022
},
{
"icon_id": "10767710",
"name": "多楼层",

BIN
src/assets/iconfonts/light/iconfont.ttf

BIN
src/assets/iconfonts/light/iconfont.woff

BIN
src/assets/iconfonts/light/iconfont.woff2

6
src/router/routers.js

@ -79,10 +79,10 @@ export const constantRouterMap = [
]
}
// {
// path: '/preview',
// component: (resolve) => require(['@/views/preview/index'], resolve),
// path: '/bookSearch',
// component: (resolve) => require(['@/views/visualCheck/checkManage/bookSearch/index'], resolve),
// hidden: true
// },
// }
// {
// path: '/fourTestReport',
// component: (resolve) => require(['@/views/fourTestReport/index'], resolve),

264
src/views/visualCheck/checkManage/checkLog/index.vue

@ -1,16 +1,274 @@
<template>
<div class="app-container">
盘点日志
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.status" clearable size="small" placeholder="盘点状态" class="filter-item" style="width: 120px" @change="crud.toQuery">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in statusOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<el-select v-model="query.status" clearable size="small" placeholder="盘点类型" class="filter-item" style="width: 120px" @change="crud.toQuery">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in TypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<el-input v-model="query.search" clearable size="small" placeholder="输入单号/备注关键字搜索" prefix-icon="el-icon-search" style="width: 220px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" />
<rrOperation />
</div>
<crudOperation :permission="permission">
<template v-slot:middle>
<el-button v-permission="permission.add" size="mini" @click="crud.toAdd">
<i class="iconfont icon-shengchengpandiandan" />
全量盘点
</el-button>
</template>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
</div>
<div class="container-wrap">
<span class="right-top-line" />
<span class="left-bottom-line" />
<el-table
ref="table"
v-loading="crud.loading"
class="archives-table"
:data="crud.data"
style="width: 100%;"
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
@row-dblclick="handleDbClick"
>
<el-table-column prop="regionName" label="盘点单号" />
<el-table-column prop="regionCode" label="盘点类型" />
<el-table-column prop="floorName" label="目标位置" />
<el-table-column prop="booksheflCount" label="目标数量" />
<el-table-column prop="booksheflCount" label="备注" />
<el-table-column prop="createTime" label="盘点开始时间">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
<el-table-column prop="createTime" label="盘点结束时间">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
<el-table-column label="盘点状态" align="center" prop="deptsStatus">
<!-- slot-scope="scope" -->
<template>
<span class="row-state row-warehousing state-active">排队中</span>
<!-- <span class="row-state row-binding state-active">盘点中</span>
<span class="row-state row-lending state-active">已终止</span>
<span class="row-state row-physical state-active">已完成</span> -->
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination v-if="crud.data.length!==0" />
</div>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="盘点单号" prop="taskName">
<el-input v-model="form.taskName" />
</el-form-item>
<el-form-item label="盘点类型" prop="taskType">
<el-input v-model="form.taskType" />
</el-form-item>
<el-form-item label="目标位置" prop="location">
<el-input v-model="form.location" />
</el-form-item>
<el-form-item label="目标数量" prop="number">
<el-input v-model="form.number" />
</el-form-item>
<el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" />
</el-form-item>
</el-row>
</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>
</template>
<script>
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null }
export default {
name: 'CheckLog',
components: { crudOperation, rrOperation, pagination },
cruds() {
return CRUD({ title: '盘点', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
add: false,
edit: false,
del: false,
download: false,
group: false,
reset: false
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
statusOptions: [
{ key: '1', display_name: '排队中' },
{ key: '2', display_name: '进行中' },
{ key: '3', display_name: '已终止' },
{ key: '4', display_name: '已完成' }
],
TypeOptions: [
{ key: '1', display_name: '计划盘点' },
{ key: '2', display_name: '全量盘点' },
{ key: '3', display_name: '区域盘点' },
{ key: '4', display_name: '书架盘点' },
{ key: '5', display_name: '架位盘点' },
{ key: '6', display_name: '层位盘点' }
],
tabIndex: 0,
permission: {
add: ['admin', 'checkLog:add'],
edit: ['admin', 'checkLog:edit'],
del: ['admin', 'checkLog:del']
},
rules: {
taskName: [
{ required: true, message: '请输入盘点单号', trigger: 'blur' }
],
taskType: [
{ required: true, message: '请输入盘点类型', trigger: 'blur' }
],
location: [
{ required: true, message: '请输入目标位置', trigger: 'blur' }
],
number: [
{ required: true, message: '请输入目标数量', trigger: 'blur' }
]
}
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
},
//
[CRUD.HOOK.beforeToAdd]() {
}, //
[CRUD.HOOK.beforeToEdit](crud, form) {
},
[CRUD.HOOK.beforeValidateCU](crud, form) {
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return false
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
toDelete(datas) {
this.$confirm('此操作将删除当前任务<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.crud.delAllLoading = true
const ids = []
datas.forEach(val => {
ids.push(val.id)
})
console.log(ids)
// crudRegion.del(ids).then(res => {
// console.log(res)
// this.$message({ message: res, type: 'success', offset: 8 })
// this.crud.delAllLoading = false
// this.crud.refresh()
// }).catch(err => {
// this.crud.delAllLoading = false
// console.log(err)
// })
}).catch(() => {
this.crud.delAllLoading = false
})
},
//
changeStatus(data, val) {
data.id = data.deptsId
this.$confirm('此操作将禁用 / 启用当前任务' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// crudDept.FetchUpdateDeptsStatus(data).then(res => {
// this.$message({ message: '', type: 'success', offset: 8 })
// this.crud.refresh()
// }).catch(() => {
// data.deptsStatus = !data.deptsStatus
// })
}).catch(() => {
this.$message({ message: '已取消修改', offset: 8 })
data.deptsStatus = data.deptsStatus ? 0 : 1
})
},
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 }))
// this.crud.downloadLoading = false
}).catch(() => {
})
},
handleCloseDialog() {
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>

565
src/views/visualCheck/checkManage/checkPlan/index.vue

@ -1,16 +1,575 @@
<template>
<div class="app-container">
盘点计划
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.status" clearable size="small" placeholder="状态" class="filter-item" style="width: 100px" @change="crud.toQuery">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<el-input v-model="query.search" clearable size="small" placeholder="输入任务名称搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" />
<rrOperation />
</div>
<crudOperation :permission="permission">
<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>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
</div>
<div class="container-wrap">
<span class="right-top-line" />
<span class="left-bottom-line" />
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
@row-dblclick="handleDbClick"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="regionName" label="任务名称" />
<el-table-column prop="regionCode" label="任务类型" />
<el-table-column prop="floorName" label="目标位置" />
<el-table-column prop="booksheflCount" label="计划" />
<el-table-column prop="booksheflCount" label="下次运行" />
<el-table-column prop="booksheflCount" label="最后运行" />
<el-table-column label="状态" align="center" prop="deptsStatus">
<template slot-scope="scope">
<el-switch v-model="scope.row.deptsStatus" active-color="#409EFF" inactive-color="#F56C6C" :active-value="1" :inactive-value="0" @change="changeStatus(scope.row, scope.row.deptsStatus)" />
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination v-if="crud.data.length!==0" />
</div>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div class="detail-tab tab-content">
<ul class="tab-nav">
<li :class="{'active-tab-nav': tabIndex === 0}" @click="changeFormTab(0)">任务设定</li>
<li :class="{'active-tab-nav': tabIndex === 1}" @click="changeFormTab(1)">计划设定</li>
</ul>
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<div v-show="tabIndex===0">
<el-form-item label="任务类型" prop="taskType">
<el-select
v-model="form.taskType"
style="width: 240px; height:30px"
clearable
placeholder="请选择"
@change="handleTaskType"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="目标位置" prop="deviceId">
<el-select
v-model="form.deviceId"
style="width: 240px; height:30px"
clearable
placeholder="请选择"
>
<el-option
v-for="item in deviceOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="form.taskName" style="width: 588px;" />
</el-form-item>
<!-- v-if="form.deviceId === 'DDAF09DDD05ED8ACF9928E'" -->
<el-row>
<el-form-item label="说明" prop="remark">
<div style="display:inline-block; width: 588px; border: 1px solid #e6e8ed; background-color: #e6e8ed; border-radius: 4px; padding: 6px 10px; line-height: 24px;">盘点任务的目标已区域进行划分在指定的计划设定时间内对所选区域的所有层位进行图书盘点操作可以指定多个盘点任务注意不要指定重复的时间计划</div>
<!-- <el-input v-model="form.remark" type="textarea" style="width: 572px;" disabled :rows="4" /> -->
</el-form-item>
</el-row>
</div>
<div v-show="tabIndex===1">
<div>
<el-form-item label="定时类型" prop="timerType">
<el-select
v-model="form.timerType"
style="width: 240px; height:30px"
clearable
placeholder="请选择"
@change="handleTimerType"
>
<el-option
v-for="item in timeTypeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</div>
<!-- <el-form-item v-if="form.timerType===1 || form.timerType===2" label="间隔" prop="timeInterval">
<div>
<el-input-number v-model="form.timeInterval" controls-position="right" :min="1" />
<span v-if="form.timerType===1" class="unit-name">小时</span>
<span v-if="form.timerType===2" class="unit-name"></span>
</div>
</el-form-item> -->
<el-form-item v-if="form.timerType===3" label="" prop="weekly">
<el-checkbox-group v-model="form.weekly" style="margin-left: 80px; width: 558px;" @change="handleWeeklyTypes">
<el-checkbox v-for="item in weeklyOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox>
</el-checkbox-group>
</el-form-item>
<!-- <el-form-item v-if="form.timerType===4" label="" prop="halfOrPart">
<el-checkbox-group v-if="form.timerType===4" v-model="form.halfOrPart" style="margin-left: 80px;">
<el-checkbox v-for="item in halfOrPartOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox>
</el-checkbox-group>
</el-form-item> -->
<div>
<el-form-item label="开始时间" prop="startTime2">
<el-date-picker
v-model="form.startTime2"
type="datetime"
placeholder="选择日期时间"
:disabled="form.nowTime === true"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
:picker-options="{
disabledDate: (time) =>{
// if (form.endTime) {
// return time.getTime() > new Date(form.endTime).getTime()
// }else{
// return time.getTime() < new Date(new Date().setHours(0, 0, 0, 0))
// }
// return time.getTime() < new Date(new Date().setHours(0, 0, 0, 0))
return time.getTime() < Date.now() - 8.64e7
}
}"
style="width: 240px; height:30px"
/>
</el-form-item>
<el-form-item label="" prop="nowTime">
<el-checkbox v-model="form.nowTime" style="margin-left: 20px;" @change="handleNowTime">现在</el-checkbox>
</el-form-item>
</div>
<div>
<el-form-item label="结束时间" prop="endTime2">
<el-date-picker
v-model="form.endTime2"
class="task-date"
type="datetime"
placeholder="选择日期时间"
:disabled="form.longTime === true"
:picker-options="endPickerOptions"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
default-time="['23:59:59']"
style="width: 240px; height:30px"
/>
</el-form-item>
<el-form-item label="" prop="longTime">
<el-checkbox v-model="form.longTime" style="margin-left: 20px;" @change="handleLongTime">长期</el-checkbox>
</el-form-item>
</div>
</div>
</el-form>
</div>
<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>
<!-- 双击详情 -->
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="detailVisible" title="定时盘点任务1 - 日志" @close="handleCloseDialog">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-table
ref="table"
:data="detailTable"
style="width: 100%;"
>
<el-table-column prop="regionCode" label="任务类型" />
<el-table-column prop="floorName" label="目标位置" />
<el-table-column prop="booksheflCount" label="执行结果" />
<el-table-column prop="createTime" label="完成时间">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</div>
</template>
<script>
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
import { parseTime, timeToTimestamp } from '@/utils/index.js'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, taskType: null, deviceId: null, weekly: [], taskName: null, timerType: 2, timeInterval: 1, status: 1, startTime2: parseTime(new Date().getTime()), endTime2: null, nowTime: null, longTime: true, remark: null, halfOrPart: [] }
export default {
name: 'CheckPlan',
components: { crudOperation, rrOperation, pagination },
cruds() {
return CRUD({ title: '盘点任务', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
add: true,
edit: true,
del: false,
download: false,
group: false,
reset: false
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
enabledTypeOptions: [
{ key: '1', display_name: '激活' },
{ key: '0', display_name: '锁定' }
],
detailVisible: false,
detailTable: [],
floorOptions: [],
tabIndex: 0,
permission: {
add: ['admin', 'checkTask:add'],
edit: ['admin', 'checkTask:edit'],
del: ['admin', 'checkTask:del']
},
typeOptions: [
{
label: '计划盘点',
value: 1
}
],
deviceOptions: [],
timeTypeOptions: [
// {
// label: '',
// value: 1
// },
{
label: '单次',
value: 2
},
{
label: '周循环',
value: 3
}
// {
// label: '/',
// value: 4
// }
],
weeklyOptions: [
{
label: '周一',
value: 1
},
{
label: '周二',
value: 2
},
{
label: '周三',
value: 3
},
{
label: '周四',
value: 4
},
{
label: '周五',
value: 5
},
{
label: '周六',
value: 6
},
{
label: '周日',
value: 7
}
],
halfOrPartOptions: [
{
label: '整点',
value: 1
},
{
label: '半点',
value: 2
}
],
rules: {
taskName: [
{ required: true, message: '请输入', trigger: 'blur' }
],
taskType: [
{ required: true, message: '请选择', trigger: 'change' }
],
deviceId: [
{ required: true, message: '请选择', trigger: 'change' }
],
timerType: [
{ required: true, message: '请选择', trigger: 'change' }
],
timeInterval: [
{ required: true, message: '请输入', trigger: 'blur' }
],
startTime: [
{ required: true, message: '请选择', trigger: 'change' },
{ validator: this.validateDateRange, trigger: 'blur' }
],
endTime: [
{
validator: (rule, value, callback) => {
if (this.isRequired && !value) {
callback(new Error('请选择结束时间'))
} else if (this.form.startTime > value) {
callback(new Error('开始时间不得大于结束时间'))
} else {
callback()
}
},
trigger: 'change'
}
]
},
endPickerOptions: {
disabledDate: (time) => {
const startTime = new Date(this.form.startTime).getTime()
// if (startTime) {
// return time.getTime() < new Date(startTime).getTime() - 1 * 24 * 60 * 60 * 1000 || time.getTime() < startTime
// }
if (startTime) {
// return time.getTime() <= new Date(startTime).getTime()
return (time.getTime()) <= startTime - 8.64e7
} else {
return time.getTime() < Date.now() - 8.64e7
}
}
}
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
},
//
[CRUD.HOOK.beforeToAdd]() {
this.form.startTime2 = parseTime(new Date().getTime())
}, //
[CRUD.HOOK.beforeToEdit](crud, form) {
// if (form.timerType === 4 && form.timeInterval) {
// form.halfOrPart = form.timeInterval.split(',').map(Number)
// }
if (form.startTime) {
this.form.startTime2 = parseTime(form.startTime)
}
if (form.endTime) {
this.form.endTime2 = parseTime(form.endTime)
form.longTime = false
} else {
this.form.endTime2 = null
form.longTime = true
}
},
[CRUD.HOOK.beforeValidateCU](crud, form) {
if (this.form.taskType === null || this.form.deviceId === null || this.form.name === null) {
this.$message.error('请制定完善 “ 任务设定 ” ')
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
if (this.form.startTime2) {
this.form.startTime = timeToTimestamp(this.form.startTime2)
} else {
this.form.startTime = null
}
if (this.form.endTime2) {
this.form.endTime = timeToTimestamp(this.form.endTime2)
} else {
this.form.endTime = null
}
// if (this.form.timerType === 4 && this.form.halfOrPart) {
// this.form.timeInterval = this.form.halfOrPart.join(',')
// }
delete crud.form.remark
delete crud.form.longTime
delete crud.form.startTime2
delete crud.form.endTime2
delete crud.form.nowTime
delete crud.form.halfOrPart
return true
},
changeFormTab(index) {
this.tabIndex = index
},
handleWeeklyTypes(val) {
if (val.length < 1) {
this.$nextTick(() => {
this.weekly = []
})
return
}
},
handleLongTime(val) {
if (val === true) {
this.form.endTime = null
}
},
handleNowTime(val) {
if (val === true) {
this.form.startTime2 = parseTime(new Date().getTime())
}
},
// validateDateRange() {
// if (this.form.startTime > this.form.endTime) {
// this.$message.warning('')
// return false
// }
// return true
// },
handleTaskType(val) {
this.form.deviceId = null
},
handleTimerType(val) {
// if (val === 4) {
// this.form.timeInterval = null
// this.form.halfOrPart = [1]
// } else {
// this.form.timeInterval = 1
// }
},
changeFloorValue(value) {
console.log(value)
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
toDelete(datas) {
this.$confirm('此操作将删除当前任务<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.crud.delAllLoading = true
const ids = []
datas.forEach(val => {
ids.push(val.id)
})
console.log(ids)
// crudRegion.del(ids).then(res => {
// console.log(res)
// this.$message({ message: res, type: 'success', offset: 8 })
// this.crud.delAllLoading = false
// this.crud.refresh()
// }).catch(err => {
// this.crud.delAllLoading = false
// console.log(err)
// })
}).catch(() => {
this.crud.delAllLoading = false
})
},
//
changeStatus(data, val) {
data.id = data.deptsId
this.$confirm('此操作将禁用 / 启用当前任务' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
// crudDept.FetchUpdateDeptsStatus(data).then(res => {
// this.$message({ message: '', type: 'success', offset: 8 })
// this.crud.refresh()
// }).catch(() => {
// data.deptsStatus = !data.deptsStatus
// })
}).catch(() => {
this.$message({ message: '已取消修改', offset: 8 })
data.deptsStatus = data.deptsStatus ? 0 : 1
})
},
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 }))
// this.crud.downloadLoading = false
}).catch(() => {
})
},
changeActiveTab(index) {
this.archivesTabIndex = index
},
handleDbClick(row) {
this.detailVisible = true
},
handleCloseDialog() {
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
::v-deep .el-dialog .el-dialog__body{
padding: 0 0 30px 0;
}
</style>

494
src/views/visualCheck/checkManage/dataScreening/index.vue

@ -1,16 +1,506 @@
<template>
<div class="app-container">
数据总览
<div class="venue-header">
<h4><i class="iconfont icon-shuju" />数据总览</h4>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="venue-content">
<crudOperation :permission="permission">
<template v-slot:middle>
<el-button v-permission="permission.add" size="mini" @click="crud.toAdd">
<i class="iconfont icon-shengchengpandiandan" />
全量盘点
</el-button>
</template>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
<div class="venue-left">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<ul class="tab-nav">
<li v-for="(item,index) in floorOptions" :key="index" :class="{ 'active-tab-nav': activeIndex == index }" @click="changeActiveTab(index)">{{ item.floorName }}<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<div class="venue-preview">
<div v-show="currentMarkData && currentMarkData.signPoint">
<canvas id="canvasPreview" :width="width" :height="height" />
</div>
<img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt="">
</div>
</div>
</div>
<div class="venue-right">
<div class="lib-right-item lib-info">
<h4>场馆概况</h4>
<ul class="data-right-list">
<li><p>楼层</p><span><i>5</i></span></li>
<li><p>区域</p><span><i>25</i></span></li>
<li><p>书架</p><span><i>100</i></span></li>
<li><p>摄像头</p><span><i>300</i></span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>盘点概况</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<ul class="data-right-list">
<li><p>在架</p><span><i>15000</i></span></li>
<li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
<li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
</ul>
</div>
<div class="lib-right-item">
<h4>流通统计</h4>
<div class="refresh-date">2024-11-28 09:46</div>
<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">
<li v-for="(item,index) in bookList" :key="index" :class="{ active: index === rightDataIndex }">
<span>{{ item }}</span>
</li>
</ul>
</swiper-slide>
</swiper>
</div>
</div>
</div>
<!-- form -->
<el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
<el-form-item label="盘点单号" prop="taskName">
<el-input v-model="form.taskName" />
</el-form-item>
<el-form-item label="盘点类型" prop="taskType">
<el-input v-model="form.taskType" />
</el-form-item>
<el-form-item label="目标位置" prop="location">
<el-input v-model="form.location" />
</el-form-item>
<el-form-item label="目标数量" prop="number">
<el-input v-model="form.number" />
</el-form-item>
<el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" />
</el-form-item>
</el-row>
</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>
</template>
<script>
import { FetchLibraryFloorListAll } from '@/api/floor/index'
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import { mapGetters } from 'vuex'
import defaultImg from '@/assets/images/system/default-img.jpg'
import { fabric } from 'fabric'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null }
export default {
name: 'DataScreening',
components: { swiper, swiperSlide, crudOperation },
cruds() {
return CRUD({ title: '数据总览', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
add: false,
edit: false,
del: false,
download: false,
group: false,
reset: false
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
const _this = this
return {
floorOptions: [],
swiperActiveIndex: 0,
rightDataIndex: null,
swiperOptionContent: {
slidesPerView: 'auto',
on: {
slideChangeTransitionStart: function() {
_this.rightDataIndex = null
_this.swiperActiveIndex = this.activeIndex
_this.swiperTitle.slideTo(this.activeIndex, 500, false)
}
}
},
swiperOptionTitle: {
slidesPerView: 'auto',
freeMode: true
},
tabListData: [{ name: '热门图书' }, { name: '热门架位' }, { name: '冷面图书' }],
bookList: [],
permission: {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
},
rules: {
taskName: [
{ required: true, message: '请输入盘点单号', trigger: 'blur' }
],
taskType: [
{ required: true, message: '请输入盘点类型', trigger: 'blur' }
],
location: [
{ required: true, message: '请输入目标位置', trigger: 'blur' }
],
number: [
{ required: true, message: '请输入目标数量', trigger: 'blur' }
]
},
activeIndex: 0,
defaultImg: defaultImg,
imageUrl: defaultImg,
imageRegionUrl: defaultImg,
sortTableData: [], // data
sortVisible: false, // dialog
markVisible: false, //
titleMark: '区域标注',
currentMarkData: null,
canvasPreview: {},
width: 900,
height: 600,
drawWidth: 2 //
}
},
computed: {
...mapGetters([
'user',
'baseApi'
]),
swiperContent() {
return this.$refs.swiperContent.$el.swiper
}
},
watch: {
width() {
this.canvasPreview.setWidth(this.width)
},
height() {
this.canvasPreview.setHeight(this.height)
}
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
this.getLibraryFloorListAll()
},
[CRUD.HOOK.afterRefresh](crud) {
if (crud.data.length !== 0) {
this.activeIndex = 0
} else {
this.imageUrl = this.defaultImg
this.imageRegionUrl = this.defaultImg
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return true
},
//
getLibraryFloorListAll() {
FetchLibraryFloorListAll().then(res => {
this.floorOptions = res
}).catch(() => {
})
},
handleCover(value) {
console.log(value)
this.crud.form.regionMap = value
},
changeFloorValue(value) {
console.log(value)
},
changeActiveTab(data) {
this.activeIndex = data
if (this.crud.selections.length === 1) {
// if (this.canvasPreview) {
// this.canvasPreview.clear()
// this.canvasPreview.dispose()
// }
if (this.crud.selections[0].floorMap) {
this.currentMarkData = this.crud.selections[0]
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.crud.selections[0].floorMap
} else {
this.imageUrl = this.defaultImg
}
if (this.crud.selections[0].regionMap) {
this.imageRegionUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.crud.selections[0].regionMap
} else {
this.imageRegionUrl = this.defaultImg
}
if (this.activeIndex === 0) {
if (this.crud.selections[0].signPoint) {
console.log('1111')
const drawinfo = JSON.parse(this.crud.selections[0].signPoint)
this.initCanvasPreview(drawinfo)
}
}
}
},
handleSlidClickFun(index) {
this.rightDataIndex = null
this.handleSlideToFun(index)
},
handleSlideToFun(index) {
this.swiperActiveIndex = index
this.swiperContent.slideTo(index, 500, false)
this.swiperTitle.slideTo(index, 500, false)
},
async handleMark() {
if (this.crud.selections[0].floorMap) {
this.markVisible = true
this.currentMarkData = this.crud.selections[0]
this.titleMark = this.currentMarkData.regionName + ' - 区域标注'
this.$nextTick(() => {
this.$refs.markRefs.drawinfo = this.currentMarkData && this.currentMarkData.signPoint ? JSON.parse(this.currentMarkData.signPoint) : null
this.$refs.markRefs.initCanvas()
})
} else {
this.$message({ message: '请先上传当前楼层图', type: 'error', offset: 8 })
}
},
initCanvasPreview(drawinfo) {
this.canvasPreview = new fabric.Canvas('canvasPreview', {
skipTargetFind: false,
selectable: false,
selection: false
})
this.canvasPreview.selectionColor = 'rgba(0,0,0,0.05)'
this.loadDrawPreview(drawinfo)
this.canvasPreview.on('mouse:wheel', this.mouse)
},
//
mouse(e) {
if (undefined === e) return
let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvasPreview.getZoom()
zoom = Math.max(0.8, zoom)
// 1/10
zoom = Math.min(3, zoom)
// 3
const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
this.canvasPreview.zoomToPoint(zoomPoint, zoom)
},
//
loadDrawPreview(drawinfo) {
const self = this
const pointGroup = drawinfo.pointInfo
const imgInfo = drawinfo.imgInfo
imgInfo.src = self.imageUrl
//
fabric.util.enlivenObjects([imgInfo], objects => {
objects.forEach(o => {
o.selectable = false
o.hasControls = false
o.centeredScaling = false
self.canvasPreview.add(o)
})
//
pointGroup.forEach(async(item, index) => {
if (item.pointInfo !== '') {
const polygon = new fabric.Polygon(item.pointInfo, {
name: item.name,
stroke: 'rgba(196,43, 1, 1)',
strokeWidth: self.drawWidth,
fill: 'rgba(196,43, 1, 0.3)',
opacity: 1,
selectable: false,
hasBorders: false,
hasControls: false,
originX: 'left', //
originY: 'top' //
})
// polygon.index = index
self.canvasPreview.add(polygon)
polygon.on('mousedown', function(e) {
console.log('Rect ' + (index + 1) + ' clicked', e)
console.log('e.target.name', e.target.name)
})
polygon.on('mouseover', function(e) {
console.log('e', e)
console.log('e.target', e.target)
console.log('e.target.name', e.target.name)
this.set({ opacity: 0.3, hoverCursor: 'pointer' })
self.canvasPreview.renderAll()
})
//
polygon.on('mouseout', function() {
this.set({ opacity: 1 })
self.canvasPreview.renderAll()
})
}
})
})
self.canvasPreview.renderAll()
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.container-right{
min-height: calc(100vh - 232px) !important;
}
.venue-content{
position: relative;
}
.crud-opts{
position: absolute;
right: 20px;
top: 10px;
}
.venue-left{
flex: 1;
margin-right: 0 !important;
.venue-preview{
height: 633px !important;
}
}
.venue-right{
display: flex;
flex-direction: column;
width: 400px;
padding: 50px 10px 20px 10px !important;
.lib-right-item{
position: relative;
padding: 10px;
// height: calc(100% / 3);
margin-bottom: 10px;
border: 1px solid #0348f3;
border-radius: 4px;
h4{
color: #000;
line-height: 30px;
border-bottom: 1px solid #edeff3;
}
.refresh-date{
position: absolute;
right: 14px;
top: 10px;
font-size: 12px;
line-height: 30px;
}
}
}
.data-right-list {
padding-top: 10px;
li{
display: flex;
justify-content: flex-start;
align-items: center;
line-height: 36px;
p{
width: 80px;
font-weight: bold;
text-align: right;
}
span{
width: 140px;
display: block;
text-align: right;
i{
font-style: normal;
font-weight: bold;
padding: 0 10px;
color: #0348f3;
}
&.percentage{
width: auto;
}
}
}
}
.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>

41
src/views/visualCheck/checkManage/statistic/index.vue

@ -1,16 +1,51 @@
<template>
<div class="app-container">
统计分析
<div class="app-container tab-container">
<div class="tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<span class="right-bottom-line" />
<ul class="tab-nav">
<li :class="{ 'active-tab-nav': activeIndex == 0 }" @click="changeActiveTab(0)">建议顺架<i /></li>
<li :class="{ 'active-tab-nav': activeIndex == 1 }" @click="changeActiveTab(1)">建议倒架<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<component :is="comName" />
</div>
</div>
</template>
<script>
import seqShelf from './seqShelf/index'
import reverseShelf from './reverseShelf/index'
export default {
name: 'Statistic',
components: {
seqShelf,
reverseShelf
},
data() {
return {
activeIndex: 0
}
},
computed: {
comName: function() {
if (this.activeIndex === 0) {
return 'seqShelf'
} else if (this.activeIndex === 1) {
return 'reverseShelf'
}
return 'seqShelf'
}
},
methods: {
changeActiveTab(data) {
this.activeIndex = data
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>

145
src/views/visualCheck/checkManage/statistic/reverseShelf/index.vue

@ -0,0 +1,145 @@
<template>
<div class="operateLog-main">
<Search :is-log-type="isLogType" :is-center="isCenter" @handleClearOperateData="handleDelt" />
<!-- calc(100vh - 396px) -->
<el-table
ref="table"
:data="crud.data"
style="width: 100%;"
:height="heightStyle"
@row-click="clickRowHandler"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span style="word-break:break-all;">{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" prop="username" label="账号" min-width="100px" />
<el-table-column align="center" prop="nickName" label="用户名" min-width="100px" />
<el-table-column prop="fondsName" label="所属机构" show-overflow-tooltip align="center" min-width="200px" />
<el-table-column prop="deptsName" label="所属部门" show-overflow-tooltip align="center" min-width="120px" />
<el-table-column prop="requestIp" label="IP" show-overflow-tooltip align="center" min-width="120px" />
<el-table-column prop="address" label="IP来源" align="center" />
<el-table-column prop="description" label="内容描述" show-overflow-tooltip align="center" min-width="200px" />
<el-table-column prop="browser" label="浏览器" align="center" min-width="100px" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="操作时间" align="center" min-width="150">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<pagination v-if="crud.data.length !== 0" />
</div>
</template>
<script>
import { FetchClearLog } from '@/api/system/logs'
import Search from '../search.vue'
import CRUD, { presenter, crud } from '@crud/crud'
import { mapGetters } from 'vuex'
import pagination from '@crud/Pagination'
export default {
name: 'OperateLog',
components: { pagination, Search },
mixins: [presenter(), crud()],
cruds() {
return CRUD({
url: 'api/log/initLog',
title: '操作日志',
optShow: {
add: false,
edit: false,
del: false,
download: false,
reset: false,
group: false
}
})
},
props: {
isCenter: {
type: Boolean,
default: false
}
},
data() {
return {
isLogType: 'operate',
selections: [],
heightStyle: 'calc(100vh - 396px)'
}
},
computed: {
...mapGetters([
'user'
])
},
mounted() {
this.$nextTick(() => {
if (this.isCenter) {
this.heightStyle = 'calc(100vh - 470px)'
} else {
this.heightStyle = 'calc(100vh - 396px)'
}
})
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
if (this.isCenter) {
this.crud.query.username = this.user.username
} else {
this.crud.query[this.optionVal] = this.keyWord
}
},
clickRowHandler(row) {
this.$refs.table.toggleRowSelection(row) //
},
handleDelt() {
this.$confirm('此操作将清空所选数据' + this.crud.title + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.crud.delAllLoading = true
FetchClearLog().then(() => {
this.$message({ message: '清空成功', type: 'success', offset: 8 })
this.crud.delAllLoading = false
this.crud.refresh()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err)
})
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
.operateLog-main{
height: calc(100vh - 236px);
}
::v-deep .el-pagination{
margin: 24px 0 10px 0 !important
}
</style>

98
src/views/visualCheck/checkManage/statistic/search.vue

@ -0,0 +1,98 @@
<template>
<div class="head-container">
<div class="head-search">
<el-select v-model="query.floor" clearable size="small" placeholder="楼层区域" class="filter-item" style="width: 200px" @change="crud.toQuery">
<el-option v-for="item in options" :key="item.key" :label="item.display_name" :value="item.key" />
</el-select>
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="crud.toQuery">搜索</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery()">重置</el-button>
</div>
<crudOperation>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>
</template>
</crudOperation>
</div>
</template>
<script>
import CRUD, { header, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import { mapGetters } from 'vuex'
import { exportFile } from '@/utils/index'
import qs from 'qs'
export default {
components: { crudOperation },
mixins: [header(), crud()],
props: {
isLogType: {
type: String,
default: ''
}
},
data() {
return {
options: []
}
},
computed: {
...mapGetters([
'baseApi',
'user'
])
},
created() {
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
resetQuery() {
this.crud.toQuery()
},
doExport(data) {
console.log(data)
crud.downloadLoading = true
this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
const ids = []
data.forEach(val => {
ids.push(val.id)
})
const params = {
'ids': ids
}
if (this.isLogType === 'login') {
exportFile(this.baseApi + '/api/log/downloadLoginLog?' + qs.stringify(params, { indices: false }))
} else if (this.isLogType === 'operate') {
exportFile(this.baseApi + '/api/log/downloadLog?' + qs.stringify(params, { indices: false }))
} else {
exportFile(this.baseApi + '/api/log/downloadErrorLog?' + qs.stringify(params, { indices: false }))
}
}).catch(() => {
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .input-prepend .el-input__inner{
padding-left: 100px;
}
::v-deep .crud-opts-left{
position: relative;
}
.double-click-btn{
top: 4px !important;
right: 0;
left: -156px !important;
}
</style>

100
src/views/visualCheck/checkManage/statistic/seqShelf/index.vue

@ -0,0 +1,100 @@
<template>
<div style="height: calc(100vh - 236px);">
<Search :is-log-type="isLogType" @handleClearData="handleDelt" />
<el-table
ref="table"
:data="crud.data"
style="width: 100%;"
height="calc(100vh - 396px)"
@row-click="clickRowHandler"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column prop="account" label="层位" min-width="150" align="center" />
<el-table-column prop="username" label="所属楼层" align="center" min-width="150" />
<el-table-column prop="fondsName" label="所属区域" align="center" min-width="150" />
<el-table-column prop="det" label="当前错架率" align="center" min-width="180" />
<el-table-column prop="createTime" label="更新时间" align="center" min-width="180">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<pagination v-if="crud.data.length !== 0" />
</div>
</template>
<script>
import { FetchClearLoginLog } from '@/api/system/logs'
import CRUD, { presenter, crud, header } from '@crud/crud'
import pagination from '@crud/Pagination'
import Search from '../search.vue'
// import { parseTime, saveAs, getBlob } from '@/utils/index'
export default {
name: 'LoginLog',
components: { pagination, Search },
filters: {
parseRole(val) {
const regex = /name=(.*)\)/
const match = regex.exec(val)
let role = ''
if (match) {
role = match[1]
} else {
role = val
}
return role
}
},
mixins: [presenter(), crud(), header()],
cruds() {
return CRUD({
url: 'api/log/initLoginLog',
sort: [],
optShow: {
add: false,
edit: false,
del: false,
download: false,
reset: false,
group: false
}
})
},
data() {
return {
isLogType: 'login',
selections: []
}
},
methods: {
handleDelt() {
this.$confirm('此操作将清空所选数据' + this.crud.title + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
this.crud.delAllLoading = true
FetchClearLoginLog().then(() => {
this.$message({ message: '清空成功', type: 'success', offset: 8 })
this.crud.delAllLoading = false
this.crud.refresh()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err)
})
}).catch(() => {
})
},
clickRowHandler(row) {
this.$refs.table.toggleRowSelection(row) //
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-pagination{
margin: 24px 0 10px 0 !important
}
</style>

16
src/views/visualCheck/checkManage/upDownLog/index.vue

@ -0,0 +1,16 @@
<template>
<div class="app-container">
上架/下架日志
</div>
</template>
<script>
export default {
name: 'UpDownLog',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

16
src/views/visualCheck/venueDevice/area/index.vue

@ -228,8 +228,24 @@ export default {
this.canvasPreview.setHeight(this.height)
}
},
beforeDestroy() {
window.removeEventListener('beforeunload', this.clearLocalStorage)
},
methods: {
clearLocalStorage() {
const key = 'formFloor'
if (localStorage.getItem(key)) {
localStorage.removeItem(key)
}
},
[CRUD.HOOK.beforeRefresh]() {
const formFloor = JSON.parse(localStorage.getItem('formFloor'))
if (formFloor) {
this.crud.query.floorId = formFloor.id
} else {
this.crud.query.floorId = null
}
this.getLibraryFloorListAll()
},
[CRUD.HOOK.afterRefresh](crud) {

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

@ -2,23 +2,18 @@
<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>
<el-tree
ref="tree"
:data="regionTreeData"
:props="defaultProps"
node-key="id"
default-expand-all
:default-checked-keys="defaultCheckedKeys"
:expand-on-click-node="false"
:highlight-current="true"
:render-content="renderContent"
@node-click="handleNodeClick"
/>
</div>
<!--用户数据-->
<div class="elect-cont-right">
@ -26,13 +21,32 @@
<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-input
v-model="search"
size="small"
clearable
placeholder="输入设备编号或名称搜索"
style="width: 320px;"
class="input-prepend filter-item"
@clear="crud.toQuery"
@keyup.enter.native="crud.toQuery"
>
<el-select slot="prepend" v-model="optionVal" style="width: 120px" @change="searchChange">
<el-option
v-for="item in options"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-input>
<!-- <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">
<el-button v-permission="permission.add" size="mini" :disabled="activeRightBtn" @click="deviceSelectVisible = true">
<i class="iconfont icon-xinzeng" />
新增
</el-button>
@ -58,10 +72,10 @@
<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>
<el-table-column prop="ipv4" label="接口IP" />
<el-table-column label="接口IP" prop="ipv4" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="scope.row.deviceIp"> {{ scope.row.deviceIp }} </span>
<span v-if="scope.row.ipv4"> {{ scope.row.ipv4 }} </span>
<span v-else></span>
</template>
</el-table-column>
@ -103,7 +117,7 @@
<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-option v-for="item in options" :key="item.id" :label="item.name" :value="item" />
</el-select>
</el-form-item>
</el-form>
@ -124,30 +138,30 @@
>
<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 label="设备名称" prop="deviceName">
<el-input v-model="form.deviceName" />
</el-form-item>
<el-form-item label="设备编号" prop="code">
<el-input v-model="form.code" />
<el-form-item label="设备编号" prop="deviveCode">
<el-input v-model="form.deviveCode" />
</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-form-item label="品牌厂商" prop="deviceBrand">
<el-select v-model="form.deviceBrand" class="filter-item" placeholder="请选择" style="width: 225px;">
<el-option v-for="(item,index) in supplierOptions" :key="index" :label="item.name" :value="item.name" />
</el-select>
</el-form-item>
</el-row>
<el-form-item label="IPv4地址" prop="deviceIp">
<el-input v-model="form.deviceIp" />
<el-form-item label="IPv4地址" prop="ipv4">
<el-input v-model="form.ipv4" />
</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 label="RTSP端口" prop="rtsp" style="margin-right: 0; margin-left: 30px;">
<el-input v-model="form.rtsp" placeholder="RTSP端口一般均为554" />
</el-form-item>
<el-form-item label="账号" prop="deviceAccount">
<el-input v-model="form.deviceAccount" />
<el-form-item label="账号" prop="account">
<el-input v-model="form.account" />
</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 label="密码" prop="password" style="margin-right: 0; margin-left: 30px;">
<el-input v-model="form.password" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="4" style="width: 585px;" />
@ -171,11 +185,11 @@
title="书架绑定"
>
<div class="setting-dialog">
<!-- @input="changePid" -->
<!-- @input="changePid" :load-options="loadMenus" -->
<treeselect
v-model="floorTreeValue"
:options="menus"
:load-options="loadMenus"
style="width: 320px; margin-bottom: 20px;"
placeholder="请选择楼层区域"
/>
@ -218,55 +232,46 @@
</template>
<script>
import crudMenu from '@/api/system/menu'
import crudDevice from '@/api/deviceVI/index'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
import crudDevice from '@/api/device/index'
// import { LOAD_CHILDREN_OPTIONS } from '@riophae/vue-treeselect'
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
'account': null,
'deviceBrand': null,
'deviceName': null,
'deviceType': null,
'deviveCode': null,
'floorId': null,
'fondsId': null,
'id': null,
'ipv4': null,
'password': null,
'regionId': null,
'remarks': null,
'rtsp': null
}
export default {
name: 'Device',
components: { Treeselect, crudOperation, pagination },
cruds() {
return CRUD({ title: '设备', url: 'api/device/list', sort: [], crudMethod: { ...crudDevice }, optShow: {
return CRUD({ title: '设备', url: 'api/device/initDeviceInfoList', sort: [], crudMethod: { ...crudDevice }, optShow: {
add: false,
edit: true,
del: false,
reset: true,
download: false,
group: false
}})
},
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
@ -282,19 +287,40 @@ export default {
return data
}
return {
regionTreeData: null,
defaultProps: {
children: 'children',
label: 'label'
},
defaultCheckedKeys: [],
selectedTreeKey: null,
search: null,
optionVal: 1,
options: [
{
'id': 1,
'name': '球型摄像机'
},
{
'id': 2,
'name': '盘点机器人'
}
],
activeRightBtn: false,
bindBookShelfVisible: false,
fondsDatas: [],
deviceType: null,
deviceTypeOptions: [],
deviceSelectVisible: false,
deviceForm: {
deviceType: null
},
addDeviceTitle: '',
supplierOptions: [],
supplierOptions: [
{ 'name': '海康威视' },
{ 'name': '大华' },
{ 'name': '天地伟业' },
{ 'name': '其他' }
],
selectedDeviceType: '球型摄像机',
defaultExpandedKeys: [],
defaultProps: { children: 'children', label: 'fondsName' },
levelNumber: 0,
permission: {
add: ['admin', 'device:add'],
@ -314,14 +340,6 @@ export default {
},
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)) {
@ -331,21 +349,20 @@ export default {
}
}
const validateRule = {
code: [{ required: true, message: '设备编号不可为空', trigger: 'blur' }],
name: [{ required: true, message: '设备名称不可为空', trigger: 'blur' }]
deviveCode: [{ required: true, message: '设备编号不可为空', trigger: 'blur' }],
deviceName: [{ required: true, message: '设备名称不可为空', trigger: 'blur' }]
}
this.$set(validateRule, 'deviceIp', [
this.$set(validateRule, 'ipv4', [
{ required: true, message: '请输入接口IP', trigger: 'blur' }
// { validator: checkDeviceIp, trigger: 'blur' }
])
this.$set(validateRule, 'port', [
this.$set(validateRule, 'rtsp', [
{ required: true, message: '请输入端口号', trigger: 'blur' },
{ validator: checkDevicePort, trigger: 'blur' }
])
this.$set(validateRule, 'deviceAccount', [
this.$set(validateRule, 'account', [
{ required: true, message: '请输入账号', trigger: 'blur' }
])
this.$set(validateRule, 'devicePassword', [
this.$set(validateRule, 'password', [
{ required: true, message: '请输入密码', trigger: 'blur' }
])
return validateRule
@ -354,79 +371,62 @@ export default {
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' }}
// ]
this.deviceTypeOptions = this.options
crudDevice.FetchRegionTree().then(res => {
this.regionTreeData = [this.transformData(res)]
this.expandDefault()
}).catch(() => {
})
},
mounted: () => {
mounted() {
},
methods: {
openBindShelf() {
this.value4 = []
this.bindBookShelfVisible = true
},
handleChange(value, direction, movedKeys) {
console.log(value, direction, movedKeys)
},
dialogSaveSeting() {
// https://www.cnblogs.com/liujiajiablog/p/15818056.html
this.bindBookShelfVisible = false
console.log(this.value4)
},
rightCheckedClear() {
this.value4 = []
},
changePid() {
// this.$refs.form.validateField('pid')
},
getMenus(tree, treeNode, resolve) {
const params = { pid: tree.id }
setTimeout(() => {
crudMenu.getMenus(params).then(res => {
resolve(res.content)
})
}, 100)
// tree
transformData(data) {
return {
id: data.fondsId,
fondsId: data.fondsId,
label: data.fondsName,
children: data.floors.map(floor => ({
id: floor.id,
floorId: floor.id,
label: floor.floorName,
children: floor.regions.map(region => ({
id: region.id,
regionId: region.id,
label: region.regionName,
parentFloorId: floor.id
}))
}))
}
},
getSupDepts(id) {
crudMenu.getMenuSuperior(id).then(res => {
const children = res.map(function(obj) {
if (!obj.leaf && !obj.children) {
obj.children = null
renderContent(h, { node, data, store }) {
return h('span', [
h('el-tooltip', {
props: {
content: data.label || '',
placement: 'top'
}
return obj
})
this.menus = [{ id: 0, label: '顶级类目', children: children }]
})
},
loadMenus({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
crudMenu.getMenusTree(parentNode.id).then(res => {
parentNode.children = res.map(function(obj) {
if (!obj.leaf) {
obj.children = null
}
return obj
})
setTimeout(() => {
callback()
}, 100)
})
}
}, [
h('span', node.label)
])
])
},
resetQuery() {
this.crud.query.blurry = ''
this.crud.toQuery()
expandDefault() {
// https://blog.csdn.net/weixin_47218354/article/details/135261449
this.defaultCheckedKeys.push(this.regionTreeData[0].id)
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(this.regionTreeData[0].id) // ()
this.handleNodeClick(this.regionTreeData[0])
})
},
//
[CRUD.HOOK.beforeRefresh]() {
this.crud.query.search = this.search
this.crud.query.deviceType = this.optionVal
},
[CRUD.HOOK.afterRefresh](crud) {
console.log('data', this.crud.data)
// this.crud.data = [
// { id: 1, deviceTypeId: { name: 'NVR' }},
// { id: 2, deviceTypeId: { name: '' }},
@ -436,45 +436,65 @@ export default {
// { id: 6, deviceTypeId: { name: 'RFID' }}
// ]
},
handleNodeClick(data) {
this.$nextTick(() => {
if (this.$refs.tree) {
this.selectedTreeKey = this.$refs.tree.getCurrentNode()
this.crud.query.fondsId = this.regionTreeData[0].id
if (this.selectedTreeKey.hasOwnProperty('floorId')) {
this.crud.query.floorId = this.selectedTreeKey.id
} else if (this.selectedTreeKey.hasOwnProperty('regionId')) {
this.crud.query.floorId = this.selectedTreeKey.parentFloorId
} else {
this.crud.query.floorId = null
}
this.crud.query.deviceType = this.optionVal
this.search = ''
this.crud.query.regionId = this.selectedTreeKey.hasOwnProperty('regionId') ? this.selectedTreeKey.id : null
if (!this.selectedTreeKey.hasOwnProperty('regionId')) {
this.activeRightBtn = true
} else {
this.activeRightBtn = false
}
this.crud.toQuery()
}
})
},
searchChange(val) {
if (val) {
this.search = ''
// this.options.forEach(option => {
// if (option.value !== val) {
// this.crud.query[option.value] = null
// }
// })
}
},
resetQuery() {
this.crud.query.deviceType = 1
this.crud.query.search = ''
this.crud.toQuery()
},
[CRUD.HOOK.beforeToEdit](crud, form, btn) {
// form.deviceTypeId.name
this.selectedDeviceType = '球形摄像机'
this.selectedDeviceType = 1
this.addDeviceTitle = '编辑设备 - ' + '球形摄像机'
},
//
[CRUD.HOOK.afterValidateCU](crud) {
return false
console.log('form', crud.form)
this.crud.form.deviceType = this.selectedDeviceType
this.crud.form.floorId = this.selectedTreeKey.parentFloorId
this.crud.form.fondsId = this.regionTreeData[0].id
this.crud.form.regionId = this.selectedTreeKey.id
return true
},
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>', '提示', {
@ -504,8 +524,8 @@ export default {
console.log('valid', valid)
if (valid) {
this.deviceSelectVisible = false
this.selectedDeviceType = this.deviceForm.deviceType.name
this.addDeviceTitle = '新增设备 - ' + this.selectedDeviceType
this.selectedDeviceType = this.deviceForm.deviceType.id
this.addDeviceTitle = '新增设备 - ' + this.deviceForm.deviceType.name
this.crud.toAdd()
} else {
console.log('error submit!!')
@ -526,12 +546,68 @@ export default {
}
//
// done()
},
openBindShelf() {
this.value4 = []
this.bindBookShelfVisible = true
},
handleChange(value, direction, movedKeys) {
console.log(value, direction, movedKeys)
},
dialogSaveSeting() {
// https://www.cnblogs.com/liujiajiablog/p/15818056.html
this.bindBookShelfVisible = false
console.log(this.value4)
},
rightCheckedClear() {
this.value4 = []
},
changePid() {
// this.$refs.form.validateField('pid')
}
// getMenus(tree, treeNode, resolve) {
// const params = { pid: tree.id }
// setTimeout(() => {
// crudMenu.getMenus(params).then(res => {
// resolve(res.content)
// })
// }, 100)
// },
// getSupDepts(id) {
// crudMenu.getMenuSuperior(id).then(res => {
// const children = res.map(function(obj) {
// if (!obj.leaf && !obj.children) {
// obj.children = null
// }
// return obj
// })
// this.menus = [{ id: 0, label: '', children: children }]
// })
// },
// loadMenus({ action, parentNode, callback }) {
// if (action === LOAD_CHILDREN_OPTIONS) {
// crudMenu.getMenusTree(parentNode.id).then(res => {
// parentNode.children = res.map(function(obj) {
// if (!obj.leaf) {
// obj.children = null
// }
// return obj
// })
// setTimeout(() => {
// callback()
// }, 100)
// })
// }
// },
}
}
</script>
<style lang="scss" scoped>
::v-deep .input-prepend .el-input__inner{
padding-left: 130px;
}
::v-deep .el-tree{
.el-tree-node__content{
font-size: 14px;

10
src/views/visualCheck/venueDevice/floor/index.vue

@ -36,6 +36,7 @@
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
@row-dblclick="onRowDblclick"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column type="index" label="排序" />
@ -199,6 +200,15 @@ export default {
this.imageUrl = this.defaultImg
}
},
onRowDblclick(row) {
// crudShelf.FetchBookShelfDetails({ 'shelfId': row.shelfId }).then(res => {
// this.$router.push({ path: '/bookshelf/bookshelfPosition', query: { 'floorName': row.floorName, 'regionName': row.regionName }})
// localStorage.setItem('bookShelfDetails', JSON.stringify(res))
// }).catch(() => {
// })
localStorage.setItem('formFloor', JSON.stringify(row))
this.$router.push({ path: '/check/venueDevice/area' })
},
toDelete(datas) {
this.$confirm('此操作将删除当前所选楼层<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',

Loading…
Cancel
Save