diff --git a/backend/DEPLOY.md b/backend/DEPLOY.md new file mode 100644 index 0000000..aa10a6c --- /dev/null +++ b/backend/DEPLOY.md @@ -0,0 +1,125 @@ +# 打包与自动部署说明 + +本文档说明如何编译、打包并自动部署 **admin 后端(miao-admin-2.2.jar)** 与 **admin 后台前端** 到远程服务器(含备份后上传、重启)。 + +--- + +## 一、环境与前置条件 + +- **本机**:已安装 JDK 8、Maven、Node.js、npm;项目根目录为 `single-shop-22`,其下包含 `backend`、`frontend`。 +- **SSH 免密**:已配置本机到目标服务器的 SSH 公钥(推荐使用 `id_ed25519_crmeb_deploy`,或通过环境变量指定密钥)。 +- **部署配置**:`backend/deploy.conf` 中配置了各环境(如 by80、miao50)的服务器地址、目录、jar 名等。 + +--- + +## 二、by80 环境一键部署(推荐) + +部署目标:Spring Profile **miao80**,产出 **miao-admin-2.2.jar** + admin 后台静态,上传到 by80 配置的服务器。 + +### 1. 配置 SSH 免密(一次性) + +在项目外任意目录执行(将 `root` 和 `123.56.214.80` 换成实际用户与主机): + +```bash +ssh-copy-id -i ~/.ssh/id_ed25519_crmeb_deploy.pub root@123.56.214.80 +``` + +提示输入 **远程服务器 root 密码**(不要用 `sudo`,否则会提示的是本机密码)。成功后即可免密 SSH/SCP。 + +### 2. 执行自动部署脚本 + +在 **backend 目录** 下执行: + +```bash +cd /path/to/single-shop-22/backend +./shell/deploy-admin-by80.sh +``` + +使用其他密钥时: + +```bash +SSH_IDENTITY=~/.ssh/你的私钥 ./shell/deploy-admin-by80.sh +``` + +### 3. 脚本会依次执行 + +| 步骤 | 说明 | +|------|------| +| 1. 编译后端 | `mvn clean package -pl crmeb-admin -am -DskipTests`,生成 `crmeb-admin/target/miao-admin-2.2.jar` | +| 2. 编译前端 | 在 `frontend` 目录执行 `npm run build:prod`(带 Node 17+ OpenSSL 兼容),生成 `frontend/dist` | +| 3. 远程备份 | 备份远程已有 jar 到 `REMOTE_DIR_JAR/backups/`,后台静态打包为 `jfadmin_backup_yyyyMMdd_HHmmss.tar.gz` | +| 4. 上传 jar | 将 `miao-admin-2.2.jar` 上传到 `REMOTE_DIR_JAR`(by80 默认 `/www/wwwroot/crmeb`) | +| 5. 上传后台静态 | 将 `frontend/dist` 通过 tar 管道上传到 `REMOTE_DIR_ADMIN`(by80 默认 `/www/wwwroot/jfadmin.bosenyuan.com`) | +| 6. 远程重启 | 在远程执行 `pkill -f miao-admin-2.2.jar` 后使用 `--spring.profiles.active=miao80`、`--server.port=30032` 启动 jar | + +--- + +## 三、部署配置(deploy.conf) + +配置位于 **backend/deploy.conf**,按段落区分环境(如 by80、miao50)。by80 段示例: + +- `SERVER_HOST`:服务器 IP(如 123.56.214.80) +- `SERVER_USER`:SSH 用户(如 root) +- `SERVER_PORT`:SSH 端口(如 22) +- `REMOTE_DIR_JAR`:jar 上传目录(如 /www/wwwroot/crmeb) +- `REMOTE_DIR_ADMIN`:admin 后台静态站点目录(如 /www/wwwroot/jfadmin.bosenyuan.com) +- `ADMIN_JAR_NAME`:admin jar 文件名(如 miao-admin-2.2.jar) +- `ADMIN_LOCAL_PORT`:admin 服务端口(如 30032) + +修改后无需改脚本,脚本会从该文件读取对应段配置。 + +--- + +## 四、仅编译/打包(不部署) + +### 仅后端(miao-admin-2.2.jar) + +```bash +cd backend +mvn clean package -pl crmeb-admin -am -DskipTests +# 产出:backend/crmeb-admin/target/miao-admin-2.2.jar +``` + +运行时指定 profile:`java -jar miao-admin-2.2.jar --spring.profiles.active=miao80 --server.port=30032`。 + +### 仅前端(admin 后台) + +```bash +cd frontend +export NODE_OPTIONS="${NODE_OPTIONS:-} --openssl-legacy-provider" # Node 17+ 需要 +npm run build:prod +# 产出:frontend/dist +``` + +--- + +## 五、远程服务器上手动重启 admin + +若自动重启未生效,可 SSH 登录后手动操作: + +```bash +ssh -i ~/.ssh/id_ed25519_crmeb_deploy root@123.56.214.80 + +cd /www/wwwroot/crmeb +pkill -f miao-admin-2.2.jar || true +sleep 2 +nohup java -jar miao-admin-2.2.jar --spring.profiles.active=miao80 --server.port=30032 > admin.log 2>&1 & + +# 检查是否启动 +pgrep -f miao-admin-2.2.jar && echo "Admin 已启动" || tail -50 admin.log +``` + +--- + +## 六、其他环境(如 miao50) + +miao50 使用脚本 **backend/shell/deploy-admin-miao50.sh**,逻辑类似:编译 admin、上传 jar、远程重启(profile=miao50)。配置来自 deploy.conf 中 miao50 段。若需同时部署前端静态,可参考 by80 脚本在 miao50 脚本中增加备份与上传 `frontend/dist` 的步骤。 + +--- + +## 七、故障排查 + +- **SSH Permission denied**:检查是否已执行 `ssh-copy-id`,且未使用 `sudo`;或指定正确 `SSH_IDENTITY`。 +- **前端构建报错 OpenSSL / digital envelope**:在运行 `npm run build:prod` 前设置 `export NODE_OPTIONS="--openssl-legacy-provider"`(脚本已包含)。 +- **远程找不到 rsync**:当前 by80 脚本已改为使用 tar 管道上传前端,不依赖远程 rsync。 +- **jar 未启动**:SSH 登录服务器查看 `admin.log` 及 `pgrep -f miao-admin-2.2.jar`。 diff --git a/backend/crmeb-admin/src/main/resources/application-miao50.yml b/backend/crmeb-admin/src/main/resources/application-miao50.yml index 5718c35..db9df57 100644 --- a/backend/crmeb-admin/src/main/resources/application-miao50.yml +++ b/backend/crmeb-admin/src/main/resources/application-miao50.yml @@ -6,6 +6,11 @@ crmeb: server: port: 30032 +# 订单同步配置(每个单商户实例需要配置不同的source-id和target-mer-id) +sync: + source-id: shop_c + target-mer-id: 5 + spring: datasource: name: yangtangyoupin diff --git a/backend/crmeb-admin/src/main/resources/application-miao80.yml b/backend/crmeb-admin/src/main/resources/application-miao80.yml index 18f6d9b..bd2111f 100644 --- a/backend/crmeb-admin/src/main/resources/application-miao80.yml +++ b/backend/crmeb-admin/src/main/resources/application-miao80.yml @@ -6,6 +6,11 @@ crmeb: server: port: 30032 +# 订单同步配置(每个单商户实例需要配置不同的source-id和target-mer-id) +sync: + source-id: shop_d + target-mer-id: 6 + spring: datasource: name: yangtangyoupin diff --git a/backend/crmeb-admin/src/main/resources/application.yml b/backend/crmeb-admin/src/main/resources/application.yml index 3378ac4..fe63e2b 100644 --- a/backend/crmeb-admin/src/main/resources/application.yml +++ b/backend/crmeb-admin/src/main/resources/application.yml @@ -38,7 +38,7 @@ server: spring: profiles: - active: miao50 + active: miao80 servlet: multipart: max-file-size: 50MB #设置单个文件大小 diff --git a/backend/crmeb-common/src/main/java/com/zbkj/common/request/UserOperateIntegralMoneyRequest.java b/backend/crmeb-common/src/main/java/com/zbkj/common/request/UserOperateIntegralMoneyRequest.java index 4c9005b..86403c2 100644 --- a/backend/crmeb-common/src/main/java/com/zbkj/common/request/UserOperateIntegralMoneyRequest.java +++ b/backend/crmeb-common/src/main/java/com/zbkj/common/request/UserOperateIntegralMoneyRequest.java @@ -41,10 +41,11 @@ public class UserOperateIntegralMoneyRequest implements Serializable { @Range(min = 1, max = 2, message = "请选择正确的类型, 【1 = 增加, 2 = 减少】") private Integer integralType; - @ApiModelProperty(value = "积分") - @Min(value = 0) - @Max(value = 999999) - private Integer integralValue; + @ApiModelProperty(value = "积分(支持小数点后3位)") + @DecimalMin(value = "0", message = "积分不能小于0") + @DecimalMax(value = "999999.999", message = "积分不能大于999999.999") + @Digits(integer = 6, fraction = 3, message = "积分最多保留小数点后3位") + private BigDecimal integralValue; @ApiModelProperty(value = "余额类型, 1 = 增加, 2 = 减少") @NotNull diff --git a/backend/crmeb-common/src/main/java/com/zbkj/common/response/UserResponse.java b/backend/crmeb-common/src/main/java/com/zbkj/common/response/UserResponse.java index 9bd3d8d..4faab34 100644 --- a/backend/crmeb-common/src/main/java/com/zbkj/common/response/UserResponse.java +++ b/backend/crmeb-common/src/main/java/com/zbkj/common/response/UserResponse.java @@ -89,8 +89,8 @@ public class UserResponse { @ApiModelProperty(value = "佣金金额") private BigDecimal brokeragePrice; - @ApiModelProperty(value = "用户剩余积分") - private Integer integral; + @ApiModelProperty(value = "用户剩余积分(支持小数点后3位)") + private BigDecimal integral; @ApiModelProperty(value = "用户剩余经验") private Integer experience; diff --git a/backend/crmeb-service/src/main/java/com/zbkj/service/service/impl/UserServiceImpl.java b/backend/crmeb-service/src/main/java/com/zbkj/service/service/impl/UserServiceImpl.java index 10b9ce3..1d4f748 100644 --- a/backend/crmeb-service/src/main/java/com/zbkj/service/service/impl/UserServiceImpl.java +++ b/backend/crmeb-service/src/main/java/com/zbkj/service/service/impl/UserServiceImpl.java @@ -40,6 +40,7 @@ import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; @@ -227,11 +228,13 @@ public class UserServiceImpl extends ServiceImpl implements UserS */ @Override public Boolean updateIntegralMoney(UserOperateIntegralMoneyRequest request) { - if (ObjectUtil.isNull(request.getMoneyValue()) || ObjectUtil.isNull(request.getIntegralValue())) { + if (ObjectUtil.isNull(request.getMoneyValue()) && ObjectUtil.isNull(request.getIntegralValue())) { throw new CrmebException("至少输入一个金额"); } - if (request.getMoneyValue().compareTo(BigDecimal.ZERO) < 1 && request.getIntegralValue() <= 0) { - throw new CrmebException("修改值不能等小于等于0"); + boolean moneyValid = request.getMoneyValue() != null && request.getMoneyValue().compareTo(BigDecimal.ZERO) > 0; + boolean integralValid = request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0; + if (!moneyValid && !integralValid) { + throw new CrmebException("修改值不能小于等于0"); } User user = getById(request.getUid()); @@ -250,16 +253,16 @@ public class UserServiceImpl extends ServiceImpl implements UserS } } - if (request.getIntegralType().equals(2) && request.getIntegralValue() != 0) { + if (request.getIntegralType().equals(2) && request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) { BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; - if (integral.subtract(BigDecimal.valueOf(request.getIntegralValue())).compareTo(BigDecimal.ZERO) < 0) { + if (integral.subtract(request.getIntegralValue()).compareTo(BigDecimal.ZERO) < 0) { throw new CrmebException("积分扣减后不能小于0"); } } - if (request.getIntegralType().equals(1) && request.getIntegralValue() != 0) { + if (request.getIntegralType().equals(1) && request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) { BigDecimal integral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; - if (integral.add(BigDecimal.valueOf(request.getIntegralValue())).compareTo(BigDecimal.valueOf(99999999)) > 0) { - throw new CrmebException("积分添加后不能大于99999999"); + if (integral.add(request.getIntegralValue()).compareTo(new BigDecimal("99999999.999")) > 0) { + throw new CrmebException("积分添加后不能大于99999999.999"); } } @@ -295,28 +298,29 @@ public class UserServiceImpl extends ServiceImpl implements UserS } } - // 处理积分 - if (request.getIntegralValue() > 0) { + // 处理积分(支持小数点后3位) + if (request.getIntegralValue() != null && request.getIntegralValue().compareTo(BigDecimal.ZERO) > 0) { + BigDecimal integralValue = request.getIntegralValue().setScale(3, RoundingMode.HALF_UP); // 生成记录 UserIntegralRecord integralRecord = new UserIntegralRecord(); integralRecord.setUid(user.getUid()); integralRecord.setLinkType(IntegralRecordConstants.INTEGRAL_RECORD_LINK_TYPE_SYSTEM); integralRecord.setTitle(IntegralRecordConstants.BROKERAGE_RECORD_TITLE_SYSTEM); - integralRecord.setIntegral(BigDecimal.valueOf(request.getIntegralValue())); + integralRecord.setIntegral(integralValue); integralRecord.setStatus(IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE); if (request.getIntegralType() == 1) {// 增加 integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_ADD); BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; - integralRecord.setBalance(userIntegral.add(BigDecimal.valueOf(request.getIntegralValue())).intValue()); - integralRecord.setMark(StrUtil.format("后台操作增加了{}积分", request.getIntegralValue())); + integralRecord.setBalance(userIntegral.add(integralValue).setScale(0, RoundingMode.HALF_UP).intValue()); + integralRecord.setMark(StrUtil.format("后台操作增加了{}积分", integralValue)); - operationIntegral(user.getUid(), BigDecimal.valueOf(request.getIntegralValue()), user.getIntegral(), "add"); + operationIntegral(user.getUid(), integralValue, user.getIntegral(), "add"); } else { integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_SUB); BigDecimal userIntegral = user.getIntegral() != null ? user.getIntegral() : BigDecimal.ZERO; - integralRecord.setBalance(userIntegral.subtract(BigDecimal.valueOf(request.getIntegralValue())).intValue()); - integralRecord.setMark(StrUtil.format("后台操作减少了{}积分", request.getIntegralValue())); - operationIntegral(user.getUid(), BigDecimal.valueOf(request.getIntegralValue()), user.getIntegral(), "sub"); + integralRecord.setBalance(userIntegral.subtract(integralValue).setScale(0, RoundingMode.HALF_UP).intValue()); + integralRecord.setMark(StrUtil.format("后台操作减少了{}积分", integralValue)); + operationIntegral(user.getUid(), integralValue, user.getIntegral(), "sub"); } userIntegralRecordService.save(integralRecord); } diff --git a/backend/deploy.conf b/backend/deploy.conf index 3c3f582..76bf113 100644 --- a/backend/deploy.conf +++ b/backend/deploy.conf @@ -1,17 +1,23 @@ by80: + spring: + profiles: + active: miao80 + SERVER_HOST=123.56.214.80 SERVER_USER=root SERVER_PORT=22 -REMOTE_DIR=/www/crmeb -LOCAL_PORT=20822 -JAR_NAME=sophia-front-2.2.jar +REMOTE_DIR_JAR=/www/wwwroot/crmeb +REMOTE_DIR_ADMIN=/www/wwwroot/jfadmin.bosenyuan.com +FRONT_LOCAL_PORT=30031 +FRONT_JAR_NAME=miao-front-2.2.jar +ADMIN_LOCAL_PORT=30032 +ADMIN_JAR_NAME=miao-admin-2.2.jar miao50: - -spring: - profiles: - active: miao50 + spring: + profiles: + active: miao50 SERVER_HOST=101.37.253.50 SERVER_USER=root diff --git a/backend/shell/deploy-admin-by80.sh b/backend/shell/deploy-admin-by80.sh new file mode 100755 index 0000000..9215c5c --- /dev/null +++ b/backend/shell/deploy-admin-by80.sh @@ -0,0 +1,97 @@ +#!/bin/bash +# 编译前后端,使用 spring profile miao80 打包 miao-admin-2.2.jar, +# 备份远程原有文件后通过 SSH 上传并重启(admin jar + admin 后台静态) +# 一次性配置免密: ssh-copy-id -i ~/.ssh/id_ed25519_crmeb_deploy.pub root@123.56.214.80 +# 或指定密钥: SSH_IDENTITY=~/.ssh/your_key ./shell/deploy-admin-by80.sh +# 使用: ./shell/deploy-admin-by80.sh(在 backend 目录下) + +set -e +SSH_IDENTITY="${SSH_IDENTITY:-$HOME/.ssh/id_ed25519_crmeb_deploy}" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +BACKEND_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +ROOT_DIR="$(cd "$BACKEND_DIR/.." && pwd)" +FRONTEND_DIR="$ROOT_DIR/frontend" +DEPLOY_CONF="$BACKEND_DIR/deploy.conf" + +# 解析 by80 段配置(deploy.conf 中 by80 段到 miao50 段之间的 KEY=value) +get_conf() { + sed -n '1,/^miao50:/p' "$DEPLOY_CONF" | grep -E "^${1}=" | tail -1 | cut -d= -f2- +} +SERVER_HOST=$(get_conf SERVER_HOST) +SERVER_USER=$(get_conf SERVER_USER) +SERVER_PORT=$(get_conf SERVER_PORT) +REMOTE_DIR_JAR=$(get_conf REMOTE_DIR_JAR) +REMOTE_DIR_ADMIN=$(get_conf REMOTE_DIR_ADMIN) +ADMIN_JAR_NAME=$(get_conf ADMIN_JAR_NAME) +ADMIN_LOCAL_PORT=$(get_conf ADMIN_LOCAL_PORT) + +[[ -z "$SERVER_HOST" ]] && SERVER_HOST=123.56.214.80 +[[ -z "$REMOTE_DIR_JAR" ]] && REMOTE_DIR_JAR=/www/wwwroot/crmeb +[[ -z "$REMOTE_DIR_ADMIN" ]] && REMOTE_DIR_ADMIN=/www/wwwroot/jfadmin.bosenyuan.com +[[ -z "$ADMIN_JAR_NAME" ]] && ADMIN_JAR_NAME=miao-admin-2.2.jar +[[ -z "$ADMIN_LOCAL_PORT" ]] && ADMIN_LOCAL_PORT=30032 +[[ -z "$SERVER_USER" ]] && SERVER_USER=root +[[ -z "$SERVER_PORT" ]] && SERVER_PORT=22 + +JAR_PATH="$BACKEND_DIR/crmeb-admin/target/$ADMIN_JAR_NAME" +REMOTE_JAR="$REMOTE_DIR_JAR/$ADMIN_JAR_NAME" +[[ -f "$SSH_IDENTITY" ]] && SSH_OPTS=(-o "IdentityFile=$SSH_IDENTITY") || SSH_OPTS=() +SSH_CMD=(ssh "${SSH_OPTS[@]}" -o StrictHostKeyChecking=accept-new -p "$SERVER_PORT" "$SERVER_USER@$SERVER_HOST") +SCP_CMD=(scp "${SSH_OPTS[@]}" -o StrictHostKeyChecking=accept-new -P "$SERVER_PORT") + +BACKUP_SUFFIX="backup_$(date +%Y%m%d_%H%M%S)" + +echo "=== 1. 编译后端 (crmeb-admin, profile=miao80) ===" +cd "$BACKEND_DIR" +mvn clean package -pl crmeb-admin -am -DskipTests -q +echo "已生成: $JAR_PATH" +[[ ! -f "$JAR_PATH" ]] && { echo "错误: jar 未生成"; exit 1; } + +echo "" +echo "=== 2. 编译前端 (admin 后台) ===" +cd "$FRONTEND_DIR" +# Node.js 17+ OpenSSL 兼容 +export NODE_OPTIONS="${NODE_OPTIONS:-} --openssl-legacy-provider" +npm run build:prod +echo "已生成: $FRONTEND_DIR/dist" +[[ ! -d "$FRONTEND_DIR/dist" ]] && { echo "错误: dist 未生成"; exit 1; } + +echo "" +echo "=== 3. 远程备份原有文件 ===" +"${SSH_CMD[@]}" "bash -s" << REMOTE_BACKUP +set -e +mkdir -p "$REMOTE_DIR_JAR/backups" +if [ -f "$REMOTE_JAR" ]; then + cp -a "$REMOTE_JAR" "$REMOTE_DIR_JAR/backups/${ADMIN_JAR_NAME}.${BACKUP_SUFFIX}" + echo "已备份 jar: $REMOTE_DIR_JAR/backups/${ADMIN_JAR_NAME}.${BACKUP_SUFFIX}" +fi +if [ -d "$REMOTE_DIR_ADMIN" ] && [ "\$(ls -A $REMOTE_DIR_ADMIN 2>/dev/null)" ]; then + BACKUP_TAR="$REMOTE_DIR_ADMIN/../jfadmin_${BACKUP_SUFFIX}.tar.gz" + tar -czf "\$BACKUP_TAR" -C "$REMOTE_DIR_ADMIN" . + echo "已备份后台静态: \$BACKUP_TAR" +fi +REMOTE_BACKUP + +echo "" +echo "=== 4. 上传 miao-admin-2.2.jar 到 $REMOTE_DIR_JAR ===" +"${SCP_CMD[@]}" "$JAR_PATH" "$SERVER_USER@$SERVER_HOST:$REMOTE_DIR_JAR/" +echo "jar 上传完成." + +echo "" +echo "=== 5. 上传 admin 后台静态 (dist) 到 $REMOTE_DIR_ADMIN ===" +# 先清空远程目录再上传,避免残留旧文件(远程可能无 rsync,统一用 tar 管道) +"${SSH_CMD[@]}" "mkdir -p $REMOTE_DIR_ADMIN && (rm -rf ${REMOTE_DIR_ADMIN}/* ${REMOTE_DIR_ADMIN}/.??* 2>/dev/null; true)" +(cd "$FRONTEND_DIR/dist" && tar cf - .) | "${SSH_CMD[@]}" "mkdir -p $REMOTE_DIR_ADMIN && cd $REMOTE_DIR_ADMIN && tar xf -" +echo "后台静态上传完成." + +echo "" +echo "=== 6. 远程重启 admin 服务 (profile=miao80, port=$ADMIN_LOCAL_PORT) ===" +"${SSH_CMD[@]}" "cd $REMOTE_DIR_JAR && \ + (pkill -f $ADMIN_JAR_NAME || true) && \ + sleep 2 && \ + nohup java -jar $ADMIN_JAR_NAME --spring.profiles.active=miao80 --server.port=$ADMIN_LOCAL_PORT > admin.log 2>&1 & \ + sleep 3 && \ + (pgrep -f $ADMIN_JAR_NAME && echo 'Admin 进程已启动' || echo '请检查 admin.log 启动是否失败')" + +echo "" +echo "=== 部署完成 ===" diff --git a/frontend/.env.development b/frontend/.env.development index ce9e95e..e7a6fcd 100644 --- a/frontend/.env.development +++ b/frontend/.env.development @@ -3,10 +3,12 @@ ENV = 'development' # base api # VUE_APP_BASE_API = '/dev-api' -# VUE_APP_BASE_API = 'http://127.0.0.1:30032' + VUE_APP_BASE_API = 'http://127.0.0.1:30032' # VUE_APP_BASE_API = 'https://jfadmin.suzhouyuqi.com' # VUE_APP_BASE_API = 'http://jfanyueadmin.szxingming.com' - VUE_APP_BASE_API = 'http://jfadmin.wenjinhui.com' +# VUE_APP_BASE_API = 'http://jfadmin.wenjinhui.com' +# VUE_APP_BASE_API = 'http://jfadmin-bsy.bosenyuan.com' + # vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, # to control whether the babel-plugin-dynamic-import-node plugin is enabled. diff --git a/frontend/.env.production b/frontend/.env.production index c2b01db..75ffd22 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -3,8 +3,11 @@ ENV = 'production' # base api # VUE_APP_BASE_API = '/prod-api' -# VUE_APP_BASE_API = 'http://127.0.0.1:8080' -# VUE_APP_BASE_API = 'https://jf.suzhouyuqi.com' -# VUE_APP_BASE_API = 'http://jfadmin.xiashengjun.com' -# VUE_APP_BASE_API = 'http://jfanyueadmin.szxingming.com' -VUE_APP_BASE_API = 'http://jfadmin.wenjinhui.com' +# VUE_APP_BASE_API = 'http://127.0.0.1:8080' +# VUE_APP_BASE_API = 'https://jf.suzhouyuqi.com' +# VUE_APP_BASE_API = 'http://jfadmin.xiashengjun.com' +# VUE_APP_BASE_API = 'http://jfadmin.wenjinhui.com' +# VUE_APP_BASE_API = 'http://jfanyueadmin.szxingming.com' +# VUE_APP_BASE_API = 'http://jfadmin-bsy.bosenyuan.com' +# miao33 项目 +VUE_APP_BASE_API = 'http://jfadmin.xiashengjun.com' diff --git a/frontend/DEPLOY.md b/frontend/DEPLOY.md new file mode 100644 index 0000000..26e07c7 --- /dev/null +++ b/frontend/DEPLOY.md @@ -0,0 +1,80 @@ +# 前端打包与自动部署发布 + +本文档说明 **admin 后台前端** 的打包、以及如何自动部署发布到远程服务器(含与后端一起一键发布)。 + +--- + +## 一、环境要求 + +- **Node.js**、**npm** 已安装。 +- **Node 17+** 需设置 OpenSSL 兼容(见下方打包命令)。 +- 部署到远程前需完成 **SSH 免密**(见 [backend/DEPLOY.md](../backend/DEPLOY.md))。 + +--- + +## 二、前端打包 + +在 **frontend 目录** 下执行: + +```bash +cd frontend + +# Node 17+ 如遇 digital envelope 报错,先执行: +export NODE_OPTIONS="${NODE_OPTIONS:-} --openssl-legacy-provider" + +npm run build:prod +``` + +- **产出目录**:`frontend/dist` +- **用途**:admin 后台静态资源,将 `dist` 内容部署到站点根目录(如 Nginx 或 CDN)。 + +--- + +## 三、自动部署发布(推荐) + +前端与后端一起发布时,使用 **backend 的一键部署脚本**,会自动完成:前端打包 → 后端打包 → 远程备份 → 上传 jar 与 `dist` → 重启服务。 + +在项目 **backend 目录** 下执行: + +```bash +cd backend +./shell/deploy-admin-by80.sh +``` + +脚本会: + +1. 编译后端,生成 `miao-admin-2.2.jar` +2. **在 frontend 目录执行 `npm run build:prod`**,生成 `dist` +3. 远程备份原有 jar 与后台静态 +4. 上传 jar 到 `REMOTE_DIR_JAR`,上传 **dist 到 REMOTE_DIR_ADMIN** +5. 远程重启 admin 服务(Spring Profile miao80) + +即:**前端无需单独操作,一次执行即可完成前端打包 + 自动部署发布**。 +SSH 配置、deploy.conf、故障排查见:**[backend/DEPLOY.md](../backend/DEPLOY.md)**。 + +--- + +## 四、部署配置(前端相关) + +配置在 **backend/deploy.conf**,by80 段示例: + +| 配置项 | 说明 | 示例 | +|--------|------|------| +| **REMOTE_DIR_ADMIN** | 前端 dist 发布目录(admin 后台站点根目录) | `/www/wwwroot/jfadmin.bosenyuan.com` | + +脚本通过 **tar 管道** 将 `frontend/dist` 内容上传到该目录,不依赖远程安装 rsync。 + +--- + +## 五、仅打包不发布 + +若只需在本地生成 `dist`、不执行上传与重启: + +```bash +cd frontend +export NODE_OPTIONS="${NODE_OPTIONS:-} --openssl-legacy-provider" +npm run build:prod +# 产出:frontend/dist +``` + +完整自动部署步骤、备份与重启说明见 **[backend/DEPLOY.md](../backend/DEPLOY.md)**。 diff --git a/frontend/deploy.conf b/frontend/deploy.conf new file mode 100644 index 0000000..76bf113 --- /dev/null +++ b/frontend/deploy.conf @@ -0,0 +1,29 @@ +by80: + spring: + profiles: + active: miao80 + +SERVER_HOST=123.56.214.80 +SERVER_USER=root +SERVER_PORT=22 +REMOTE_DIR_JAR=/www/wwwroot/crmeb +REMOTE_DIR_ADMIN=/www/wwwroot/jfadmin.bosenyuan.com +FRONT_LOCAL_PORT=30031 +FRONT_JAR_NAME=miao-front-2.2.jar +ADMIN_LOCAL_PORT=30032 +ADMIN_JAR_NAME=miao-admin-2.2.jar + + +miao50: + spring: + profiles: + active: miao50 + +SERVER_HOST=101.37.253.50 +SERVER_USER=root +SERVER_PORT=22 +REMOTE_DIR=/www/wwwroot/crmeb +FRONT_LOCAL_PORT=30031 +FRONT_JAR_NAME=miao-front-2.2.jar +ADMIN_LOCAL_PORT=30032 +ADMIN_JAR_NAME=miao-admin-2.2.jar diff --git a/frontend/src/views/user/list/index.vue b/frontend/src/views/user/list/index.vue index 117a6cd..a3baaf4 100644 --- a/frontend/src/views/user/list/index.vue +++ b/frontend/src/views/user/list/index.vue @@ -345,8 +345,8 @@ - +