Browse Source

表单优化/统计数据

master
xuhuajiao 2 weeks ago
parent
commit
6ed314b393
  1. 42
      src/api/statistics/statistics.js
  2. 1
      src/views/archiveUtilize/archiveSearch/index.vue
  3. 33
      src/views/archiveUtilize/archiveSearch/module/resultList.vue
  4. 302
      src/views/archivesStatistics/annualReportStatistics/index.vue
  5. 2
      src/views/archivesStatistics/borrowingStatistics/index.vue
  6. 396
      src/views/archivesStatistics/dataStatistics/index.vue
  7. 169
      src/views/archivesStatistics/roomCollectionStatistics/index.vue
  8. 156
      src/views/archivesStatistics/usageCountStatistics/index.vue
  9. 156
      src/views/archivesStatistics/utilizeRegistrationStatistics/index.vue
  10. 102
      src/views/components/category/PreviewForm.vue

42
src/api/statistics/statistics.js

@ -0,0 +1,42 @@
import request from '@/utils/request'
import qs from 'qs'
// 总量统计
// fondsIds=1&fondsIds=2&fondsIds=3&fondsIds=4&years=2024&years=2025&years=2026
export function FetchTotalStatistics(params) {
return request({
url: 'api/control/getTotalStatistics' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 管理库档案年度
export function FetchArchivedAllYear(params) {
return request({
url: 'api/control/getArchivedAllYear' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 室藏统计
export function FetchRoomCollectionStatistics(params) {
return request({
url: 'api/control/getRoomCollectionStatistics' + '?' + qs.stringify(params, { indices: false }),
method: 'get'
})
}
// 删除AI辅助著录
// export function FetchDelAssistEnter(data) {
// return request({
// url: 'api/ai/delAssistEnter',
// method: 'post',
// data
// })
// }
export default {
FetchTotalStatistics,
FetchArchivedAllYear,
FetchRoomCollectionStatistics
}

1
src/views/archiveUtilize/archiveSearch/index.vue

@ -366,6 +366,7 @@ export default {
if (wheresql) {
this.isResult = true
this.$nextTick(() => {
this.$refs.resultListRef.conditionData = this.conditionData
this.$refs.resultListRef.condition = wheresql
this.$refs.resultListRef.getSeniorSearch(wheresql)
})

33
src/views/archiveUtilize/archiveSearch/module/resultList.vue

@ -105,7 +105,7 @@
</div>
<div class="search-tip">
<div v-if="isCommon">检索 <span>{{ keywords }}</span> 成功获得<i>{{ page.total }}</i>条结果</div>
<div v-else>检索成功获得<i>{{ page.total }}</i>条结果<p>高级检索 点击查看检索条件</p></div>
<div v-else>检索成功获得<i>{{ page.total }}</i>条结果<p style="font-size: 12px; cursor: pointer; color: #409EFF;" @click="returnAdvanced">高级检索: {{ advancedSearchDisplayText }}</p></div>
</div>
</div>
<div v-loading="resultLoading">
@ -259,13 +259,40 @@ export default {
resultData: [],
classifyLoading: false,
resultLoading: false,
condition: ''
condition: '',
conditionData: []
}
},
computed: {
...mapGetters([
'user'
])
]),
//
advancedSearchDisplayText() {
if (!this.conditionData || this.conditionData.length === 0) {
return ''
}
// condition
return this.conditionData.map(item => {
if (item.field) {
//
let keywordDisplay = item.keyWord
if (item.symbol === '包含' || item.symbol === '不包含') {
keywordDisplay = `'%${item.keyWord}%'`
} else if (item.keyWord && isNaN(parseInt(item.keyWord))) {
keywordDisplay = `'${item.keyWord}'`
}
return `${item.field} ${item.symbol} ${keywordDisplay}`
} else if (item.connector) {
//
return item.connector
} else if (item.bracket) {
//
return item.bracket
}
return ''
}).join(' ')
}
},
watch: {
filterFondsText(val) {

302
src/views/archivesStatistics/annualReportStatistics/index.vue

@ -1,302 +0,0 @@
<template>
<div class="app-container">
<div class="container-main">
<div class="elect-cont-left">
<div class="head-container">
<el-select v-model="form.fondsId" placeholder="请选择" style="width: 225px;" @change="changeFondsValue($event)">
<el-option
v-for="(item,index) in fondsOptions"
:key="index"
:label="item.fondsName"
:value="item.id"
/>
</el-select>
</div>
<div class="container-left">
<span class="right-top-line" />
<span class="left-bottom-line" />
<ul class="left-annual-type">
<li class="active">本单位填报6</li>
<li>下级上报0</li>
<li>汇总上报0</li>
</ul>
</div>
</div>
<div class="elect-cont-right">
<div class="head-container" style="position: relative;">
<crudOperation :permission="permission">
<template v-slot:middle>
<el-button slot="reference" size="mini" :loading="crud.delAllLoading" :disabled="crud.selections.length === 0" @click="toDelete(crud.selections)">
<i class="iconfont icon-shanchu" />
删除
</el-button>
</template>
</crudOperation>
<div class="double-click-btn" style="top: 3px;"><i class="iconfont icon-zhuyi-lan" /><span>双击列表数据查看年报详情</span></div>
</div>
<div class="container-right">
<span class="right-top-line" />
<span class="left-bottom-line" />
<el-table
ref="table"
v-loading="loading"
class="archives-table"
:data="tableData"
@selection-change="crud.selectionChangeHandler"
@row-click="clickRowHandler"
@row-dblclick="handleDbClick"
>
<el-table-column type="selection" align="center" width="55" />
<el-table-column label="年度" prop="year" />
<el-table-column label="统计模板" prop="template" min-width="150px" />
<el-table-column label="填报单位" prop="unit" />
<el-table-column label="创建人" prop="creator" />
<el-table-column prop="create_time" label="创建日期">
<template slot-scope="scope">
<div>{{ scope.row.create_time | parseTime }}</div>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" />
<el-table-column label="状态" prop="status" align="center">
<template slot-scope="scope">
<!-- <div>{{ scope.row.status === 0 ? '录入中' : '已汇总' }}</div> -->
<span v-if="scope.row.status === 0" class="row-state row-physical state-active">录入中</span>
<span v-else class="row-state row-binding state-active">已汇总</span>
</template>
</el-table-column>
<!-- <el-table-column label="操作" align="center" prop="deptsStatus" /> -->
</el-table>
<!--分页组件-->
<!-- <pagination v-if="crud.data.length!==0" /> -->
</div>
</div>
</div>
<el-dialog append-to-body :close-on-click-modal="false" :before-close="handleCloseDialog" :visible.sync="detailVisible" title="详情">
<div class="setting-dialog">
<ul class="annual-dialog-detail">
<li class="detail-item">
<div class="detail-item-left">年度</div>
<div class="detail-item-right">{{ detailContent && detailContent.year }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">年报模板</div>
<div class="detail-item-right">2019</div>
</li>
<li class="detail-item">
<div class="detail-item-left">填报单位</div>
<div class="detail-item-right">{{ detailContent && detailContent.unit }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">报表模板</div>
<div class="detail-item-right">{{ detailContent && detailContent.template }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">填报人</div>
<div class="detail-item-right">{{ detailContent && detailContent.creator }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">上报至</div>
<div class="detail-item-right">{{ detailContent && detailContent.upToUint }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">上报日期</div>
<div class="detail-item-right">{{ detailContent && detailContent.upToDate | parseTime }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">备注</div>
<div class="detail-item-right">{{ detailContent && detailContent.remark }}</div>
</li>
<li class="detail-item">
<div class="detail-item-left">附件列表</div>
<div class="detail-item-right" />
</li>
</ul>
<div slot="footer" class="dialog-footer">
<!-- <router-link to="/local-html">跳转到本地HTML文件</router-link> -->
<el-button type="primary" @click="goToHtml">报表详情</el-button>
<!-- <el-button type="text" @click="detailVisible=false">确定</el-button> -->
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import crudDept from '@/api/system/dept'
import { FetchFondsAll } from '@/api/system/fonds'
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
const defaultForm = { id: null, fondsId: null }
const data = [
{
'year': 2024,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '',
'upToDate': null
},
{
'year': 2023,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '武汉飞天智能',
'upToDate': '1706078799000'
},
{
'year': 2022,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '',
'upToDate': null
},
{
'year': 2021,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '',
'upToDate': null
},
{
'year': 2020,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '',
'upToDate': null
},
{
'year': 2019,
'template': '《档案室基本情况表》(2019版)',
'unit': '武汉飞天智能',
'creator': '系统管理员',
'create_time': '1706078799000',
'status': 1,
'remark': '',
'upToUint': '',
'upToDate': null
}
]
export default {
name: 'AnnualReportStatistics',
components: { crudOperation },
cruds() {
return CRUD({ title: '年报统计', idField: 'deptsId', url: 'api/depts/initDeptsList', crudMethod: { ...crudDept }, optShow: {
add: false,
edit: false,
del: false,
reset: false,
download: false,
group: false
},
queryOnPresenterCreated: false
})
},
mixins: [presenter(), header(), form(defaultForm), crud()],
data() {
return {
permission: {},
fondsOptions: [],
form: {
'fondsId': null
},
loading: false,
tableData: data,
detailVisible: false,
detailContent: {}
}
},
mounted() {
this.getFondsDatas()
},
methods: {
getFondsDatas() {
FetchFondsAll().then(res => {
this.fondsOptions = res
if (this.fondsOptions.length > 0) {
this.form.fondsId = this.fondsOptions[0].id
}
})
},
changeFondsValue(value) {
const obj = this.fondsOptions.find(function(item) {
return item.id === value
})
console.log('obj', obj)
},
clickRowHandler(row) {
this.$refs.table.clearSelection()
this.$refs.table.toggleRowSelection(row)
},
handleDbClick(row) {
this.detailVisible = true
this.detailContent = row
},
handleCloseDialog() {
this.detailVisible = false
},
goToHtml() {
// 'test.html' public HTML
// window.location.href = 'report/annual.htm'
window.open('report/annual.htm', '_blank')
}
}
}
</script>
<style lang="scss" scoped>
.left-annual-type{
// padding: 20px 0;
line-height: 36px;
font-size: 14px;
color: #0c0e1e;
li{
padding: 0 10px;
&:hover,
&.active{
background-color: #e8f2ff;
color: #0348f3;
cursor: default;
}
}
}
.annual-dialog-detail{
.detail-item{
display: flex;
justify-content: flex-start;
line-height: 38px;
font-size: 16px;
.detail-item-left{
width: 120px;
text-align: right;
}
.detail-item-right{
color: #0c0e1e;
}
}
}
</style>

2
src/views/archivesStatistics/customDefinedStatistics/index.vue → src/views/archivesStatistics/borrowingStatistics/index.vue

@ -60,7 +60,7 @@ import 'katex/dist/katex.min.css'
import markdownText2 from '@/assets/test.md'
export default {
name: 'CustomDefinedStatistics',
name: 'BorrowingStatistics',
components: { },
data() {
return {

396
src/views/archivesStatistics/dataStatistics/index.vue

@ -1,287 +1,157 @@
<template>
<div class="app-container">
<div v-for="(company, companyIndex) in allData" :key="'company-' + companyIndex" class="company-section">
<h3 class="table-header">{{ company.name }}</h3>
<div class="grid-table">
<div class="grid-header">
<div class="grid-header-tr">
<div class="header-row colspan2 rowspan2 th-style">档案门类</div>
</div>
<div class="grid-header-tr">
<div class="header-row th-style">收集整编</div>
<div class="row-cell">
<div class="colspan th-style">回收站</div>
<div class="colspan6 th-style">收集库</div>
</div>
</div>
<div class="grid-header-tr">
<div class="header-row th-style">档案管理</div>
<div class="row-cell">
<div class="colspan th-style">销毁库</div>
<div class="colspan6 th-style">管理库</div>
</div>
</div>
</div>
<div v-for="(row, rowIndex) in company.tableData" :key="'row-' + rowIndex" class="grid-content">
<div class="colspan2 rowspan3"> {{ row.category }} </div>
<div>
<div class="colspan rowspan2"> {{ row.recycle }} </div>
<div class="grid-item placeholder-line" />
</div>
<div>
<div class="grid-item">
<div class="colspan">未归档</div>
<div class="colspan">{{ row.unfiled }}</div>
<div class="colspan">归档中</div>
<div class="colspan">{{ row.collectArchiving }}</div>
</div>
<div class="grid-item">
<div class="colspan">未装盒</div>
<div class="colspan">{{ row.collectPacked }}</div>
<div class="colspan">已装盒</div>
<div class="colspan">{{ row.collectPacked }}</div>
</div>
<div class="grid-item placeholder-line " />
</div>
<div>
<div class="grid-item">
<div class="colspan rowspan2">全部</div>
<div class="colspan rowspan2">{{ row.collectAll }}</div>
</div>
<div class="grid-item placeholder-line placeholder-line-right" />
</div>
<div class="colspan rowspan3"> {{ row.destroy }} </div>
<div>
<div class="grid-item">
<div class="colspan">未装盒</div>
<div class="colspan">{{ row.manageUnpacked }}</div>
<div class="colspan">已装盒</div>
<div class="colspan">{{ row.managePacked }}</div>
</div>
<div class="grid-item">
<div class="colspan">未入库</div>
<div class="colspan">{{ row.manageUnstored }}</div>
<div class="colspan">已入库</div>
<div class="colspan">{{ row.manageStored }}</div>
</div>
<div class="grid-item">
<div class="colspan">空闲中</div>
<div class="colspan">{{ row.manageIdle }}</div>
<div class="colspan">审批中</div>
<div class="colspan">{{ row.manageApproving }}</div>
</div>
</div>
<div class="grid-item">
<div class="colspan rowspan3">全部</div>
<div class="colspan rowspan3">{{ row.collectAll }}</div>
</div>
</div>
</div>
</div>
<div class="app-container row-container">
<div class="connection-header">
<div class="head-search">
<el-select
v-model="fondsIds"
multiple
collapse-tags
placeholder="请选择所属全宗"
style="width: 320px;"
>
<el-option
v-for="item in fondsOptions"
:key="item.id"
:label="item.fondsName"
:value="item.id"
/>
</el-select>
<el-select
v-model="years"
multiple
collapse-tags
placeholder="请选择年份"
style="width: 150px;"
>
<el-option
v-for="item in yearsOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getTotalStatistics">查询</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div>
</div>
<el-table class="archives-table" :data="allData" :summary-method="getSummaries" show-summary border style="width: 100%;">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="categoryName" label="档案门类(国标分类)" align="center" />
<el-table-column prop="archivesCount" label="案卷数(卷)" align="center" />
<el-table-column prop="singleCount" label="卷内件数(件)" align="center" />
<el-table-column prop="fileCount" label="电子原文数量(份)" align="center" />
<el-table-column prop="fileSize" label="电子档案存储容量(GB)" align="center" />
</el-table>
</div>
</template>
<script>
const allData = [
{
name: '武汉飞天智能',
tableData: [
{
category: '文书档案(文件)',
recycle: 4,
unfiled: 0,
collectArchiving: 0,
collectPacked: 1,
collectAll: 5,
destroy: 4,
manageUnpacked: 4,
managePacked: 1,
manageUnstored: 4,
manageStored: 1,
manageIdle: 5,
manageApproving: 0,
manageAll: 5
import { FetchFondsAll } from '@/api/system/fonds'
import { FetchTotalStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics'
export default {
name: 'DataStatistics',
data() {
return {
allData: [],
fondsOptions: [],
fondsIds: [],
yearsOptions: [],
years: []
}
},
{
category: '文书档案(案卷)',
recycle: 4,
unfiled: 0,
collectArchiving: 0,
collectPacked: 1,
collectAll: 5,
destroy: 4,
manageUnpacked: 4,
managePacked: 1,
manageUnstored: 4,
manageStored: 1,
manageIdle: 5,
manageApproving: 0,
manageAll: 5
mounted() {
this.getFondsDatas()
this.getArchivedAllYearDatas()
this.getTotalStatistics()
},
{
category: '互联网项目',
recycle: 4,
unfiled: 0,
collectArchiving: 0,
collectPacked: 1,
collectAll: 5,
destroy: 4,
manageUnpacked: 4,
managePacked: 1,
manageUnstored: 4,
manageStored: 1,
manageIdle: 5,
manageApproving: 0,
manageAll: 5
methods: {
getSummaries(param) {
const { columns, data } = param
const sums = []
console.log('columns', columns)
console.log('data', data)
columns.forEach((column, index) => {
if (index === 1) {
sums[index] = '合计(全库总量)'
return
}
]
const values = data.map(item => Number(item[column.property]))
console.log(values)
if (!values.every(value => isNaN(value))) {
if (column.property === 'fileSize') {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0).toFixed(3)
} else {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0)
}
} else {
sums[index] = '-'
}
})
return sums
},
{
name: '闵行客(武汉)科技',
tableData: [
{
category: '文书档案(文件)',
recycle: 4,
unfiled: 0,
collectArchiving: 0,
collectPacked: 1,
collectAll: 5,
destroy: 4,
manageUnpacked: 4,
managePacked: 1,
manageUnstored: 4,
manageStored: 1,
manageIdle: 5,
manageApproving: 0,
manageAll: 5
resetQuery() {
this.fondsIds = []
this.years = []
this.getTotalStatistics()
},
{
category: '文书档案(案卷)',
recycle: 4,
unfiled: 0,
collectArchiving: 0,
collectPacked: 1,
collectAll: 5,
destroy: 4,
manageUnpacked: 4,
managePacked: 1,
manageUnstored: 4,
manageStored: 1,
manageIdle: 5,
manageApproving: 0,
manageAll: 5
}
]
getFondsDatas() {
FetchFondsAll().then(res => {
this.fondsOptions = res
//
// this.fondsIds = res.map(item => item.id)
// this.checkAndQuery()
})
},
getArchivedAllYearDatas() {
FetchArchivedAllYear().then(res => {
this.yearsOptions = res.map(item => ({
id: item,
name: item
}))
//
// this.years = res.map(item => item)
// this.checkAndQuery()
})
},
checkAndQuery() {
//
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
this.getTotalStatistics()
}
]
export default {
name: 'DataStatistics',
data() {
return {
allData: allData
},
getTotalStatistics() {
FetchTotalStatistics({
fondsIds: this.fondsIds,
years: this.years
}).then(res => {
this.allData = res
})
}
}
}
</script>
<style lang="scss" scoped>
$base-line-height: 30px;
$border-color: #ddd;
$bg-color: #e8f2ff;
.grid-table{
border-left: 1px solid $border-color;
}
.app-container {
height: calc(100vh - 140px);
line-height: $base-line-height;
}
.company-section {
margin-bottom: 20px;
}
.table-header{
height: 40px;
line-height: 40px;
text-align: center;
border: 1px solid $border-color;
border-bottom: none;
width: calc(100vw - 297px);
color: #000;
background-color: $bg-color;
}
.grid-header{
display: flex;
justify-content: flex-start;
.grid-header-tr{
border-top: 1px solid $border-color;
text-align: center;
.head-search{
.el-select,
.el-button{
margin-right: 10px;
}
.header-row{
@extend .cell-base;
}
}
.cell-base {
border-right: 1px solid $border-color;
border-bottom: 1px solid $border-color;
text-align: center;
}
.colspan{
@extend .cell-base;
width: calc((100vw - 298px) / 16);
}
.colspan2{
@extend .colspan;
width: calc((100vw - 298px) / 16 * 2);
}
.colspan6{
@extend .colspan;
width: calc((100vw - 298px) / 16 * 6);
}
.th-style{
// background-color: $bg-color;
color: #000;
font-weight: bold;
}
.placeholder-line{
height: $base-line-height + 1;
border-bottom: 1px solid $border-color;
}
.placeholder-line-right{
border-right: 1px solid $border-color;
}
.rowspan2{
height: $base-line-height * 2 + 2;
line-height: $base-line-height * 2 + 2;
}
.rowspan3{
height: $base-line-height * 3 + 3;
line-height: $base-line-height * 3 + 3;
}
.row-cell{
display: flex;
justify-content: flex-start;
div{
border-right:1px solid $border-color;
::v-deep .el-table__footer{
font-size: 14px;
}
::v-deep .el-table__empty-block{
border-bottom: 1px solid #e4e7ed;
}
}
.grid-content, .grid-item{
display: flex;
justify-content: flex-start;
}
</style>

169
src/views/archivesStatistics/roomCollectionStatistics/index.vue

@ -0,0 +1,169 @@
<template>
<div class="app-container row-container">
<div class="connection-header">
<div class="head-search">
<el-select
v-model="fondsIds"
multiple
collapse-tags
placeholder="请选择所属全宗"
style="width: 320px;"
>
<el-option
v-for="item in fondsOptions"
:key="item.id"
:label="item.fondsName"
:value="item.id"
/>
</el-select>
<el-select
v-model="years"
multiple
collapse-tags
placeholder="请选择年份"
style="width: 150px;"
>
<el-option
v-for="item in yearsOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getRoomCollectionStatistics">查询</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div>
</div>
<el-table class="archives-table" :data="displayData" :summary-method="getSummaries" show-summary border style="width: 100%;">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="categoryName" label="档案门类" align="center" />
<el-table-column prop="year" label="统计年度" align="center" />
<el-table-column prop="permanentCount" label="永久保管(Y)数量" align="center" />
<el-table-column prop="thirtyYearCount" label="定期30年(D30)数量" align="center" />
<el-table-column prop="tenYearCount" label="定期10年(D10)数量" align="center" />
<el-table-column prop="totalCount" label="该类型该年度总量" align="center" />
</el-table>
</div>
</template>
<script>
import { FetchFondsAll } from '@/api/system/fonds'
import { FetchRoomCollectionStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics'
export default {
name: 'RoomCollectionStatistics',
data() {
return {
allData: [],
fondsOptions: [],
fondsIds: [],
yearsOptions: [],
years: []
}
},
computed: {
displayData() {
//
const result = []
this.allData.forEach(category => {
category.statistics.forEach(stat => {
result.push({
categoryName: category.categoryName,
year: stat.year + '年度',
permanentCount: stat.permanentCount,
thirtyYearCount: stat.thirtyYearCount,
tenYearCount: stat.tenYearCount,
totalCount: stat.totalCount
})
})
})
return result
}
},
mounted() {
this.getFondsDatas()
this.getArchivedAllYearDatas()
this.getRoomCollectionStatistics()
},
methods: {
getSummaries(param) {
const { columns, data } = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '-'
} else if (index === 1) {
sums[index] = '该年度全类型合计'
} else if (index === 2) {
sums[index] = '-'
} else {
const values = data.map(item => Number(item[column.property]))
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => prev + curr, 0)
} else {
sums[index] = '-'
}
}
})
return sums
},
resetQuery() {
this.fondsIds = []
this.years = []
this.getRoomCollectionStatistics()
},
getFondsDatas() {
FetchFondsAll().then(res => {
this.fondsOptions = res
//
// this.fondsIds = res.map(item => item.id)
// this.checkAndQuery()
})
},
getArchivedAllYearDatas() {
FetchArchivedAllYear().then(res => {
this.yearsOptions = res.map(item => ({
id: item,
name: item
}))
//
// this.years = res.map(item => item)
// this.checkAndQuery()
})
},
checkAndQuery() {
//
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
this.getRoomCollectionStatistics()
}
},
getRoomCollectionStatistics() {
FetchRoomCollectionStatistics({
fondsIds: this.fondsIds,
years: this.years
}).then(res => {
this.allData = res
})
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
height: calc(100vh - 140px);
.head-search{
.el-select,
.el-button{
margin-right: 10px;
}
}
::v-deep .el-table__footer{
font-size: 14px;
}
::v-deep .el-table__empty-block{
border-bottom: 1px solid #e4e7ed;
}
}
</style>

156
src/views/archivesStatistics/usageCountStatistics/index.vue

@ -0,0 +1,156 @@
<template>
<div class="app-container row-container">
<div class="connection-header">
<div class="head-search">
<el-select
v-model="fondsIds"
multiple
collapse-tags
placeholder="请选择所属全宗"
style="width: 320px;"
>
<el-option
v-for="item in fondsOptions"
:key="item.id"
:label="item.fondsName"
:value="item.id"
/>
</el-select>
<el-select
v-model="years"
multiple
collapse-tags
placeholder="请选择年份"
style="width: 150px;"
>
<el-option
v-for="item in yearsOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getTotalStatistics">查询</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div>
</div>
<div class="table-container">
<el-table class="archives-table" :data="allData" :summary-method="getSummaries" show-summary border style="width: 100%;">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="categoryName" label="档案门类(国标分类)" align="center" />
<el-table-column prop="archivesCount" label="案卷数(卷)" align="center" />
<el-table-column prop="singleCount" label="卷内件数(件)" align="center" />
<el-table-column prop="fileCount" label="电子原文数量(份)" align="center" />
<el-table-column prop="fileSize" label="电子档案存储容量(GB)" align="center" />
</el-table>
</div>
</div>
</template>
<script>
import { FetchFondsAll } from '@/api/system/fonds'
import { FetchTotalStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics'
export default {
name: 'UsageCountStatistics',
data() {
return {
allData: [],
fondsOptions: [],
fondsIds: [],
yearsOptions: [],
years: []
}
},
mounted() {
this.getFondsDatas()
this.getArchivedAllYearDatas()
this.getTotalStatistics()
},
methods: {
getSummaries(param) {
const { columns, data } = param
const sums = []
console.log('columns', columns)
console.log('data', data)
columns.forEach((column, index) => {
if (index === 1) {
sums[index] = '合计(全库总量)'
return
}
const values = data.map(item => Number(item[column.property]))
console.log(values)
if (!values.every(value => isNaN(value))) {
if (column.property === 'fileSize') {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0).toFixed(3)
} else {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0)
}
} else {
sums[index] = '-'
}
})
return sums
},
resetQuery() {
this.fondsIds = []
this.years = []
this.getTotalStatistics()
},
getFondsDatas() {
FetchFondsAll().then(res => {
this.fondsOptions = res
//
// this.fondsIds = res.map(item => item.id)
// this.checkAndQuery()
})
},
getArchivedAllYearDatas() {
FetchArchivedAllYear().then(res => {
this.yearsOptions = res.map(item => ({
id: item,
name: item
}))
//
// this.years = res.map(item => item)
// this.checkAndQuery()
})
},
checkAndQuery() {
//
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
this.getTotalStatistics()
}
},
getTotalStatistics() {
FetchTotalStatistics({
fondsIds: this.fondsIds,
years: this.years
}).then(res => {
this.allData = res
})
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
height: calc(100vh - 140px);
.head-search{
.el-select,
.el-button{
margin-right: 10px;
}
}
::v-deep .el-table__footer{
font-size: 14px;
}
}
</style>

156
src/views/archivesStatistics/utilizeRegistrationStatistics/index.vue

@ -0,0 +1,156 @@
<template>
<div class="app-container row-container">
<div class="connection-header">
<div class="head-search">
<el-select
v-model="fondsIds"
multiple
collapse-tags
placeholder="请选择所属全宗"
style="width: 320px;"
>
<el-option
v-for="item in fondsOptions"
:key="item.id"
:label="item.fondsName"
:value="item.id"
/>
</el-select>
<el-select
v-model="years"
multiple
collapse-tags
placeholder="请选择年份"
style="width: 150px;"
>
<el-option
v-for="item in yearsOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-button class="filter-item filter-search" size="mini" type="success" icon="el-icon-search" @click="getTotalStatistics">查询</el-button>
<el-button class="filter-item filter-refresh" size="mini" type="warning" icon="el-icon-refresh-left" @click="resetQuery">重置</el-button>
</div>
</div>
<div class="table-container">
<el-table class="archives-table" :data="allData" :summary-method="getSummaries" show-summary border style="width: 100%;">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="categoryName" label="档案门类(国标分类)" align="center" />
<el-table-column prop="archivesCount" label="案卷数(卷)" align="center" />
<el-table-column prop="singleCount" label="卷内件数(件)" align="center" />
<el-table-column prop="fileCount" label="电子原文数量(份)" align="center" />
<el-table-column prop="fileSize" label="电子档案存储容量(GB)" align="center" />
</el-table>
</div>
</div>
</template>
<script>
import { FetchFondsAll } from '@/api/system/fonds'
import { FetchTotalStatistics, FetchArchivedAllYear } from '@/api/statistics/statistics'
export default {
name: 'UtilizeRegistrationStatistics',
data() {
return {
allData: [],
fondsOptions: [],
fondsIds: [],
yearsOptions: [],
years: []
}
},
mounted() {
this.getFondsDatas()
this.getArchivedAllYearDatas()
this.getTotalStatistics()
},
methods: {
getSummaries(param) {
const { columns, data } = param
const sums = []
console.log('columns', columns)
console.log('data', data)
columns.forEach((column, index) => {
if (index === 1) {
sums[index] = '合计(全库总量)'
return
}
const values = data.map(item => Number(item[column.property]))
console.log(values)
if (!values.every(value => isNaN(value))) {
if (column.property === 'fileSize') {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0).toFixed(3)
} else {
sums[index] = values.reduce((prev, curr) => {
return prev + curr
}, 0)
}
} else {
sums[index] = '-'
}
})
return sums
},
resetQuery() {
this.fondsIds = []
this.years = []
this.getTotalStatistics()
},
getFondsDatas() {
FetchFondsAll().then(res => {
this.fondsOptions = res
//
// this.fondsIds = res.map(item => item.id)
// this.checkAndQuery()
})
},
getArchivedAllYearDatas() {
FetchArchivedAllYear().then(res => {
this.yearsOptions = res.map(item => ({
id: item,
name: item
}))
//
// this.years = res.map(item => item)
// this.checkAndQuery()
})
},
checkAndQuery() {
//
if (this.fondsOptions.length > 0 && this.yearsOptions.length > 0) {
this.getTotalStatistics()
}
},
getTotalStatistics() {
FetchTotalStatistics({
fondsIds: this.fondsIds,
years: this.years
}).then(res => {
this.allData = res
})
}
}
}
</script>
<style lang="scss" scoped>
.app-container {
height: calc(100vh - 140px);
.head-search{
.el-select,
.el-button{
margin-right: 10px;
}
}
::v-deep .el-table__footer{
font-size: 14px;
}
}
</style>

102
src/views/components/category/PreviewForm.vue

@ -22,7 +22,7 @@
:span="item.isLine || item.fieldName === 'barcode' ? 24 : 12"
>
<el-form-item :label="item.fieldCnName" :prop="item.fieldName">
<!-- select :load-options="loadOptions"-->
<!-- select :load-options="load-options"-->
<treeselect
v-if="item.isInputClass === 'select'"
v-model="addOrUpdateForm[item.fieldName]"
@ -36,11 +36,16 @@
:disabled="isDisabled || (item.fieldName === 'fonds_no' && isDesFormType !== 'category') || (item.fieldName === 'fonds_name' && isDesFormType !== 'category') "
:validate-event="!isDisabled"
no-options-text="无数据"
:class="{ 'treeselect-error': fieldErrors[item.fieldName] }"
@select="selectTree"
@open="openTree(item)"
@blur="() => { this.$refs.addOrUpdateForm.validateField(item.fieldName) }"
>
<div slot="value-label" slot-scope="{ node }">{{ getAutoNameUnknown(node.label) }}</div>
</treeselect>
<div v-if="item.isInputClass === 'select' && fieldErrors[item.fieldName]" class="el-form-item__error treeselect-error-tip">
{{ fieldErrors[item.fieldName] }}
</div>
<!-- text / number / textarea / popover -->
<!-- :validate-event="isDisabled" -->
<!-- :disabled="isDisabled || (item.fieldName === 'archival_category_code') || (item.fieldName === 'fonds_no' && isDesFormType !== 'category') || (item.fieldName === 'fonds_name' && isDesFormType !== 'category') "-->
@ -62,13 +67,11 @@
"
:max="addOrUpdateForm.is_entity === 0 && (item.fieldName === 'doc_qty' || item.fieldName === 'doc_qty_now') ? 0 : null"
:min="0"
:validate-event="!isDisabled"
@mousewheel.native.prevent
@DOMMouseScroll.native.prevent
@keyup.enter.native="isRepeatHandle(item)"
@input="autoAddZero(item.isFilling, item.fieldName, addOrUpdateForm[item.fieldName], item.fillingDigit)"
@blur="isRepeatHandle(item); syncEntityByQty(item)"
>
<i v-if="item.isInputClass === 'popover'" slot="suffix" class="el-input__icon iconfont icon-gengduo1" @click="handleCurrentFieldName(item)" />
@ -287,6 +290,7 @@ export default {
},
rules: {
},
fieldErrors: {},
isTableType: 1,
tableTitle: '字典列表',
popoverTableData: [], // popover - popoverTableData
@ -458,29 +462,6 @@ export default {
Vue.set(this.loadingStatus, fieldName, true)
console.log(`字段${fieldName}加载状态:`, this.loadingStatus[fieldName])
// try {
// // 2.
// // const response = await new Promise((resolve) => {
// // setTimeout(() => {
// // resolve({ data: { code: 200, data: `NO-${Date.now().slice(-6)}` }})
// // }, 2000)
// // })
// // // 3.
// // if (response.data.code === 200) {
// // this.inputValue = response.data.data
// // this.$message?.success('') || alert('')
// // }
// } catch (error) {
// console.error('', error)
// this.$message?.error('') || alert('')
// } finally {
// // 4. /false
// Vue.set(this.loadingStatus, fieldName, false)
// console.log('isMaxLoading', this.isMaxLoading)
// }
},
preUplpadClose() {
@ -494,24 +475,6 @@ export default {
this.fileJsonString = null
this.newFileCount = 0
},
// handleSuccessResource(data, fileName, jsonArrayToSend) {
// this.minioPreResult = data
// // console.log('handleSuccessResource', filePath)
// // console.log('handleSuccessResource', fileName)
// // console.log('handleSuccessResource', jsonArrayToSend)
// // console.log('handleSuccessResource', jsonArrayToSend[0].fileJsonString)
// this.fileOriginal = fileName.join(',')
// // this.fileOriginal = fileName
// const fileJson = JSON.parse(jsonArrayToSend[0].fileJsonString)
// fileJson[0].file_path = '/' + data.filePath
// fileJson[0].is_quote = null
// fileJson[0].last_modified = jsonArrayToSend[0].last_modified
// fileJson[0].ca_id = this.minioPreResult.caId
// fileJson[0].encryption_time = this.minioPreResult.timestamp
// fileJson[0].signature = this.minioPreResult.signature
// this.fileJsonString = JSON.stringify(fileJson)
// },
// 1.
handleSuccessResource(data, fileName, jsonArrayToSend) {
console.log('原始fileJsonString:', this.fileJsonString)
@ -1308,6 +1271,9 @@ export default {
this.addOrUpdateForm[this.treeCurrentFiled.fieldName] = val.dictionaryName
}
//
this.$set(this.fieldErrors, this.treeCurrentFiled.fieldName, '')
//
if (this.treeCurrentFiled.isRepeat) {
const params = this.isDesFormType !== 'prearchiveLibrary' && this.isDesFormType !== 'mergeFile'
@ -1475,12 +1441,13 @@ export default {
}
if (item.fieldName === 'fonds_name' && this.isDesFormType !== 'category') {
console.log(' this.selectedCategory.fondName', this.selectedCategory.fondName)
this.$set(this.addOrUpdateForm, item.fieldName, this.selectedCategory.fondName)
}
console.log('item', item)
console.log('item.isRequired', item.isRequired)
const rule = {
required: !!item.isRequired,
message: (item.isInputClass === 'text' ? '请输入' : '请选择') + item.fieldCnName,
message: ((item.isInputClass === 'text' || item.isInputClass === 'textarea') ? '请输入' : '请选择') + item.fieldCnName,
trigger: item.isInputClass === 'text' ? 'blur' : 'change'
}
@ -1503,7 +1470,7 @@ export default {
}
if (isRequired && value === '') {
rule.message = item.isInputClass === 'text' ? `请输入${item.fieldCnName}` : `请选择${item.fieldCnName}`
rule.message = (item.isInputClass === 'text' || item.isInputClass === 'textarea') ? `请输入${item.fieldCnName}` : `请选择${item.fieldCnName}`
callback(new Error(rule.message))
return
}
@ -1538,7 +1505,7 @@ export default {
}
if (isRequired && value === '') {
rule.message = item.isInputClass === 'text' ? `请输入${item.fieldCnName}` : `请选择${item.fieldCnName}`
rule.message = (item.isInputClass === 'text' || item.isInputClass === 'textarea') ? `请输入${item.fieldCnName}` : `请选择${item.fieldCnName}`
callback(new Error(rule.message))
return
}
@ -1670,15 +1637,28 @@ export default {
console.log('this.addOrUpdateForm', this.addOrUpdateForm)
//
// if (this.archivesType !== 'edit') {
const isRepeatValid = await this.validateRepeatFieldsBeforeSubmit(formName)
if (!isRepeatValid) {
return false
}
// }
this.$nextTick(() => {
this.$refs[formName].validate((valid, fields) => {
// treeselect Element UI el-form
this.fieldErrors = {}
let hasRequiredError = false
const requiredFields = this.formPreviewData.filter(item => item.isRequired)
for (const item of requiredFields) {
const fieldValue = this.addOrUpdateForm[item.fieldName]
if (!fieldValue && fieldValue !== 0 && fieldValue !== false) {
//
this.$set(this.fieldErrors, item.fieldName, (item.isInputClass === 'text' || item.isInputClass === 'textarea' ? '请输入' : '请选择') + item.fieldCnName)
hasRequiredError = true
}
}
if (hasRequiredError) {
return false
}
if (valid) {
this.addOrUpdateForm.archive_no = originalArchiveNo
delete this.addOrUpdateForm.id
@ -1701,7 +1681,6 @@ export default {
'fondsAffiliation': this.selectedDocument.fondsId
}
console.log('this.fileJsonString', JSON.parse(this.fileJsonString))
console.log('params', params)
prearchEdit(params).then(res => {
if (res) {
@ -1723,7 +1702,6 @@ export default {
'archivesNo': this.addOrUpdateForm.archive_no,
'jsonString': JSON.stringify(this.addOrUpdateForm)
}
console.log('合并成件this.selectedCategory', this.selectedCategory)
console.log('params', params)
FetchMergeToFile(params).then(res => {
if (res.code !== 500) {
@ -1768,7 +1746,6 @@ export default {
} else if (this.selectedCategory.arrangeType === 3 && this.activeIndex === 1 && (this.archivesType === 'add' || this.archivesType === 'copy')) {
// parentsId === null
const fileIds = []
console.log('this.uploadedFileData', this.uploadedFileData)
if (this.uploadedFileData) {
if (Array.isArray(this.uploadedFileData)) {
this.uploadedFileData.forEach(item => {
@ -2017,10 +1994,6 @@ export default {
* @param {String} pickerVal 面板选择的yyyyMMdd格式日期
*/
handlePickerChange(item, pickerVal) {
console.log('item', item)
console.log('item.fieldName', item.fieldName)
console.log('pickerVal', pickerVal)
//
if (pickerVal) {
this.$set(this.addOrUpdateForm, item.fieldName, pickerVal)
@ -2089,6 +2062,21 @@ export default {
::v-deep .vue-treeselect__control{
height: 32px !important;
}
::v-deep .treeselect-error .vue-treeselect__control {
border-color: #ff4949 !important;
}
::v-deep .treeselect-error .vue-treeselect__control:hover {
border-color: #ff4949 !important;
}
.treeselect-error-tip {
color: #ff4949 !important;
font-size: 12px !important;
line-height: 1 !important;
padding-top: 4px !important;
position: absolute !important;
top: 100% !important;
left: 0 !important;
}
::v-deep .el-input__prefix {
text-align: right;
right: 5px !important;

Loading…
Cancel
Save