Browse Source

图书馆藏/盘点/首页

master
xuhuajiao 6 months ago
parent
commit
e21ac47384
  1. 10
      src/api/area/index.js
  2. 17
      src/api/bookBasice/index.js
  3. 27
      src/api/collectionBook/index.js
  4. 18
      src/api/shelf/index.js
  5. 14
      src/assets/iconfonts/light/iconfont.css
  6. 2
      src/assets/iconfonts/light/iconfont.js
  7. 14
      src/assets/iconfonts/light/iconfont.json
  8. BIN
      src/assets/iconfonts/light/iconfont.ttf
  9. BIN
      src/assets/iconfonts/light/iconfont.woff
  10. BIN
      src/assets/iconfonts/light/iconfont.woff2
  11. 13
      src/assets/styles/mixin.scss
  12. 131
      src/views/components/bookSwiper.vue
  13. 8
      src/views/dashboard/PanelGroup.vue
  14. 18
      src/views/home.vue
  15. 63
      src/views/visualCheck/bookstore/book/index.vue
  16. 254
      src/views/visualCheck/bookstore/collection/index.vue
  17. 438
      src/views/visualCheck/checkManage/bookSearch/index.vue
  18. 240
      src/views/visualCheck/checkManage/bookshelfSearch/index.vue
  19. 151
      src/views/visualCheck/checkManage/index.vue
  20. 183
      src/views/visualCheck/checkManage/statistic/reverseShelf/index.vue
  21. 2
      src/views/visualCheck/checkManage/statistic/search.vue
  22. 21
      src/views/visualCheck/venueDevice/area/index.vue

10
src/api/area/index.js

@ -48,4 +48,12 @@ export function saveLibraryRegionSignPoint(parameter) {
})
}
export default { add, edit, del, sort, saveLibraryRegionSignPoint, FetchInitLibraryRegionList }
// 根据楼层获取全部区域
export function FetchRegionAllByFloor(params) {
return request({
url: 'api/libraryRegion/getRegionAllByFloor' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { add, edit, del, sort, saveLibraryRegionSignPoint, FetchInitLibraryRegionList, FetchRegionAllByFloor }

17
src/api/bookBasice/index.js

@ -1,4 +1,12 @@
import request from '@/utils/request'
import qs from 'qs'
export function FetchCollectionLocationAll(params) {
return request({
url: 'api/bookBasice/getCollectionLocationAll' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export function add(data) {
return request({
@ -24,4 +32,11 @@ export function del(ids) {
})
}
export default { add, edit, del }
export function FetchCreateBarcode(params) {
return request({
url: 'api/bookBasice/createBarcode' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { add, edit, del, FetchCollectionLocationAll, FetchCreateBarcode }

27
src/api/collectionBook/index.js

@ -0,0 +1,27 @@
import request from '@/utils/request'
export function add(data) {
return request({
url: 'api/bookBasice/editBookDetails',
method: 'post',
data
})
}
export function edit(data) {
return request({
url: 'api/bookBasice/editBookDetails',
method: 'post',
data
})
}
export function del(ids) {
return request({
url: 'api/bookBasice/delBookDetails',
method: 'post',
data: ids
})
}
export default { add, edit, del }

18
src/api/shelf/index.js

@ -84,4 +84,20 @@ export function FetchChangeCheckByGrid(parameter) {
})
}
export default { add, edit, del, FetchInitBookShelfList, FetchBookShelfDetails, saveBookShelfSignPoint, FetchInitShelfGridByShelfId, FetcheEditSortmarkByGrid, FetchChangeOrderByGrid, FetchChangeCheckByGrid }
// 根据书架查看所有层架位
export function FetchShelfGridAllByShelfId(params) {
return request({
url: 'api/bookShelf/getShelfGridAllByShelfId' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 根据区域查看所有书架
export function FetchShelfAllByRegionId(params) {
return request({
url: 'api/bookShelf/getShelfAllByRegionId' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
export default { add, edit, del, FetchInitBookShelfList, FetchBookShelfDetails, saveBookShelfSignPoint, FetchInitShelfGridByShelfId, FetcheEditSortmarkByGrid, FetchChangeOrderByGrid, FetchChangeCheckByGrid, FetchShelfGridAllByShelfId, FetchShelfAllByRegionId }

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

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

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

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

@ -5,6 +5,20 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "4487893",
"name": "标签",
"font_class": "biaoqian",
"unicode": "e693",
"unicode_decimal": 59027
},
{
"icon_id": "6796688",
"name": "2_标签-06",
"font_class": "_biaoqian-",
"unicode": "e68f",
"unicode_decimal": 59023
},
{
"icon_id": "15392667",
"name": "数据",

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

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

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

13
src/assets/styles/mixin.scss

@ -1065,6 +1065,11 @@
border: 1px solid #CAA4FF;
opacity: 0.6;
}
&.no-state{
color: #a6adb6;
border: 1px solid #e6e8ed;
opacity: 0.6;
}
}
[data-theme="light"] & {
&.ing-state{
@ -1087,10 +1092,10 @@
background-color: #FFF3E5;
border: 1px solid #FEBD98
}
&.other-state{
color: #8B43F0;
background-color: #F4EDFF;
border: 1px solid #CAA4FF;
&.no-state{
color: #a6adb6;
background-color: #f3f5f9;
border: 1px solid #e6e8ed;
}
}
}

131
src/views/components/bookSwiper.vue

@ -0,0 +1,131 @@
<template>
<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>
</template>
<script>
import { mapGetters } from 'vuex'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
export default {
name: 'BookSwiper',
components: { swiper, swiperSlide },
props: {
},
data() {
const _this = this
return {
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: []
}
},
computed: {
...mapGetters([
'baseApi'
])
},
methods: {
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)
}
}
}
</script>
<style lang="scss" scoped>
.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>

8
src/views/dashboard/PanelGroup.vue

@ -6,7 +6,7 @@
<img src="@/assets/images/home-icon1.png" alt="">
</div>
<div class="card-panel-description">
档案盒
盘点区域
<div class="card-panel-text">
<count-to :start-val="0" :end-val="topObjectNum && topObjectNum.caseNum" :duration="3200" class="card-panel-num" />
</div>
@ -19,7 +19,7 @@
<img src="@/assets/images/home-icon2.png" alt="">
</div>
<div class="card-panel-description">
案卷条目
盘点书架
<div class="card-panel-text">
<count-to :start-val="0" :end-val="topObjectNum && topObjectNum.archivesNum" :duration="3200" class="card-panel-num" />
</div>
@ -32,7 +32,7 @@
<img src="@/assets/images/home-icon3.png" alt="">
</div>
<div class="card-panel-description">
文件条目
盘点层位
<div class="card-panel-text">
<count-to :start-val="0" :end-val="topObjectNum && topObjectNum.documentNum" :duration="3200" class="card-panel-num" />
</div>
@ -45,7 +45,7 @@
<img src="@/assets/images/home-icon4.png" alt="">
</div>
<div class="card-panel-description">
电子文件
盘点设备
<div class="card-panel-text">
<count-to :start-val="0" :end-val="topObjectNum && topObjectNum.fileNum" :duration="3200" class="card-panel-num" />
</div>

18
src/views/home.vue

@ -8,12 +8,14 @@
<span class="right-top-line" />
<span class="left-bottom-line" />
<h3 class="home-item-title">
流程中心
盘点任务
</h3>
<div class="home-flowable" style="height: calc(100% - 54px); overflow-x: hidden;">
<div class="home-tab">
<span :class="{'home-tab-active': flowableTabIndex == 0}">待处理({{ flowableData.length !==0? flowableData.length: 0 }})</span>
<span :class="{'home-tab-active': flowableTabIndex == 1}" @click="toMoreProcess">更多流程</span>
<span :class="{'home-tab-active': flowableTabIndex == 0}">全部任务({{ flowableData.length !==0? flowableData.length: 0 }})</span>
<span :class="{'home-tab-active': flowableTabIndex == 1}">进行中({{ flowableData.length !==0? flowableData.length: 0 }})</span>
<span :class="{'home-tab-active': flowableTabIndex == 2}">已完成({{ flowableData.length !==0? flowableData.length: 0 }})</span>
<span :class="{'home-tab-active': flowableTabIndex == 3}" @click="toMoreProcess">更多流程</span>
</div>
<div class="home-flowable-list" style="height: calc(100% - 45px); overflow-y: auto; overflow-x: hidden;">
<el-table v-if="flowableData.length !== 0" height="calc(100%)" :data="flowableData" stripe style="width: 100%">
@ -53,7 +55,7 @@
<span class="right-top-line" />
<span class="left-bottom-line" />
<h3 class="home-item-title">
档案统计
盘点概况
</h3>
<div v-if="lendData.otherData.length !== 0" class="chart-wrapper">
<lend-across :lend-data="lendData" />
@ -70,10 +72,10 @@
<span class="right-top-line" />
<span class="left-bottom-line" />
<h3 class="home-item-title">
档案类型
流通统计
</h3>
<div class="chart-wrapper">
<cate-pie :add-arcives-data="addArcivesData" />
<bookSwiper />
</div>
</div>
</el-col>
@ -83,7 +85,7 @@
<span class="right-top-line" />
<span class="left-bottom-line" />
<h3 class="home-item-title">
档案门类
馆藏统计
</h3>
<div v-if="typeData.length !== 0" class="chart-wrapper">
<type-pie :type-data="typeData" />
@ -104,6 +106,7 @@ import PanelGroup from './dashboard/PanelGroup'
import lendAcross from '@/views/components/echarts/lendAcross.vue'
import catePie from '@/views/components/echarts/catePie.vue'
import typePie from '@/views/components/echarts/typePie.vue'
import bookSwiper from '@/views/components/bookSwiper.vue'
import serverProgress from '@/views/components/echarts/serverProgress.vue'
import { FetchMainData } from '@/api/archivesManage/library'
import { FetchSystemInfo } from '@/api/home/cpu/index'
@ -115,6 +118,7 @@ export default {
PanelGroup,
lendAcross,
catePie,
bookSwiper,
typePie,
serverProgress
},

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

@ -27,15 +27,16 @@
<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>
<rrOperation />
<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 :permission="permission">
<!-- <template v-slot:middle>
<el-button v-permission="permission.edit" size="mini" :disabled="crud.selections.length !== 1" @click="toEdit()">
<i class="iconfont icon-bianji" />
编辑
<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>
</crudOperation>
</div>
<!--表单渲染-->
@ -62,7 +63,7 @@
</div>
<UploadCover :label-name="labelName" :form="form" @childCover="handleCover" />
</div>
<div v-if="bookCover" class="preview-cover">
<div v-if="form.bookCover" class="preview-cover">
<p>封面预览</p>
<img :src="bookCover" alt="">
</div>
@ -110,7 +111,6 @@
import crudBook from '@/api/book/index'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import UploadCover from '@/views/components/upload.vue'
@ -119,13 +119,13 @@ import { mapGetters } from 'vuex'
const defaultForm = { id: null, title: null, author: null, isbn: null, classNo: null, publisher: null, bookCover: null, bookRecNo: null }
export default {
name: 'Book',
components: { crudOperation, rrOperation, pagination, UploadCover },
components: { crudOperation, pagination, UploadCover },
cruds() {
return CRUD({ title: '图书', idField: 'id || bookRecNo', url: 'api/bookBasice/initBookBasiceList', crudMethod: { ...crudBook },
optShow: {
add: true,
edit: true,
del: true,
del: false,
download: false,
group: false,
reset: true
@ -185,6 +185,7 @@ export default {
} else {
this.crud.query.status = this.status
}
this.crud.query[this.optionVal] = this.keyWord
},
//
[CRUD.HOOK.afterToCU](crud, form) {
@ -194,11 +195,11 @@ export default {
},
//
[CRUD.HOOK.beforeToEdit](crud, form) {
// crudBook.FetchBookBasiceByISBN({ 'isbn': this.crud.selections[0].isbn }).then(res => {
// console.log(res)
// this.crud.form.bookRecNo = res.bookRecNo
// this.crud.form.id = res.bookRecNo
// })
if (this.crud.form.bookCover) {
this.bookCover = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.crud.form.bookCover
} else {
this.bookCover = require('@/assets/images/cover-bg.png')
}
},
//
[CRUD.HOOK.afterValidateCU](crud) {
@ -215,6 +216,12 @@ export default {
})
}
},
resetQuery() {
this.keyWord = ''
this.crud.query[this.optionVal] = this.keyWord
this.status = null
this.crud.toQuery()
},
handleCover(value) {
console.log(value)
if (value) {
@ -228,6 +235,32 @@ export default {
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.bookRecNo)
})
console.log(ids)
crudBook.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
})
}
}
}

254
src/views/visualCheck/bookstore/collection/index.vue

@ -23,11 +23,12 @@
</el-select>
</el-input>
<el-select v-model="query.userStatus" clearable size="small" placeholder="状态" class="filter-item" style="width: 100px" @change="crud.toQuery">
<el-select v-model="query.isShelf" 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>
<rrOperation />
<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 :permission="permission">
<template v-slot:middle>
@ -50,8 +51,8 @@
<div class="setting-dialog">
<el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="90px">
<div style="width: 696px;">
<el-form-item class="brcode-input" label="ISBN" prop="isbn">
<el-input v-model="form.isbn" placeholder="请输入" />
<el-form-item class="barcode-input" label="ISBN" prop="isbn">
<el-input v-model="form.isbn" placeholder="请输入" @blur="toIsbnSearch" />
<div class="search-box">
<i class="iconfont icon-sousuo" @click="toIsbnSearch" />
</div>
@ -59,32 +60,48 @@
<el-form-item label="题名" prop="title">
<el-input v-model="form.title" readonly />
</el-form-item>
<el-form-item class="brcode-input" label="条码" prop="brcode">
<el-input v-model="form.brcode" placeholder="请输入" />
<el-form-item class="barcode-input" label="条码" prop="barcode">
<el-input v-model="form.barcode" placeholder="点击按钮可自动生成" />
<div :class="isAutoBrcode?'auto-box auto-loading':'auto-box'">
<i class="iconfont icon-zidonggengxin" @click="autoBrcode" />
</div>
</el-form-item>
<el-form-item label="馆藏地" prop="library">
<el-select v-model="form.library" placeholder="请选择" style="width: 225px;" @change="changeLibrarysValue($event)">
<el-form-item label="索书号" prop="sortmark">
<el-input v-model="form.sortmark" placeholder="请输入" />
</el-form-item>
<el-form-item label="馆藏地" prop="collectionName">
<el-select v-model="form.collectionName" placeholder="请选择" style="width: 586px;" @change="changeLibrarysValue($event)">
<el-option
v-for="(item,index) in librarysOptions"
:key="index"
:label="item.label"
:value="item.id"
:label="item.collectionName"
:value="item.collectionName"
/>
</el-select>
</el-form-item>
<div>
<el-form-item label="所在架位" prop="bookshelf">
<el-form-item class="collection-tree-select" label="所在架位" prop="actualLocation">
<treeselect
v-model="form.bookshelf"
:options="bookshelfNum"
:load-options="loadDepts"
placeholder="选择层位架"
v-model="form.actualShelfId"
:options="regionTreeData"
flat
:multiple="false"
placeholder="选择架"
:normalizer="normalizer"
:default-expand-level="levelNumber"
style="width: 586px;"
style="width: 282px;"
@select="node=>treeSelectInput(node)"
>
<div slot="value-label" slot-scope="{ node }">{{ getAutoNameUnknown(node.label) }}</div>
</treeselect>
<treeselect
v-model="form.actualLocation"
:options="girdData"
placeholder="选择层位"
:normalizer="normalizerGird"
:default-expand-level="levelNumber"
style="width: 282px; margin-left: 20px;"
@select="node=>gridSelectInput(node)"
>
<div slot="value-label" slot-scope="{ node }">{{ getAutoNameUnknown(node.label) }}</div>
</treeselect>
@ -115,16 +132,16 @@
@row-click="clickRowHandler"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column label="条码" prop="brcode" />
<el-table-column label="条码" prop="barcode" />
<el-table-column label="[ISBN]题名" prop="isbn">
<template slot-scope="scope">
<p>[{{ scope.row.isbn }}]{{ scope.row.title }}</p>
<p>[{{ scope.row.isbn }}]{{ scope.row.collectionName }}</p>
</template>
</el-table-column>
<el-table-column prop="floor" label="所在楼层" />
<el-table-column prop="area" label="所在区域" />
<el-table-column prop="bookshelf" label="所在架位" />
<el-table-column prop="library" label="所属馆藏" />
<el-table-column prop="actualShelfId" label="所在架位" />
<el-table-column prop="actualLocation" label="所属馆藏" />
<el-table-column prop="createTime" label="创建日期" :show-overflow-tooltip="true">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
@ -138,7 +155,7 @@
<div ref="printDiv" style="display: none;">
<div v-for="item in selectedRows" :key="item.barcode" style="page-break-after:always; margin-top: 8px; margin-left: 20px;">
<div>
<img :src="item.barcode | creatBarCode(item.barcode, item.title)" style="border: 1px solid #000; width: 160px;">
<img :src="item.barcode | creatBarCode(item.barcode, item.collectionName)" style="border: 1px solid #000; width: 160px;">
</div>
</div>
</div>
@ -147,10 +164,13 @@
</template>
<script>
import crudMenu from '@/api/system/menu'
import crudCollBook from '@/api/collectionBook/index'
import { FetchRegionTree } from '@/api/deviceVI/index'
import { FetchBookBasiceByISBN } from '@/api/book/index'
import { FetchShelfGridAllByShelfId } from '@/api/shelf/index'
import { FetchCollectionLocationAll, FetchCreateBarcode } from '@/api/bookBasice/index'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import Treeselect from '@riophae/vue-treeselect'
@ -161,13 +181,12 @@ import qs from 'qs'
import { mapGetters } from 'vuex'
import JsBarcode from 'jsbarcode'
const defaultForm = { id: null, title: null, author: null, isbn: null, code: null, publish: null, cover: null }
const defaultForm = { id: null, title: null, sortmark: null, isbn: null, barcode: null, collectionName: null, actualLocation: null, actualShelfId: null }
export default {
name: 'Collection',
components: { crudOperation, rrOperation, pagination, Treeselect },
components: { crudOperation, pagination, Treeselect },
filters: {
creatBarCode(barCodeData, codePrintData, barCodeText) {
// console.log('')
console.log('codePrintData', codePrintData)
console.log('barCodeText', barCodeText)
const canvas = document.createElement('canvas')
@ -189,7 +208,7 @@ export default {
}
},
cruds() {
return CRUD({ title: '图书馆藏', url: 'api/bookBasice/initBookDetailsList', crudMethod: { ...crudMenu },
return CRUD({ title: '图书馆藏', url: 'api/bookBasice/initBookDetailsList', crudMethod: { ...crudCollBook },
optShow: {
add: true,
edit: true,
@ -204,13 +223,13 @@ export default {
data() {
return {
keyWord: null,
optionVal: 'brcode',
optionVal: 'barcode',
bookshelfNum: [],
levelNumber: 0,
levelNumber: 4,
librarysOptions: [],
options: [
{ value: 'brcode', label: '条码' },
{ value: 'username', label: '题名/著者/出版社' },
{ value: 'barcode', label: '条码' },
{ value: 'search', label: '题名/著者/出版社' },
{ value: 'isbn', label: 'ISBN' }
],
permission: {
@ -219,26 +238,32 @@ export default {
del: ['admin', 'collection:del']
},
enabledTypeOptions: [
{ key: '1', display_name: '在架' },
{ key: '0', display_name: '不在架' }
{ key: 1, display_name: '在架' },
{ key: 0, display_name: '不在架' }
],
imageUrl: require('@/assets/images/system/default-img.jpg'),
rules: {
title: [
{ required: true, message: '题名不可为空', trigger: 'blur' }
],
library: [
collectionName: [
{ required: true, message: '馆藏地不可为空', trigger: 'blur' }
],
isbn: [
{ required: true, message: 'ISBN不可为空', trigger: 'blur' }
],
brcode: [
barcode: [
{ required: true, message: '条码不可为空', trigger: 'blur' }
],
sortmark: [
{ required: true, message: '索书号不可为空', trigger: 'blur' }
]
},
selectedRows: [],
isAutoBrcode: false
isAutoBrcode: false,
regionTreeData: [],
selectShelfVal: null,
girdData: []
}
},
computed: {
@ -247,10 +272,82 @@ export default {
])
},
methods: {
// vue-treeSelectunknown
getAutoNameUnknown(name) {
if (name.lastIndexOf('unknown') > -1) {
return name.split('(')[0]
} else {
return name
}
},
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.label,
children: node.children,
isDisabled: !node.shelfId
}
},
normalizerGird(node) {
return {
id: node.gridCode,
label: node.gridName
}
},
transformData(data) {
return {
id: data.fondsId,
fondsId: data.fondsId,
label: data.fondsName,
children: data.floors.map(floor => ({
id: floor.id,
floorId: floor.id,
label: floor.floorName,
children: floor.regions.map(region => ({
id: region.id,
regionId: region.id,
label: region.regionName,
parentFloorId: floor.id,
children: region.bookShelf.map(shelfItem => ({
id: shelfItem.shelfId,
shelfId: shelfItem.shelfId,
label: shelfItem.shelfName,
parentRegionId: region.id
}))
}))
}))
}
},
treeSelectInput(value) {
console.log(value)
this.selectShelfVal = value.id
this.crud.form.actualLocation = null
this.getShelfGridAllByShelfId()
},
gridSelectInput(value) {
console.log(value)
},
getShelfGridAllByShelfId() {
const params = {
'shelfId': this.selectShelfVal
}
FetchShelfGridAllByShelfId(params).then(res => {
this.girdData = res
}).catch(() => {
})
},
[CRUD.HOOK.beforeRefresh]() {
},
//
[CRUD.HOOK.afterToCU](crud, form) {
FetchRegionTree().then(res => {
this.regionTreeData = [this.transformData(res)]
}).catch(() => {
})
this.getCollectionLocationAll()
},
//
[CRUD.HOOK.beforeToAdd]() {
@ -260,8 +357,11 @@ export default {
},
//
[CRUD.HOOK.afterValidateCU](crud) {
// 9787020015016
// idisbnsortmarkbarcode actualLocation gridCodeactualShelfId id id collectionName
console.log(crud.form)
return false
delete crud.form.title
return true
},
searchChange(val) {
if (val) {
@ -273,9 +373,25 @@ export default {
})
}
},
resetQuery() {
this.keyWord = ''
this.crud.query[this.optionVal] = this.keyWord
// this.status = null
this.crud.toQuery()
},
toIsbnSearch() {
if (this.form.isbn) {
console.log(this.form.isbn)
FetchBookBasiceByISBN({ 'isbn': this.form.isbn }).then(res => {
console.log(res)
if (res) {
this.crud.form.title = res.title
this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + res.bookCover
} else {
this.crud.form.title = null
this.imageUrl = require('@/assets/images/system/default-img.jpg')
}
})
} else {
this.$refs.form.validateField(['isbn'], err => {
if (err) {
@ -286,10 +402,15 @@ export default {
},
autoBrcode() {
this.isAutoBrcode = true
setTimeout(() => {
FetchCreateBarcode().then(res => {
console.log(res)
if (res) {
this.crud.form.barcode = res
} else {
this.crud.form.barcode = null
}
this.isAutoBrcode = false
}, 5000)
})
},
changeLibrarysValue(value) {
// this.depts = []
@ -303,41 +424,15 @@ export default {
// 'fondsName': obj.fondsName,
// 'status': 1
// }
this.getLirarys()
},
getLirarys(params) {
// crudDept.getDepts(params).then(res => {
// this.depts = res.content.map(function(obj) {
// if (obj.sonNum !== 0) {
// obj.hasChildren = true
// } else {
// obj.hasChildren = false
// }
// if (obj.hasChildren) {
// obj.children = null
// }
// return obj
// })
// })
},
// vue-treeSelectunknown
getAutoNameUnknown(name) {
if (name.lastIndexOf('unknown') > -1) {
return name.split('(')[0]
} else {
return name
}
},
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.deptsId,
label: node.deptsName,
children: node.children
}
getCollectionLocationAll() {
FetchCollectionLocationAll().then(res => {
console.log(res)
this.librarysOptions = res
})
},
//
loadDepts({ action, parentNode, callback }) {
if (action === LOAD_CHILDREN_OPTIONS) {
@ -463,7 +558,7 @@ export default {
justify-content: flex-start;
}
.brcode-input{
.barcode-input{
::v-deep .el-form-item__content{
position: relative;
}
@ -503,4 +598,15 @@ export default {
height: 120px;
}
}
.collection-tree-select{
display: flex;
justify-content: space-between;
margin-right: 0 !important;
::v-deep .el-form-item__content{
display: flex;
justify-content: flex-start;
width: 606px !important;
}
}
</style>

438
src/views/visualCheck/checkManage/bookSearch/index.vue

@ -1,16 +1,448 @@
<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 statusOptions" :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:right>
<el-button size="mini" :disabled="crud.selections.length === 0" @click="handleBatchListing">
<i class="iconfont icon-ruku" />
批量上架
</el-button>
<el-button size="mini" :loading="crud.downloadLoading" :disabled="crud.selections.length === 0" @click="handleRemoveShelf(crud.selections)">
<i class="iconfont icon-chuku" />
一键下架
</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 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 label="状态" align="center" prop="deptsStatus">
<!-- slot-scope="scope" -->
<template>
<span class="row-state row-warehousing">未知</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-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>
<!--分页组件-->
<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="handleCloseDialog" :visible="addBookShelfVisible" title="批量上架">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<div class="dialog-batch-listing">
<div class="batch-left">
<h5>已选图书</h5>
<ul class="left-book-list">
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
<li>条码号图书题名1</li>
</ul>
</div>
<div class="batch-right">
<h5>选择上架位置</h5>
<el-form ref="form" :rules="rules" :model="form" size="small" label-width="30px">
<el-form-item prop="floorId">
<el-select v-model="form.floorId" placeholder="选择楼层" style="width: 280px;" @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 prop="regionId">
<el-select v-model="form.regionId" placeholder="选择区域" style="width: 280px;" @change="changeRegionValue($event)">
<el-option
v-for="(item,index) in regionOptions"
:key="index"
:label="item.regionName"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item prop="shelfId">
<el-select v-model="form.shelfId" placeholder="选择书架" style="width: 280px;" @change="changeShelfValue($event)">
<el-option
v-for="(item,index) in shelfOptions"
:key="index"
:label="item.shelfName"
:value="item.shelfId"
/>
</el-select>
</el-form-item>
<el-form-item prop="girdId">
<el-select v-model="form.girdId" placeholder="选择层位" style="width: 280px;" @change="changeGirdValue($event)">
<el-option
v-for="(item,index) in girdOptions"
:key="index"
:label="item.gridName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-form>
</div>
</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 class="detailBook" append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="handleCloseDialog" :visible="detailVisible" 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="changeDetailTab(0)">基础信息</li>
<li :class="{'active-tab-nav': tabIndex === 1}" @click="changeDetailTab(1)">盘点信息</li>
</ul>
<ul v-if="tabIndex===0" class="book-detail">
<li><span>题名</span>三国演义</li>
<li><span>著者</span>罗贯中</li>
<li><span>出版社</span>人民出版社</li>
<li><span>索书号</span>I247.57/454:2</li>
<li><span>ISBN</span>95431578551345</li>
<li><span>条码号</span>54898789124454</li>
<li><span>馆藏地</span>机构-楼层-馆藏地名称</li>
<li class="book-img"><img :src="imageUrl" :onerror="defaultImg" alt=""></li>
</ul>
<ul v-if="tabIndex===1" class="book-detail book-other">
<li>
<span>状态</span>
<i class="row-state no-state">未知</i>
<!-- <i class="row-state end-state">在架</i>
<i class="row-state cancel-state">错架</i>
<i class="row-state ing-state">错序</i> -->
</li>
<li><span>当前位置</span>一楼-区域A-001排A面01架1层</li>
<li><span>应在位置</span>一楼-区域A-001排A面01架1层</li>
<li><span>更新时间</span>2024-12-05 15:14</li>
</ul>
</div>
<div slot="footer" class="dialog-footer">
<el-button :loading="crud.status.cu === 2" type="primary" @click="detailVisible=false">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { FetchLibraryFloorListAll } from '@/api/floor/index'
import { FetchRegionAllByFloor } from '@/api/area/index'
import { FetchShelfAllByRegionId, FetchShelfGridAllByShelfId } from '@/api/shelf/index'
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 defaultImg from '@/assets/images/system/default-img.jpg'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, floorId: null, regionId: null, shelfId: null, girdId: null }
export default {
name: 'BookSearch',
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: true
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
statusOptions: [
{ key: '1', display_name: '在架' },
{ key: '2', display_name: '错架' },
{ key: '3', display_name: '错序' },
{ key: '4', display_name: '未知' }
],
permission: {
add: ['admin', 'search:add'],
edit: ['admin', 'search:edit'],
del: ['admin', 'search:del']
},
addBookShelfVisible: false,
detailVisible: false,
floorOptions: [],
regionOptions: [],
shelfOptions: [],
girdOptions: [],
rules: {
floorId: [
{ required: true, message: '请选择楼层', trigger: 'change' }
],
regionId: [
{ required: true, message: '请选择区域', trigger: 'change' }
],
shelfId: [
{ required: true, message: '请选择架位', trigger: 'change' }
],
girdId: [
{ required: true, message: '请选择层位', trigger: 'change' }
]
},
tabIndex: 0,
imageUrl: defaultImg
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
created() {
this.getLibraryFloorListAll()
},
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
},
changeDetailTab(index) {
this.tabIndex = index
},
//
getLibraryFloorListAll() {
FetchLibraryFloorListAll().then(res => {
this.floorOptions = res
}).catch(() => {
})
},
changeFloorValue(value) {
console.log(value)
this.crud.form.regionId = null
this.crud.form.shelfId = null
this.crud.form.girdId = null
this.shelfOptions = []
this.girdOptions = []
const params = {
'floorId': value
}
FetchRegionAllByFloor(params).then(res => {
this.regionOptions = res
}).catch(() => {
})
},
changeRegionValue(value) {
console.log(value)
this.crud.form.shelfId = null
this.crud.form.girdId = null
this.girdOptions = []
const params = {
'regionId': value
}
FetchShelfAllByRegionId(params).then(res => {
this.shelfOptions = res
}).catch(() => {
})
},
changeShelfValue(value) {
console.log(value)
this.crud.form.girdId = null
const params = {
'shelfId': value
}
FetchShelfGridAllByShelfId(params).then(res => {
this.girdOptions = res
}).catch(() => {
})
},
changeGirdValue(value) {
console.log(value)
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
handleDbClick(row) {
this.detailVisible = true
},
handleBatchListing() {
this.addBookShelfVisible = true
},
handleRemoveShelf(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(() => {
this.crud.downloadLoading = false
})
},
handleCloseDialog() {
this.addBookShelfVisible = false
this.detailVisible = false
if (this.$refs.form) {
this.crud.cancelCU()
this.$refs.form.resetFields()
}
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.dialog-batch-listing{
display: flex;
justify-content: space-between;
border: 1px solid #E6E8ED;
.batch-left{
width: calc(100%/2);
border-right: 1px solid #E6E8ED;
.left-book-list{
height: 400px;
padding: 10px 0;
overflow: hidden;
overflow-y: scroll;
li{
padding: 0 10px;
line-height: 40px;
border-bottom: 1px solid #E6E8ED;
}
}
}
.batch-right{
width: calc(100%/2);
.el-form{
padding-top: 20px
}
}
h5{
height: 40px;
line-height: 40px;
font-size: 14px;
text-align: center;
background-color: #F5F9FC;
color: #0C0E1E;
}
}
.detailBook {
::v-deep .el-dialog .el-dialog__body{
padding: 0 0 30px 0;
}
.book-detail{
position: relative;
padding: 20px 30px;
background-color: #F6F8FC;
li{
line-height: 40px;
span{
display: inline-block;
width: 60px;
text-align: right;
margin-right: 20px;
color: #0C0E1E;
}
}
.book-img{
position: absolute;
right: 20px;
top: 20px;
height: 140px;
img{
display: block;
height: 100%;
}
}
}
.book-other{
li{
span{
width: 80px;
}
i{
font-style: normal;
padding: 0 8px;
}
}
}
}
</style>

240
src/views/visualCheck/checkManage/bookshelfSearch/index.vue

@ -1,16 +1,248 @@
<template>
<div class="app-container">
图架检索
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.floorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 100px" @change="changeFloorValue">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in floorOptions" :key="item.key" :label="item.floorName" :value="item.id" />
</el-select>
<el-select v-model="query.regionId" clearable size="small" placeholder="区域" class="filter-item" style="width: 180px" @change="crud.toQuery">
<i slot="prefix" class="iconfont icon-zhuangtai" />
<el-option v-for="item in regionOptions" :key="item.key" :label="item.regionName" :value="item.id" />
</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:right>
<el-button size="mini" :loading="crud.downloadLoading" :disabled="crud.selections.length === 0" @click="handleRemoveShelf(crud.selections)">
<i class="iconfont icon-chuku" />
一键下架
</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"
>
<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="盘点开关" align="center">
<!-- slot-scope="scope" -->
<template>
<span class="row-state row-binding state-active">盘点开启</span>
<!-- <span class="row-state row-lending state-active">盘点关闭</span> -->
</template>
</el-table-column>
<el-table-column prop="booksheflCount" label="有序检查" align="center">
<!-- slot-scope="scope" -->
<template>
<span class="row-state row-binding state-active"></span>
<!-- <span class="row-state row-lending state-active"></span> -->
</template>
</el-table-column>
<el-table-column prop="booksheflCount" label="索书号范围" />
<el-table-column prop="deptsStatus" label="盘点概况" min-width="340">
<!-- slot-scope="scope" -->
<template>
<ul class="tag-list">
<li class="blue-tag"><p>错序</p><span><em>1</em><i class="iconfont icon-biaoqian" /></span></li>
<li class="yellow-tag"><p>错架</p><span><em>2</em><i class="iconfont icon-biaoqian" /></span></li>
<li class="green-tag"><p>在架</p><span><em>33</em><i class="iconfont icon-biaoqian" /></span></li>
</ul>
<!-- <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-column prop="createTime" label="操作">
<!-- slot-scope="scope" -->
<template>
<el-button>定位</el-button>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination v-if="crud.data.length!==0" />
</div>
</div>
</template>
<script>
import { FetchLibraryFloorListAll } from '@/api/floor/index'
import { FetchRegionAllByFloor } from '@/api/area/index'
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, 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'
export default {
name: 'BookshelfSearch',
name: 'BookSearch',
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: true
}})
},
mixins: [presenter(), header(), crud()],
data() {
return {
permission: {
add: ['admin', 'search:add'],
edit: ['admin', 'search:edit'],
del: ['admin', 'search:del']
},
floorOptions: [],
regionOptions: []
}
},
computed: {
...mapGetters([
'user',
'baseApi'
])
},
created() {
this.getLibraryFloorListAll()
},
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
},
//
getLibraryFloorListAll() {
FetchLibraryFloorListAll().then(res => {
this.floorOptions = res
}).catch(() => {
})
},
changeFloorValue(value) {
console.log(value)
this.crud.query.regionId = null
const params = {
'floorId': value
}
FetchRegionAllByFloor(params).then(res => {
this.regionOptions = res
}).catch(() => {
})
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
handleRemoveShelf(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(() => {
this.crud.downloadLoading = false
})
},
handleCloseDialog() {
this.addBookShelfVisible = false
this.detailVisible = false
if (this.$refs.form) {
this.crud.cancelCU()
this.$refs.form.resetFields()
}
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.tag-list{
display: flex;
justify-content: flex-start;
li{
display: flex;
justify-content: flex-start;
align-items: center;
margin-right: 10px;
p{
font-weight: bold;
}
span{
display: flex;
justify-content: flex-start;
align-items: center;
font-size: 18px;
}
i{
font-size: 22px;
}
em{
display: inline-block;
font-style: normal;
font-weight: bold;
margin-right: 4px
}
}
.blue-tag{
i,em{
color: #0348F3;
}
}
.yellow-tag{
i,em{
color: #FF8329;
}
}
.green-tag{
i,em{
color: #2ECAAC;
}
}
}
</style>

151
src/views/visualCheck/checkManage/index.vue

@ -1,16 +1,159 @@
<template>
<div>
<router-view />
<div class="app-container row-container">
<div class="head-container">
<div class="head-search">
<!-- 搜索 -->
<el-select v-model="query.type" 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-select v-model="query.other" 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 otherOptions" :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:right>
<el-button :loading="crud.downloadLoading" size="mini" @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="590"
@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="booksheflCount" 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>
<!--分页组件-->
<pagination v-if="crud.data.length!==0" />
</div>
</div>
</template>
<script>
import crudRegion from '@/api/area/index'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import rrOperation from '@crud/RR.operation'
import pagination from '@crud/Pagination'
import { mapGetters } from 'vuex'
// import { exportFile } from '@/utils/index'
// import qs from 'qs'
const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null }
export default {
name: 'CheckManage',
name: 'UpDownLog',
components: { crudOperation, rrOperation, pagination },
cruds() {
return CRUD({ title: '上架/下架日志', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
add: false,
edit: false,
del: false,
download: false,
group: false,
reset: false
}})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
otherOptions: [
{ key: '1', display_name: '自动' },
{ key: '2', display_name: '手动' }
],
typeOptions: [
{ key: '1', display_name: '上架' },
{ key: '2', display_name: '下架' }
],
permission: {
add: ['admin', 'checkLog:add'],
edit: ['admin', 'checkLog:edit'],
del: ['admin', 'checkLog:del']
}
}
},
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)
},
doExport(data) {
console.log(data)
this.crud.downloadLoading = true
this.$confirm('此操作将导出所选数据' + '<span>你是否还要继续?</span>', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
dangerouslyUseHTMLString: true
}).then(() => {
const ids = []
data.forEach(val => {
ids.push(val.deptsId)
})
const params = {
'deptsIds': ids
}
console.log(params)
// exportFile(this.baseApi + '/api/depts/download?' + qs.stringify(params, { indices: false }))
// this.crud.downloadLoading = false
}).catch(() => {
})
},
handleCloseDialog() {
}
}
}
</script>
<style scoped>
<style lang="scss" scoped>
</style>

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

@ -1,63 +1,37 @@
<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 class="statistic-shelf">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>架满列表上架率 100% - 80%</span>
</div>
<div v-for="(item,index) in leftData" :key="index" class="statistic-item">
<span class="statistic-item-name">{{ item.girdName }}</span>
<el-progress :percentage="item.percentage" :stroke-width="36" :color="customColorMethod" />
</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>架空列表上架率 0% - 50%</span>
</div>
<div v-for="(item,index) in rightData" :key="index" class="statistic-item">
<span class="statistic-item-name">{{ item.girdName }}</span>
<el-progress :percentage="item.percentage" :stroke-width="36" :color="customColorMethod" />
</div>
</el-card>
</div>
</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 },
components: { Search },
mixins: [presenter(), crud()],
cruds() {
return CRUD({
@ -75,16 +49,26 @@ export default {
},
props: {
isCenter: {
type: Boolean,
default: false
}
},
data() {
return {
isLogType: 'operate',
selections: [],
heightStyle: 'calc(100vh - 396px)'
leftData: [
{ id: 0, percentage: 100, girdName: '一楼区域A001排01架1层' },
{ id: 0, percentage: 100, girdName: '一楼区域A001排01架1层' },
{ id: 1, percentage: 90, girdName: '一楼区域A001排01架1层' },
{ id: 2, percentage: 80, girdName: '一楼区域A001排01架1层' },
{ id: 3, percentage: 70, girdName: '一楼区域A001排01架1层' },
{ id: 3, percentage: 60, girdName: '一楼区域A001排01架1层' }
],
rightData: [
{ id: 0, percentage: 0, girdName: '一楼区域A001排01架1层' },
{ id: 1, percentage: 0, girdName: '一楼区域A001排01架1层' },
{ id: 2, percentage: 10, girdName: '一楼区域A001排01架1层' },
{ id: 3, percentage: 20, girdName: '一楼区域A001排01架1层' },
{ id: 4, percentage: 22, girdName: '一楼区域A001排01架1层' },
{ id: 5, percentage: 50, girdName: '一楼区域A001排01架1层' }
]
}
},
computed: {
@ -93,13 +77,6 @@ export default {
])
},
mounted() {
this.$nextTick(() => {
if (this.isCenter) {
this.heightStyle = 'calc(100vh - 470px)'
} else {
this.heightStyle = 'calc(100vh - 396px)'
}
})
},
methods: {
[CRUD.HOOK.beforeRefresh]() {
@ -109,37 +86,73 @@ export default {
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(() => {
})
customColorMethod(percentage) {
if (percentage === 0) {
return ''
} else if (percentage <= 50) {
return '#5cb87a'
} else if (percentage <= 80) {
return '#FFCA28'
} else if (percentage >= 90 && percentage !== 100) {
return '#FFA000'
} else if (percentage === 100) {
return '#f56c6c'
}
}
}
}
</script>
<style lang="scss" scoped>
.operateLog-main{
height: calc(100vh - 236px);
.statistic-shelf{
display: flex;
justify-content: space-between;
height: calc(100vh - 284px);
.box-card{
width: calc(100% / 2);
height: 100%;
&:first-child{
margin-right: 40px;
}
}
.statistic-item{
position: relative;
margin-bottom: 20px;
.statistic-item-name{
position: absolute;
left: 10px;
top: 0;
height: 36px;
line-height: 36px;
font-size: 12px;
color: #0C0E1E;
z-index: 9999;
}
}
}
::v-deep .el-card__header{
font-weight: bold;
color: #0C0E1E;
background-color: #EEF5FE;
}
::v-deep .el-card__body{
padding: 20px;
height: calc(100% - 68px);
overflow: hidden;
overflow-y: scroll;
}
::v-deep .el-progress-bar__outer{
border-radius: 6px !important;
}
::v-deep .el-progress-bar__inner{
border-radius: 0 !important;
}
::v-deep .el-progress-bar__innerText {
color: #0C0E1E;
}
::v-deep .el-pagination{
margin: 24px 0 10px 0 !important
::v-deep .el-progress__text{
color: #0C0E1E;
font-size: 13px !important;
margin-left: 20px !important;
}
</style>

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

@ -9,7 +9,7 @@
</div>
<crudOperation>
<template v-slot:right>
<el-button :loading="crud.downloadLoading" size="mini" :disabled="crud.selections.length === 0" @click="doExport(crud.selections)">
<el-button :loading="crud.downloadLoading" size="mini" @click="doExport(crud.selections)">
<i class="iconfont icon-daochu" />
导出
</el-button>

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

@ -9,7 +9,7 @@
<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-select v-model="setfloorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 80px" @change="crud.toQuery">
<el-option v-for="item in floorOptions" :key="item.id" :label="item.floorName" :value="item.id" />
</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" />
@ -76,6 +76,7 @@
<canvas id="canvasPreview" :width="width" :height="height" />
</div>
<img v-if="currentMarkData && !currentMarkData.signPoint" :src="imageUrl" :onerror="defaultImg" alt="">
<img v-if="!currentMarkData" :src="imageUrl" :onerror="defaultImg" alt="">
</div>
<div v-if="activeIndex == 1" class="venue-preview">
<img :src="imageRegionUrl" :onerror="defaultImg" alt="">
@ -180,6 +181,7 @@ export default {
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
setfloorId: null,
floorOptions: [],
labelName: '区域地图',
permission: {
@ -239,20 +241,23 @@ export default {
}
},
[CRUD.HOOK.beforeRefresh]() {
const formFloor = JSON.parse(localStorage.getItem('formFloor'))
if (formFloor) {
this.crud.query.floorId = formFloor.id
} else {
this.crud.query.floorId = null
}
this.getLibraryFloorListAll()
console.log('this.setfloorId', this.setfloorId)
this.crud.query.floorId = this.setfloorId
// const formFloor = JSON.parse(localStorage.getItem('formFloor'))
// if (formFloor) {
// this.crud.query.floorId = formFloor.id
// } else {
// this.crud.query.floorId = null
// }
},
[CRUD.HOOK.afterRefresh](crud) {
console.log('crud.data', crud.data)
if (crud.data.length !== 0) {
this.clickRowHandler(crud.data[0])
this.activeIndex = 0
} else {
this.currentMarkData = null
this.imageUrl = this.defaultImg
this.imageRegionUrl = this.defaultImg
}

Loading…
Cancel
Save