From 87f8bfe4b38a6bab588a4f777576cd7ecc1c9a4c Mon Sep 17 00:00:00 2001 From: linyongLynn <15926056+linyonglynn@user.noreply.gitee.com> Date: Sat, 9 Aug 2025 16:48:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BE=9B=E9=9C=80=E5=8F=91=E5=B8=83=E4=BF=AE?= =?UTF-8?q?=E6=94=B9+=E5=9B=BE=E4=B9=A6=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/student/index.js | 9 + src/views/library/index.vue | 203 ++++++++++++--- .../student/components/SupplyDemandDetail.vue | 174 ++++++++++++- .../student/components/SupplyDemandEdit.vue | 236 ++++++++++++++++-- src/views/student/supply_demand.vue | 62 ++++- 5 files changed, 615 insertions(+), 69 deletions(-) diff --git a/src/api/student/index.js b/src/api/student/index.js index c9a5bee..2384cce 100644 --- a/src/api/student/index.js +++ b/src/api/student/index.js @@ -107,3 +107,12 @@ export function supplyDemandDestroy(params) { params }) } + +// 供需管理 - 获取详情 +export function supplyDemandDetail(params) { + return request({ + method: 'get', + url: '/api/mobile/supply-demand/detail', + params + }) +} diff --git a/src/views/library/index.vue b/src/views/library/index.vue index db243e6..9575a24 100644 --- a/src/views/library/index.vue +++ b/src/views/library/index.vue @@ -35,26 +35,26 @@
- - - @@ -77,10 +77,11 @@ 搜索 - 导出数据 - - - 批量导入 + 导出数据
@@ -180,6 +181,8 @@ :page-size="listQuery.limit" layout="total, sizes, prev, pager, next, jumper" :total="total" + :pager-count="7" + background > @@ -413,7 +416,7 @@ export default { total: 0, listQuery: { page: 1, - limit: 10 + page_size: 10 }, multipleSelection: [], bookForm: { @@ -456,7 +459,7 @@ export default { try { const params = { page: this.listQuery.page, - limit: this.listQuery.limit + page_size: this.listQuery.page_size } // 构建二维数组形式的filter参数 @@ -487,7 +490,13 @@ export default { this.total = res.list?.total || 0 this.listQuery.page = res.list?.current_page || 1 this.chartData = res.chart || {} - this.categoryList = res.category || [] + + // 处理分类数据:将键值对转换为数组格式 + if (res.category && typeof res.category === 'object') { + this.categoryList = Object.values(res.category).filter(category => category && category.trim() !== '') + } else { + this.categoryList = [] + } } catch (error) { console.error('获取图书列表失败:', error) this.$message.error('获取图书列表失败') @@ -497,14 +506,122 @@ export default { this.listQuery.page = 1 this.getList() }, - handleExport() { - console.log('导出数据') - this.$message.info('数据导出中...') - }, - handleImport() { - console.log('批量导入') - this.$message.info('批量导入功能') + async handleExport() { + try { + this.$message.info('正在获取所有图书数据,请稍候...') + + // 先获取总数据量 + const countParams = { + page: 1, + page_size: 1 + } + + // 应用当前筛选条件 + let filterIndex = 0 + + if (this.filters.keyword) { + countParams.keyword = this.filters.keyword + } + + if (this.filters.category) { + countParams[`filter[${filterIndex}][key]`] = 'category' + countParams[`filter[${filterIndex}][op]`] = 'eq' + countParams[`filter[${filterIndex}][value]`] = this.filters.category + filterIndex++ + } + + if (this.filters.status !== '') { + countParams[`filter[${filterIndex}][key]`] = 'status' + countParams[`filter[${filterIndex}][op]`] = 'eq' + countParams[`filter[${filterIndex}][value]`] = this.filters.status + filterIndex++ + } + + const countRes = await index(countParams) + const totalCount = countRes.list?.total || 0 + + if (totalCount === 0) { + this.$message.warning('没有找到可导出的图书数据') + return + } + + // 使用总数据量作为page_size来获取所有数据 + const params = { + page: 1, + page_size: totalCount + } + + // 应用相同的筛选条件 + filterIndex = 0 + + if (this.filters.keyword) { + params.keyword = this.filters.keyword + } + + if (this.filters.category) { + params[`filter[${filterIndex}][key]`] = 'category' + params[`filter[${filterIndex}][op]`] = 'eq' + params[`filter[${filterIndex}][value]`] = this.filters.category + filterIndex++ + } + + if (this.filters.status !== '') { + params[`filter[${filterIndex}][key]`] = 'status' + params[`filter[${filterIndex}][op]`] = 'eq' + params[`filter[${filterIndex}][value]`] = this.filters.status + filterIndex++ + } + + const res = await index(params) + const allBooks = res.list?.data || [] + + // 构建导出数据 + const exportData = allBooks.map(book => ({ + 书名: book.title || '未设置', + 作者: book.author || '未知', + ISBN: book.isbn || '未设置', + 出版社: book.publisher || '未设置', + 出版年份: book.publish_year || '未设置', + 分类: book.category || '未分类', + 状态: this.getStatusText(book.status), + 图书简介: book.description || '暂无简介', + 添加时间: this.formatDateTime(book.created_at) + })) + + // 创建CSV内容 + const headers = Object.keys(exportData[0]) + const csvContent = [ + headers.join(','), + ...exportData.map(row => + headers.map(header => { + const value = row[header] || '' + // 处理包含逗号、引号或换行符的值 + if (typeof value === 'string' && (value.includes(',') || value.includes('"') || value.includes('\n'))) { + return `"${value.replace(/"/g, '""')}"` + } + return value + }).join(',') + ) + ].join('\n') + + // 创建下载链接 + const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' }) + const link = document.createElement('a') + const url = URL.createObjectURL(blob) + link.setAttribute('href', url) + link.setAttribute('download', `图书数据_${new Date().toISOString().slice(0, 10)}.csv`) + link.style.visibility = 'hidden' + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + + this.$message.success(`成功导出 ${allBooks.length} 本图书数据`) + } catch (error) { + console.error('导出失败:', error) + this.$message.error('导出失败,请重试') + } }, + handleSelectionChange(val) { this.multipleSelection = val }, @@ -514,9 +631,9 @@ export default { }, getStatusTagType(status) { const statusMap = { - 0: 'success', // 可借阅 - 1: 'warning', // 已借出 - 2: 'danger' // 维护中 + 0: 'success', // 可借阅 + 1: 'warning', // 已借出 + 2: 'danger' // 维护中 } return statusMap[status] || 'info' }, @@ -606,6 +723,19 @@ export default { this.listQuery.page = val this.getList() }, + + // 处理分页链接跳转 + handlePageJump(url) { + if (url) { + // 从URL中提取页码 + const pageMatch = url.match(/page=(\d+)/) + if (pageMatch) { + const page = parseInt(pageMatch[1]) + this.listQuery.page = page + this.getList() + } + } + }, handleCloseModal() { this.resetForm() this.isEdit = false @@ -851,13 +981,25 @@ export default { .pagination-container { display: flex; - justify-content: center; + flex-direction: column; + align-items: center; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } +.pagination-info { + margin-top: 15px; + color: #666; + font-size: 14px; + text-align: center; +} + +.pagination-info span { + margin: 0 10px; +} + .form-section { background: #f8f9fa; padding: 20px; @@ -991,6 +1133,11 @@ export default { border: 1px dashed #d1d5db; } +.no-location { + color: #999; + font-size: 12px; +} + /* Element UI 表格样式覆盖 */ ::v-deep .el-table th { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); diff --git a/src/views/student/components/SupplyDemandDetail.vue b/src/views/student/components/SupplyDemandDetail.vue index dbe1f23..c2002dc 100644 --- a/src/views/student/components/SupplyDemandDetail.vue +++ b/src/views/student/components/SupplyDemandDetail.vue @@ -1,31 +1,78 @@ \ No newline at end of file + +.no-data { + text-align: center; + padding: 40px; + color: #999; +} + +.no-data i { + font-size: 24px; + margin-bottom: 10px; +} + +.image-list { + display: flex; + flex-wrap: wrap; + gap: 8px; +} + +.detail-image { + width: 80px; + height: 80px; + object-fit: cover; + border-radius: 4px; + cursor: pointer; + border: 1px solid #e4e7ed; +} + +.detail-image:hover { + border-color: #409eff; +} + diff --git a/src/views/student/components/SupplyDemandEdit.vue b/src/views/student/components/SupplyDemandEdit.vue index bd14935..780d3ce 100644 --- a/src/views/student/components/SupplyDemandEdit.vue +++ b/src/views/student/components/SupplyDemandEdit.vue @@ -1,5 +1,5 @@