From 36b676de507ff96bd8a8c856b5cc415089e70a5f Mon Sep 17 00:00:00 2001 From: minimaxagent1 Date: Thu, 31 Jul 2025 15:29:40 +0800 Subject: [PATCH] =?UTF-8?q?institutionalStructure.vue=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E7=9A=84=E6=8A=BD=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/base-background/README.md | 94 ++++++++++++- .../components/status-display.vue | 55 ++++++++ .../institutionalStructure.vue | 129 ++++-------------- .../mixins/data-manager.js | 90 ++++++++++++ .../utils/data-formatter.js | 65 +++++++++ 5 files changed, 329 insertions(+), 104 deletions(-) create mode 100644 pages/institutionalStructure/components/status-display.vue create mode 100644 pages/institutionalStructure/mixins/data-manager.js create mode 100644 pages/institutionalStructure/utils/data-formatter.js diff --git a/components/base-background/README.md b/components/base-background/README.md index 0519ecb..1edbccf 100644 --- a/components/base-background/README.md +++ b/components/base-background/README.md @@ -1 +1,93 @@ - \ No newline at end of file + # BaseBackground 背景图片组件 + +一个可复用的背景图片组件,支持自定义背景图片源和样式。 + +## 功能特性 + +- 支持自定义背景图片源 +- 支持自定义图片裁剪模式 +- 支持自定义样式 +- 默认使用 CommonEnum.BACKGROUND 作为背景 + +## 使用方法 + +### 基础用法 + +```vue + + + +``` + +### 自定义背景图片 + +```vue + +``` + +### 自定义裁剪模式 + +```vue + +``` + +### 自定义样式 + +```vue + +``` + +## Props + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| src | String | '' | 背景图片源,如果不传则使用默认背景 | +| mode | String | 'aspectFill' | 图片裁剪模式 | +| customStyle | Object | {} | 自定义样式对象 | + +## 裁剪模式说明 + +- `aspectFill`: 保持纵横比缩放图片,只保证图片的短边能完全显示出来 +- `aspectFit`: 保持纵横比缩放图片,使图片的长边能完全显示出来 +- `scaleToFill`: 不保持纵横比缩放图片,使图片完全适应容器 +- `widthFix`: 宽度不变,高度自动变化,保持原图宽高比不变 +- `heightFix`: 高度不变,宽度自动变化,保持原图宽高比不变 + +## 注意事项 + +1. 组件会自动设置 `position: absolute` 和 `z-index: -1`,确保背景图片在内容下方 +2. 默认样式包含 `border-radius: 16rpx`,可以通过 `customStyle` 覆盖 +3. 组件会自动导入 `CommonEnum`,使用默认背景图片 \ No newline at end of file diff --git a/pages/institutionalStructure/components/status-display.vue b/pages/institutionalStructure/components/status-display.vue new file mode 100644 index 0000000..d1c2fb1 --- /dev/null +++ b/pages/institutionalStructure/components/status-display.vue @@ -0,0 +1,55 @@ + + + + + \ No newline at end of file diff --git a/pages/institutionalStructure/institutionalStructure.vue b/pages/institutionalStructure/institutionalStructure.vue index 4c740b2..8449dbf 100644 --- a/pages/institutionalStructure/institutionalStructure.vue +++ b/pages/institutionalStructure/institutionalStructure.vue @@ -3,14 +3,17 @@ - - - 加载中... - - - - 暂无数据 - + + + ({ - topLeft: this.formatTopLeft(item.startYear, item.proName), - topRight: this.getStatusText(item.state), - bottomLeft: `建造金额:${this.formatAmount(item.totalAmount)}`, - bottomRight: `捐赠人数:${item.donorCount}人` - })) || [] - - if (isLoadMore) { - this.institutionalData = [...this.institutionalData, ...newData] - } else { - this.institutionalData = newData - } - - // 判断是否还有更多数据 - this.hasMore = response.rows.length === this.pageSize - } else { - uni.showToast({ - title: response.msg || '获取数据失败', - icon: 'none' - }) - } - } catch (error) { - console.error('获取建制数据失败:', error) - uni.showToast({ - title: '网络错误', - icon: 'none' - }) - } finally { - this.loading = false - } - }, - - // 格式化金额 - formatAmount(amount) { - if (!amount) return '不详' - if (amount >= 100000000) { - return `${(amount / 100000000).toFixed(1)}亿` - } else if (amount >= 10000) { - return `${(amount / 10000).toFixed(1)}万` - } else { - return `${amount.toLocaleString()}` - } - }, - - // 格式化左上角内容 - formatTopLeft(year, projectName) { - if (!year || !projectName) return '暂无数据' - return `${year}年 ${projectName}` - }, - - // 获取状态文本 - getStatusText(state) { - switch (state) { - case '1': - return '规划' - case '2': - return '进行中' - case '3': - return '已完成' - case '4': - return '已取消' - default: - return '未知状态' - } + await this.fetchData( + isLoadMore, + getInstitutionalList, + InstitutionalDataFormatter.transformData + ) + // 将数据赋值给 institutionalData + this.institutionalData = this.dataList }, // 刷新数据 @@ -178,12 +108,5 @@ page { } -.loading, .empty { - display: flex; - justify-content: center; - align-items: center; - color: #999; - font-size: 28rpx; - background-color: #FFFBF5; -} + \ No newline at end of file diff --git a/pages/institutionalStructure/mixins/data-manager.js b/pages/institutionalStructure/mixins/data-manager.js new file mode 100644 index 0000000..3d66096 --- /dev/null +++ b/pages/institutionalStructure/mixins/data-manager.js @@ -0,0 +1,90 @@ +/** + * 数据管理 Mixin + * 提供通用的数据获取、分页加载功能 + */ +export const dataManagerMixin = { + data() { + return { + // 数据数组 + dataList: [], + // 加载状态 + loading: false, + // 分页参数 + pageNum: 1, + pageSize: 10, + hasMore: true + } + }, + + methods: { + /** + * 获取数据 + * @param {boolean} isLoadMore 是否为加载更多 + * @param {Function} apiCall API调用函数 + * @param {Function} dataTransformer 数据转换函数 + */ + async fetchData(isLoadMore = false, apiCall, dataTransformer) { + this.loading = true + try { + if (isLoadMore) { + this.pageNum++ + } else { + this.pageNum = 1 + } + + // 调用API + const response = await apiCall({ + pageNum: this.pageNum, + pageSize: this.pageSize + }) + + if (response.code === 200) { + // 转换数据 + const newData = dataTransformer ? dataTransformer(response.rows) : response.rows || [] + + if (isLoadMore) { + this.dataList = [...this.dataList, ...newData] + } else { + this.dataList = newData + } + + // 判断是否还有更多数据 + this.hasMore = response.rows.length === this.pageSize + } else { + uni.showToast({ + title: response.msg || '获取数据失败', + icon: 'none' + }) + } + } catch (error) { + console.error('获取数据失败:', error) + uni.showToast({ + title: '网络错误', + icon: 'none' + }) + } finally { + this.loading = false + } + }, + + /** + * 刷新数据 + * @param {Function} apiCall API调用函数 + * @param {Function} dataTransformer 数据转换函数 + */ + refreshData(apiCall, dataTransformer) { + this.fetchData(false, apiCall, dataTransformer) + }, + + /** + * 加载更多数据 + * @param {Function} apiCall API调用函数 + * @param {Function} dataTransformer 数据转换函数 + */ + loadMoreData(apiCall, dataTransformer) { + if (this.hasMore && !this.loading) { + this.fetchData(true, apiCall, dataTransformer) + } + } + } +} \ No newline at end of file diff --git a/pages/institutionalStructure/utils/data-formatter.js b/pages/institutionalStructure/utils/data-formatter.js new file mode 100644 index 0000000..e78bd9e --- /dev/null +++ b/pages/institutionalStructure/utils/data-formatter.js @@ -0,0 +1,65 @@ +/** + * 建制数据格式化工具类 + */ +export class InstitutionalDataFormatter { + /** + * 格式化金额 + * @param {number} amount 金额 + * @returns {string} 格式化后的金额字符串 + */ + static formatAmount(amount) { + if (!amount) return '不详' + if (amount >= 100000000) { + return `${(amount / 100000000).toFixed(1)}亿` + } else if (amount >= 10000) { + return `${(amount / 10000).toFixed(1)}万` + } else { + return `${amount.toLocaleString()}` + } + } + + /** + * 格式化左上角内容 + * @param {string} year 年份 + * @param {string} projectName 项目名称 + * @returns {string} 格式化后的内容 + */ + static formatTopLeft(year, projectName) { + if (!year || !projectName) return '暂无数据' + return `${year}年 ${projectName}` + } + + /** + * 获取状态文本 + * @param {string} state 状态码 + * @returns {string} 状态文本 + */ + static getStatusText(state) { + switch (state) { + case '1': + return '规划' + case '2': + return '进行中' + case '3': + return '已完成' + case '4': + return '已取消' + default: + return '未知状态' + } + } + + /** + * 转换后端数据为前端格式 + * @param {Array} rows 后端数据 + * @returns {Array} 转换后的数据 + */ + static transformData(rows) { + return rows.map(item => ({ + topLeft: InstitutionalDataFormatter.formatTopLeft(item.startYear, item.proName), + topRight: InstitutionalDataFormatter.getStatusText(item.state), + bottomLeft: `建造金额:${InstitutionalDataFormatter.formatAmount(item.totalAmount)}`, + bottomRight: `捐赠人数:${item.donorCount}人` + })) + } +} \ No newline at end of file