Browse Source

更新商品联系人信息相关文件

蛋吧eggbar
徐飞洋 1 month ago
parent
commit
91bbeef443
  1. 254
      MULTI_PROJECT_DEPLOYMENT.md
  2. 103
      TEST_PLAN.md
  3. 19
      pages/evaluate2/one.js
  4. 8
      pages/goods-detail/goods-detail.js
  5. 90
      server-example/server-mysql.js
  6. 38
      utils/api.js

254
MULTI_PROJECT_DEPLOYMENT.md

@ -1,254 +0,0 @@
# 多项目统一部署方案
## 目录结构设计
在云服务器上创建以下目录结构:
```
/projects/
├── project1/
│ ├── source/ # 项目源代码
│ ├── logs/ # 项目日志
│ ├── docker/ # Docker相关文件
│ └── docker-compose.yml
├── project2/
│ ├── source/
│ ├── logs/
│ ├── docker/
│ └── docker-compose.yml
├── project3/
│ ├── source/
│ ├── logs/
│ ├── docker/
│ └── docker-compose.yml
├── project4/
│ ├── source/
│ ├── logs/
│ ├── docker/
│ └── docker-compose.yml
└── scripts/ # 统一管理脚本
├── deploy-all.sh # 一键部署所有项目
├── update-all.sh # 一键更新所有项目
├── restart-all.sh # 一键重启所有项目
└── status-all.sh # 查看所有项目状态
```
## 部署脚本
### 1. 创建目录结构脚本
```bash
#!/bin/bash
# create-project-structure.sh
echo "创建多项目统一部署目录结构..."
# 创建主目录
mkdir -p /projects/{project1,project2,project3,project4}/{source,logs,docker}
mkdir -p /projects/scripts
echo "目录结构创建完成!"
echo "目录结构:"
find /projects -type d | sort
```
### 2. 统一部署脚本
```bash
#!/bin/bash
# /projects/scripts/deploy-all.sh
echo "开始部署所有项目..."
# 项目列表
projects=("project1" "project2" "project3" "project4")
for project in "${projects[@]}"; do
echo "\n=== 部署 $project ==="
cd /projects/$project
# 拉取最新代码
echo "拉取最新代码..."
cd source
git pull origin BOSS
cd ..
# 构建并启动容器
echo "构建并启动容器..."
docker-compose down
docker-compose up -d --build
echo "$project 部署完成!"
done
echo "\n所有项目部署完成!"
```
### 3. 统一更新脚本
```bash
#!/bin/bash
# /projects/scripts/update-all.sh
echo "开始更新所有项目..."
# 项目列表
projects=("project1" "project2" "project3" "project4")
for project in "${projects[@]}"; do
echo "\n=== 更新 $project ==="
cd /projects/$project
# 拉取最新代码
echo "拉取最新代码..."
cd source
git pull origin BOSS
cd ..
# 重新构建并启动容器
echo "重新构建并启动容器..."
docker-compose down
docker-compose up -d --build
echo "$project 更新完成!"
done
echo "\n所有项目更新完成!"
```
### 4. 统一状态查看脚本
```bash
#!/bin/bash
# /projects/scripts/status-all.sh
echo "查看所有项目状态..."
# 项目列表
projects=("project1" "project2" "project3" "project4")
for project in "${projects[@]}"; do
echo "\n=== $project 状态 ==="
cd /projects/$project
docker-compose ps
echo "\n$project 日志(最近10行):"
docker-compose logs --tail=10
done
echo "\n所有项目状态查看完成!"
```
### 5. 统一重启脚本
```bash
#!/bin/bash
# /projects/scripts/restart-all.sh
echo "开始重启所有项目..."
# 项目列表
projects=("project1" "project2" "project3" "project4")
for project in "${projects[@]}"; do
echo "\n=== 重启 $project ==="
cd /projects/$project
docker-compose restart
echo "$project 重启完成!"
done
echo "\n所有项目重启完成!"
```
## 项目配置示例
### 以当前项目为例,创建docker-compose.yml
```yaml
# /projects/project1/docker-compose.yml
version: '3.8'
services:
app:
build: ./source/server-example
container_name: project1-server
restart: always
ports:
- "3000:3000"
environment:
- NODE_ENV=production
volumes:
- ./logs:/app/logs
- ./source/server-example/uploads:/app/uploads
depends_on:
- db
db:
image: mysql:8.0
container_name: project1-db
restart: always
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=wechat_miniprogram
- MYSQL_USER=wechat_user
- MYSQL_PASSWORD=wechat_password
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
```
## 使用说明
1. **创建目录结构**
```bash
chmod +x create-project-structure.sh
./create-project-structure.sh
```
2. **部署项目**
- 将每个项目的源代码克隆到对应的`/projects/{projectN}/source/`目录
- 为每个项目创建docker-compose.yml文件
- 执行统一部署脚本:
```bash
chmod +x /projects/scripts/*.sh
/projects/scripts/deploy-all.sh
```
3. **管理项目**
- 更新所有项目:`/projects/scripts/update-all.sh`
- 查看所有项目状态:`/projects/scripts/status-all.sh`
- 重启所有项目:`/projects/scripts/restart-all.sh`
## 运维最佳实践
1. **日志管理**
- 所有项目的日志统一存储在`/projects/{projectN}/logs/`目录
- 可以使用ELK等工具进行统一日志收集和分析
2. **备份策略**
- 定期备份数据库:
```bash
docker exec -t project1-db mysqldump -u wechat_user -p wechat_miniprogram > /projects/backups/project1_db_$(date +%Y%m%d_%H%M%S).sql
```
- 定期备份源代码和配置文件
3. **监控告警**
- 使用Prometheus和Grafana监控容器和应用状态
- 设置告警规则,及时发现问题
4. **安全措施**
- 定期更新容器镜像和依赖
- 配置防火墙,只开放必要的端口
- 定期检查系统安全漏洞
## 注意事项
1. 确保每个项目使用不同的端口,避免端口冲突
2. 为每个项目的数据库设置强密码
3. 定期清理无用的容器和镜像:`docker system prune -f`
4. 监控磁盘空间使用情况,及时清理日志文件
5. 考虑使用CI/CD工具(如Jenkins、GitLab CI)实现自动化部署

103
TEST_PLAN.md

@ -1,103 +0,0 @@
# 修复功能测试计划
## 1. 测试默认排序规则
**测试目的**:验证商品是否按照要求的默认排序规则显示
**测试步骤**:
1. 打开小程序首页
2. 观察商品列表顺序
3. 确认排序规则:
- 已发布商品(published)在已售罄商品(sold_out)之前
- 同一状态内,预订数量(reservedCount)高的在前
- 预订数量相同时,价格低的在前
- 价格相同时,创建时间晚的在前
**预期结果**:商品按照上述规则正确排序
## 2. 测试sold_out商品加载逻辑
**测试目的**:验证只有当数据库中找不到published商品时才加载sold_out商品
**测试步骤**:
1. 打开小程序首页
2. 检查初始加载的商品是否都是published状态
3. 向下滑动页面,直到加载更多商品
4. 确认在所有published商品加载完毕后,才开始加载sold_out商品
**预期结果**:
- 初始加载的商品都是published状态
- 当published商品加载完毕后,自动开始加载sold_out商品
## 3. 测试sold_out商品加载功能
**测试目的**:验证sold_out商品能够正常加载
**测试步骤**:
1. 打开小程序首页
2. 向下滑动页面,直到加载sold_out商品
3. 检查是否有sold_out状态的商品显示
**预期结果**:sold_out商品能够正常显示在列表中
## 4. 测试下滑到底部加载功能
**测试目的**:验证下滑到底部能够加载更多商品,包括sold_out商品
**测试步骤**:
1. 打开小程序首页
2. 连续向下滑动页面,直到到达列表底部
3. 观察是否自动加载更多商品
4. 继续滑动,直到加载sold_out商品
**预期结果**:
- 下滑到底部时自动加载更多商品
- published商品加载完毕后,自动加载sold_out商品
## 5. 测试下拉刷新功能
**测试目的**:验证下拉刷新不会改变已加载商品的顺序
**测试步骤**:
1. 打开小程序首页
2. 观察初始商品顺序,记住前几个商品
3. 下拉页面进行刷新
4. 刷新完成后,观察商品顺序是否变化
**预期结果**:下拉刷新后,已加载商品的顺序保持不变,新商品添加在列表底部
## 6. 测试分类和搜索功能
**测试目的**:验证分类和搜索功能下,排序和加载逻辑依然正常
**测试步骤**:
1. 选择一个分类(如"粉壳")
2. 观察商品排序是否正确
3. 向下滑动加载更多商品,验证是否正常加载sold_out商品
4. 进行搜索,重复步骤2和3
**预期结果**:分类和搜索功能下,所有排序和加载逻辑都正常工作
## 7. 测试缓存功能
**测试目的**:验证缓存机制不会影响排序和加载逻辑
**测试步骤**:
1. 打开小程序首页,加载商品
2. 关闭小程序
3. 重新打开小程序
4. 观察商品是否从缓存加载,排序是否正确
**预期结果**:缓存加载的商品保持正确的排序顺序
## 测试环境要求
- WeChat Developer Tools最新版本
- 测试用手机(推荐)或模拟器
- 稳定的网络连接
## 测试注意事项
1. 记录测试过程中的任何异常情况
2. 如果发现问题,尝试重现并记录详细步骤
3. 测试完成后,汇总测试结果

19
pages/evaluate2/one.js

@ -22,6 +22,15 @@ Page({
}
}
// 增加用户估价点击次数(进入页面时自动增加)
const API = require('../../utils/api');
API.incrementAppraisalNum().then(res => {
console.log('增加估价次数成功:', res);
}).catch(err => {
console.error('增加估价次数失败:', err);
// 即使失败也不影响主流程
});
if (productName) {
this.setData({ productName: productName });
this.loadSpecifications(productName);
@ -447,6 +456,16 @@ Page({
const specItem = e.currentTarget.dataset.spec;
console.log('点击的规格项:', specItem);
console.log('传递的价格:', specItem.finalPriceText);
// 增加用户估价点击次数
const API = require('../../utils/api');
API.incrementAppraisalNum().then(res => {
console.log('增加估价次数成功:', res);
}).catch(err => {
console.error('增加估价次数失败:', err);
// 即使失败也不影响主流程
});
wx.navigateTo({
url: `/pages/evaluate1/spec-detail?productName=${encodeURIComponent(this.data.productName)}&specification=${encodeURIComponent(specItem.name)}&price=${encodeURIComponent(specItem.finalPriceText)}`
});

8
pages/goods-detail/goods-detail.js

@ -3063,6 +3063,14 @@ Page({
// 即使记录失败,也不影响主流程
});
// 增加用户对比价格点击次数
API.incrementCompareNum().then(res => {
console.log('增加对比价格次数成功:', res);
}).catch(err => {
console.error('增加对比价格次数失败:', err);
// 即使失败也不影响主流程
});
// 检查用户身份证认证状态
let idcardstatus = 0;
const users = wx.getStorageSync('users') || {};

90
server-example/server-mysql.js

@ -1548,7 +1548,7 @@ User.init({
// 身份证认证状态字段
idcardstatus: {
type: DataTypes.INTEGER, // 0: 待审核, 1: 审核通过, 2: 审核失败
defaultValue: 0, // 默认值为待审核
defaultValue: null, // 默认值为null
comment: '身份证认证状态'
},
// 授权区域字段 - 用于存储用户位置信息
@ -1576,6 +1576,18 @@ User.init({
notice: {
type: DataTypes.STRING(255) // 通知提醒
},
// 新增字段:点击估价次数
appraisalnum: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '点击估价次数'
},
// 新增字段:点击对比价格次数
comparenum: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: '点击对比价格次数'
},
idcard1: {
type: DataTypes.TEXT, // 身份证正面
comment: '身份证正面'
@ -11110,6 +11122,82 @@ app.get('/api/orders', async (req, res) => {
}
});
// 新增:增加用户估价点击次数接口
app.post('/api/user/increment-appraisal', async (req, res) => {
try {
const { openid, userId } = req.body;
console.log('增加估价次数请求:', { openid, userId });
if (!openid || !userId) {
return res.status(400).json({
success: false,
code: 400,
message: '缺少必要参数'
});
}
// 更新用户的估价点击次数(使用 COALESCE 处理 NULL 值)
const [result] = await sequelize.query(
'UPDATE users SET appraisalnum = COALESCE(appraisalnum, 0) + 1 WHERE openid = ? OR userId = ?',
{ replacements: [openid, userId] }
);
console.log('增加估价次数结果:', result, '影响行数:', result.affectedRows);
res.json({
success: true,
code: 200,
message: '增加估价次数成功',
affectedRows: result.affectedRows
});
} catch (error) {
console.error('增加估价次数失败:', error);
res.status(500).json({
success: false,
code: 500,
message: '增加估价次数失败: ' + error.message
});
}
});
// 新增:增加用户对比价格点击次数接口
app.post('/api/user/increment-compare', async (req, res) => {
try {
const { openid, userId } = req.body;
console.log('增加对比价格次数请求:', { openid, userId });
if (!openid || !userId) {
return res.status(400).json({
success: false,
code: 400,
message: '缺少必要参数'
});
}
// 更新用户的对比价格点击次数(使用 COALESCE 处理 NULL 值)
const [result] = await sequelize.query(
'UPDATE users SET comparenum = COALESCE(comparenum, 0) + 1 WHERE openid = ? OR userId = ?',
{ replacements: [openid, userId] }
);
console.log('增加对比价格次数结果:', result, '影响行数:', result.affectedRows);
res.json({
success: true,
code: 200,
message: '增加对比价格次数成功',
affectedRows: result.affectedRows
});
} catch (error) {
console.error('增加对比价格次数失败:', error);
res.status(500).json({
success: false,
code: 500,
message: '增加对比价格次数失败: ' + error.message
});
}
});
// 在服务器启动前执行商品联系人更新
updateProductContacts().then(() => {
console.log('\n📦 商品联系人信息更新完成!');

38
utils/api.js

@ -3584,6 +3584,44 @@ module.exports = {
openid: openid
});
},
// 增加用户估价点击次数
incrementAppraisalNum: function () {
const openid = wx.getStorageSync('openid');
const userId = wx.getStorageSync('userId');
console.log('API.incrementAppraisalNum - openid:', openid, 'userId:', userId);
if (!openid || !userId) {
return Promise.reject(new Error('用户未登录'));
}
return request('/api/user/increment-appraisal', 'POST', {
openid: openid,
userId: userId
}).catch(err => {
console.error('增加估价次数失败:', err);
// 即使失败也返回成功,不影响主流程
return { success: true };
});
},
// 增加用户对比价格点击次数
incrementCompareNum: function () {
const openid = wx.getStorageSync('openid');
const userId = wx.getStorageSync('userId');
console.log('API.incrementCompareNum - openid:', openid, 'userId:', userId);
if (!openid || !userId) {
return Promise.reject(new Error('用户未登录'));
}
return request('/api/user/increment-compare', 'POST', {
openid: openid,
userId: userId
}).catch(err => {
console.error('增加对比价格次数失败:', err);
// 即使失败也返回成功,不影响主流程
return { success: true };
});
},
// 编辑商品方法 - 修复版
editProduct: function (productId, productData) {
const openid = wx.getStorageSync('openid');

Loading…
Cancel
Save