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> | |||
|   <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> | |||
| @ -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>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> | |||
| </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> | |||
| @ -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