modify:新增小程序
This commit is contained in:
208
Sale/utils/CLAUDE.md
Normal file
208
Sale/utils/CLAUDE.md
Normal 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
236
Sale/utils/request.js
Normal 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
19
Sale/utils/util.js
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user