modify:新增小程序

This commit is contained in:
ECRZ
2026-01-06 18:00:43 +08:00
parent 498fa0e915
commit da4a055c1c
47 changed files with 7321 additions and 61 deletions

208
Sale/utils/CLAUDE.md Normal file
View File

@@ -0,0 +1,208 @@
[根目录](../CLAUDE.md) > **utils**
---
# utils - 工具函数模块
> 最后更新2026-01-06 15:26:54
---
## 变更记录 (Changelog)
### 2026-01-06
- 初始化模块文档
- 识别当前包含时间格式化工具函数
---
## 模块职责
**当前职责**:提供通用的工具函数,当前仅包含日期时间格式化功能。
**扩展方向**
- 封装 API 请求方法(`wx.request`
- 添加数据验证与格式化工具
- 添加本地存储管理工具
- 添加常用业务逻辑工具函数
---
## 入口与启动
### 模块路径
- **物理路径**`utils/util.js`
- **导出方式**CommonJS `module.exports`
### 引入方式
```javascript
const util = require('../../utils/util.js')
// 使用工具函数
const formattedTime = util.formatTime(new Date())
```
---
## 对外接口
### 当前提供的工具函数
#### 1. formatTime(date)
**功能**:将日期对象格式化为 `YYYY/MM/DD HH:mm:ss` 格式
**参数**
- `date`Date 对象
**返回值**
- 格式化的时间字符串,例如:`'2026/01/06 15:26:54'`
**示例**
```javascript
const now = new Date()
const formatted = util.formatTime(now)
console.log(formatted) // 输出2026/01/06 15:26:54
```
---
## 关键依赖与配置
### 依赖文件
| 文件 | 用途 |
|------|------|
| `util.js` | 工具函数实现 |
### 外部依赖
- 无外部依赖(纯 JavaScript 实现)
---
## 数据模型
### formatTime 实现细节
```javascript
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : `0${n}`
}
```
---
## 测试与质量
### 测试覆盖
- **手动测试**:在 `pages/logs` 中使用正常
- **单元测试**:暂无
### 边界情况
- 月份补零1 → 01
- 时分秒补零8 → 08
---
## 常见问题 (FAQ)
### Q: 如何添加新的工具函数?
A: 在 `util.js` 中添加函数并导出:
```javascript
// 添加新函数
const formatPrice = price => {
return ${price.toFixed(2)}`
}
// 在 module.exports 中导出
module.exports = {
formatTime,
formatPrice // 新增
}
```
### Q: 是否需要拆分为多个文件?
A: 当前项目规模小,单文件足够。随着功能增加,建议拆分为:
- `utils/api.js`API 请求封装
- `utils/storage.js`:本地存储管理
- `utils/validator.js`:数据验证
- `utils/format.js`:格式化工具
---
## 相关文件清单
```
utils/
├── util.js # 工具函数实现20 行)
└── CLAUDE.md # 本文档
```
---
## 下一步建议
### 推荐新增工具函数
#### 1. API 请求封装(`utils/request.js`
```javascript
const BASE_URL = 'http://localhost:3000/api'
function request(url, data = {}, method = 'GET') {
return new Promise((resolve, reject) => {
wx.request({
url: `${BASE_URL}${url}`,
data,
method,
success: res => resolve(res.data),
fail: err => reject(err)
})
})
}
module.exports = { request }
```
#### 2. 价格格式化(扩展 `util.js`
```javascript
const formatPrice = (price, unit = '元/吨') => {
return `${price.toFixed(2)} ${unit}`
}
const formatNumberWithComma = num => {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}
```
#### 3. 本地存储管理(`utils/storage.js`
```javascript
const STORAGE_KEYS = {
SEARCH_HISTORY: 'search_history',
USER_FAVORITES: 'user_favorites'
}
function getStorage(key) {
return wx.getStorageSync(key) || []
}
function setStorage(key, data) {
wx.setStorageSync(key, data)
}
module.exports = { STORAGE_KEYS, getStorage, setStorage }
```
---
**模块状态**:可用,待扩展
**优先级**API 封装为高优先级)
**预估工作量**1-2 小时(封装常用工具函数)

236
Sale/utils/request.js Normal file
View File

@@ -0,0 +1,236 @@
/**
* API 请求封装工具
* 统一处理 wx.request支持 baseURL、错误处理、加载状态
*/
// API 基础地址配置
const API_BASE_URL = 'http://makepower.top:9333'
/**
* 发起 HTTP 请求
* @param {string} url - 请求路径
* @param {object} options - 请求配置
* @param {string} options.method - 请求方法 (GET/POST/PUT/DELETE)
* @param {object} options.data - 请求数据
* @param {boolean} options.showLoading - 是否显示加载提示
* @param {string} options.loadingText - 加载提示文字
* @returns {Promise} 返回 Promise 对象
*/
function request(url, options = {}) {
const {
method = 'GET',
data = {},
showLoading = true,
loadingText = '加载中...'
} = options
// 显示加载提示
if (showLoading) {
wx.showLoading({
title: loadingText,
mask: true
})
}
return new Promise((resolve, reject) => {
wx.request({
url: `${API_BASE_URL}${url}`,
method: method.toUpperCase(),
data: method.toUpperCase() === 'GET' ? data : JSON.stringify(data),
header: {
'content-type': 'application/json'
},
success: (res) => {
// 隐藏加载提示
if (showLoading) {
wx.hideLoading()
}
// 检查业务状态码
if (res.statusCode === 200) {
if (res.data.success !== false) {
resolve(res.data)
} else {
// 业务错误
showError(res.data.message || '请求失败')
reject(res.data)
}
} else {
// HTTP 错误
showError(`网络错误: ${res.statusCode}`)
reject({
success: false,
message: `网络错误: ${res.statusCode}`,
statusCode: res.statusCode
})
}
},
fail: (err) => {
// 隐藏加载提示
if (showLoading) {
wx.hideLoading()
}
// 网络请求失败
showError('网络连接失败,请检查网络设置')
reject({
success: false,
message: '网络连接失败',
error: err
})
}
})
})
}
/**
* 显示错误提示
* @param {string} message - 错误信息
*/
function showError(message) {
wx.showToast({
title: message,
icon: 'none',
duration: 2000
})
}
/**
* 显示成功提示
* @param {string} message - 成功信息
*/
function showSuccess(message) {
wx.showToast({
title: message,
icon: 'success',
duration: 2000
})
}
/**
* GET 请求
*/
function get(url, data = {}, options = {}) {
return request(url, {
...options,
method: 'GET',
data
})
}
/**
* POST 请求
*/
function post(url, data = {}, options = {}) {
return request(url, {
...options,
method: 'POST',
data
})
}
/**
* PUT 请求
*/
function put(url, data = {}, options = {}) {
return request(url, {
...options,
method: 'PUT',
data
})
}
/**
* DELETE 请求
*/
function del(url, data = {}, options = {}) {
return request(url, {
...options,
method: 'DELETE',
data
})
}
// ========== API 接口定义 ==========
/**
* 健康检查
*/
function checkHealth() {
return get('/api/health', {}, { showLoading: false })
}
/**
* 按地区查询价格
* @param {string} region - 地区名称
* @param {string} date - 价格日期 (可选)
*/
function getPricesByRegion(region, date = '') {
const params = { region }
if (date) params.date = date
return get('/api/prices/region', params)
}
/**
* 搜索价格数据
* @param {object} params - 搜索参数
* @param {string} params.material - 材质
* @param {string} params.specification - 规格型号
* @param {string} params.startDate - 开始日期
* @param {string} params.endDate - 结束日期
* @param {string} params.region - 地区
* @param {number} params.page - 页码
* @param {number} params.pageSize - 每页数量
*/
function searchPrices(params = {}) {
return get('/api/prices/search', params)
}
/**
* 获取价格统计
* @param {object} params - 统计参数
* @param {string} params.region - 地区
* @param {string} params.material - 材质
* @param {number} params.days - 统计天数
* @param {string} params.startDate - 开始日期
* @param {string} params.endDate - 结束日期
*/
function getPriceStats(params = {}) {
return get('/api/prices/stats', params)
}
/**
* 获取价格趋势
* @param {object} params - 查询参数
* @param {string} params.region - 地区
* @param {string} params.material - 材质
* @param {number} params.days - 统计天数 (默认30)
*/
function getPriceTrend(params = {}) {
return get('/api/prices/trend', params)
}
/**
* 导入价格数据
* @param {array} prices - 价格数据数组
*/
function importPrices(prices) {
return post('/api/prices/import', { prices })
}
module.exports = {
request,
get,
post,
put,
del,
showSuccess,
showError,
// API 接口
checkHealth,
getPricesByRegion,
searchPrices,
getPriceStats,
getPriceTrend,
importPrices
}

19
Sale/utils/util.js Normal file
View File

@@ -0,0 +1,19 @@
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : `0${n}`
}
module.exports = {
formatTime
}