18 changed files with 1396 additions and 266 deletions
-
35src/api/floor/index.js
-
38src/assets/iconfonts/light/iconfont.css
-
2src/assets/iconfonts/light/iconfont.js
-
56src/assets/iconfonts/light/iconfont.json
-
BINsrc/assets/iconfonts/light/iconfont.ttf
-
BINsrc/assets/iconfonts/light/iconfont.woff
-
BINsrc/assets/iconfonts/light/iconfont.woff2
-
125src/assets/styles/manage.scss
-
9src/assets/styles/mixin.scss
-
11src/main.js
-
25src/router/routers.js
-
188src/views/components/upload.vue
-
18src/views/system/menu/index.vue
-
174src/views/visualCheck/bookstore/book/index.vue
-
331src/views/visualCheck/venueDevice/area/index.vue
-
368src/views/visualCheck/venueDevice/bookshelf/index.vue
-
16src/views/visualCheck/venueDevice/bookshelfPosition/index.vue
-
176src/views/visualCheck/venueDevice/floor/index.vue
@ -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 } |
2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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> |
@ -1,16 +1,341 @@ |
|||||
<template> |
<template> |
||||
<div class="app-container"> |
<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> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<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 { |
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() { |
data() { |
||||
return { |
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> |
</script> |
||||
<style scoped> |
|
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
</style> |
</style> |
@ -1,16 +1,380 @@ |
|||||
<template> |
<template> |
||||
<div class="app-container"> |
<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>6✕8</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> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<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 { |
export default { |
||||
name: 'Bookshelf', |
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() { |
data() { |
||||
return { |
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> |
</script> |
||||
<style scoped> |
|
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
</style> |
</style> |
@ -0,0 +1,16 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
架位管理 |
||||
|
</div> |
||||
|
</template> |
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'BookshelfPosition', |
||||
|
data() { |
||||
|
return { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue