19 changed files with 2085 additions and 199 deletions
			
			
		- 
					72src/api/deviceVI/index.js
- 
					10src/assets/iconfonts/light/iconfont.css
- 
					2src/assets/iconfonts/light/iconfont.js
- 
					7src/assets/iconfonts/light/iconfont.json
- 
					BINsrc/assets/iconfonts/light/iconfont.ttf
- 
					BINsrc/assets/iconfonts/light/iconfont.woff
- 
					BINsrc/assets/iconfonts/light/iconfont.woff2
- 
					6src/router/routers.js
- 
					264src/views/visualCheck/checkManage/checkLog/index.vue
- 
					565src/views/visualCheck/checkManage/checkPlan/index.vue
- 
					494src/views/visualCheck/checkManage/dataScreening/index.vue
- 
					41src/views/visualCheck/checkManage/statistic/index.vue
- 
					145src/views/visualCheck/checkManage/statistic/reverseShelf/index.vue
- 
					98src/views/visualCheck/checkManage/statistic/search.vue
- 
					100src/views/visualCheck/checkManage/statistic/seqShelf/index.vue
- 
					16src/views/visualCheck/checkManage/upDownLog/index.vue
- 
					16src/views/visualCheck/venueDevice/area/index.vue
- 
					438src/views/visualCheck/venueDevice/device/index.vue
- 
					10src/views/visualCheck/venueDevice/floor/index.vue
| @ -0,0 +1,72 @@ | |||||
|  | import request from '@/utils/request' | ||||
|  | 
 | ||||
|  | // 获取区域树
 | ||||
|  | export function FetchRegionTree(params) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/getRegionTree', | ||||
|  |     method: 'get', | ||||
|  |     params | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | // 设备列表
 | ||||
|  | export function FetchinitDeviceInfoList(params) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/initDeviceInfoList', | ||||
|  |     method: 'get', | ||||
|  |     params | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function add(data) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/editDeviceInfo', | ||||
|  |     method: 'post', | ||||
|  |     data | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function edit(data) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/editDeviceInfo', | ||||
|  |     method: 'post', | ||||
|  |     data | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | export function del(data) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/delDeviceInfo', | ||||
|  |     method: 'post', | ||||
|  |     data | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | // 摄像头绑定书架
 | ||||
|  | export function FetchDeviceShelfGridBinding(data) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/deviceShelfGridBinding', | ||||
|  |     method: 'post', | ||||
|  |     data | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | // 根据设备和条件获取已绑定书架
 | ||||
|  | export function FetchBoundGridByDevice(params) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/getBoundGridByDevice', | ||||
|  |     method: 'get', | ||||
|  |     params | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | // 根据条件获取未绑定书架
 | ||||
|  | export function FetchUnboundGrid(params) { | ||||
|  |   return request({ | ||||
|  |     url: 'api/device/getUnboundGrid', | ||||
|  |     method: 'get', | ||||
|  |     params | ||||
|  |   }) | ||||
|  | } | ||||
|  | 
 | ||||
|  | export default { add, edit, del, FetchRegionTree, FetchinitDeviceInfoList, FetchDeviceShelfGridBinding, FetchBoundGridByDevice, FetchUnboundGrid } | ||||
						
							
						
						
							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
								
							
						| @ -1,16 +1,274 @@ | |||||
| <template> | <template> | ||||
|   <div class="app-container"> |  | ||||
|     盘点日志 |  | ||||
|  |   <div class="app-container  row-container"> | ||||
|  |     <div class="head-container"> | ||||
|  |       <div class="head-search"> | ||||
|  |         <!-- 搜索 --> | ||||
|  |         <el-select v-model="query.status" clearable size="small" placeholder="盘点状态" class="filter-item" style="width: 120px" @change="crud.toQuery"> | ||||
|  |           <i slot="prefix" class="iconfont icon-zhuangtai" /> | ||||
|  |           <el-option v-for="item in statusOptions" :key="item.key" :label="item.display_name" :value="item.key" /> | ||||
|  |         </el-select> | ||||
|  |         <el-select v-model="query.status" clearable size="small" placeholder="盘点类型" class="filter-item" style="width: 120px" @change="crud.toQuery"> | ||||
|  |           <i slot="prefix" class="iconfont icon-zhuangtai" /> | ||||
|  |           <el-option v-for="item in TypeOptions" :key="item.key" :label="item.display_name" :value="item.key" /> | ||||
|  |         </el-select> | ||||
|  |         <el-input v-model="query.search" clearable size="small" placeholder="输入单号/备注关键字搜索" prefix-icon="el-icon-search" style="width: 220px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" /> | ||||
|  |         <rrOperation /> | ||||
|  |       </div> | ||||
|  |       <crudOperation :permission="permission"> | ||||
|  |         <template v-slot:middle> | ||||
|  |           <el-button v-permission="permission.add" size="mini" @click="crud.toAdd"> | ||||
|  |             <i class="iconfont icon-shengchengpandiandan" /> | ||||
|  |             全量盘点 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |         <template v-slot:right> | ||||
|  |           <el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)"> | ||||
|  |             <i class="iconfont icon-daochu" /> | ||||
|  |             导出 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |       </crudOperation> | ||||
|  |     </div> | ||||
|  |     <div class="container-wrap"> | ||||
|  |       <span class="right-top-line" /> | ||||
|  |       <span class="left-bottom-line" /> | ||||
|  |       <el-table | ||||
|  |         ref="table" | ||||
|  |         v-loading="crud.loading" | ||||
|  |         class="archives-table" | ||||
|  |         :data="crud.data" | ||||
|  |         style="width: 100%;" | ||||
|  |         height="540" | ||||
|  |         @selection-change="crud.selectionChangeHandler" | ||||
|  |         @row-click="clickRowHandler" | ||||
|  |         @row-dblclick="handleDbClick" | ||||
|  |       > | ||||
|  |         <el-table-column prop="regionName" label="盘点单号" /> | ||||
|  |         <el-table-column prop="regionCode" label="盘点类型" /> | ||||
|  |         <el-table-column prop="floorName" label="目标位置" /> | ||||
|  |         <el-table-column prop="booksheflCount" label="目标数量" /> | ||||
|  |         <el-table-column prop="booksheflCount" label="备注" /> | ||||
|  |         <el-table-column prop="createTime" label="盘点开始时间"> | ||||
|  |           <template slot-scope="scope"> | ||||
|  |             <div>{{ scope.row.createTime | parseTime }}</div> | ||||
|  |           </template> | ||||
|  |         </el-table-column> | ||||
|  |         <el-table-column prop="createTime" label="盘点结束时间"> | ||||
|  |           <template slot-scope="scope"> | ||||
|  |             <div>{{ scope.row.createTime | parseTime }}</div> | ||||
|  |           </template> | ||||
|  |         </el-table-column> | ||||
|  |         <el-table-column label="盘点状态" align="center" prop="deptsStatus"> | ||||
|  |           <!--  slot-scope="scope" --> | ||||
|  |           <template> | ||||
|  |             <span class="row-state row-warehousing state-active">排队中</span> | ||||
|  |             <!-- <span class="row-state row-binding state-active">盘点中</span> | ||||
|  |             <span class="row-state row-lending state-active">已终止</span> | ||||
|  |             <span class="row-state row-physical state-active">已完成</span> --> | ||||
|  |           </template> | ||||
|  |         </el-table-column> | ||||
|  |       </el-table> | ||||
|  |       <!--分页组件--> | ||||
|  |       <pagination v-if="crud.data.length!==0" /> | ||||
|  |     </div> | ||||
|  | 
 | ||||
|  |     <!-- form --> | ||||
|  |     <el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title"> | ||||
|  |       <span class="dialog-right-top" /> | ||||
|  |       <span class="dialog-left-bottom" /> | ||||
|  |       <div class="setting-dialog"> | ||||
|  |         <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> | ||||
|  |           <el-form-item label="盘点单号" prop="taskName"> | ||||
|  |             <el-input v-model="form.taskName" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="盘点类型" prop="taskType"> | ||||
|  |             <el-input v-model="form.taskType" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="目标位置" prop="location"> | ||||
|  |             <el-input v-model="form.location" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="目标数量" prop="number"> | ||||
|  |             <el-input v-model="form.number" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-row> | ||||
|  |             <el-form-item label="备注" prop="remark"> | ||||
|  |               <el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" /> | ||||
|  |             </el-form-item> | ||||
|  |           </el-row> | ||||
|  |         </el-form> | ||||
|  |         <div slot="footer" class="dialog-footer"> | ||||
|  |           <el-button type="text" @click="crud.cancelCU">取消</el-button> | ||||
|  |           <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |     </el-dialog> | ||||
|  | 
 | ||||
|   </div> |   </div> | ||||
| </template> | </template> | ||||
|  | 
 | ||||
| <script> | <script> | ||||
|  | import crudRegion from '@/api/area/index' | ||||
|  | import CRUD, { presenter, header, form, crud } from '@crud/crud' | ||||
|  | import crudOperation from '@crud/CRUD.operation' | ||||
|  | import rrOperation from '@crud/RR.operation' | ||||
|  | import pagination from '@crud/Pagination' | ||||
|  | import { mapGetters } from 'vuex' | ||||
|  | // import { exportFile } from '@/utils/index' | ||||
|  | // import qs from 'qs' | ||||
|  | 
 | ||||
|  | const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null } | ||||
| export default { | export default { | ||||
|   name: 'CheckLog', |   name: 'CheckLog', | ||||
|  |   components: { crudOperation, rrOperation, pagination }, | ||||
|  |   cruds() { | ||||
|  |     return CRUD({ title: '盘点', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: { | ||||
|  |       add: false, | ||||
|  |       edit: false, | ||||
|  |       del: false, | ||||
|  |       download: false, | ||||
|  |       group: false, | ||||
|  |       reset: false | ||||
|  |     }}) | ||||
|  |   }, | ||||
|  |   mixins: [presenter(), header(), form(defaultForm), crud()], | ||||
|   data() { |   data() { | ||||
|     return { |     return { | ||||
|  |       statusOptions: [ | ||||
|  |         { key: '1', display_name: '排队中' }, | ||||
|  |         { key: '2', display_name: '进行中' }, | ||||
|  |         { key: '3', display_name: '已终止' }, | ||||
|  |         { key: '4', display_name: '已完成' } | ||||
|  |       ], | ||||
|  |       TypeOptions: [ | ||||
|  |         { key: '1', display_name: '计划盘点' }, | ||||
|  |         { key: '2', display_name: '全量盘点' }, | ||||
|  |         { key: '3', display_name: '区域盘点' }, | ||||
|  |         { key: '4', display_name: '书架盘点' }, | ||||
|  |         { key: '5', display_name: '架位盘点' }, | ||||
|  |         { key: '6', display_name: '层位盘点' } | ||||
|  |       ], | ||||
|  |       tabIndex: 0, | ||||
|  |       permission: { | ||||
|  |         add: ['admin', 'checkLog:add'], | ||||
|  |         edit: ['admin', 'checkLog:edit'], | ||||
|  |         del: ['admin', 'checkLog:del'] | ||||
|  |       }, | ||||
|  |       rules: { | ||||
|  |         taskName: [ | ||||
|  |           { required: true, message: '请输入盘点单号', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         taskType: [ | ||||
|  |           { required: true, message: '请输入盘点类型', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         location: [ | ||||
|  |           { required: true, message: '请输入目标位置', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         number: [ | ||||
|  |           { required: true, message: '请输入目标数量', trigger: 'blur' } | ||||
|  |         ] | ||||
|  |       } | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     ...mapGetters([ | ||||
|  |       'user', | ||||
|  |       'baseApi' | ||||
|  |     ]) | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     [CRUD.HOOK.beforeRefresh]() { | ||||
|  |     }, | ||||
|  |     [CRUD.HOOK.afterRefresh](crud) { | ||||
|  |     }, | ||||
|  |     // 新增前将多选的值设置为空 | ||||
|  |     [CRUD.HOOK.beforeToAdd]() { | ||||
|  |     }, // 初始化编辑时候的角色与岗位 | ||||
|  |     [CRUD.HOOK.beforeToEdit](crud, form) { | ||||
|  |     }, | ||||
|  |     [CRUD.HOOK.beforeValidateCU](crud, form) { | ||||
|  |     }, | ||||
|  |     // 提交前做的操作 | ||||
|  |     [CRUD.HOOK.afterValidateCU](crud) { | ||||
|  |       return false | ||||
|  |     }, | ||||
|  |     clickRowHandler(row) { | ||||
|  |       this.$refs.table.clearSelection() | ||||
|  |       this.$refs.table.toggleRowSelection(row) | ||||
|  |     }, | ||||
|  |     toDelete(datas) { | ||||
|  |       this.$confirm('此操作将删除当前任务<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         this.crud.delAllLoading = true | ||||
|  |         const ids = [] | ||||
|  |         datas.forEach(val => { | ||||
|  |           ids.push(val.id) | ||||
|  |         }) | ||||
|  |         console.log(ids) | ||||
|  |         // crudRegion.del(ids).then(res => { | ||||
|  |         //   console.log(res) | ||||
|  |         //   this.$message({ message: res, type: 'success', offset: 8 }) | ||||
|  |         //   this.crud.delAllLoading = false | ||||
|  |         //   this.crud.refresh() | ||||
|  |         // }).catch(err => { | ||||
|  |         //   this.crud.delAllLoading = false | ||||
|  |         //   console.log(err) | ||||
|  |         // }) | ||||
|  |       }).catch(() => { | ||||
|  |         this.crud.delAllLoading = false | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     // 改变状态 | ||||
|  |     changeStatus(data, val) { | ||||
|  |       data.id = data.deptsId | ||||
|  |       this.$confirm('此操作将禁用 / 启用当前任务' + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         // crudDept.FetchUpdateDeptsStatus(data).then(res => { | ||||
|  |         //   this.$message({ message: '修改成功', type: 'success', offset: 8 }) | ||||
|  |         //   this.crud.refresh() | ||||
|  |         // }).catch(() => { | ||||
|  |         //   data.deptsStatus = !data.deptsStatus | ||||
|  |         // }) | ||||
|  |       }).catch(() => { | ||||
|  |         this.$message({ message: '已取消修改', offset: 8 }) | ||||
|  |         data.deptsStatus = data.deptsStatus ? 0 : 1 | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     doExport(data) { | ||||
|  |       console.log(data) | ||||
|  |       this.crud.downloadLoading = true | ||||
|  |       this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         const ids = [] | ||||
|  |         data.forEach(val => { | ||||
|  |           ids.push(val.deptsId) | ||||
|  |         }) | ||||
|  |         const params = { | ||||
|  |           'deptsIds': ids | ||||
|  |         } | ||||
|  |         console.log(params) | ||||
|  |         // exportFile(this.baseApi + '/api/depts/download?' + qs.stringify(params, { indices: false })) | ||||
|  |         // this.crud.downloadLoading = false | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     handleCloseDialog() { | ||||
|  | 
 | ||||
|     } |     } | ||||
|   } |   } | ||||
| } | } | ||||
| </script> | </script> | ||||
| <style scoped> |  | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
| </style> | </style> | ||||
| @ -1,16 +1,575 @@ | |||||
| <template> | <template> | ||||
|   <div class="app-container"> |  | ||||
|     盘点计划 |  | ||||
|  |   <div class="app-container  row-container"> | ||||
|  |     <div class="head-container"> | ||||
|  |       <div class="head-search"> | ||||
|  |         <!-- 搜索 --> | ||||
|  |         <el-select v-model="query.status" clearable size="small" placeholder="状态" class="filter-item" style="width: 100px" @change="crud.toQuery"> | ||||
|  |           <i slot="prefix" class="iconfont icon-zhuangtai" /> | ||||
|  |           <el-option v-for="item in enabledTypeOptions" :key="item.key" :label="item.display_name" :value="item.key" /> | ||||
|  |         </el-select> | ||||
|  |         <el-input v-model="query.search" clearable size="small" placeholder="输入任务名称搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" /> | ||||
|  |         <rrOperation /> | ||||
|  |       </div> | ||||
|  |       <crudOperation :permission="permission"> | ||||
|  |         <template v-slot:middle> | ||||
|  |           <el-button slot="reference" size="mini" :loading="crud.delAllLoading" :disabled="crud.selections.length === 0" @click="toDelete(crud.selections)"> | ||||
|  |             <i class="iconfont icon-shanchu" /> | ||||
|  |             删除 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |         <template v-slot:right> | ||||
|  |           <el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)"> | ||||
|  |             <i class="iconfont icon-daochu" /> | ||||
|  |             导出 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |       </crudOperation> | ||||
|  |     </div> | ||||
|  |     <div class="container-wrap"> | ||||
|  |       <span class="right-top-line" /> | ||||
|  |       <span class="left-bottom-line" /> | ||||
|  |       <el-table | ||||
|  |         ref="table" | ||||
|  |         v-loading="crud.loading" | ||||
|  |         :data="crud.data" | ||||
|  |         style="width: 100%;" | ||||
|  |         height="540" | ||||
|  |         @selection-change="crud.selectionChangeHandler" | ||||
|  |         @row-click="clickRowHandler" | ||||
|  |         @row-dblclick="handleDbClick" | ||||
|  |       > | ||||
|  |         <el-table-column type="selection" align="center" width="55" /> | ||||
|  |         <el-table-column prop="regionName" label="任务名称" /> | ||||
|  |         <el-table-column prop="regionCode" label="任务类型" /> | ||||
|  |         <el-table-column prop="floorName" label="目标位置" /> | ||||
|  |         <el-table-column prop="booksheflCount" label="计划" /> | ||||
|  |         <el-table-column prop="booksheflCount" label="下次运行" /> | ||||
|  |         <el-table-column prop="booksheflCount" label="最后运行" /> | ||||
|  |         <el-table-column label="状态" align="center" prop="deptsStatus"> | ||||
|  |           <template slot-scope="scope"> | ||||
|  |             <el-switch v-model="scope.row.deptsStatus" active-color="#409EFF" inactive-color="#F56C6C" :active-value="1" :inactive-value="0" @change="changeStatus(scope.row, scope.row.deptsStatus)" /> | ||||
|  |           </template> | ||||
|  |         </el-table-column> | ||||
|  |       </el-table> | ||||
|  |       <!--分页组件--> | ||||
|  |       <pagination v-if="crud.data.length!==0" /> | ||||
|  |     </div> | ||||
|  | 
 | ||||
|  |     <!-- form --> | ||||
|  |     <el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title"> | ||||
|  |       <span class="dialog-right-top" /> | ||||
|  |       <span class="dialog-left-bottom" /> | ||||
|  |       <div class="setting-dialog"> | ||||
|  |         <div class="detail-tab tab-content"> | ||||
|  |           <ul class="tab-nav"> | ||||
|  |             <li :class="{'active-tab-nav': tabIndex === 0}" @click="changeFormTab(0)">任务设定</li> | ||||
|  |             <li :class="{'active-tab-nav': tabIndex === 1}" @click="changeFormTab(1)">计划设定</li> | ||||
|  |           </ul> | ||||
|  |           <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> | ||||
|  |             <div v-show="tabIndex===0"> | ||||
|  |               <el-form-item label="任务类型" prop="taskType"> | ||||
|  |                 <el-select | ||||
|  |                   v-model="form.taskType" | ||||
|  |                   style="width: 240px; height:30px" | ||||
|  |                   clearable | ||||
|  |                   placeholder="请选择" | ||||
|  |                   @change="handleTaskType" | ||||
|  |                 > | ||||
|  |                   <el-option | ||||
|  |                     v-for="item in typeOptions" | ||||
|  |                     :key="item.value" | ||||
|  |                     :label="item.label" | ||||
|  |                     :value="item.value" | ||||
|  |                   /> | ||||
|  |                 </el-select> | ||||
|  |               </el-form-item> | ||||
|  |               <el-form-item label="目标位置" prop="deviceId"> | ||||
|  |                 <el-select | ||||
|  |                   v-model="form.deviceId" | ||||
|  |                   style="width: 240px; height:30px" | ||||
|  |                   clearable | ||||
|  |                   placeholder="请选择" | ||||
|  |                 > | ||||
|  |                   <el-option | ||||
|  |                     v-for="item in deviceOptions" | ||||
|  |                     :key="item.value" | ||||
|  |                     :label="item.label" | ||||
|  |                     :value="item.value" | ||||
|  |                   /> | ||||
|  |                 </el-select> | ||||
|  |               </el-form-item> | ||||
|  |               <el-form-item label="任务名称" prop="taskName"> | ||||
|  |                 <el-input v-model="form.taskName" style="width: 588px;" /> | ||||
|  |               </el-form-item> | ||||
|  |               <!-- v-if="form.deviceId === 'DDAF09DDD05ED8ACF9928E'"  --> | ||||
|  |               <el-row> | ||||
|  |                 <el-form-item label="说明" prop="remark"> | ||||
|  |                   <div style="display:inline-block; width: 588px;  border: 1px solid #e6e8ed; background-color: #e6e8ed; border-radius: 4px; padding: 6px 10px; line-height: 24px;">盘点任务的目标已区域进行划分,在指定的计划设定时间内对所选区域的所有层位进行图书盘点操作。可以指定多个盘点任务,注意不要指定重复的时间计划!</div> | ||||
|  |                   <!-- <el-input v-model="form.remark" type="textarea" style="width: 572px;" disabled :rows="4" /> --> | ||||
|  |                 </el-form-item> | ||||
|  |               </el-row> | ||||
|  |             </div> | ||||
|  |             <div v-show="tabIndex===1"> | ||||
|  |               <div> | ||||
|  |                 <el-form-item label="定时类型" prop="timerType"> | ||||
|  |                   <el-select | ||||
|  |                     v-model="form.timerType" | ||||
|  |                     style="width: 240px; height:30px" | ||||
|  |                     clearable | ||||
|  |                     placeholder="请选择" | ||||
|  |                     @change="handleTimerType" | ||||
|  |                   > | ||||
|  |                     <el-option | ||||
|  |                       v-for="item in timeTypeOptions" | ||||
|  |                       :key="item.value" | ||||
|  |                       :label="item.label" | ||||
|  |                       :value="item.value" | ||||
|  |                     /> | ||||
|  |                   </el-select> | ||||
|  |                 </el-form-item> | ||||
|  |               </div> | ||||
|  |               <!-- <el-form-item v-if="form.timerType===1 || form.timerType===2" label="间隔" prop="timeInterval"> | ||||
|  |                 <div> | ||||
|  |                   <el-input-number v-model="form.timeInterval" controls-position="right" :min="1" /> | ||||
|  |                   <span v-if="form.timerType===1" class="unit-name">小时</span> | ||||
|  |                   <span v-if="form.timerType===2" class="unit-name">天</span> | ||||
|  |                 </div> | ||||
|  |               </el-form-item> --> | ||||
|  |               <el-form-item v-if="form.timerType===3" label="" prop="weekly"> | ||||
|  |                 <el-checkbox-group v-model="form.weekly" style="margin-left: 80px; width: 558px;" @change="handleWeeklyTypes"> | ||||
|  |                   <el-checkbox v-for="item in weeklyOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox> | ||||
|  |                 </el-checkbox-group> | ||||
|  |               </el-form-item> | ||||
|  |               <!-- <el-form-item v-if="form.timerType===4" label="" prop="halfOrPart"> | ||||
|  |                 <el-checkbox-group v-if="form.timerType===4" v-model="form.halfOrPart" style="margin-left: 80px;"> | ||||
|  |                   <el-checkbox v-for="item in halfOrPartOptions" :key="item.value" :label="item.value">{{ item.label }}</el-checkbox> | ||||
|  |                 </el-checkbox-group> | ||||
|  |               </el-form-item> --> | ||||
|  |               <div> | ||||
|  |                 <el-form-item label="开始时间" prop="startTime2"> | ||||
|  |                   <el-date-picker | ||||
|  |                     v-model="form.startTime2" | ||||
|  |                     type="datetime" | ||||
|  |                     placeholder="选择日期时间" | ||||
|  |                     :disabled="form.nowTime === true" | ||||
|  |                     format="yyyy-MM-dd HH:mm:ss" | ||||
|  |                     value-format="yyyy-MM-dd HH:mm:ss" | ||||
|  |                     :picker-options="{ | ||||
|  |                       disabledDate: (time) =>{ | ||||
|  |                         // if (form.endTime) { | ||||
|  |                         //   return time.getTime() > new Date(form.endTime).getTime() | ||||
|  |                         // }else{ | ||||
|  |                         //   return time.getTime() < new Date(new Date().setHours(0, 0, 0, 0)) | ||||
|  |                         // } | ||||
|  |                         // return time.getTime() < new Date(new Date().setHours(0, 0, 0, 0)) | ||||
|  |                         return time.getTime() < Date.now() - 8.64e7 | ||||
|  |                       } | ||||
|  |                     }" | ||||
|  |                     style="width: 240px; height:30px" | ||||
|  |                   /> | ||||
|  |                 </el-form-item> | ||||
|  |                 <el-form-item label="" prop="nowTime"> | ||||
|  |                   <el-checkbox v-model="form.nowTime" style="margin-left: 20px;" @change="handleNowTime">现在</el-checkbox> | ||||
|  |                 </el-form-item> | ||||
|  |               </div> | ||||
|  |               <div> | ||||
|  |                 <el-form-item label="结束时间" prop="endTime2"> | ||||
|  |                   <el-date-picker | ||||
|  |                     v-model="form.endTime2" | ||||
|  |                     class="task-date" | ||||
|  |                     type="datetime" | ||||
|  |                     placeholder="选择日期时间" | ||||
|  |                     :disabled="form.longTime === true" | ||||
|  |                     :picker-options="endPickerOptions" | ||||
|  |                     format="yyyy-MM-dd HH:mm:ss" | ||||
|  |                     value-format="yyyy-MM-dd HH:mm:ss" | ||||
|  |                     default-time="['23:59:59']" | ||||
|  |                     style="width: 240px; height:30px" | ||||
|  |                   /> | ||||
|  |                 </el-form-item> | ||||
|  |                 <el-form-item label="" prop="longTime"> | ||||
|  |                   <el-checkbox v-model="form.longTime" style="margin-left: 20px;" @change="handleLongTime">长期</el-checkbox> | ||||
|  |                 </el-form-item> | ||||
|  |               </div> | ||||
|  |             </div> | ||||
|  |           </el-form> | ||||
|  |         </div> | ||||
|  |         <div slot="footer" class="dialog-footer"> | ||||
|  |           <el-button type="text" @click="crud.cancelCU">取消</el-button> | ||||
|  |           <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |     </el-dialog> | ||||
|  | 
 | ||||
|  |     <!-- 双击详情 --> | ||||
|  |     <el-dialog append-to-body :close-on-click-modal="false" :visible.sync="detailVisible" title="定时盘点任务1 - 日志" @close="handleCloseDialog"> | ||||
|  |       <span class="dialog-right-top" /> | ||||
|  |       <span class="dialog-left-bottom" /> | ||||
|  |       <div class="setting-dialog"> | ||||
|  |         <el-table | ||||
|  |           ref="table" | ||||
|  |           :data="detailTable" | ||||
|  |           style="width: 100%;" | ||||
|  |         > | ||||
|  |           <el-table-column prop="regionCode" label="任务类型" /> | ||||
|  |           <el-table-column prop="floorName" label="目标位置" /> | ||||
|  |           <el-table-column prop="booksheflCount" label="执行结果" /> | ||||
|  |           <el-table-column prop="createTime" label="完成时间"> | ||||
|  |             <template slot-scope="scope"> | ||||
|  |               <div>{{ scope.row.createTime | parseTime }}</div> | ||||
|  |             </template> | ||||
|  |           </el-table-column> | ||||
|  |         </el-table> | ||||
|  |       </div> | ||||
|  |     </el-dialog> | ||||
|  | 
 | ||||
|   </div> |   </div> | ||||
| </template> | </template> | ||||
|  | 
 | ||||
| <script> | <script> | ||||
|  | import crudRegion from '@/api/area/index' | ||||
|  | import CRUD, { presenter, header, form, crud } from '@crud/crud' | ||||
|  | import crudOperation from '@crud/CRUD.operation' | ||||
|  | import rrOperation from '@crud/RR.operation' | ||||
|  | import pagination from '@crud/Pagination' | ||||
|  | import { mapGetters } from 'vuex' | ||||
|  | import { parseTime, timeToTimestamp } from '@/utils/index.js' | ||||
|  | // import { exportFile } from '@/utils/index' | ||||
|  | // import qs from 'qs' | ||||
|  | 
 | ||||
|  | const defaultForm = { id: null, taskType: null, deviceId: null, weekly: [], taskName: null, timerType: 2, timeInterval: 1, status: 1, startTime2: parseTime(new Date().getTime()), endTime2: null, nowTime: null, longTime: true, remark: null, halfOrPart: [] } | ||||
| export default { | export default { | ||||
|   name: 'CheckPlan', |   name: 'CheckPlan', | ||||
|  |   components: { crudOperation, rrOperation, pagination }, | ||||
|  |   cruds() { | ||||
|  |     return CRUD({ title: '盘点任务', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: { | ||||
|  |       add: true, | ||||
|  |       edit: true, | ||||
|  |       del: false, | ||||
|  |       download: false, | ||||
|  |       group: false, | ||||
|  |       reset: false | ||||
|  |     }}) | ||||
|  |   }, | ||||
|  |   mixins: [presenter(), header(), form(defaultForm), crud()], | ||||
|   data() { |   data() { | ||||
|     return { |     return { | ||||
|  |       enabledTypeOptions: [ | ||||
|  |         { key: '1', display_name: '激活' }, | ||||
|  |         { key: '0', display_name: '锁定' } | ||||
|  |       ], | ||||
|  |       detailVisible: false, | ||||
|  |       detailTable: [], | ||||
|  |       floorOptions: [], | ||||
|  |       tabIndex: 0, | ||||
|  |       permission: { | ||||
|  |         add: ['admin', 'checkTask:add'], | ||||
|  |         edit: ['admin', 'checkTask:edit'], | ||||
|  |         del: ['admin', 'checkTask:del'] | ||||
|  |       }, | ||||
|  |       typeOptions: [ | ||||
|  |         { | ||||
|  |           label: '计划盘点', | ||||
|  |           value: 1 | ||||
|  |         } | ||||
|  |       ], | ||||
|  |       deviceOptions: [], | ||||
|  |       timeTypeOptions: [ | ||||
|  |         // { | ||||
|  |         //   label: '单次', | ||||
|  |         //   value: 1 | ||||
|  |         // }, | ||||
|  |         { | ||||
|  |           label: '单次', | ||||
|  |           value: 2 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周循环', | ||||
|  |           value: 3 | ||||
|  |         } | ||||
|  |         // { | ||||
|  |         //   label: '整点/半点', | ||||
|  |         //   value: 4 | ||||
|  |         // } | ||||
|  |       ], | ||||
|  |       weeklyOptions: [ | ||||
|  |         { | ||||
|  |           label: '周一', | ||||
|  |           value: 1 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周二', | ||||
|  |           value: 2 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周三', | ||||
|  |           value: 3 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周四', | ||||
|  |           value: 4 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周五', | ||||
|  |           value: 5 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周六', | ||||
|  |           value: 6 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '周日', | ||||
|  |           value: 7 | ||||
|  |         } | ||||
|  |       ], | ||||
|  |       halfOrPartOptions: [ | ||||
|  |         { | ||||
|  |           label: '整点', | ||||
|  |           value: 1 | ||||
|  |         }, | ||||
|  |         { | ||||
|  |           label: '半点', | ||||
|  |           value: 2 | ||||
|  |         } | ||||
|  |       ], | ||||
|  |       rules: { | ||||
|  |         taskName: [ | ||||
|  |           { required: true, message: '请输入', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         taskType: [ | ||||
|  |           { required: true, message: '请选择', trigger: 'change' } | ||||
|  |         ], | ||||
|  |         deviceId: [ | ||||
|  |           { required: true, message: '请选择', trigger: 'change' } | ||||
|  |         ], | ||||
|  |         timerType: [ | ||||
|  |           { required: true, message: '请选择', trigger: 'change' } | ||||
|  |         ], | ||||
|  |         timeInterval: [ | ||||
|  |           { required: true, message: '请输入', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         startTime: [ | ||||
|  |           { required: true, message: '请选择', trigger: 'change' }, | ||||
|  |           { validator: this.validateDateRange, trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         endTime: [ | ||||
|  |           { | ||||
|  |             validator: (rule, value, callback) => { | ||||
|  |               if (this.isRequired && !value) { | ||||
|  |                 callback(new Error('请选择结束时间')) | ||||
|  |               } else if (this.form.startTime > value) { | ||||
|  |                 callback(new Error('开始时间不得大于结束时间')) | ||||
|  |               } else { | ||||
|  |                 callback() | ||||
|  |               } | ||||
|  |             }, | ||||
|  |             trigger: 'change' | ||||
|  |           } | ||||
|  |         ] | ||||
|  |       }, | ||||
|  |       endPickerOptions: { | ||||
|  |         disabledDate: (time) => { | ||||
|  |           const startTime = new Date(this.form.startTime).getTime() | ||||
|  |           // if (startTime) { | ||||
|  |           //   return time.getTime() < new Date(startTime).getTime() - 1 * 24 * 60 * 60 * 1000 || time.getTime() < startTime | ||||
|  |           // } | ||||
|  |           if (startTime) { | ||||
|  |             // return time.getTime() <= new Date(startTime).getTime() | ||||
|  |             return (time.getTime()) <= startTime - 8.64e7 | ||||
|  |           } else { | ||||
|  |             return time.getTime() < Date.now() - 8.64e7 | ||||
|  |           } | ||||
|  |         } | ||||
|  |       } | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     ...mapGetters([ | ||||
|  |       'user', | ||||
|  |       'baseApi' | ||||
|  |     ]) | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     [CRUD.HOOK.beforeRefresh]() { | ||||
|  |     }, | ||||
|  |     [CRUD.HOOK.afterRefresh](crud) { | ||||
|  |     }, | ||||
|  |     // 新增前将多选的值设置为空 | ||||
|  |     [CRUD.HOOK.beforeToAdd]() { | ||||
|  |       this.form.startTime2 = parseTime(new Date().getTime()) | ||||
|  |     }, // 初始化编辑时候的角色与岗位 | ||||
|  |     [CRUD.HOOK.beforeToEdit](crud, form) { | ||||
|  |       // if (form.timerType === 4 && form.timeInterval) { | ||||
|  |       //   form.halfOrPart = form.timeInterval.split(',').map(Number) | ||||
|  |       // } | ||||
|  |       if (form.startTime) { | ||||
|  |         this.form.startTime2 = parseTime(form.startTime) | ||||
|  |       } | ||||
|  |       if (form.endTime) { | ||||
|  |         this.form.endTime2 = parseTime(form.endTime) | ||||
|  |         form.longTime = false | ||||
|  |       } else { | ||||
|  |         this.form.endTime2 = null | ||||
|  |         form.longTime = true | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     [CRUD.HOOK.beforeValidateCU](crud, form) { | ||||
|  |       if (this.form.taskType === null || this.form.deviceId === null || this.form.name === null) { | ||||
|  |         this.$message.error('请制定完善 “ 任务设定 ” ') | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     // 提交前做的操作 | ||||
|  |     [CRUD.HOOK.afterValidateCU](crud) { | ||||
|  |       if (this.form.startTime2) { | ||||
|  |         this.form.startTime = timeToTimestamp(this.form.startTime2) | ||||
|  |       } else { | ||||
|  |         this.form.startTime = null | ||||
|  |       } | ||||
|  |       if (this.form.endTime2) { | ||||
|  |         this.form.endTime = timeToTimestamp(this.form.endTime2) | ||||
|  |       } else { | ||||
|  |         this.form.endTime = null | ||||
|  |       } | ||||
|  |       // if (this.form.timerType === 4 && this.form.halfOrPart) { | ||||
|  |       //   this.form.timeInterval = this.form.halfOrPart.join(',') | ||||
|  |       // } | ||||
|  |       delete crud.form.remark | ||||
|  |       delete crud.form.longTime | ||||
|  |       delete crud.form.startTime2 | ||||
|  |       delete crud.form.endTime2 | ||||
|  |       delete crud.form.nowTime | ||||
|  |       delete crud.form.halfOrPart | ||||
|  |       return true | ||||
|  |     }, | ||||
|  |     changeFormTab(index) { | ||||
|  |       this.tabIndex = index | ||||
|  |     }, | ||||
|  |     handleWeeklyTypes(val) { | ||||
|  |       if (val.length < 1) { | ||||
|  |         this.$nextTick(() => { | ||||
|  |           this.weekly = [] | ||||
|  |         }) | ||||
|  |         return | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     handleLongTime(val) { | ||||
|  |       if (val === true) { | ||||
|  |         this.form.endTime = null | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     handleNowTime(val) { | ||||
|  |       if (val === true) { | ||||
|  |         this.form.startTime2 = parseTime(new Date().getTime()) | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     // validateDateRange() { | ||||
|  |     //   if (this.form.startTime > this.form.endTime) { | ||||
|  |     //     this.$message.warning('开始时间不能大于结束时间') | ||||
|  |     //     return false | ||||
|  |     //   } | ||||
|  |     //   return true | ||||
|  |     // }, | ||||
|  |     handleTaskType(val) { | ||||
|  |       this.form.deviceId = null | ||||
|  |     }, | ||||
|  |     handleTimerType(val) { | ||||
|  |       // if (val === 4) { | ||||
|  |       //   this.form.timeInterval = null | ||||
|  |       //   this.form.halfOrPart = [1] | ||||
|  |       // } else { | ||||
|  |       //   this.form.timeInterval = 1 | ||||
|  |       // } | ||||
|  |     }, | ||||
|  |     changeFloorValue(value) { | ||||
|  |       console.log(value) | ||||
|  |     }, | ||||
|  |     clickRowHandler(row) { | ||||
|  |       this.$refs.table.clearSelection() | ||||
|  |       this.$refs.table.toggleRowSelection(row) | ||||
|  |     }, | ||||
|  |     toDelete(datas) { | ||||
|  |       this.$confirm('此操作将删除当前任务<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         this.crud.delAllLoading = true | ||||
|  |         const ids = [] | ||||
|  |         datas.forEach(val => { | ||||
|  |           ids.push(val.id) | ||||
|  |         }) | ||||
|  |         console.log(ids) | ||||
|  |         // crudRegion.del(ids).then(res => { | ||||
|  |         //   console.log(res) | ||||
|  |         //   this.$message({ message: res, type: 'success', offset: 8 }) | ||||
|  |         //   this.crud.delAllLoading = false | ||||
|  |         //   this.crud.refresh() | ||||
|  |         // }).catch(err => { | ||||
|  |         //   this.crud.delAllLoading = false | ||||
|  |         //   console.log(err) | ||||
|  |         // }) | ||||
|  |       }).catch(() => { | ||||
|  |         this.crud.delAllLoading = false | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     // 改变状态 | ||||
|  |     changeStatus(data, val) { | ||||
|  |       data.id = data.deptsId | ||||
|  |       this.$confirm('此操作将禁用 / 启用当前任务' + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         // crudDept.FetchUpdateDeptsStatus(data).then(res => { | ||||
|  |         //   this.$message({ message: '修改成功', type: 'success', offset: 8 }) | ||||
|  |         //   this.crud.refresh() | ||||
|  |         // }).catch(() => { | ||||
|  |         //   data.deptsStatus = !data.deptsStatus | ||||
|  |         // }) | ||||
|  |       }).catch(() => { | ||||
|  |         this.$message({ message: '已取消修改', offset: 8 }) | ||||
|  |         data.deptsStatus = data.deptsStatus ? 0 : 1 | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     doExport(data) { | ||||
|  |       console.log(data) | ||||
|  |       this.crud.downloadLoading = true | ||||
|  |       this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         const ids = [] | ||||
|  |         data.forEach(val => { | ||||
|  |           ids.push(val.deptsId) | ||||
|  |         }) | ||||
|  |         const params = { | ||||
|  |           'deptsIds': ids | ||||
|  |         } | ||||
|  |         console.log(params) | ||||
|  |         // exportFile(this.baseApi + '/api/depts/download?' + qs.stringify(params, { indices: false })) | ||||
|  |         // this.crud.downloadLoading = false | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     changeActiveTab(index) { | ||||
|  |       this.archivesTabIndex = index | ||||
|  |     }, | ||||
|  |     handleDbClick(row) { | ||||
|  |       this.detailVisible = true | ||||
|  |     }, | ||||
|  |     handleCloseDialog() { | ||||
|  | 
 | ||||
|     } |     } | ||||
|   } |   } | ||||
| } | } | ||||
| </script> | </script> | ||||
| <style scoped> |  | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
|  | ::v-deep .el-dialog .el-dialog__body{ | ||||
|  |   padding: 0 0 30px 0; | ||||
|  | } | ||||
| </style> | </style> | ||||
| @ -1,16 +1,506 @@ | |||||
| <template> | <template> | ||||
|   <div class="app-container"> |   <div class="app-container"> | ||||
|     数据总览 |  | ||||
|  |     <div class="venue-header"> | ||||
|  |       <h4><i class="iconfont icon-shuju" />数据总览</h4> | ||||
|  |       <p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p> | ||||
|  |     </div> | ||||
|  |     <div class="venue-content"> | ||||
|  |       <crudOperation :permission="permission"> | ||||
|  |         <template v-slot:middle> | ||||
|  |           <el-button v-permission="permission.add" size="mini" @click="crud.toAdd"> | ||||
|  |             <i class="iconfont icon-shengchengpandiandan" /> | ||||
|  |             全量盘点 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |         <template v-slot:right> | ||||
|  |           <el-button :loading="crud.downloadLoading" size="mini" @click="doExport(crud.selections)"> | ||||
|  |             <i class="iconfont icon-daochu" /> | ||||
|  |             导出 | ||||
|  |           </el-button> | ||||
|  |         </template> | ||||
|  |       </crudOperation> | ||||
|  |       <div class="venue-left"> | ||||
|  |         <div class="container-right tab-content"> | ||||
|  |           <span class="right-top-line" /> | ||||
|  |           <span class="left-bottom-line" /> | ||||
|  |           <ul class="tab-nav"> | ||||
|  |             <li v-for="(item,index) in floorOptions" :key="index" :class="{ 'active-tab-nav': activeIndex == index }" @click="changeActiveTab(index)">{{ item.floorName }}<i /></li> | ||||
|  |             <!-- 最右侧装饰img --> | ||||
|  |             <span class="tab-right-img" /> | ||||
|  |           </ul> | ||||
|  |           <div class="venue-preview"> | ||||
|  |             <div v-show="currentMarkData && currentMarkData.signPoint"> | ||||
|  |               <canvas id="canvasPreview" :width="width" :height="height" /> | ||||
|  |             </div> | ||||
|  |             <img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt=""> | ||||
|  |           </div> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |       <div class="venue-right"> | ||||
|  |         <div class="lib-right-item lib-info"> | ||||
|  |           <h4>场馆概况</h4> | ||||
|  |           <ul class="data-right-list"> | ||||
|  |             <li><p>楼层</p><span><i>5</i>层</span></li> | ||||
|  |             <li><p>区域</p><span><i>25</i>层</span></li> | ||||
|  |             <li><p>书架</p><span><i>100</i>层</span></li> | ||||
|  |             <li><p>摄像头</p><span><i>300</i>层</span></li> | ||||
|  |           </ul> | ||||
|  |         </div> | ||||
|  |         <div class="lib-right-item"> | ||||
|  |           <h4>盘点概况</h4> | ||||
|  |           <div class="refresh-date">2024-11-28 09:46</div> | ||||
|  |           <ul class="data-right-list"> | ||||
|  |             <li><p>在架</p><span><i>15000</i>册</span></li> | ||||
|  |             <li><p>错架</p><span><i>300</i>层</span> <span class="percentage">(2.00%)</span></li> | ||||
|  |             <li><p>错序</p><span><i>0</i>层</span><span class="percentage">(0.00%)</span></li> | ||||
|  |           </ul> | ||||
|  |         </div> | ||||
|  |         <div class="lib-right-item"> | ||||
|  |           <h4>流通统计</h4> | ||||
|  |           <div class="refresh-date">2024-11-28 09:46</div> | ||||
|  |           <swiper | ||||
|  |             ref="swiperTitle" | ||||
|  |             class="swiper-title" | ||||
|  |             :options="swiperOptionTitle" | ||||
|  |             :auto-update="true" | ||||
|  |             :auto-destroy="true" | ||||
|  |             :delete-instance-on-destroy="true" | ||||
|  |             :cleanup-styles-on-destroy="true" | ||||
|  |           > | ||||
|  |             <swiper-slide | ||||
|  |               v-for="(item, index) of tabListData" | ||||
|  |               ref="swiperSlideItem" | ||||
|  |               :key="'name' + index" | ||||
|  |               :iname="item.name" | ||||
|  |               class="swiper-slide-title" | ||||
|  |             > | ||||
|  |               <div | ||||
|  |                 class="tab-name" | ||||
|  |                 :class="{ active: index === swiperActiveIndex }" | ||||
|  |                 @click="handleSlidClickFun(index)" | ||||
|  |               > | ||||
|  |                 {{ item.name }} | ||||
|  |               </div> | ||||
|  |             </swiper-slide> | ||||
|  |           </swiper> | ||||
|  |           <swiper | ||||
|  |             ref="swiperContent" | ||||
|  |             class="swiper-content" | ||||
|  |             :options="swiperOptionContent" | ||||
|  |             :auto-update="true" | ||||
|  |             :auto-destroy="true" | ||||
|  |             :delete-instance-on-destroy="true" | ||||
|  |             :cleanup-styles-on-destroy="true" | ||||
|  |           > | ||||
|  |             <swiper-slide | ||||
|  |               v-for="(item, index) of tabListData" | ||||
|  |               :key="'content' + index" | ||||
|  |               class="swiper-slide-content" | ||||
|  |             > | ||||
|  |               <ul class="cabinet-row"> | ||||
|  |                 <li v-for="(item,index) in bookList" :key="index" :class="{ active: index === rightDataIndex }"> | ||||
|  |                   <span>{{ item }}</span> | ||||
|  |                 </li> | ||||
|  |               </ul> | ||||
|  |             </swiper-slide> | ||||
|  |           </swiper> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |     </div> | ||||
|  | 
 | ||||
|  |     <!-- form --> | ||||
|  |     <el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title"> | ||||
|  |       <span class="dialog-right-top" /> | ||||
|  |       <span class="dialog-left-bottom" /> | ||||
|  |       <div class="setting-dialog"> | ||||
|  |         <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px"> | ||||
|  |           <el-form-item label="盘点单号" prop="taskName"> | ||||
|  |             <el-input v-model="form.taskName" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="盘点类型" prop="taskType"> | ||||
|  |             <el-input v-model="form.taskType" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="目标位置" prop="location"> | ||||
|  |             <el-input v-model="form.location" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-form-item label="目标数量" prop="number"> | ||||
|  |             <el-input v-model="form.number" /> | ||||
|  |           </el-form-item> | ||||
|  |           <el-row> | ||||
|  |             <el-form-item label="备注" prop="remark"> | ||||
|  |               <el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" /> | ||||
|  |             </el-form-item> | ||||
|  |           </el-row> | ||||
|  |         </el-form> | ||||
|  |         <div slot="footer" class="dialog-footer"> | ||||
|  |           <el-button type="text" @click="crud.cancelCU">取消</el-button> | ||||
|  |           <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button> | ||||
|  |         </div> | ||||
|  |       </div> | ||||
|  |     </el-dialog> | ||||
|   </div> |   </div> | ||||
| </template> | </template> | ||||
|  | 
 | ||||
| <script> | <script> | ||||
|  | import { FetchLibraryFloorListAll } from '@/api/floor/index' | ||||
|  | import crudRegion from '@/api/area/index' | ||||
|  | import CRUD, { presenter, header, form, crud } from '@crud/crud' | ||||
|  | import crudOperation from '@crud/CRUD.operation' | ||||
|  | import { mapGetters } from 'vuex' | ||||
|  | import defaultImg from '@/assets/images/system/default-img.jpg' | ||||
|  | import { fabric } from 'fabric' | ||||
|  | import { swiper, swiperSlide } from 'vue-awesome-swiper' | ||||
|  | import 'swiper/dist/css/swiper.css' | ||||
|  | 
 | ||||
|  | const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null } | ||||
| export default { | export default { | ||||
|   name: 'DataScreening', |   name: 'DataScreening', | ||||
|  |   components: { swiper, swiperSlide, crudOperation }, | ||||
|  |   cruds() { | ||||
|  |     return CRUD({ title: '数据总览', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: { | ||||
|  |       add: false, | ||||
|  |       edit: false, | ||||
|  |       del: false, | ||||
|  |       download: false, | ||||
|  |       group: false, | ||||
|  |       reset: false | ||||
|  |     }}) | ||||
|  |   }, | ||||
|  |   mixins: [presenter(), header(), form(defaultForm), crud()], | ||||
|   data() { |   data() { | ||||
|  |     const _this = this | ||||
|     return { |     return { | ||||
|  |       floorOptions: [], | ||||
|  |       swiperActiveIndex: 0, | ||||
|  |       rightDataIndex: null, | ||||
|  |       swiperOptionContent: { | ||||
|  |         slidesPerView: 'auto', | ||||
|  |         on: { | ||||
|  |           slideChangeTransitionStart: function() { | ||||
|  |             _this.rightDataIndex = null | ||||
|  |             _this.swiperActiveIndex = this.activeIndex | ||||
|  |             _this.swiperTitle.slideTo(this.activeIndex, 500, false) | ||||
|  |           } | ||||
|  |         } | ||||
|  |       }, | ||||
|  |       swiperOptionTitle: { | ||||
|  |         slidesPerView: 'auto', | ||||
|  |         freeMode: true | ||||
|  |       }, | ||||
|  |       tabListData: [{ name: '热门图书' }, { name: '热门架位' }, { name: '冷面图书' }], | ||||
|  |       bookList: [], | ||||
|  |       permission: { | ||||
|  |         add: ['admin', 'floor:add'], | ||||
|  |         edit: ['admin', 'floor:edit'], | ||||
|  |         del: ['admin', 'floor:del'] | ||||
|  |       }, | ||||
|  |       rules: { | ||||
|  |         taskName: [ | ||||
|  |           { required: true, message: '请输入盘点单号', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         taskType: [ | ||||
|  |           { required: true, message: '请输入盘点类型', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         location: [ | ||||
|  |           { required: true, message: '请输入目标位置', trigger: 'blur' } | ||||
|  |         ], | ||||
|  |         number: [ | ||||
|  |           { required: true, message: '请输入目标数量', trigger: 'blur' } | ||||
|  |         ] | ||||
|  |       }, | ||||
|  |       activeIndex: 0, | ||||
|  |       defaultImg: defaultImg, | ||||
|  |       imageUrl: defaultImg, | ||||
|  |       imageRegionUrl: defaultImg, | ||||
|  |       sortTableData: [], // 排序data | ||||
|  |       sortVisible: false, // 排序dialog | ||||
|  |       markVisible: false, // 区域标注 | ||||
|  |       titleMark: '区域标注', | ||||
|  |       currentMarkData: null, | ||||
|  | 
 | ||||
|  |       canvasPreview: {}, | ||||
|  |       width: 900, | ||||
|  |       height: 600, | ||||
|  |       drawWidth: 2 // 笔触宽度 | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     ...mapGetters([ | ||||
|  |       'user', | ||||
|  |       'baseApi' | ||||
|  |     ]), | ||||
|  |     swiperContent() { | ||||
|  |       return this.$refs.swiperContent.$el.swiper | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   watch: { | ||||
|  |     width() { | ||||
|  |       this.canvasPreview.setWidth(this.width) | ||||
|  |     }, | ||||
|  |     height() { | ||||
|  |       this.canvasPreview.setHeight(this.height) | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     [CRUD.HOOK.beforeRefresh]() { | ||||
|  |       this.getLibraryFloorListAll() | ||||
|  |     }, | ||||
|  |     [CRUD.HOOK.afterRefresh](crud) { | ||||
|  |       if (crud.data.length !== 0) { | ||||
|  |         this.activeIndex = 0 | ||||
|  |       } else { | ||||
|  |         this.imageUrl = this.defaultImg | ||||
|  |         this.imageRegionUrl = this.defaultImg | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     // 提交前的验证 | ||||
|  |     [CRUD.HOOK.afterValidateCU](crud) { | ||||
|  |       return true | ||||
|  |     }, | ||||
|  |     // 获取楼层数据 | ||||
|  |     getLibraryFloorListAll() { | ||||
|  |       FetchLibraryFloorListAll().then(res => { | ||||
|  |         this.floorOptions = res | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     handleCover(value) { | ||||
|  |       console.log(value) | ||||
|  |       this.crud.form.regionMap = value | ||||
|  |     }, | ||||
|  |     changeFloorValue(value) { | ||||
|  |       console.log(value) | ||||
|  |     }, | ||||
|  |     changeActiveTab(data) { | ||||
|  |       this.activeIndex = data | ||||
|  |       if (this.crud.selections.length === 1) { | ||||
|  |         // if (this.canvasPreview) { | ||||
|  |         //   this.canvasPreview.clear() | ||||
|  |         //   this.canvasPreview.dispose() | ||||
|  |         // } | ||||
|  |         if (this.crud.selections[0].floorMap) { | ||||
|  |           this.currentMarkData = this.crud.selections[0] | ||||
|  |           this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.crud.selections[0].floorMap | ||||
|  |         } else { | ||||
|  |           this.imageUrl = this.defaultImg | ||||
|  |         } | ||||
|  |         if (this.crud.selections[0].regionMap) { | ||||
|  |           this.imageRegionUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.crud.selections[0].regionMap | ||||
|  |         } else { | ||||
|  |           this.imageRegionUrl = this.defaultImg | ||||
|  |         } | ||||
|  | 
 | ||||
|  |         if (this.activeIndex === 0) { | ||||
|  |           if (this.crud.selections[0].signPoint) { | ||||
|  |             console.log('1111') | ||||
|  |             const drawinfo = JSON.parse(this.crud.selections[0].signPoint) | ||||
|  |             this.initCanvasPreview(drawinfo) | ||||
|  |           } | ||||
|  |         } | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     handleSlidClickFun(index) { | ||||
|  |       this.rightDataIndex = null | ||||
|  |       this.handleSlideToFun(index) | ||||
|  |     }, | ||||
|  |     handleSlideToFun(index) { | ||||
|  |       this.swiperActiveIndex = index | ||||
|  |       this.swiperContent.slideTo(index, 500, false) | ||||
|  |       this.swiperTitle.slideTo(index, 500, false) | ||||
|  |     }, | ||||
|  |     async handleMark() { | ||||
|  |       if (this.crud.selections[0].floorMap) { | ||||
|  |         this.markVisible = true | ||||
|  |         this.currentMarkData = this.crud.selections[0] | ||||
|  |         this.titleMark = this.currentMarkData.regionName + ' - 区域标注' | ||||
|  |         this.$nextTick(() => { | ||||
|  |           this.$refs.markRefs.drawinfo = this.currentMarkData && this.currentMarkData.signPoint ? JSON.parse(this.currentMarkData.signPoint) : null | ||||
|  |           this.$refs.markRefs.initCanvas() | ||||
|  |         }) | ||||
|  |       } else { | ||||
|  |         this.$message({ message: '请先上传当前楼层图', type: 'error', offset: 8 }) | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     initCanvasPreview(drawinfo) { | ||||
|  |       this.canvasPreview = new fabric.Canvas('canvasPreview', { | ||||
|  |         skipTargetFind: false, | ||||
|  |         selectable: false, | ||||
|  |         selection: false | ||||
|  |       }) | ||||
|  | 
 | ||||
|  |       this.canvasPreview.selectionColor = 'rgba(0,0,0,0.05)' | ||||
|  |       this.loadDrawPreview(drawinfo) | ||||
|  |       this.canvasPreview.on('mouse:wheel', this.mouse) | ||||
|  |     }, | ||||
|  |     // 鼠标滚轮放大缩小 | ||||
|  |     mouse(e) { | ||||
|  |       if (undefined === e) return | ||||
|  |       let zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + this.canvasPreview.getZoom() | ||||
|  |       zoom = Math.max(0.8, zoom) | ||||
|  |       // 最小为原来的1/10 | ||||
|  |       zoom = Math.min(3, zoom) | ||||
|  |       // 最大是原来的3倍 | ||||
|  |       const zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY) | ||||
|  |       this.canvasPreview.zoomToPoint(zoomPoint, zoom) | ||||
|  |     }, | ||||
|  |     // 回显详情信息 | ||||
|  |     loadDrawPreview(drawinfo) { | ||||
|  |       const self = this | ||||
|  |       const pointGroup = drawinfo.pointInfo | ||||
|  |       const imgInfo = drawinfo.imgInfo | ||||
|  |       imgInfo.src = self.imageUrl | ||||
|  |       // 加载底图 | ||||
|  |       fabric.util.enlivenObjects([imgInfo], objects => { | ||||
|  |         objects.forEach(o => { | ||||
|  |           o.selectable = false | ||||
|  |           o.hasControls = false | ||||
|  |           o.centeredScaling = false | ||||
|  |           self.canvasPreview.add(o) | ||||
|  |         }) | ||||
|  |         // 处理多边形绘制回显操作 | ||||
|  |         pointGroup.forEach(async(item, index) => { | ||||
|  |           if (item.pointInfo !== '') { | ||||
|  |             const polygon = new fabric.Polygon(item.pointInfo, { | ||||
|  |               name: item.name, | ||||
|  |               stroke: 'rgba(196,43, 1, 1)', | ||||
|  |               strokeWidth: self.drawWidth, | ||||
|  |               fill: 'rgba(196,43, 1, 0.3)', | ||||
|  |               opacity: 1, | ||||
|  |               selectable: false, | ||||
|  |               hasBorders: false, | ||||
|  |               hasControls: false, | ||||
|  |               originX: 'left', // 设置原点为左上角 | ||||
|  |               originY: 'top' // 设置原点为左上角 | ||||
|  |             }) | ||||
|  |             // polygon.index = index | ||||
|  |             self.canvasPreview.add(polygon) | ||||
|  | 
 | ||||
|  |             polygon.on('mousedown', function(e) { | ||||
|  |               console.log('Rect ' + (index + 1) + ' clicked', e) | ||||
|  |               console.log('e.target.name', e.target.name) | ||||
|  |             }) | ||||
|  | 
 | ||||
|  |             polygon.on('mouseover', function(e) { | ||||
|  |               console.log('e', e) | ||||
|  |               console.log('e.target', e.target) | ||||
|  |               console.log('e.target.name', e.target.name) | ||||
|  |               this.set({ opacity: 0.3, hoverCursor: 'pointer' }) | ||||
|  |               self.canvasPreview.renderAll() | ||||
|  |             }) | ||||
|  | 
 | ||||
|  |             // 监听鼠标移出事件 | ||||
|  |             polygon.on('mouseout', function() { | ||||
|  |               this.set({ opacity: 1 }) | ||||
|  |               self.canvasPreview.renderAll() | ||||
|  |             }) | ||||
|  |           } | ||||
|  |         }) | ||||
|  |       }) | ||||
|  |       self.canvasPreview.renderAll() | ||||
|     } |     } | ||||
|   } |   } | ||||
| } | } | ||||
| </script> | </script> | ||||
| <style scoped> |  | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
|  | .container-right{ | ||||
|  |   min-height: calc(100vh - 232px) !important; | ||||
|  | } | ||||
|  | .venue-content{ | ||||
|  |   position: relative; | ||||
|  | } | ||||
|  | .crud-opts{ | ||||
|  |   position: absolute; | ||||
|  |   right: 20px; | ||||
|  |   top: 10px; | ||||
|  | } | ||||
|  | .venue-left{ | ||||
|  |   flex: 1; | ||||
|  |   margin-right: 0 !important; | ||||
|  |   .venue-preview{ | ||||
|  |     height: 633px !important; | ||||
|  |   } | ||||
|  | } | ||||
|  | .venue-right{ | ||||
|  |   display: flex; | ||||
|  |   flex-direction: column; | ||||
|  |   width: 400px; | ||||
|  |   padding: 50px 10px 20px 10px !important; | ||||
|  |   .lib-right-item{ | ||||
|  |     position: relative; | ||||
|  |     padding: 10px; | ||||
|  |     // height: calc(100% / 3); | ||||
|  |     margin-bottom: 10px; | ||||
|  |     border: 1px solid #0348f3; | ||||
|  |     border-radius: 4px; | ||||
|  |     h4{ | ||||
|  |       color: #000; | ||||
|  |       line-height: 30px; | ||||
|  |       border-bottom: 1px solid #edeff3; | ||||
|  |     } | ||||
|  |     .refresh-date{ | ||||
|  |       position: absolute; | ||||
|  |       right: 14px; | ||||
|  |       top: 10px; | ||||
|  |       font-size: 12px; | ||||
|  |       line-height: 30px; | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | 
 | ||||
|  | .data-right-list { | ||||
|  |   padding-top: 10px; | ||||
|  |   li{ | ||||
|  |     display: flex; | ||||
|  |     justify-content: flex-start; | ||||
|  |     align-items: center; | ||||
|  |     line-height: 36px; | ||||
|  | 
 | ||||
|  |     p{ | ||||
|  |       width: 80px; | ||||
|  |       font-weight: bold; | ||||
|  |       text-align: right; | ||||
|  |     } | ||||
|  |     span{ | ||||
|  |       width: 140px; | ||||
|  |       display: block; | ||||
|  |       text-align: right; | ||||
|  |       i{ | ||||
|  |         font-style: normal; | ||||
|  |         font-weight: bold; | ||||
|  |         padding: 0 10px; | ||||
|  |         color: #0348f3; | ||||
|  |       } | ||||
|  |       &.percentage{ | ||||
|  |         width: auto; | ||||
|  |       } | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | .swiper-title{ | ||||
|  |   ::v-deep .swiper-wrapper{ | ||||
|  |     margin: 10px 0; | ||||
|  |     border-bottom: 1px solid #EDEFF3; | ||||
|  |   } | ||||
|  | } | ||||
|  | .swiper-slide-title { | ||||
|  | 	width: auto !important; | ||||
|  |   margin-right: 20px; | ||||
|  |   cursor: pointer; | ||||
|  | 	.tab-name { | ||||
|  | 		padding: 10px; | ||||
|  | 		&.active { | ||||
|  | 			color: #0348F3; | ||||
|  |       border-bottom: 3px solid #0348F3; | ||||
|  | 		} | ||||
|  | 	} | ||||
|  | } | ||||
|  | 
 | ||||
|  | .swiper-content{ | ||||
|  |   // height: 544px; | ||||
|  | } | ||||
|  | .swiper-slide-content { | ||||
|  | 	// padding: 0 10px; | ||||
|  |   // margin: 0 10px 0 0; | ||||
|  | } | ||||
| </style> | </style> | ||||
| @ -1,16 +1,51 @@ | |||||
| <template> | <template> | ||||
|   <div class="app-container"> |  | ||||
|     统计分析 |  | ||||
|  |   <div class="app-container tab-container"> | ||||
|  |     <div class="tab-content"> | ||||
|  |       <span class="right-top-line" /> | ||||
|  |       <span class="left-bottom-line" /> | ||||
|  |       <span class="right-bottom-line" /> | ||||
|  |       <ul class="tab-nav"> | ||||
|  |         <li :class="{ 'active-tab-nav': activeIndex == 0 }" @click="changeActiveTab(0)">建议顺架<i /></li> | ||||
|  |         <li :class="{ 'active-tab-nav': activeIndex == 1 }" @click="changeActiveTab(1)">建议倒架<i /></li> | ||||
|  |         <!-- 最右侧装饰img --> | ||||
|  |         <span class="tab-right-img" /> | ||||
|  |       </ul> | ||||
|  |       <component :is="comName" /> | ||||
|  |     </div> | ||||
|   </div> |   </div> | ||||
| </template> | </template> | ||||
|  | 
 | ||||
| <script> | <script> | ||||
|  | import seqShelf from './seqShelf/index' | ||||
|  | import reverseShelf from './reverseShelf/index' | ||||
| export default { | export default { | ||||
|   name: 'Statistic', |   name: 'Statistic', | ||||
|  |   components: { | ||||
|  |     seqShelf, | ||||
|  |     reverseShelf | ||||
|  |   }, | ||||
|   data() { |   data() { | ||||
|     return { |     return { | ||||
|  |       activeIndex: 0 | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     comName: function() { | ||||
|  |       if (this.activeIndex === 0) { | ||||
|  |         return 'seqShelf' | ||||
|  |       } else if (this.activeIndex === 1) { | ||||
|  |         return 'reverseShelf' | ||||
|  |       } | ||||
|  |       return 'seqShelf' | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     changeActiveTab(data) { | ||||
|  |       this.activeIndex = data | ||||
|     } |     } | ||||
|   } |   } | ||||
| } | } | ||||
| </script> | </script> | ||||
| <style scoped> |  | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
| </style> | </style> | ||||
| @ -0,0 +1,145 @@ | |||||
|  | <template> | ||||
|  |   <div class="operateLog-main"> | ||||
|  |     <Search :is-log-type="isLogType" :is-center="isCenter" @handleClearOperateData="handleDelt" /> | ||||
|  |     <!-- calc(100vh - 396px) --> | ||||
|  |     <el-table | ||||
|  |       ref="table" | ||||
|  |       :data="crud.data" | ||||
|  |       style="width: 100%;" | ||||
|  |       :height="heightStyle" | ||||
|  |       @row-click="clickRowHandler" | ||||
|  |       @selection-change="crud.selectionChangeHandler" | ||||
|  |     > | ||||
|  |       <el-table-column type="selection" width="55" align="center" /> | ||||
|  |       <el-table-column type="expand"> | ||||
|  |         <template slot-scope="props"> | ||||
|  |           <el-form label-position="left" inline class="demo-table-expand"> | ||||
|  |             <el-form-item label="请求方法"> | ||||
|  |               <span>{{ props.row.method }}</span> | ||||
|  |             </el-form-item> | ||||
|  |             <el-form-item label="请求参数"> | ||||
|  |               <span style="word-break:break-all;">{{ props.row.params }}</span> | ||||
|  |             </el-form-item> | ||||
|  |           </el-form> | ||||
|  |         </template> | ||||
|  |       </el-table-column> | ||||
|  |       <el-table-column align="center" prop="username" label="账号" min-width="100px" /> | ||||
|  |       <el-table-column align="center" prop="nickName" label="用户名" min-width="100px" /> | ||||
|  |       <el-table-column prop="fondsName" label="所属机构" show-overflow-tooltip align="center" min-width="200px" /> | ||||
|  |       <el-table-column prop="deptsName" label="所属部门" show-overflow-tooltip align="center" min-width="120px" /> | ||||
|  |       <el-table-column prop="requestIp" label="IP" show-overflow-tooltip align="center" min-width="120px" /> | ||||
|  |       <el-table-column prop="address" label="IP来源" align="center" /> | ||||
|  |       <el-table-column prop="description" label="内容描述" show-overflow-tooltip align="center" min-width="200px" /> | ||||
|  |       <el-table-column prop="browser" label="浏览器" align="center" min-width="100px" /> | ||||
|  |       <el-table-column prop="time" label="请求耗时" align="center"> | ||||
|  |         <template slot-scope="scope"> | ||||
|  |           <el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag> | ||||
|  |           <el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag> | ||||
|  |           <el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag> | ||||
|  |         </template> | ||||
|  |       </el-table-column> | ||||
|  |       <el-table-column prop="createTime" label="操作时间" align="center" min-width="150"> | ||||
|  |         <template slot-scope="scope"> | ||||
|  |           <div>{{ scope.row.createTime | parseTime }}</div> | ||||
|  |         </template> | ||||
|  |       </el-table-column> | ||||
|  |     </el-table> | ||||
|  |     <pagination v-if="crud.data.length !== 0" /> | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script> | ||||
|  | import { FetchClearLog } from '@/api/system/logs' | ||||
|  | import Search from '../search.vue' | ||||
|  | import CRUD, { presenter, crud } from '@crud/crud' | ||||
|  | import { mapGetters } from 'vuex' | ||||
|  | import pagination from '@crud/Pagination' | ||||
|  | 
 | ||||
|  | export default { | ||||
|  |   name: 'OperateLog', | ||||
|  |   components: { pagination, Search }, | ||||
|  |   mixins: [presenter(), crud()], | ||||
|  |   cruds() { | ||||
|  |     return CRUD({ | ||||
|  |       url: 'api/log/initLog', | ||||
|  |       title: '操作日志', | ||||
|  |       optShow: { | ||||
|  |         add: false, | ||||
|  |         edit: false, | ||||
|  |         del: false, | ||||
|  |         download: false, | ||||
|  |         reset: false, | ||||
|  |         group: false | ||||
|  |       } | ||||
|  |     }) | ||||
|  |   }, | ||||
|  | 
 | ||||
|  |   props: { | ||||
|  |     isCenter: { | ||||
|  |       type: Boolean, | ||||
|  |       default: false | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   data() { | ||||
|  |     return { | ||||
|  |       isLogType: 'operate', | ||||
|  |       selections: [], | ||||
|  |       heightStyle: 'calc(100vh - 396px)' | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     ...mapGetters([ | ||||
|  |       'user' | ||||
|  |     ]) | ||||
|  |   }, | ||||
|  |   mounted() { | ||||
|  |     this.$nextTick(() => { | ||||
|  |       if (this.isCenter) { | ||||
|  |         this.heightStyle = 'calc(100vh - 470px)' | ||||
|  |       } else { | ||||
|  |         this.heightStyle = 'calc(100vh - 396px)' | ||||
|  |       } | ||||
|  |     }) | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     [CRUD.HOOK.beforeRefresh]() { | ||||
|  |       if (this.isCenter) { | ||||
|  |         this.crud.query.username = this.user.username | ||||
|  |       } else { | ||||
|  |         this.crud.query[this.optionVal] = this.keyWord | ||||
|  |       } | ||||
|  |     }, | ||||
|  |     clickRowHandler(row) { | ||||
|  |       this.$refs.table.toggleRowSelection(row) // 单击选中 | ||||
|  |     }, | ||||
|  |     handleDelt() { | ||||
|  |       this.$confirm('此操作将清空所选数据' + this.crud.title + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         this.crud.delAllLoading = true | ||||
|  |         FetchClearLog().then(() => { | ||||
|  |           this.$message({ message: '清空成功', type: 'success', offset: 8 }) | ||||
|  |           this.crud.delAllLoading = false | ||||
|  |           this.crud.refresh() | ||||
|  |         }).catch(err => { | ||||
|  |           this.crud.delAllLoading = false | ||||
|  |           console.log(err) | ||||
|  |         }) | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
|  | .operateLog-main{ | ||||
|  |   height: calc(100vh - 236px); | ||||
|  | } | ||||
|  | ::v-deep .el-pagination{ | ||||
|  |   margin: 24px 0 10px 0 !important | ||||
|  | } | ||||
|  | </style> | ||||
| @ -0,0 +1,98 @@ | |||||
|  | <template> | ||||
|  |   <div class="head-container"> | ||||
|  |     <div class="head-search"> | ||||
|  |       <el-select v-model="query.floor" clearable size="small" placeholder="楼层区域" class="filter-item" style="width: 200px" @change="crud.toQuery"> | ||||
|  |         <el-option v-for="item in options" :key="item.key" :label="item.display_name" :value="item.key" /> | ||||
|  |       </el-select> | ||||
|  |       <el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="crud.toQuery">搜索</el-button> | ||||
|  |       <el-button class="filter-item  filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery()">重置</el-button> | ||||
|  |     </div> | ||||
|  |     <crudOperation> | ||||
|  |       <template v-slot:right> | ||||
|  |         <el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)"> | ||||
|  |           <i class="iconfont icon-daochu" /> | ||||
|  |           导出 | ||||
|  |         </el-button> | ||||
|  |       </template> | ||||
|  |     </crudOperation> | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script> | ||||
|  | import CRUD, { header, crud } from '@crud/crud' | ||||
|  | import crudOperation from '@crud/CRUD.operation' | ||||
|  | import { mapGetters } from 'vuex' | ||||
|  | import { exportFile } from '@/utils/index' | ||||
|  | import qs from 'qs' | ||||
|  | export default { | ||||
|  |   components: { crudOperation }, | ||||
|  |   mixins: [header(), crud()], | ||||
|  |   props: { | ||||
|  |     isLogType: { | ||||
|  |       type: String, | ||||
|  |       default: '' | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   data() { | ||||
|  |     return { | ||||
|  |       options: [] | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   computed: { | ||||
|  |     ...mapGetters([ | ||||
|  |       'baseApi', | ||||
|  |       'user' | ||||
|  |     ]) | ||||
|  |   }, | ||||
|  |   created() { | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     [CRUD.HOOK.beforeRefresh]() { | ||||
|  |     }, | ||||
|  |     resetQuery() { | ||||
|  |       this.crud.toQuery() | ||||
|  |     }, | ||||
|  |     doExport(data) { | ||||
|  |       console.log(data) | ||||
|  |       crud.downloadLoading = true | ||||
|  |       this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         const ids = [] | ||||
|  |         data.forEach(val => { | ||||
|  |           ids.push(val.id) | ||||
|  |         }) | ||||
|  |         const params = { | ||||
|  |           'ids': ids | ||||
|  |         } | ||||
|  |         if (this.isLogType === 'login') { | ||||
|  |           exportFile(this.baseApi + '/api/log/downloadLoginLog?' + qs.stringify(params, { indices: false })) | ||||
|  |         } else if (this.isLogType === 'operate') { | ||||
|  |           exportFile(this.baseApi + '/api/log/downloadLog?' + qs.stringify(params, { indices: false })) | ||||
|  |         } else { | ||||
|  |           exportFile(this.baseApi + '/api/log/downloadErrorLog?' + qs.stringify(params, { indices: false })) | ||||
|  |         } | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     } | ||||
|  | 
 | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
|  | ::v-deep .input-prepend .el-input__inner{ | ||||
|  |   padding-left: 100px; | ||||
|  | } | ||||
|  | ::v-deep .crud-opts-left{ | ||||
|  |   position: relative; | ||||
|  | } | ||||
|  | .double-click-btn{ | ||||
|  |   top: 4px !important; | ||||
|  |   right: 0; | ||||
|  |   left: -156px !important; | ||||
|  | } | ||||
|  | </style> | ||||
| @ -0,0 +1,100 @@ | |||||
|  | <template> | ||||
|  |   <div style="height: calc(100vh - 236px);"> | ||||
|  |     <Search :is-log-type="isLogType" @handleClearData="handleDelt" /> | ||||
|  |     <el-table | ||||
|  |       ref="table" | ||||
|  |       :data="crud.data" | ||||
|  |       style="width: 100%;" | ||||
|  |       height="calc(100vh - 396px)" | ||||
|  |       @row-click="clickRowHandler" | ||||
|  |       @selection-change="crud.selectionChangeHandler" | ||||
|  |     > | ||||
|  |       <el-table-column prop="account" label="层位" min-width="150" align="center" /> | ||||
|  |       <el-table-column prop="username" label="所属楼层" align="center" min-width="150" /> | ||||
|  |       <el-table-column prop="fondsName" label="所属区域" align="center" min-width="150" /> | ||||
|  |       <el-table-column prop="det" label="当前错架率" align="center" min-width="180" /> | ||||
|  |       <el-table-column prop="createTime" label="更新时间" align="center" min-width="180"> | ||||
|  |         <template slot-scope="scope"> | ||||
|  |           <div>{{ scope.row.createTime | parseTime }}</div> | ||||
|  |         </template> | ||||
|  |       </el-table-column> | ||||
|  |     </el-table> | ||||
|  |     <pagination v-if="crud.data.length !== 0" /> | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | 
 | ||||
|  | <script> | ||||
|  | import { FetchClearLoginLog } from '@/api/system/logs' | ||||
|  | import CRUD, { presenter, crud, header } from '@crud/crud' | ||||
|  | import pagination from '@crud/Pagination' | ||||
|  | import Search from '../search.vue' | ||||
|  | // import { parseTime, saveAs, getBlob } from '@/utils/index' | ||||
|  | export default { | ||||
|  |   name: 'LoginLog', | ||||
|  |   components: { pagination, Search }, | ||||
|  |   filters: { | ||||
|  |     parseRole(val) { | ||||
|  |       const regex = /name=(.*)\)/ | ||||
|  |       const match = regex.exec(val) | ||||
|  |       let role = '' | ||||
|  |       if (match) { | ||||
|  |         role = match[1] | ||||
|  |       } else { | ||||
|  |         role = val | ||||
|  |       } | ||||
|  |       return role | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   mixins: [presenter(), crud(), header()], | ||||
|  |   cruds() { | ||||
|  |     return CRUD({ | ||||
|  |       url: 'api/log/initLoginLog', | ||||
|  |       sort: [], | ||||
|  |       optShow: { | ||||
|  |         add: false, | ||||
|  |         edit: false, | ||||
|  |         del: false, | ||||
|  |         download: false, | ||||
|  |         reset: false, | ||||
|  |         group: false | ||||
|  |       } | ||||
|  |     }) | ||||
|  |   }, | ||||
|  |   data() { | ||||
|  |     return { | ||||
|  |       isLogType: 'login', | ||||
|  |       selections: [] | ||||
|  |     } | ||||
|  |   }, | ||||
|  |   methods: { | ||||
|  |     handleDelt() { | ||||
|  |       this.$confirm('此操作将清空所选数据' + this.crud.title + '<span>你是否还要继续?</span>', '提示', { | ||||
|  |         confirmButtonText: '继续', | ||||
|  |         cancelButtonText: '取消', | ||||
|  |         type: 'warning', | ||||
|  |         dangerouslyUseHTMLString: true | ||||
|  |       }).then(() => { | ||||
|  |         this.crud.delAllLoading = true | ||||
|  |         FetchClearLoginLog().then(() => { | ||||
|  |           this.$message({ message: '清空成功', type: 'success', offset: 8 }) | ||||
|  |           this.crud.delAllLoading = false | ||||
|  |           this.crud.refresh() | ||||
|  |         }).catch(err => { | ||||
|  |           this.crud.delAllLoading = false | ||||
|  |           console.log(err) | ||||
|  |         }) | ||||
|  |       }).catch(() => { | ||||
|  |       }) | ||||
|  |     }, | ||||
|  |     clickRowHandler(row) { | ||||
|  |       this.$refs.table.toggleRowSelection(row) // 单击选中 | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | 
 | ||||
|  | <style lang="scss" scoped> | ||||
|  | ::v-deep .el-pagination{ | ||||
|  |   margin: 24px 0 10px 0 !important | ||||
|  | } | ||||
|  | </style> | ||||
| @ -0,0 +1,16 @@ | |||||
|  | <template> | ||||
|  |   <div class="app-container"> | ||||
|  |     上架/下架日志 | ||||
|  |   </div> | ||||
|  | </template> | ||||
|  | <script> | ||||
|  | export default { | ||||
|  |   name: 'UpDownLog', | ||||
|  |   data() { | ||||
|  |     return { | ||||
|  |     } | ||||
|  |   } | ||||
|  | } | ||||
|  | </script> | ||||
|  | <style scoped> | ||||
|  | </style> | ||||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue