longz
2026-06-11 e1b58eabfaeb88469ac14172607438a243dbc23c
优化订单信息查询中的评分处理逻辑
1个文件已添加
2个文件已修改
298 ■■■■■ 已修改文件
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/OrderInfoWarpper.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
约客多出行系统全模块部署方案.md 273 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/crossCity/server/impl/OrderCrossCityServiceImpl.java
@@ -1557,6 +1557,7 @@
    @Override
    public Map<String, Object> queryOrderInfo(Integer orderId) throws Exception {
        Map<String, Object> map = orderCrossCityMapper.queryOrderInfo(orderId);
        fillDriverScoreForOrderScore(map);
        if (null != map.get("reassignNotice") && Integer.valueOf(String.valueOf(map.get("reassignNotice"))) == 2) {//如果订单有改派提醒,则查询后重置为未提醒
            OrderCrossCity orderCrossCity = this.selectById(orderId);
            orderCrossCity.setReassignNotice(0);
@@ -1585,6 +1586,16 @@
        map.put("device", ToolUtil.isNotEmpty(driverId) ? 2 : 1);
        map.put("orderType", 3);
        return map;
    }
    private void fillDriverScoreForOrderScore(Map<String, Object> map) {
        if (map == null || map.get("score") == null) {
            return;
        }
        Object orderScore = map.get("orderScore");
        if (orderScore == null || Double.valueOf(String.valueOf(orderScore)) == 0D) {
            map.put("orderScore", map.get("score"));
        }
    }
    
    /**
@@ -2791,9 +2802,7 @@
            
            UnPayOrderVO unPayOrderVO = new UnPayOrderVO();
            //添加司机信息
            DriverInfoWarpper driverInfoWarpper = new DriverInfoWarpper();
            Driver driver = driverService.selectById(orderCrossCity.getDriverId());
            BeanUtils.copyProperties(driver, driverInfoWarpper);
            DriverInfoWarpper driverInfoWarpper = DriverInfoWarpper.getDriverInfoWarpper(driverService.queryDriverInfo(orderCrossCity.getDriverId()));
            unPayOrderVO.setDriverInfoWarpper(driverInfoWarpper);
            //其他信息
            BeanUtils.copyProperties(orderCrossCity, unPayOrderVO);
UserYKDTravel/guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/OrderInfoWarpper.java
@@ -119,7 +119,7 @@
    @ApiModelProperty("小费金额")
    private Double tipMoney;
    @ApiModelProperty("订单评分")
    private Integer orderScore;
    private Double orderScore;
    @ApiModelProperty("评价内容")
    private String evaluate;
    @ApiModelProperty("接单设备(1=APP,2=车载端)")
@@ -737,12 +737,12 @@
        this.endLat = endLat;
    }
    public Integer getOrderScore() {
    public Double getOrderScore() {
        return orderScore;
    }
    public void setOrderScore(Integer orderScore) {
        this.orderScore = orderScore;
    public void setOrderScore(Double orderScore) {
        this.orderScore = roundOneDecimal(orderScore);
    }
    public String getEvaluate() {
@@ -1115,7 +1115,7 @@
            orderInfoWarpper.setStartLat(null != map.get("startLat") ? Double.valueOf(String.valueOf(map.get("startLat"))) : 0);
            orderInfoWarpper.setEndLon(null != map.get("endLon") ? Double.valueOf(String.valueOf(map.get("endLon"))) : 0);
            orderInfoWarpper.setEndLat(null != map.get("endLat") ? Double.valueOf(String.valueOf(map.get("endLat"))) : 0);
            orderInfoWarpper.setOrderScore(null != map.get("orderScore") ? Double.valueOf(String.valueOf(map.get("orderScore"))).intValue() : 0);
            orderInfoWarpper.setOrderScore(null != map.get("orderScore") ? Double.valueOf(String.valueOf(map.get("orderScore"))) : 0);
            orderInfoWarpper.setEvaluate(null != map.get("evaluate") ? String.valueOf(map.get("evaluate")) : "");
            orderInfoWarpper.setCarColor(null != map.get("carColor") ? String.valueOf(map.get("carColor")) : "");
            orderInfoWarpper.setCancelId(null != map.get("cancelId") ? Integer.valueOf(String.valueOf(map.get("cancelId"))) : 0);
约客多出行系统全模块部署方案.md
New file
@@ -0,0 +1,273 @@
# 约客多出行系统全模块部署方案
编制日期:2026年06月09日
适用范围:Eureka 注册中心、Zuul 网关、管理后台、用户端接口、司机端接口、调度端接口、消息推送服务及公共中间件。
## 1. 部署目标
本文档用于指导约客多出行系统在生产或准生产环境中的全模块部署、启动、验证、回滚和运维检查。部署目标是确保各服务按依赖顺序启动,统一接入 MySQL、Redis、MongoDB、Eureka 注册中心和 Zuul 网关,并为后续版本发布提供标准化流程。
- 明确所有后端服务模块、端口、部署产物和启动顺序。
- 规范服务器目录、配置文件、日志、备份和回滚方式。
- 避免敏感配置在交付文档中明文传播,实际密码、密钥以服务器配置或运维密钥库为准。
- 提供部署后验收清单,便于快速确认管理端、用户端、司机端、调度端和消息推送链路是否可用。
## 2. 系统模块总览
| 序号 | 模块 | 工程目录 | 服务名/应用名 | 默认端口 | 部署说明 |
| --- | --- | --- | --- | --- | --- |
| 1 | 服务注册中心 | `EurekaYKDTravel` | `eureka-center` | `8000` | Spring Cloud Eureka Server,其他微服务注册到该中心。 |
| 2 | API 网关 | `ZuulYKDTravel` | `zuul-gateway` | `5000` | 统一转发 `/user/**`、`/driver/**`、`/dispatch/**` 请求。 |
| 3 | 管理后台 | `ManagementYKDTravel/guns-admin` | `management` | `8010` | 后台管理系统,含企业、司机、车辆、订单、跨城线路等管理功能。 |
| 4 | 用户端接口 | `UserYKDTravel/guns-admin` | `user-server` | `8006` | 乘客端、小程序、用户侧接口服务,注册到 Eureka。 |
| 5 | 司机端接口 | `DriverYKDTravel/guns-admin` | `driver-server` | `8007` | 司机 App 接口服务,含司机订单、出车、提现等功能,注册到 Eureka。 |
| 6 | 调度端接口 | `DispatchYKDTravel/guns-admin` | `dispatch-server` | `8008` | 调度相关接口服务,注册到 Eureka。 |
| 7 | 调度 REST 模块 | `DispatchYKDTravel/guns-rest` | `guns-rest` | `8080` | 独立 REST 模块,如现场仍使用则单独部署。 |
| 8 | 消息推送服务 | `MessagePushTravel` | `message` | `6000` | 消息、长连接、推送相关服务,依赖 Redis。 |
说明:端口以各模块 `application-prod.yml` 为准;如生产环境存在端口映射、容器部署或云负载均衡,以实际运维配置为准。
## 3. 基础环境要求
| 类别 | 建议配置 | 说明 |
| --- | --- | --- |
| 操作系统 | Linux x86_64,建议 CentOS 7、Alibaba Cloud Linux 或 Ubuntu LTS | 需开放服务端口并配置时间同步。 |
| JDK | JDK 1.8 | 各模块 `pom.xml` 使用 Java 8 编译目标。 |
| Maven | Maven 3.5+ | 用于生产包构建,建议在构建机执行,不建议生产机临时编译。 |
| 数据库 | MySQL 5.7/8.0 | 默认库名 `yuekeduo`,字符集建议 `utf8mb4`。 |
| 缓存 | Redis | 生产配置默认端口 `6410`,用于会话、缓存、推送等。 |
| 轨迹库 | MongoDB | 生产配置默认端口 `27009`,用于行程轨迹等数据。 |
| 反向代理 | Nginx | 建议统一做域名、HTTPS、静态资源和网关转发。 |
| 文件目录 | `/home/yuekeduo/server/resources` | 管理端生产配置中的本地上传资源目录。 |
## 4. 中间件与外部依赖
- MySQL:提前创建业务库并导入全量结构、基础字典、菜单、角色、系统参数等初始化数据。
- Redis:确认 `host`、`port`、`password`、`database` 与各模块 `application-prod.yml` 一致。管理端开启 Spring Session 时需保证 Redis 可用。
- MongoDB:确认轨迹库账号、密码、库名和网络连通性。用户端、司机端、调度端、管理端均可能读取轨迹数据。
- 对象存储/图片资源:管理端当前可使用本地资源目录,若启用 COS、OSS 或 OBS,需配置访问域名、Bucket、SecretId、SecretKey 等密钥。
- 第三方服务:短信、极光推送、融云、支付、腾讯实名/人脸、地图服务、邮箱等参数需在上线前由运维或项目负责人确认。
- 注册中心认证:Eureka 生产配置开启 Basic 认证,默认账号密码应在实际部署时按安全要求修改。
## 5. 端口规划
| 端口 | 服务 | 访问方向 | 备注 |
| --- | --- | --- | --- |
| `8000` | Eureka 注册中心 | 内网访问为主 | 服务注册、发现;不建议公网暴露。 |
| `5000` | Zuul 网关 | 公网/内网 | 移动端 API 入口,建议由 Nginx 代理。 |
| `8010` | 管理后台 | 公网或办公网 | 后台管理入口,建议限制来源 IP 或 VPN。 |
| `8006` | 用户端接口 | 内网 | 通过 Zuul `/user/**` 转发。 |
| `8007` | 司机端接口 | 内网 | 通过 Zuul `/driver/**` 转发。 |
| `8008` | 调度端接口 | 内网 | 通过 Zuul `/dispatch/**` 转发。 |
| `8080` | 调度 REST 模块 | 内网 | 仅在实际使用时开放。 |
| `6000` | 消息推送服务 | 内网/按业务开放 | 推送或长连接服务。 |
| `6410` | Redis | 内网 | 禁止公网开放。 |
| `27009` | MongoDB | 内网 | 禁止公网开放。 |
| `8066` | MySQL | 内网 | 如使用 MyCat 或代理端口,以实际为准。 |
## 6. 推荐服务器目录
| 目录 | 用途 |
| --- | --- |
| `/home/yuekeduo/server/apps` | 存放各模块 jar 包和启动脚本。 |
| `/home/yuekeduo/server/config` | 存放外置 `application-prod.yml`、密钥配置或环境变量文件。 |
| `/home/yuekeduo/server/logs` | 应用日志目录,每个模块独立子目录。 |
| `/home/yuekeduo/server/resources` | 图片、附件、本地上传资源目录。 |
| `/home/yuekeduo/server/backup` | 历史 jar、配置文件、SQL 备份目录。 |
| `/etraffic/server/chuxing/tomcat` | 各模块配置中的 Tomcat basedir,可按实际环境创建。 |
## 7. 构建打包
建议在构建机完成编译,并将产物上传到服务器。不要在生产服务器上直接修改源码后临时打包。
| 模块 | 构建命令 | 主要产物路径 |
| --- | --- | --- |
| Eureka | `mvn clean package -Pprod -DskipTests` | `EurekaYKDTravel/target/eureka-*.jar` |
| Zuul | `mvn clean package -Pprod -DskipTests` | `ZuulYKDTravel/target/zuul-*.jar` |
| Message | `mvn clean package -Pprod -DskipTests` | `MessagePushTravel/target/message-*.jar` |
| Management | `mvn -pl guns-admin -am clean package -Pprod -DskipTests` | `ManagementYKDTravel/guns-admin/target/management-*.jar` |
| User | `mvn -pl guns-admin -am clean package -Pprod -DskipTests` | `UserYKDTravel/guns-admin/target/user-*.jar` |
| Driver | `mvn -pl guns-admin -am clean package -Pprod -DskipTests` | `DriverYKDTravel/guns-admin/target/driver-*.jar` |
| Dispatch | `mvn -pl guns-admin -am clean package -Pprod -DskipTests` | `DispatchYKDTravel/guns-admin/target/dispatch-*.jar` |
| Dispatch REST | `mvn -pl guns-rest -am clean package -Pprod -DskipTests` | `DispatchYKDTravel/guns-rest/target/guns-rest-*.jar` |
如项目 profile 或产物名称与现场不同,以 `pom.xml` 中 `artifactId`、`version` 和实际 `target` 目录为准。
## 8. 配置项检查
- 确认 `spring.profiles.active` 为 `prod`,或启动命令中显式指定 `--spring.profiles.active=prod`。
- 确认数据库 URL、账号、密码、库名、字符集和时区配置正确。文档中不保存明文密码。
- 确认 Redis、MongoDB 连接配置可用,且生产环境安全组已放通内网访问。
- 确认 Eureka `defaultZone` 中的地址、账号、密码与注册中心一致。
- 确认 Zuul 路由指向用户端、司机端、调度端的实际部署地址。
- 确认文件上传目录存在且 Java 进程有读写权限。
- 确认第三方支付、短信、推送、地图、对象存储等密钥与回调域名已切换为生产环境。
## 9. 部署步骤
1. 停止待更新服务,并确认进程已退出。首次部署可跳过停止步骤。
2. 备份旧 jar、外置配置、Nginx 配置、数据库变更脚本和关键日志。
3. 上传新 jar 到对应模块目录,例如 `/home/yuekeduo/server/apps/user/user.jar`。
4. 上传或更新外置配置文件,确认敏感配置不提交到公开仓库。
5. 执行数据库变更脚本,先在测试库验证,再在生产库执行。
6. 按启动顺序启动服务并观察日志。
7. 在 Eureka 页面确认用户端、司机端、调度端和网关服务注册状态。
8. 通过 Nginx、网关、后台页面执行功能验收。
9. 验收通过后清理临时包,保留本次版本备份和部署记录。
## 10. 启动顺序
1. 启动基础中间件:MySQL、Redis、MongoDB、Nginx。
2. 启动 Eureka 注册中心,确认 `http://服务器:8000` 可访问。
3. 启动用户端、司机端、调度端服务,确认注册到 Eureka。
4. 启动 Zuul 网关,确认路由可转发到各业务服务。
5. 启动管理后台,确认后台登录页可打开。
6. 启动消息推送服务,确认 Redis 连接正常。
7. 如启用 Dispatch REST 模块,按业务依赖单独启动并验证。
## 11. 启动脚本示例
以下为通用启动示例,实际路径、JVM 参数和配置文件位置按现场调整:
```bash
#!/bin/bash
APP_NAME=user-server
APP_JAR=/home/yuekeduo/server/apps/user/user.jar
LOG_DIR=/home/yuekeduo/server/logs/user
CONFIG_DIR=/home/yuekeduo/server/config/user
mkdir -p ${LOG_DIR}
nohup java -Xms512m -Xmx1024m \
  -Dfile.encoding=UTF-8 \
  -Dspring.config.location=${CONFIG_DIR}/application-prod.yml \
  -jar ${APP_JAR} \
  --spring.profiles.active=prod \
  > ${LOG_DIR}/console.log 2>&1 &
echo $! > ${LOG_DIR}/app.pid
```
## 12. Nginx 反向代理示例
当前真实部署使用统一域名 `rideapi.yuekeduo.com.cn`,HTTP 强制跳转 HTTPS;`/resources/` 走本地静态资源目录,`/user/**`、`/driver/**`、`/dispatch/**` 走 Zuul 网关,其余请求走管理后台。
```nginx
server {
    listen 80;
    listen [::]:80;
    server_name rideapi.yuekeduo.com.cn;
    # HTTP 全部跳转到 HTTPS
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl;
    server_name rideapi.yuekeduo.com.cn;
    ssl_certificate      /home/yuekeduo/cert/nginx/rideapi.yuekeduo.com.cn.pem;
    ssl_certificate_key  /home/yuekeduo/cert/nginx/rideapi.yuekeduo.com.cn.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    client_max_body_size 100m;
    client_header_timeout 30000;
    client_body_timeout 30000;
    proxy_read_timeout 60000;
    proxy_send_timeout 60000;
    # 静态资源:访问 /resources/xxx 时映射到 /home/yuekeduo/server/resources/xxx
    location ^~ /resources/ {
        root /home/yuekeduo/server;
        expires 30d;
        access_log off;
        add_header Cache-Control "public, max-age=2592000";
    }
    # API 走 Zuul 网关(5000)
    location ~ ^/(user|driver|dispatch)(/|$) {
        proxy_pass http://127.0.0.1:5000;
        proxy_redirect off;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Port  443;
    }
    # 其他页面走管理后台(8010)
    location / {
        proxy_pass http://127.0.0.1:8010;
        proxy_redirect off;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Port  443;
    }
}
```
## 13. 部署后验证
| 检查项 | 验证方式 | 期望结果 |
| --- | --- | --- |
| Eureka 注册中心 | 访问 `http://服务器:8000` | 注册中心页面正常打开。 |
| 服务注册 | 查看 Eureka 服务列表 | `user-server`、`driver-server`、`dispatch-server`、`zuul-gateway` 状态 UP。 |
| 网关路由 | 访问 `/user/**`、`/driver/**`、`/dispatch/**` 测试接口 | 网关可正常转发。 |
| 管理后台 | 访问后台域名或 `http://服务器:8010/login` | 登录页正常展示,可登录。 |
| 数据库连接 | 查看各模块启动日志 | 无数据库连接失败、表不存在、SQL 异常。 |
| Redis 连接 | 查看启动日志和登录态功能 | 无 Redis 连接失败,管理端 session 正常。 |
| MongoDB 连接 | 访问轨迹或订单详情相关接口 | 轨迹数据读取正常。 |
| 文件上传 | 后台上传图片或附件 | 文件保存成功,外网可访问资源。 |
| 消息推送 | 触发订单、公告或系统消息 | 推送服务无异常,客户端可收到消息。 |
| 定时任务 | 观察用户端、司机端、管理端日志 | 定时任务无重复执行或异常堆栈。 |
## 14. 回滚方案
1. 保留上一版本 jar、配置文件和数据库备份。
2. 如仅代码异常,停止当前服务并替换为上一版本 jar 后重启。
3. 如配置异常,恢复上一版本 `application-prod.yml` 或环境变量。
4. 如数据库脚本已执行且不可兼容,按变更脚本准备对应回滚 SQL;涉及数据删除时先备份再处理。
5. 回滚后按部署后验证清单重新检查服务注册、接口、后台登录、订单链路和推送链路。
## 15. 运维注意事项
- 生产环境禁止直接暴露 MySQL、Redis、MongoDB 到公网。
- 管理后台建议配置 VPN、办公网白名单或堡垒机访问。
- Eureka 默认账号密码应在正式环境修改,并同步所有 `defaultZone` 配置。
- 日志需按模块拆分,并配置定期压缩和清理,避免磁盘被打满。
- 图片资源目录应纳入备份策略;若切换对象存储,需同步调整 `picture-server-address`。
- 发版前先在测试环境执行完整回归,尤其是登录、下单、派单、支付、取消、退款、提现、推送和跨城线路相关链路。
- 所有支付、短信、推送、地图、对象存储密钥均按生产环境密钥管理,不应写入文档或聊天记录。
## 16. 常用命令
```bash
# 查看 Java 进程
jps -l
ps -ef | grep java
# 查看端口占用
netstat -tunlp | grep 8006
# 查看实时日志
tail -f /home/yuekeduo/server/logs/user/console.log
# 停止服务
kill $(cat /home/yuekeduo/server/logs/user/app.pid)
# 检查 Eureka 服务
curl -u 用户名:密码 http://127.0.0.1:8000/eureka/apps
# 检查网关
curl http://127.0.0.1:5000/user/health
```