Browse Source

楼层/架位/区域

master
xuhuajiao 7 months ago
parent
commit
df3fbd291e
  1. 35
      src/api/floor/index.js
  2. 38
      src/assets/iconfonts/light/iconfont.css
  3. 2
      src/assets/iconfonts/light/iconfont.js
  4. 56
      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. 125
      src/assets/styles/manage.scss
  9. 9
      src/assets/styles/mixin.scss
  10. 11
      src/main.js
  11. 25
      src/router/routers.js
  12. 188
      src/views/components/upload.vue
  13. 18
      src/views/system/menu/index.vue
  14. 174
      src/views/visualCheck/bookstore/book/index.vue
  15. 331
      src/views/visualCheck/venueDevice/area/index.vue
  16. 368
      src/views/visualCheck/venueDevice/bookshelf/index.vue
  17. 16
      src/views/visualCheck/venueDevice/bookshelfPosition/index.vue
  18. 266
      src/views/visualCheck/venueDevice/floor/index.vue

35
src/api/floor/index.js

@ -0,0 +1,35 @@
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/libraryFloor/editLibraryFloor',
method: 'post',
data
})
}
export function edit(data) {
return request({
url: 'api/libraryFloor/editLibraryFloor',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/libraryFloor/delLibraryFloor',
method: 'post',
data: ids
})
}
export function sort(parameter) {
return request({
url: 'api/libraryFloor/libraryFloorSort',
method: 'post',
data: parameter
})
}
export default { add, edit, del, sort }

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

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1716796171009') format('woff2'),
url('iconfont.woff?t=1716796171009') format('woff'),
url('iconfont.ttf?t=1716796171009') format('truetype');
src: url('iconfont.woff2?t=1733797195168') format('woff2'),
url('iconfont.woff?t=1733797195168') format('woff'),
url('iconfont.ttf?t=1733797195168') format('truetype');
}
.iconfont {
@ -13,6 +13,34 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-duolouceng:before {
content: "\e87c";
}
.icon-shujia:before {
content: "\e68c";
}
.icon-hangzhengquyuguanli:before {
content: "\e68d";
}
.icon-quyu1:before {
content: "\e68b";
}
.icon-gongsi:before {
content: "\e689";
}
.icon-louceng:before {
content: "\e68a";
}
.icon-wodeshujia:before {
content: "\e688";
}
.icon-ceshi:before {
content: "\e687";
}
@ -489,6 +517,10 @@
content: "\e613";
}
.icon-weizhi-copy:before {
content: "\e7d5";
}
.icon-xuanzhong:before {
content: "\e614";
}

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

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

@ -5,6 +5,55 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "10767710",
"name": "多楼层",
"font_class": "duolouceng",
"unicode": "e87c",
"unicode_decimal": 59516
},
{
"icon_id": "16328040",
"name": "书架",
"font_class": "shujia",
"unicode": "e68c",
"unicode_decimal": 59020
},
{
"icon_id": "23855671",
"name": "行政区域管理",
"font_class": "hangzhengquyuguanli",
"unicode": "e68d",
"unicode_decimal": 59021
},
{
"icon_id": "24272021",
"name": "区域",
"font_class": "quyu1",
"unicode": "e68b",
"unicode_decimal": 59019
},
{
"icon_id": "6901606",
"name": "公司",
"font_class": "gongsi",
"unicode": "e689",
"unicode_decimal": 59017
},
{
"icon_id": "7032903",
"name": "楼层",
"font_class": "louceng",
"unicode": "e68a",
"unicode_decimal": 59018
},
{
"icon_id": "15085894",
"name": "我的书架",
"font_class": "wodeshujia",
"unicode": "e688",
"unicode_decimal": 59016
},
{
"icon_id": "18585490",
"name": "数据测试名称",
@ -838,6 +887,13 @@
"unicode": "e613",
"unicode_decimal": 58899
},
{
"icon_id": "40682301",
"name": "位置-copy",
"font_class": "weizhi-copy",
"unicode": "e7d5",
"unicode_decimal": 59349
},
{
"icon_id": "34690923",
"name": "选中",

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

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

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

125
src/assets/styles/manage.scss

@ -1,9 +1,32 @@
@import 'variables';
@import 'mixin';
.venue-container{
.venue-header{
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px 30px 10px 20px;
color: #0C0E1E;
background-color: #fff;
h4{
font-size: 18px;
i{
font-size: 22px;
color: #0348F3;
padding-right: 6px;
}
}
p{
i{
font-size: 18px;
}
}
}
.venue-content{
display: flex;
justify-content: space-between;
// height: calc(100% - 52px);
}
.venue-left{
@ -31,12 +54,12 @@
.container-right{
@include table_height_min;
&.tab-content{
@include tab_height_min;
@include tab_height_min_lib;
}
}
}
.venue-container{
.venue-content{
.tab-content{
position: relative;
@include row_tab_style;
@ -49,7 +72,7 @@
.venue-preview{
width: 100%;
height: 690px;
height: 630px;
margin-top: 20px;
overflow: hidden;
img{
@ -57,3 +80,97 @@
width: 100%;
}
}
::v-deep .book-cover-upload {
display: flex;
justify-content: flex-start;
.el-form-item__content{
position: relative;
width: 580px !important;
display: flex;
justify-content: space-between;
.input-style{
width: 490px;
height: 34px;
line-height: 34px;
padding: 0 20px;
border: 1px solid #e6e8ed;
border-radius: 3px;
&.error-box{
border-color: #ed4a41;
}
}
.error-tip{
position: absolute;
left: 0;
bottom: -26px;
font-size: 12px;
color: #ff4949;
}
}
}
.venue-mark{
position: absolute;
right: 10px;
top: 0;
i{
font-weight: bold;
}
}
.mark-dialog{
.el-dialog{
width: auto !important;
}
}
.mark-handle{
display: flex;
justify-content: space-between;
align-items: center;
.mark-img{
width: 900px;
overflow: hidden;
img{
display: block;
width: 100%;
}
}
.mark-right{
// display: flex;
// flex-direction: column;
// justify-content: space-between;
width: 200px;
padding: 0 20px;
}
.mark-info{
font-size: 16px;
li{
margin-bottom: 14px;
p{
font-weight: bold;
color: #0C0E1E;
line-height: 30px;
}
}
}
}
.mark-button{
margin-top: 80px;
.el-button{
width: 150px;
height: 40px;
line-height: 40px;
padding: 0;
margin-bottom: 10px;
margin-left: 0;
border-color: #E6E8ED;
background-color: transparent;
color: #545B65;
font-weight: normal;
&.el-button--primary{
color: #fff;
background-color: #0348F3;
border-color: #0348F3;
}
}
}

9
src/assets/styles/mixin.scss

@ -347,6 +347,15 @@
}
}
@mixin tab_height_min_lib{
[data-theme="dark"] & {
min-height: calc(100vh - 230px);
}
[data-theme="light"] & {
min-height: calc(100vh - 230px);
}
}
@mixin input_style{
[data-theme="dark"] & {
border: 1px solid $mainColor;

11
src/main.js

@ -43,6 +43,17 @@ import { parseTime } from '@/utils/index.js'
Vue.filter('parseTime', function(time, cFormat) {
return parseTime(time, cFormat)
})
// 解决el-radio报错
Vue.directive('removeAriaHidden', {
bind(el, binding) {
const ariaEls = el.querySelectorAll('.el-radio__original')
ariaEls.forEach((item) => {
item.removeAttribute('aria-hidden')
})
}
})
Vue.use(uploader)
Vue.use(checkPer)
Vue.use(VueHighlightJS)

25
src/router/routers.js

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

188
src/views/components/upload.vue

@ -0,0 +1,188 @@
<template>
<div>
<el-form-item class="book-cover-upload" :label="labelName" prop="cover">
<el-input v-model="fileNames" placeholder="请上传" :readonly="true" />
<!-- <p :class="['input-style', form.cover === null ? 'error-box' :'']">{{ form.cover }}</p> -->
<!-- <span v-if="form.cover === null" class="error-tip">请上传图书封面</span> -->
<div class="upload-btn">
<input id="upFile" type="file" name="upFile" @change="changeFile($event)">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button>
</div>
</el-form-item>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { getCurrentTime } from '@/utils/index'
import { upload } from '@/utils/upload'
export default {
name: 'Upload',
props: {
form: {
type: Object,
require: true,
default: function() {
return {}
}
},
labelName: {
type: String,
default: ''
}
},
data() {
return {
bookCover: null,
file: null, // change
fileNames: '', // - name
formatType: '', // - type
postfix: '', // -
fileSize: '', // -
filePath: '', // - path
px: '', // -
nowDate: '', //
fileJsonString: null,
imageUrl: null
}
},
computed: {
...mapGetters([
'baseApi'
])
},
methods: {
//
async changeFile(e) {
const file = e.target.files[0]
if (file && file.type.startsWith('image/')) {
this.file = e.target.files[0]
this.fileSize = this.file.size
// this.formatType = this.file.type.substring(0, this.file.type.indexOf('/'))
this.fileNames = this.file.name
const fileBase64 = await this.getBase64(this.file)
const res = await this.getImgPx(fileBase64)
this.imageUrl = fileBase64
this.px = res.width + 'px*' + res.height + 'px'
//
upload(this.baseApi + '/api/fileRelevant/uploadImg', this.file).then(res => {
console.log(res)
if (res.data.code === 200) {
this.filePath = res.data.data
this.$emit('childCover', res.data.data)
// this.uploadSave()
}
})
} else {
this.$message({ message: '只可上传图片', type: 'error', offset: 8 })
this.imageUrl = null
}
},
// -
uploadSave() {
this.nowDate = getCurrentTime()
const json = {
'file_name': this.fileNames,
'file_size': this.fileSize,
'file_type': this.postfix,
'file_path': this.filePath,
'sequence': null,
'file_dpi': this.px,
'file_thumbnail': '',
'create_time': this.nowDate,
'id': null,
'is_quote': null,
'last_modified': this.file.lastModified
}
const arrayUpload = []
arrayUpload.push(json)
this.$emit('childCover', this.fileNames)
this.fileJsonString = JSON.stringify(arrayUpload)
console.log(this.fileJsonString)
},
// base64
getBase64(file) {
const reader = new FileReader()
reader.readAsDataURL(file)
return new Promise((resolve) => {
reader.onload = () => {
resolve(reader.result)
}
})
},
//
getImgPx(img) {
const image = new Image()
image.src = img
return new Promise((resolve) => {
image.onload = () => {
const width = image.width
const height = image.height
resolve({ width, height })
}
})
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .book-cover-upload {
display: flex;
justify-content: flex-start;
.el-form-item__content{
position: relative;
width: 580px !important;
display: flex;
justify-content: space-between;
margin-left: 0 !important;
.input-style{
width: 490px;
height: 34px;
line-height: 34px;
padding: 0 20px;
border: 1px solid #e6e8ed;
border-radius: 3px;
&.error-box{
border-color: #ed4a41;
}
}
.error-tip{
position: absolute;
left: 0;
bottom: -26px;
font-size: 12px;
color: #ff4949;
}
}
}
.upload-btn{
position: relative;
width: 62px;
margin-right: 0 !important;
margin-left: 10px;
overflow: initial !important;
#upFile{
position: absolute;
left: 0;
top: 0;
width: 84px;
height: 34px;
}
.el-button{
margin-top: -2px;
font-weight: bold;
border-color: #0348f3;
color: #0348f3;
}
}
.el-form{
display: flex;
justify-content: flex-start;
}
</style>

18
src/views/system/menu/index.vue

@ -39,8 +39,8 @@
</el-form-item>
</el-row>
<el-row>
<el-form-item v-show="form.type.toString() !== '2'" class="menu-radio" label="外链菜单" prop="iFrame">
<el-radio-group v-model="form.iFrame" size="mini">
<el-form-item v-show="form.type.toString() !== '2'" class="menu-radio" label="外链菜单" prop="iframe">
<el-radio-group v-model="form.iframe" size="mini">
<el-radio-button label="true"></el-radio-button>
<el-radio-button label="false"></el-radio-button>
</el-radio-group>
@ -67,7 +67,7 @@
</el-form-item>
</el-row>
<el-form-item v-if="form.type.toString() !== '0'" label="权限标识" prop="permission">
<el-input v-model="form.permission" :disabled="form.iFrame.toString() === 'true'" placeholder="请输入" />
<el-input v-model="form.permission" :disabled="form.iframe.toString() === 'true'" placeholder="请输入" />
</el-form-item>
<el-form-item v-if="form.type.toString() !== '2'" label="路由地址" prop="path">
<el-input v-model="form.path" placeholder="请输入" />
@ -75,10 +75,10 @@
<el-form-item label="排序" prop="menuSort">
<el-input-number v-model.number="form.menuSort" :min="0" :max="999" controls-position="right" />
</el-form-item>
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
<el-form-item v-show="form.iframe.toString() !== 'true' && form.type.toString() === '1'" label="组件名称" prop="componentName">
<el-input v-model="form.componentName" placeholder="匹配组件内Name字段" />
</el-form-item>
<el-form-item v-show="form.iFrame.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
<el-form-item v-show="form.iframe.toString() !== 'true' && form.type.toString() === '1'" label="组件路径" prop="component">
<el-input v-model="form.component" placeholder="请输入" />
</el-form-item>
<el-row>
@ -130,9 +130,9 @@
{{ scope.row.menuSort }}
</template>
</el-table-column>
<el-table-column prop="iFrame" label="外链" width="75px">
<el-table-column prop="iframe" label="外链" width="75px">
<template slot-scope="scope">
<span v-if="scope.row.iFrame"></span>
<span v-if="scope.row.iframe"></span>
<span v-else></span>
</template>
</el-table-column>
@ -169,7 +169,7 @@ import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
// crudpresenter
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iFrame: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null }
const defaultForm = { id: null, title: null, menuSort: 999, path: null, component: null, componentName: null, iframe: false, roles: [], pid: 0, icon: null, cache: false, hidden: false, type: 0, permission: null }
export default {
name: 'Menu',
components: { Treeselect, IconSelect, crudOperation, rrOperation },
@ -192,7 +192,7 @@ export default {
// icon: [
// { required: true, message: '', trigger: 'change' }
// ],
iFrame: [
iframe: [
{ required: true, message: '请选择是否为外链菜单', trigger: 'change' }
],
hidden: [

174
src/views/visualCheck/bookstore/book/index.vue

@ -53,21 +53,11 @@
<el-input v-model="form.publish" placeholder="请输入" style="width: 586px;" />
</el-form-item>
</div>
<div>
<el-form-item class="book-cover-upload" label="图书封面" prop="cover">
<el-input v-model="form.cover" placeholder="请上传图书封面" :readonly="true" />
<!-- <p :class="['input-style', form.cover === null ? 'error-box' :'']">{{ form.cover }}</p> -->
<!-- <span v-if="form.cover === null" class="error-tip">请上传图书封面</span> -->
<div class="upload-btn">
<input id="upFile" type="file" name="upFile" @change="changeFile($event)">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button>
</div>
</el-form-item>
</div>
<UploadCover :label-name="labelName" :form="form" @childCover="handleCover" />
</div>
<div v-if="imageUrl" class="preview-cover">
<div v-if="bookCover" class="preview-cover">
<p>封面预览</p>
<img :src="imageUrl" alt="">
<img :src="bookCover" alt="">
</div>
</el-form>
<div slot="footer" class="dialog-footer">
@ -116,12 +106,13 @@ import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import { getCurrentTime } from '@/utils/index'
import UploadCover from '@/views/components/upload.vue'
import { mapGetters } from 'vuex'
const defaultForm = { id: null, title: null, author: null, isbn: null, code: null, publish: null, cover: null }
export default {
name: 'Book',
components: { crudOperation, rrOperation, pagination },
components: { crudOperation, rrOperation, pagination, UploadCover },
cruds() {
return CRUD({ title: '图书', url: 'api/menus', crudMethod: { ...crudMenu },
optShow: {
@ -137,6 +128,7 @@ export default {
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
labelName: '图书封面',
keyWord: null,
optionVal: 'username',
options: [
@ -154,16 +146,6 @@ export default {
{ key: '0', display_name: '馆藏数量不为0' }
],
bookCover: null,
file: null, // change
fileNames: '', // - name
formatType: '', // - type
postfix: '', // -
fileSize: '', // -
filePath: '', // - path
px: '', // -
nowDate: '', //
fileJsonString: null,
imageUrl: null,
rules: {
title: [
{ required: true, message: '题名不可为空', trigger: 'blur' }
@ -183,6 +165,11 @@ export default {
}
}
},
computed: {
...mapGetters([
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
@ -210,81 +197,19 @@ export default {
})
}
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
//
async changeFile(e) {
const file = e.target.files[0]
if (file && file.type.startsWith('image/')) {
this.file = e.target.files[0]
this.fileSize = this.file.size
// this.formatType = this.file.type.substring(0, this.file.type.indexOf('/'))
this.fileNames = this.file.name
const fileBase64 = await this.getBase64(this.file)
const res = await this.getImgPx(fileBase64)
this.imageUrl = fileBase64
this.px = res.width + 'px*' + res.height + 'px'
//
// reDocumentUpload(this.baseApi + '/api/re-document/uploadFile', this.file, this.selectedDocument.id).then(res => {
// if (res.data.code === 200) {
// this.filePath = res.data.data
// this.uploadSave()
// }
// })
this.uploadSave()
handleCover(value) {
console.log(value)
if (value) {
this.form.cover = value
this.bookCover = this.baseApi + '/api/fileRelevant/getImg?imgId=' + value
} else {
this.$message({ message: '只可上传图片', type: 'error', offset: 8 })
this.imageUrl = null
this.form.cover = null
this.bookCover = null
}
},
// -
uploadSave() {
this.nowDate = getCurrentTime()
const json = {
'file_name': this.fileNames,
'file_size': this.fileSize,
'file_type': this.postfix,
'file_path': this.filePath,
'sequence': null,
'file_dpi': this.px,
'file_thumbnail': '',
'create_time': this.nowDate,
'id': null,
'is_quote': null,
'last_modified': this.file.lastModified
}
const arrayUpload = []
arrayUpload.push(json)
this.form.cover = this.fileNames
this.fileJsonString = JSON.stringify(arrayUpload)
console.log(this.fileJsonString)
},
// base64
getBase64(file) {
const reader = new FileReader()
reader.readAsDataURL(file)
return new Promise((resolve) => {
reader.onload = () => {
resolve(reader.result)
}
})
},
//
getImgPx(img) {
const image = new Image()
image.src = img
return new Promise((resolve) => {
image.onload = () => {
const width = image.width
const height = image.height
resolve({ width, height })
}
})
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
}
}
}
@ -301,61 +226,6 @@ export default {
}
}
::v-deep .book-cover-upload {
display: flex;
justify-content: flex-start;
.el-form-item__content{
position: relative;
width: 580px !important;
display: flex;
justify-content: space-between;
.input-style{
width: 490px;
height: 34px;
line-height: 34px;
padding: 0 20px;
border: 1px solid #e6e8ed;
border-radius: 3px;
&.error-box{
border-color: #ed4a41;
}
}
.error-tip{
position: absolute;
left: 0;
bottom: -26px;
font-size: 12px;
color: #ff4949;
}
}
}
.upload-btn{
position: relative;
width: 62px;
margin-right: 0 !important;
margin-left: 10px;
overflow: initial !important;
#upFile{
position: absolute;
left: 0;
top: 0;
width: 84px;
height: 34px;
}
.el-button{
margin-top: -2px;
font-weight: bold;
border-color: #0348f3;
color: #0348f3;
}
}
.el-form{
display: flex;
justify-content: flex-start;
}
.preview-cover{
flex: 1;
padding-left: 10px;

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

@ -1,16 +1,341 @@
<template>
<div class="app-container">
区域管理
<div class="venue-header">
<h4><i class="iconfont icon-hangzhengquyuguanli" />区域列表</h4>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="venue-content">
<div class="venue-left">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.floorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 80px" @change="crud.toQuery">
<el-option v-for="item in floorOptions" :key="item.key" :label="item.floorName" :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 <= 1" @click="showSort">
<i class="iconfont icon-paixu" />
排序
</el-button>
</template>
</crudOperation>
</div>
<div>
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column type="index" label="排序" />
<el-table-column prop="floorName" label="区域名称" />
<el-table-column prop="collectionFloor" label="区域编码" />
<el-table-column prop="floorName" label="所在楼层" />
<el-table-column prop="floorName" label="书架" />
<el-table-column prop="floorMap" label="标注">
<template slot-scope="scope">
<span :class="['row-state', scope.row.floorMap ? 'end-state' : 'cancel-state' ]">{{ scope.row.floorMap ? '已标注': '未标注' }}</span>
</template>
</el-table-column>
<!-- <el-table-column prop="floorDescription" label="说明">
<template slot-scope="scope">
<div>{{ scope.row.floorDescription ? scope.row.floorDescription : '-' }}</div>
</template>
</el-table-column> -->
<!-- <el-table-column prop="createTime" label="创建时间" 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>
</div>
<div class="venue-right">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-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" />
<el-button size="mini" class="venue-mark" :disabled="crud.selections.length === 0" @click="markVisible = true">
<i class="el-icon-edit" />
区域标注
</el-button>
</ul>
<div v-if="activeIndex == 0" class="venue-preview">
<img :src="imageUrl" :onerror="defaultImg" alt="">
</div>
<div v-if="activeIndex == 1">区域预览</div>
</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" :rules="rules" :model="form" size="small" label-width="100px">
<el-form-item label="所属楼层" prop="floorId">
<el-select v-model="form.floorId" placeholder="请选择" style="width: 225px;" @change="changeFloorValue($event)">
<el-option
v-for="(item,index) in floorOptions"
:key="index"
:label="item.floorName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="区域名称" prop="areaName">
<el-input v-model="form.floorName" style="width: 580px;" />
</el-form-item>
<el-form-item label="区域编码" prop="areaCode">
<el-input v-model="form.floorName" style="width: 580px;" />
</el-form-item>
<el-form-item label="描述信息" prop="floorDescription">
<el-input v-model="form.floorDescription" placeholder="请输入" type="textarea" rows="3" style="width: 580px;" />
</el-form-item>
<UploadCover :label-name="labelName" :form="form" @childCover="handleCover" />
</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>
<!-- 排序 -->
<el-dialog :close-on-click-modal="false" :append-to-body="true" title="排序" :visible.sync="sortVisible" @opened="opened">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<i class="drag-tip">提示请通过拖动鼠标来调整当前顺序</i>
<el-table :data="sortTableData" class="file-sort" style="width: 100%;max-height: 70vh;" row-key="id">
<el-table-column type="index" label="序号" width="100" align="center" />
<el-table-column prop="areaName" label="区域名称" />
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click.native="handleSort">保存</el-button>
</div>
</div>
</el-dialog>
<!-- 标注 -->
<el-dialog class="mark-dialog" :close-on-click-modal="false" :append-to-body="true" title="区域A-区域标注" :visible.sync="markVisible">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog mark-handle">
<div class="mark-img">
<img :src="imageUrl" :onerror="defaultImg" alt="">
</div>
<div class="mark-right">
<ul class="mark-info">
<li>
<p>所属机构</p>
<span>机构A</span>
</li>
<li>
<p>所属楼层</p>
<span>五楼</span>
</li>
<li>
<p>书架</p>
<span>4</span>
</li>
<li><span :class="['row-state', true ? 'end-state' : 'cancel-state' ]">{{ true ? '已标注': '未标注' }}</span></li>
</ul>
<div class="mark-button">
<el-button type="primary" disabled><i class="iconfont icon-shanchu" />清空</el-button>
<el-button type="primary"><i class="el-icon-edit" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />标注</el-button>
<el-button type="primary" disabled><i class="el-icon-folder-checked" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />保存</el-button>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudFloor from '@/api/floor/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 UploadCover from '@/views/components/upload.vue'
import Sortable from 'sortablejs'
import { mapGetters } from 'vuex'
import defaultImg from '@/assets/images/system/default-img.jpg'
const defaultForm = { id: null, floorId: null, areaName: null, areaCode: null, floorDescription: null, floorMap: null }
export default {
name: 'Area',
name: 'Bookshelf',
components: { crudOperation, rrOperation, pagination, UploadCover },
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(), form(defaultForm), crud()],
data() {
return {
floorOptions: [
{ key: '1', floorName: '一楼' },
{ key: '0', floorName: '二楼' }
],
labelName: '区域地图',
permission: {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
},
rules: {
floorId: [
{ required: true, message: '请选择所属楼层', trigger: 'change' }
],
areaName: [
{ required: true, message: '区域名称不可为空', trigger: 'blur' }
],
areaCode: [
{ required: true, message: '区域编码不可为空', trigger: 'blur' }
]
},
activeIndex: 0,
defaultImg: defaultImg,
imageUrl: defaultImg,
sortTableData: [], // data
sortVisible: false, // dialog
markVisible: false //
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
console.log(crud.data)
if (crud.data.length !== 0) {
// this.$nextTick(() => {
// this.$refs.table.toggleRowSelection(crud.data[0], true)
// })
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
return true
},
handleCover(value) {
console.log(value)
this.form.floorMap = value
},
changeFloorValue(value) {
console.log(value)
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
// http://192.168.99.67:12010/api/fileRelevant/getImg?imgId=f6d3ecea-0456-4429-ba77-1a4921d5c806
if (row.floorMap) {
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + row.floorMap
} else {
this.imageUrl = this.defaultImg
}
},
changeActiveTab(data) {
this.activeIndex = data
},
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)
crudFloor.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
})
},
// -
rowDrop(className, targetName) {
//
const tbody = document.querySelector('.' + className + ' .el-table__body-wrapper tbody')
const that = this
Sortable.create(tbody, {
//
draggable: '.el-table__row',
onEnd({ newIndex, oldIndex }) {
if (newIndex === oldIndex) return
that[targetName].splice(newIndex, 0, that[targetName].splice(oldIndex, 1)[0])
}
})
},
//
opened() {
this.rowDrop('file-sort', 'sortTableData')
},
showSort() {
this.sortVisible = true
this.sortTableData = JSON.parse(JSON.stringify(this.crud.selections))
},
handleSort() {
const data = this.sortTableData.map((value, index) => {
return { id: value.id, isSequence: index + 1 }
})
this.sortTableData.forEach((item, index) => {
item.isSequence = index + 1
})
crudFloor.sort(data).then(() => {
this.sortVisible = false
this.$message({ message: '保存成功', type: 'success', offset: 8 })
this.crud.refresh()
})
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>

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

@ -1,16 +1,380 @@
<template>
<div class="app-container">
架位管理
<div class="venue-header">
<h4><i class="iconfont icon-shujia" />书架列表</h4>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="venue-content">
<div class="venue-left">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.floorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 80px" @change="crud.toQuery">
<el-option v-for="item in floorOptions" :key="item.key" :label="item.floorName" :value="item.key" />
</el-select>
<el-select v-model="query.floorId" clearable size="small" placeholder="区域" class="filter-item" style="width: 80px" @change="crud.toQuery">
<el-option v-for="item in floorOptions" :key="item.key" :label="item.floorName" :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>
</crudOperation>
</div>
<div>
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
>
<el-table-column type="selection" align="center" width="55" />
<!-- <el-table-column type="index" label="排序" /> -->
<el-table-column prop="shelfName" label="书架名称" />
<el-table-column prop="collectionFloor" label="书架规格" />
<el-table-column prop="floorName" label="单/双面" />
<el-table-column prop="floorName" label="所属楼层" />
<el-table-column prop="floorName" label="所属区域" />
<el-table-column prop="floorMap" label="标注">
<template slot-scope="scope">
<span :class="['row-state', scope.row.floorMap ? 'end-state' : 'cancel-state' ]">{{ scope.row.floorMap ? '已标注': '未标注' }}</span>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination v-if="crud.data.length!==0" />
</div>
</div>
<div class="venue-right">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<ul class="tab-nav">
<li class="active-tab-nav">区域书架<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
<el-button size="mini" class="venue-mark" :disabled="crud.selections.length === 0" @click="markVisible = true">
<i class="el-icon-edit" />
书架标注
</el-button>
</ul>
<div class="venue-preview">
<img :src="imageUrl" :onerror="defaultImg" alt="">
</div>
</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" :rules="rules" :model="form" inline size="small" label-width="90px">
<el-form-item label="所属楼层" prop="floorId">
<el-input v-model="form.floorId" disabled />
</el-form-item>
<el-form-item label="所属区域" prop="areaName">
<el-input v-model="form.areaName" disabled />
</el-form-item>
<el-row>
<el-form-item label="单/双排" prop="singleOrDouble">
<el-radio-group v-model="form.singleOrDouble" v-removeAriaHidden size="mini" @change="changeSingleOrDouble($event)">
<el-radio :label="1">单排</el-radio>
<el-radio :label="2">双排</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.singleOrDouble===1" label="A/B面" prop="ab">
<el-select v-model="form.ab" placeholder="请选择" style="width: 225px;" @change="changeAB($event)">
<el-option
v-for="(item,index) in abOptions"
:key="index"
:label="item.name"
:value="item.key"
/>
</el-select>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="书架排号" prop="rackNum">
<el-input v-model="form.rackNum" />
</el-form-item>
<el-form-item label="书架名称" prop="rackName">
<el-input v-model="form.rackName" disabled />
</el-form-item>
</el-row>
<el-form-item label="书架规格" prop="rackSpecs">
<el-input-number v-model.number="form.rackSpecsMin" :min="0" :max="999" controls-position="right" style="width: 90px;" />
<span style="padding:0 12px;"></span>
<el-input-number v-model.number="form.rackSpecsMax" :min="0" :max="999" controls-position="right" style="width: 90px;" />
</el-form-item>
<el-form-item label="架起始标" prop="rackStartNum">
<el-input-number v-model.number="form.rackStartNum" :min="0" :max="999" controls-position="right" />
</el-form-item>
<el-row>
<el-form-item label="架号顺序" prop="rackOrder">
<el-select v-model="form.rackOrder" placeholder="请选择" style="width: 586px;" @change="changeOrder($event)">
<el-option
v-for="(item,index) in rackOrderOptions"
:key="index"
:label="item.name"
:value="item.key"
/>
</el-select>
</el-form-item>
</el-row>
<el-row>
<el-form-item label="层号顺序" prop="layerSeq">
<el-select v-model="form.layerSeq" placeholder="请选择" style="width: 586px;" @change="changeLayerSeq($event)">
<el-option
v-for="(item,index) in layerSeqOptions"
:key="index"
:label="item.name"
:value="item.key"
/>
</el-select>
</el-form-item>
</el-row>
<el-form-item label="倒架规则" prop="invRules">
<el-radio-group v-model="form.invRules" v-removeAriaHidden size="mini">
<el-radio :label="1">无序</el-radio>
<el-radio :label="2">有序</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="错架判断" prop="wrongJudge">
<el-radio-group v-model="form.wrongJudge" v-removeAriaHidden size="mini">
<el-radio :label="1">书架</el-radio>
<el-radio :label="2">格子</el-radio>
</el-radio-group>
</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>
<!-- 标注 -->
<el-dialog class="mark-dialog" :close-on-click-modal="false" :append-to-body="true" title="001排A面-书架标注" :visible.sync="markVisible">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog mark-handle">
<div class="mark-img">
<img :src="imageUrl" :onerror="defaultImg" alt="">
</div>
<div class="mark-right">
<ul class="mark-info">
<li>
<p>所属机构</p>
<span>机构A</span>
</li>
<li>
<p>所属楼层</p>
<span>五楼</span>
</li>
<li>
<p>所属区域</p>
<span>A楼</span>
</li>
<li>
<p>/双面</p>
<span>单面</span>
</li>
<li>
<p>书架规格</p>
<span>68</span>
</li>
<li><span :class="['row-state', true ? 'end-state' : 'cancel-state' ]">{{ true ? '已标注': '未标注' }}</span></li>
</ul>
<div class="mark-button">
<el-button type="primary" disabled><i class="iconfont icon-shanchu" />清空</el-button>
<el-button type="primary"><i class="el-icon-edit" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />标注</el-button>
<el-button type="primary" disabled><i class="el-icon-folder-checked" style="font-weight: bold; padding-right: 4px; font-size: 16px;" />保存</el-button>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudFloor from '@/api/floor/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 UploadCover from '@/views/components/upload.vue'
import { mapGetters } from 'vuex'
import defaultImg from '@/assets/images/system/default-img.jpg'
const defaultForm = { id: null, floorId: null, areaName: null, singleOrDouble: null, ab: null, rackNum: null, rackName: null, rackSpecsMin: null, rackSpecsMax: null, rackStartNum: null, rackOrder: null, layerSeq: null, invRules: null, wrongJudge: null }
export default {
name: 'Bookshelf',
components: { crudOperation, pagination },
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(), form(defaultForm), crud()],
data() {
return {
abOptions: [
{ key: '1', name: 'A面' },
{ key: '0', name: 'B面' }
],
floorOptions: [
{ key: '1', floorName: '一楼' },
{ key: '0', floorName: '二楼' }
],
rackOrderOptions: [
{ key: 0, name: '始终最左边为第1架(S型排架)' },
{ key: 1, name: 'A面最左为第1架(B面最左为最后1架)' },
{ key: 2, name: 'B面最左为第1架(A面最左为最后1架)' }
],
layerSeqOptions: [
{ key: 0, name: '最顶层为第一层(从上至下)' },
{ key: 1, name: '最底层为第一层(从下至上)' }
],
permission: {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
},
rules: {
floorId: [
{ required: true, message: '所属楼层不可为空', trigger: 'blur' }
],
areaName: [
{ required: true, message: '所属区域不可为空', trigger: 'blur' }
],
singleOrDouble: [
{ required: true, message: '请选择单双排', trigger: 'change' }
],
rackNum: [
{ required: true, message: '书架排号不可为空', trigger: 'blur' }
],
rackName: [
{ required: true, message: '书架名称不可为空', trigger: 'blur' }
],
rackSpecs: [
{ required: true, message: '书架规格不可为空', trigger: 'blur' }
],
rackStartNum: [
{ required: true, message: '架起始标不可为空', trigger: 'blur' }
],
rackOrder: [
{ required: true, message: '请选择架号顺序', trigger: 'change' }
],
layerSeq: [
{ required: true, message: '请选择层号顺序', trigger: 'change' }
],
invRules: [
{ required: true, message: '请选择倒架规则', trigger: 'change' }
],
wrongJudge: [
{ required: true, message: '请选择错架判断', trigger: 'change' }
]
},
defaultImg: defaultImg,
imageUrl: defaultImg,
markVisible: false //
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
console.log(crud.data)
if (crud.data.length !== 0) {
// this.$nextTick(() => {
// this.$refs.table.toggleRowSelection(crud.data[0], true)
// })
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
console.log(crud.form)
return true
},
changeSingleOrDouble(value) {
console.log(value)
},
changeAB(value) {
console.log(value)
},
changeOrder(value) {
console.log(value)
},
changeFloorValue(value) {
console.log(value)
},
changeLayerSeq(value) {
console.log(value)
},
clickRowHandler(row) {
this.$router.push({ path: '/bookshelfPosition', query: { }})
// this.$router.push({ path: '/check/venueDevice/bookshelf/bookshelfPosition', query: { }})
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
// http://192.168.99.67:12010/api/fileRelevant/getImg?imgId=f6d3ecea-0456-4429-ba77-1a4921d5c806
if (row.floorMap) {
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + row.floorMap
} else {
this.imageUrl = this.defaultImg
}
},
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)
crudFloor.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
})
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>

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

@ -0,0 +1,16 @@
<template>
<div class="app-container">
架位管理
</div>
</template>
<script>
export default {
name: 'BookshelfPosition',
data() {
return {
}
}
}
</script>
<style scoped>
</style>

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

@ -1,63 +1,79 @@
<template>
<div class="app-container venue-container">
<div class="venue-left">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-input v-model="query.collectionName" clearable size="small" placeholder="输入馆藏名称搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<rrOperation />
<div class="app-container">
<div class="venue-header">
<h4><i class="iconfont icon-duolouceng" />楼层列表</h4>
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
</div>
<div class="venue-content">
<div class="venue-left">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<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 <= 1" @click="showSort">
<i class="iconfont icon-paixu" />
排序
</el-button>
</template>
</crudOperation>
</div>
<div>
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
height="540"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column type="index" label="排序" />
<el-table-column prop="floorName" label="楼层名称" />
<el-table-column prop="collectionFloor" label="区域" />
<el-table-column prop="floorMap" label="地图">
<template slot-scope="scope">
<span :class="['row-state', scope.row.floorMap ? 'end-state' : 'cancel-state' ]">{{ scope.row.floorMap ? '已上传': '未上传' }}</span>
</template>
</el-table-column>
<!-- <el-table-column prop="floorDescription" label="说明">
<template slot-scope="scope">
<div>{{ scope.row.floorDescription ? scope.row.floorDescription : '-' }}</div>
</template>
</el-table-column> -->
<!-- <el-table-column prop="createTime" label="创建时间" 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>
<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">
<i class="iconfont icon-paixu" />
排序
</el-button>
</template>
</crudOperation>
</div>
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
style="width: 100%;"
height="590"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="collectionName" label="馆藏地名称" />
<el-table-column prop="collectionFloor" label="楼层" />
<el-table-column prop="collectionExplain" label="说明">
<template slot-scope="scope">
<div>{{ scope.row.collectionExplain ? scope.row.collectionExplain : '-' }}</div>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" 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>
<div class="venue-right">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<ul class="tab-nav">
<li class="active-tab-nav">楼层预览<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<div class="venue-preview">
<img src="~@/assets/images/system/default-img.jpg" alt="">
<div class="venue-right">
<div class="container-right tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<ul class="tab-nav">
<li class="active-tab-nav">楼层预览<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<div class="venue-preview">
<!-- <img src="~@/assets/images/system/default-img.jpg" alt=""> -->
<img :src="imageUrl" :onerror="defaultImg" alt="">
</div>
</div>
</div>
</div>
@ -68,23 +84,13 @@
<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="collectionFloor">
<el-input v-model="form.collectionFloor" style="width: 580px;" />
<el-form-item label="楼层名称" prop="floorName">
<el-input v-model="form.floorName" style="width: 580px;" />
</el-form-item>
<el-form-item label="描述信息" prop="collectionExplain">
<el-input v-model="form.collectionExplain" placeholder="请输入" type="textarea" rows="3" style="width: 580px;" />
<el-form-item label="描述信息" prop="floorDescription">
<el-input v-model="form.floorDescription" placeholder="请输入" type="textarea" rows="3" style="width: 580px;" />
</el-form-item>
<div>
<el-form-item class="book-cover-upload" label="楼层地图" prop="cover">
<el-input v-model="form.cover" placeholder="请上传" :readonly="true" />
<!-- <p :class="['input-style', form.cover === null ? 'error-box' :'']">{{ form.cover }}</p> -->
<!-- <span v-if="form.cover === null" class="error-tip">请上传图书封面</span> -->
<div class="upload-btn">
<input id="upFile" type="file" name="upFile" @change="changeFile($event)">
<el-button size="small" type="primary"><i class="iconfont icon-shangchuan" />上传</el-button>
</div>
</el-form-item>
</div>
<UploadCover :label-name="labelName" :form="form" @childCover="handleCover" />
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="crud.cancelCU">取消</el-button>
@ -92,22 +98,42 @@
</div>
</div>
</el-dialog>
<!-- 排序 -->
<el-dialog :close-on-click-modal="false" :append-to-body="true" title="排序" :visible.sync="sortVisible" @opened="opened">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<i class="drag-tip">提示请通过拖动鼠标来调整当前顺序</i>
<el-table :data="sortTableData" class="file-sort" style="width: 100%;max-height: 70vh;" row-key="id">
<el-table-column type="index" label="序号" width="100" align="center" />
<el-table-column prop="floorName" label="楼层名称" />
</el-table>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click.native="handleSort">保存</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudBookBasice from '@/api/bookBasice/index'
import crudFloor from '@/api/floor/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
// import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import UploadCover from '@/views/components/upload.vue'
import Sortable from 'sortablejs'
import { mapGetters } from 'vuex'
import defaultImg from '@/assets/images/system/default-img.jpg'
const defaultForm = { id: null, fondsId: null, collectionFloor: null, collectionName: null, collectionCode: null, collectionExplain: null }
const defaultForm = { id: null, floorName: null, floorDescription: null, floorMap: null }
export default {
name: 'Floor',
components: { crudOperation, rrOperation, pagination },
components: { crudOperation, pagination, UploadCover },
cruds() {
return CRUD({ title: '楼层', url: 'api/bookBasice/initCollectionLocationList', crudMethod: { ...crudBookBasice }, sort: [], optShow: {
return CRUD({ title: '楼层', url: 'api/libraryFloor/initLibraryFloorList', crudMethod: { ...crudFloor }, sort: [], optShow: {
add: true,
edit: true,
del: false,
@ -119,36 +145,63 @@ export default {
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
labelName: '楼层地图',
permission: {
add: ['admin', 'floor:add'],
edit: ['admin', 'floor:edit'],
del: ['admin', 'floor:del']
},
rules: {
collectionFloor: [
floorName: [
{ required: true, message: '所在楼层不可为空', trigger: 'blur' }
],
collectionName: [
{ required: true, message: '馆藏名不可为空', trigger: 'blur' }
]
}
},
defaultImg: defaultImg,
imageUrl: defaultImg,
sortTableData: [], // data
sortVisible: false // dialog
}
},
method: {
computed: {
...mapGetters([
'user',
'baseApi'
])
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
},
[CRUD.HOOK.afterRefresh](crud) {
console.log(crud.data)
if (crud.data.length !== 0) {
// this.clickRowHandler(crud.data[0])
this.$nextTick(() => {
this.$refs.table.toggleRowSelection(crud.data[0], true)
})
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
crud.form.fondsId = this.user.fonds.id
console.log(crud.form)
return true
},
handleCover(value) {
console.log(value)
this.form.floorMap = value
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
// http://192.168.99.67:12010/api/fileRelevant/getImg?imgId=f6d3ecea-0456-4429-ba77-1a4921d5c806
if (row.floorMap) {
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + row.floorMap
} else {
this.imageUrl = this.defaultImg
}
},
toDelete(datas) {
this.$confirm('此操作将删除当前所选机构<span>你是否还要继续?</span>', '提示', {
this.$confirm('此操作将删除当前所选楼层<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
@ -160,8 +213,9 @@ export default {
ids.push(val.id)
})
console.log(ids)
crudBookBasice.del(ids).then(() => {
this.$message({ message: '删除成功', type: 'success', offset: 8 })
crudFloor.del(ids).then(res => {
console.log(res)
this.$message({ message: res, type: 'success', offset: 8 })
this.crud.delAllLoading = false
this.crud.refresh()
}).catch(err => {
@ -171,9 +225,45 @@ export default {
}).catch(() => {
this.crud.delAllLoading = false
})
},
// -
rowDrop(className, targetName) {
//
const tbody = document.querySelector('.' + className + ' .el-table__body-wrapper tbody')
const that = this
Sortable.create(tbody, {
//
draggable: '.el-table__row',
onEnd({ newIndex, oldIndex }) {
if (newIndex === oldIndex) return
that[targetName].splice(newIndex, 0, that[targetName].splice(oldIndex, 1)[0])
}
})
},
//
opened() {
this.rowDrop('file-sort', 'sortTableData')
},
showSort() {
this.sortVisible = true
this.sortTableData = JSON.parse(JSON.stringify(this.crud.selections))
},
handleSort() {
const data = this.sortTableData.map((value, index) => {
return { id: value.id, isSequence: index + 1 }
})
this.sortTableData.forEach((item, index) => {
item.isSequence = index + 1
})
crudFloor.sort(data).then(() => {
this.sortVisible = false
this.$message({ message: '保存成功', type: 'success', offset: 8 })
this.crud.refresh()
})
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>
Loading…
Cancel
Save