Bladeren bron

基于临时站点创建模板

chenlei1231 3 weken geleden
bovenliggende
commit
8e9b210db6

+ 703 - 633
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/site/service/SelfWebSiteService.java

@@ -1,9 +1,11 @@
 package org.jeecg.modules.adweb.site.service;
 
 import jakarta.annotation.Resource;
-
+import java.io.File;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Date;
 import lombok.extern.slf4j.Slf4j;
-
 import org.apache.commons.lang3.StringUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.SymbolConstant;
@@ -18,16 +20,13 @@ import org.jeecg.modules.adweb.server.service.IAdwebServerService;
 import org.jeecg.modules.adweb.site.entity.AdwebSite;
 import org.jeecg.modules.adweb.system.entity.SysException;
 import org.jeecg.modules.adweb.system.service.ISysExceptionService;
+import org.jeecg.modules.adweb.theme.entity.AdwebTheme;
+import org.jeecg.modules.adweb.theme.service.IAdwebThemeService;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.stereotype.Service;
 
-import java.io.File;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-
 /**
  * @author jerry
  */
@@ -36,664 +35,735 @@ import java.util.Date;
 @EnableAsync
 public class SelfWebSiteService {
 
-    @Resource private IAdwebSiteService siteService;
-
-    /** 远程脚本执行服务类 */
-    @Resource private ShellService shellService;
-
-    @Resource private SelfWebSiteServiceCommon selfWebSiteServiceCommon;
-
-    @Resource private WebSocketService webSocketService;
-
-    @Resource private IAdwebServerService serverService;
-
-    @Value("${AdwebSiteConnect.host}")
-    private String host;
-
-    @Value("${AdwebSiteConnect.port}")
-    private int port;
-
-    @Value("${AdwebSiteConnect.username}")
-    private String username;
-
-    @Value("${AdwebSiteConnect.password}")
-    private String password;
-
-    @Value(value = "${jeecg.path.upload}")
-    private String uploadpath;
-
-    @Resource private FeishuService openFeishuMsgService;
-
-    @Resource private ISysExceptionService sysExceptionService;
-
-    private String errorMsg = "";
-
-    /**
-     * 创建站点的方法
-     *
-     * @param user 当前登录用户
-     * @param tempId 模板ID
-     * @param uid 用户ID
-     * @param name 站点名称
-     * @param planId 套餐ID
-     * @param sysUser 系统用户
-     * @param giveDay 赠送天数
-     * @param compensateDay 补偿天数
-     */
-    @Async
-    public void createSite(
-            LoginUser user,
-            Long tempId,
-            String uid,
-            String name,
-            String planId,
-            LoginUser sysUser,
-            Integer giveDay,
-            Integer compensateDay) {
-        // 创建站点信息,生成code,拼接域名等,并将站点信息写入数据库
-
-        AdwebSite adwebSite = null;
-        try {
-            adwebSite =
-                    selfWebSiteServiceCommon.saveNewSiteInfo(
-                            tempId, uid, name, planId, sysUser, giveDay, compensateDay);
-        } catch (Exception e) {
-            log.error("新建站点时保存站点信息失败", e);
-        }
-
-        try {
-
-            // 执行临时服务器shell脚本,生成临时站点
-            String cmd =
-                    "sh /opt/adweb3/shell/auto-wpsite "
-                            + adwebSite.getCode()
-                            + " "
-                            + adwebSite.getParentCode();
-
-            AdwebSite finalAdwebSite = adwebSite;
-            shellService.createShareSiteByPwd(
-                    cmd,
-                    host,
-                    port,
-                    username,
-                    password,
-                    new ShellSSH2Util.StdoutListener() {
-                        @Override
-                        public void stdout(String line) {
-                            log.info("标准 :{}", line);
-
-                            if (line.startsWith("执行命令成功")) {
-                                log.info("站点创建成功!更新站点状态");
-
-                                // 更新站点流程状态
-                                siteService.updateSiteFlow(finalAdwebSite.getCode());
-
-                                // 临时站点创建成功
-                                finalAdwebSite.setStatus(2);
-                                siteService.updateById(finalAdwebSite);
-
-                                String[] userIds = {user.getId()};
-                                // 给该站点所属的用户发送消息
-                                log.info("发送创建站点通知");
-                                webSocketService.sendMessage(
-                                        userIds,
-                                        "站点创建完成通知",
-                                        "您的站点已经创建成功,请在站点管理中查看该站点详细信息",
-                                        WebsocketConst.CMD_MANAGE_SITE);
-                            }
-                        }
-
-                        @Override
-                        public void stderr(String line) {
-                            log.info("错误 :{}", line);
-                            errorMsg += line;
-                        }
-                    });
-
-            if (StringUtils.isNotBlank(errorMsg)) {
-                createSiteFailed(adwebSite, errorMsg, 4);
-            }
-        } catch (Exception e) {
-            log.error("在wp服务器上生成站点文件失败");
-            createSiteFailed(adwebSite, e.getMessage(), 4);
-        }
-    }
+  @Resource private IAdwebSiteService siteService;
 
-    /**
-     * 删除指定的广告网站
-     *
-     * <p>此方法通过执行远程服务器上的Shell脚本来删除广告网站资源,并在删除成功后通知用户 如果删除失败,会记录错误信息并抛出异常
-     *
-     * @param user 当前操作的用户,用于发送通知
-     * @param adwebSite 要删除的广告网站对象,包含网站代码和域名等信息
-     */
-    @Async
-    public void removeSite(LoginUser user, AdwebSite adwebSite) {
-        try {
-
-            // 执行临时服务器shell脚本,生成临时站点
-            String cmd = "sh /opt/adweb3/shell/remove-and-bak-wpsite.sh " + adwebSite.getCode();
-
-            AdwebSite finalAdwebSite = adwebSite;
-            shellService.createShareSiteByPwd(
-                    cmd,
-                    host,
-                    port,
-                    username,
-                    password,
-                    new ShellSSH2Util.StdoutListener() {
-                        @Override
-                        public void stdout(String line) {
-                            log.info("标准 :{}", line);
-
-                            if (line.startsWith("执行命令成功")) {
-                                log.info("站点资源删除成功!");
-
-                                String[] userIds = {user.getId()};
-                                // 给该站点所属的用户发送消息
-                                log.info("发送删除站点资源通知");
-                                webSocketService.sendMessage(
-                                        userIds,
-                                        "站点删除通知",
-                                        "站点资源" + finalAdwebSite.getDomain() + "已经从系统删除!",
-                                        WebsocketConst.CMD_MANAGE_SITE);
-                            }
-                        }
-
-                        @Override
-                        public void stderr(String line) {
-                            log.info("错误 :{}", line);
-                            errorMsg += line;
-                        }
-                    });
-
-            if (StringUtils.isNotBlank(errorMsg)) {
-                exceShellFailed("删除站点资源", adwebSite, errorMsg);
-            }
-        } catch (Exception e) {
-            log.error("在wp服务器上删除站点资源失败");
-            exceShellFailed("删除站点资源", adwebSite, e.getMessage());
-        }
-    }
+  @Resource private IAdwebThemeService themeService;
 
-    /**
-     * 当执行Shell命令失败时调用此方法记录错误信息
-     *
-     * @param cmd 执行的Shell命令,用于标识操作
-     * @param adwebSite 发生错误的广告网站实例,包含站点信息
-     * @param errorMsg 错误信息描述,详细说明执行失败的原因
-     */
-    private void exceShellFailed(String cmd, AdwebSite adwebSite, String errorMsg) {
-        SysException sysException = new SysException();
-
-        sysException.setType(1);
-        sysException.setFunctionModule(cmd);
-        sysException.setExceptionDetail(
-                String.format(
-                        "站点code:%s, 站点名称:%s,临时连接:%s",
-                        adwebSite.getCode(), adwebSite.getName(), adwebSite.getDomain()));
-        sysException.setExceptionDescription(errorMsg);
-
-        sysExceptionService.save(sysException);
-    }
+  /** 远程脚本执行服务类 */
+  @Resource private ShellService shellService;
 
-    /**
-     * 处理临时站点创建失败的逻辑 当临时站点创建失败时,此方法会被调用,更新站点状态并记录错误信息
-     *
-     * @param adwebSite 代表临时站点的对象,包含站点的相关信息
-     * @param errorMsg 描述创建失败的错误信息
-     */
-    private void createSiteFailed(AdwebSite adwebSite, String errorMsg, int status) {
-        adwebSite.setStatus(status); // 临时站点创建失败 或者正式站点创建失败
-        siteService.updateById(adwebSite);
+  @Resource private SelfWebSiteServiceCommon selfWebSiteServiceCommon;
+
+  @Resource private WebSocketService webSocketService;
+
+  @Resource private IAdwebServerService serverService;
+
+  @Value("${AdwebSiteConnect.host}")
+  private String host;
+
+  @Value("${AdwebSiteConnect.port}")
+  private int port;
+
+  @Value("${AdwebSiteConnect.username}")
+  private String username;
+
+  @Value("${AdwebSiteConnect.password}")
+  private String password;
+
+  @Value(value = "${jeecg.path.upload}")
+  private String uploadpath;
+
+  @Value("${AdwebSiteConnect.tempDomain}")
+  private String tempDomain;
+
+  @Resource private FeishuService openFeishuMsgService;
 
-        SysException sysException = new SysException();
+  @Resource private ISysExceptionService sysExceptionService;
 
-        sysException.setType(1); // 业务错误
-        sysException.setFunctionModule("拉取站点错误");
-        sysException.setExceptionDetail(
-                String.format(
-                        "站点code:%s, 站点名称:%s,临时连接:%s",
-                        adwebSite.getCode(), adwebSite.getName(), adwebSite.getDomain()));
-        sysException.setExceptionDescription(errorMsg);
+  private String errorMsg = "";
 
-        sysExceptionService.save(sysException);
+  /**
+   * 创建站点的方法
+   *
+   * @param user 当前登录用户
+   * @param tempId 模板ID
+   * @param uid 用户ID
+   * @param name 站点名称
+   * @param planId 套餐ID
+   * @param sysUser 系统用户
+   * @param giveDay 赠送天数
+   * @param compensateDay 补偿天数
+   */
+  @Async
+  public void createSite(
+      LoginUser user,
+      Long tempId,
+      String uid,
+      String name,
+      String planId,
+      LoginUser sysUser,
+      Integer giveDay,
+      Integer compensateDay) {
+    // 创建站点信息,生成code,拼接域名等,并将站点信息写入数据库
+
+    AdwebSite adwebSite = null;
+    try {
+      adwebSite =
+          selfWebSiteServiceCommon.saveNewSiteInfo(
+              tempId, uid, name, planId, sysUser, giveDay, compensateDay);
+    } catch (Exception e) {
+      log.error("新建站点时保存站点信息失败", e);
     }
 
-    /**
-     * 发布站点到生产环境
-     *
-     * @param user 当前登录用户
-     * @param serverId 服务器ID,未在方法体内使用
-     * @param domain 域名,用于站点发布
-     * @param siteCode 站点代码,标识特定的站点
-     */
-    @Async
-    public void releaseSite(LoginUser user, String serverId, String domain, String siteCode) {
-        log.info("===== releaseSite domain:{},siteCode:{} ====", domain, siteCode);
-        StringBuilder statusSuccess = new StringBuilder();
-        StringBuilder statusFail = new StringBuilder();
-        AdwebSite adwebSite = siteService.getSiteByCode(siteCode);
-        AdwebServer adwebServer = serverService.getById(serverId);
-
-        if (adwebServer == null) {
-            log.error("发布生产环境时未指定服务器");
-            return;
-        }
-
-        String serverShellPath = "/opt/adweb3/shell";
-
-        // 原始域名
-        String originDomain = domain;
-        // 检验域名是否以www开头
-        if (domain.startsWith("www.")) {
-            domain = domain.replace("www.", "");
-        }
-        String dbName = domain.replaceAll("[^a-zA-Z0-9]", "") + "_" + adwebSite.getCode();
-
-        log.info(
-                "===== releaseSite domain:{}, siteCode:{},originDomain:{},domain:{},dbName:{} ====",
-                domain,
-                siteCode,
-                originDomain,
-                domain,
-                dbName);
-
-        String cmd =
-                "sudo sh "
-                        + serverShellPath
-                        + "/publish_wp_site.sh "
-                        + adwebSite.getCode()
-                        + " "
-                        + domain
-                        + " "
-                        + dbName;
-
-        log.info(
-                "===== releaseSite originDomain:{},domain:{},siteCode:{},cmd:{} ====",
-                originDomain,
-                domain,
-                siteCode,
-                cmd);
-
-        try {
-            if (StringUtils.isBlank(adwebServer.getServerPem())) {
+    try {
+      // 执行临时服务器shell脚本,生成临时站点
+      String cmd =
+          "sh /opt/adweb3/shell/auto-wpsite "
+              + adwebSite.getCode()
+              + " "
+              + adwebSite.getParentCode();
+
+      AdwebSite finalAdwebSite = adwebSite;
+      shellService.createShareSiteByPwd(
+          cmd,
+          host,
+          port,
+          username,
+          password,
+          new ShellSSH2Util.StdoutListener() {
+            @Override
+            public void stdout(String line) {
+              log.info("标准 :{}", line);
+
+              if (line.startsWith("执行命令成功")) {
+                log.info("站点创建成功!更新站点状态");
+
+                // 更新站点流程状态
+                siteService.updateSiteFlow(finalAdwebSite.getCode());
+
+                // 临时站点创建成功
+                finalAdwebSite.setStatus(2);
+                siteService.updateById(finalAdwebSite);
+
                 String[] userIds = {user.getId()};
                 // 给该站点所属的用户发送消息
-                log.info("生产服务器:{},未配置连接秘钥", adwebServer.getServerName());
+                log.info("发送创建站点通知");
                 webSocketService.sendMessage(
-                        userIds,
-                        "站点发布失败通知",
-                        "该站点发布失败,请联系管理员配置服务器连接秘钥",
-                        WebsocketConst.CMD_MANAGE_SITE);
-                return;
+                    userIds,
+                    "站点创建完成通知",
+                    "您的站点已经创建成功,请在站点管理中查看该站点详细信息",
+                    WebsocketConst.CMD_MANAGE_SITE);
+              }
             }
 
-            adwebSite.setStatus(5); // 正式站点正在创建
-            siteService.updateById(adwebSite);
-
-            String pemPath = adwebServer.getServerPem().replace("..", "").replace("../", "");
-            if (pemPath.endsWith(SymbolConstant.COMMA)) {
-                pemPath = pemPath.substring(0, pemPath.length() - 1);
+            @Override
+            public void stderr(String line) {
+              log.info("错误 :{}", line);
+              errorMsg += line;
             }
-
-            String filePath = uploadpath + File.separator + pemPath;
-            adwebServer.setServerPem(filePath); // 设置秘钥绝对路径
-
-            shellService.exceShell(
-                    cmd,
-                    new ShellSSH2Util.StdoutListener() {
-                        @Override
-                        public void stdout(String line) {
-                            log.info("标准 :{}", line);
-
-                            if ("[Creation completed]".equals(line)) {
-                                log.info("======网站上线成功======");
-                                statusSuccess.append("ok");
-                            }
-                        }
-
-                        @Override
-                        public void stderr(String line) {
-                            log.info("错误 :{}", line);
-                            statusFail.append(line);
-                        }
-                    },
-                    adwebServer);
-
-            // 正式域名
-            log.info(
-                    "===== releaseSite originDomain:{},domain:{},siteCode:{},statusSuccess:{} ====",
-                    originDomain,
-                    domain,
-                    siteCode,
-                    statusSuccess);
-            log.info(
-                    "===== releaseSite originDomain:{},domain:{},siteCode:{},statusFail:{} ====",
-                    originDomain,
-                    domain,
-                    siteCode,
-                    statusFail);
-            if (StringUtils.isNotEmpty(statusFail.toString())) {
-                String title = "网站域名:" + originDomain + " 站点发布失败";
-                String message = "**站点CODE:** " + siteCode + "\n";
-                message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
-                message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
-                message += "**错误信息:** " + statusFail.toString() + "\n";
-                sendAdWebV3FeiShuMsg(title, message);
-
-                // 站点发布失败
-                createSiteFailed(adwebSite, statusFail.toString(), 6);
-
-            } else {
-                String title = "网站域名:" + originDomain + " 站点发布成功";
-                String message = "**站点CODE:** " + siteCode + "\n";
-                message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
-                message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
-                sendAdWebV3FeiShuMsg(title, message); // 发送飞书消息
+          });
+
+      if (StringUtils.isNotBlank(errorMsg)) {
+        createSiteFailed(adwebSite, errorMsg, 4);
+      }
+    } catch (Exception e) {
+      log.error("在wp服务器上生成站点文件失败");
+      createSiteFailed(adwebSite, e.getMessage(), 4);
+    }
+  }
+
+  /**
+   * 删除站点资源
+   *
+   * <p>此方法通过执行远程服务器上的Shell脚本来删除广告网站资源,并在删除成功后通知用户 如果删除失败,会记录错误信息并抛出异常
+   *
+   * @param user 当前操作的用户,用于发送通知
+   * @param adwebSite 要删除的广告网站对象,包含网站代码和域名等信息
+   */
+  @Async
+  public void removeSite(LoginUser user, AdwebSite adwebSite) {
+    try {
+
+      // 执行临时服务器shell脚本,生成临时站点
+      String cmd = "sh /opt/adweb3/shell/remove-and-bak-wpsite.sh " + adwebSite.getCode();
+
+      AdwebSite finalAdwebSite = adwebSite;
+      shellService.createShareSiteByPwd(
+          cmd,
+          host,
+          port,
+          username,
+          password,
+          new ShellSSH2Util.StdoutListener() {
+            @Override
+            public void stdout(String line) {
+              log.info("标准 :{}", line);
+
+              if (line.startsWith("执行命令成功")) {
+                log.info("站点资源删除成功!");
 
                 String[] userIds = {user.getId()};
                 // 给该站点所属的用户发送消息
-                log.info("发布站点成功通知");
+                log.info("发送删除站点资源通知");
                 webSocketService.sendMessage(
-                        userIds,
-                        "站点发布完成通知",
-                        "您的站点已经发布成功,请在站点管理中查看该站点详细信息",
-                        WebsocketConst.CMD_MANAGE_SITE);
-
-                // 创建站点完成-操作
-                adwebSite.setDomain(originDomain);
-                adwebSite.setIsDomain(1);
-                // 添加发布时间
-                adwebSite.setIssueTime(new Date());
-                // 发布成功后修改状态为发布成功状态 :1
-                adwebSite.setStatus(1);
-                adwebSite.setProdServerIp(adwebServer.getServerIp());
-                siteService.updateById(adwebSite);
+                    userIds,
+                    "站点删除通知",
+                    "站点资源" + finalAdwebSite.getDomain() + "已经从系统删除!",
+                    WebsocketConst.CMD_MANAGE_SITE);
+              }
+            }
+
+            @Override
+            public void stderr(String line) {
+              log.info("错误 :{}", line);
+              errorMsg += line;
             }
-        } catch (Exception e) {
-            log.error("站点发布失败,退出执行;{}", e.getMessage(), e);
-            createSiteFailed(adwebSite, e.getMessage(), 6);
-        }
+          });
+
+      if (StringUtils.isNotBlank(errorMsg)) {
+        exceShellFailed("删除站点资源", adwebSite, errorMsg);
+      }
+    } catch (Exception e) {
+      log.error("在wp服务器上删除站点资源失败");
+      exceShellFailed("删除站点资源", adwebSite, e.getMessage());
     }
+  }
+
+  @Async
+  public void createThemeBySite(LoginUser user, AdwebTheme adwebTheme, AdwebSite adwebSite) {
+    try {
+      // 执行临时服务器shell脚本,基于临时站点创建模板
+      String cmd =
+          "sh /opt/adweb3/shell/create_v3_wp_template.sh "
+              + adwebTheme.getCode()
+              + " "
+              + adwebSite.getCode();
+
+      AdwebTheme finalAdwebTheme = adwebTheme;
+      shellService.createShareSiteByPwd(
+          cmd,
+          host,
+          port,
+          username,
+          password,
+          new ShellSSH2Util.StdoutListener() {
+            @Override
+            public void stdout(String line) {
+              log.info("标准 :{}", line);
+
+              if (line.startsWith("执行命令成功")) {
+                log.info("模板站点创建成功!更新站点状态");
+
+                // 临时站点创建成功
+                String domain = finalAdwebTheme.getCode() + "." + tempDomain;
+                finalAdwebTheme.setDomain(domain);
+                finalAdwebTheme.setStatus(1); // 创建模板成功
+                themeService.updateById(finalAdwebTheme);
 
-    /**
-     * 删除发布失败的站点(生产环境)
-     *
-     * @param domain 新域名
-     * @param siteId 站点ID
-     */
-    public Result<?> delReleaseWebsite(String domain, Integer siteId) {
-        log.info("===== delReleaseWebsite domain:{},siteId:{} ====", domain, siteId);
-        StringBuilder delSuccess = new StringBuilder();
-        StringBuilder delFail = new StringBuilder();
-        AdwebSite adwebSite = siteService.getById(siteId);
-        String usWest118ServerShellPath = "/home/ci-user/shell";
-        // 检验域名是否以www开头
-        if (domain.startsWith("www.")) {
-            domain = domain.replace("www.", "");
-        }
-        // 删除已发布的站点,重新发布
-        if (adwebSite.getStatus() == 5) {
-            String cmd =
-                    "sudo sh " + usWest118ServerShellPath + "/adweb-remove_prod_site.sh " + domain;
-            log.info(
-                    "===== delReleaseWebsite domain:{},siteId:{},cmd:{} ====", domain, siteId, cmd);
-            try {
-                String finalDomain = domain;
-                //                shellService.exceShellByUsWest118(cmd, new
-                // ShellSSH2Util.StdoutListener() {
-                //                    @Override
-                //                    public void stdout(String line) {
-                //                        log.info("标准 :" + line);
-                //                        if ("remove site success".equals(line) || "remove site
-                // nginx success".equals(line)) {
-                //                            log.info("======执行删除旧站点,成功通知======");
-                //                            String title = "网站域名:" + finalDomain + "
-                // 删除发布失败的旧站点成功";
-                //                            String message = "**站点ID:** " + siteId + "\n";
-                //                            message += "**临时域名:** " + adwebSite.getDomainDev() +
-                // "\n";
-                //                            message += "**服务器IP:** " + adwebSite.getDevServerIp()
-                // + "\n";
-                //                            sendAdWebV3FeiShuMsg(title, message);
-                //
-                //                            delSuccess.append(line);
-                //                        }
-                //
-                //                        if ("remove site failed".equals(line) || "remove site
-                // nginx failed".equals(line)) {
-                //                            log.info("======执行删除旧站点,失败通知======");
-                //                            String title = "网站域名:" + finalDomain + "
-                // 删除发布失败的旧站点失败";
-                //                            String message = "**站点ID:** " + siteId + "\n";
-                //                            message += "**临时域名:** " + adwebSite.getDomainDev() +
-                // "\n";
-                //                            message += "**服务器IP:** " + adwebSite.getDevServerIp()
-                // + "\n";
-                //                            message += "**错误信息:** " + line + "\n";
-                //                            sendAdWebV3FeiShuMsg(title, message);
-                //
-                //                            delFail.append(line);
-                //                        }
-                //                    }
-                //
-                //                    @Override
-                //                    public void stderr(String line) {
-                //                        log.info("错误 :" + line);
-                //                        String title = "网站域名:" + finalDomain + " 删除发布失败的旧站点失败";
-                //                        String message = "**站点ID:** " + siteId + "\n";
-                //                        message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
-                //                        message += "**服务器IP:** " + adwebSite.getDevServerIp() +
-                // "\n";
-                //                        message += "**错误信息:** " + line + "\n";
-                //                        sendAdWebV3FeiShuMsg(title, message);
-                //
-                //                        delFail.append(line);
-                //                    }
-                //                });
-            } catch (Exception e) {
-                log.error("删除发布失败的旧站点失败,退出执行;" + e.getMessage(), e);
-                delFail.append(e.getMessage());
+                String[] userIds = {user.getId()};
+                // 给该站点所属的用户发送消息
+                log.info("发送创建模板通知");
+                webSocketService.sendMessage(
+                    userIds, "模板创建完成通知", "您的模板站点已经创建成功", WebsocketConst.CMD_MANAGE_SITE);
+              }
             }
 
-            if (StringUtils.isNotBlank(delFail.toString())) {
-                return Result.error("旧站点删除失败,请重试!");
-            } else {
-                return Result.OK("旧站点删除成功!");
+            @Override
+            public void stderr(String line) {
+              log.info("错误 :{}", line);
+              errorMsg += line;
             }
-        } else {
-            return Result.error("该站点状态不是发布失败,执行失败!");
-        }
-    }
+          });
 
-    /**
-     * 站点启动/停止
-     *
-     * @param sysUser
-     * @param siteId
-     * @param status
-     * @return
-     */
-    public boolean siteStartOrStop(LoginUser sysUser, Integer siteId, Integer status) {
-        AdwebSite adwebSite = siteService.getById(siteId);
-
-        // 获取站点所在生产服务器信息
-        AdwebServer serverInfo = new AdwebServer();
-        boolean flag = false;
-        switch (status) {
-            case 1:
-                flag = startSiteLocal(sysUser, adwebSite);
-                break;
-            case 2:
-                flag = stopSiteLocal(sysUser, adwebSite);
-                break;
-            case 3:
-                flag = startSite(sysUser, adwebSite, serverInfo);
-                break;
-            case 4:
-                flag = stopSite(sysUser, adwebSite, serverInfo);
-                break;
-        }
-        return flag;
-    }
+      if (StringUtils.isNotBlank(errorMsg)) {
+        createThemeFailed(adwebTheme, errorMsg, 2);
+      }
+    } catch (Exception e) {
 
-    /**
-     * 站点启动脚本调用(未发布)
-     *
-     * @param sysUser
-     * @param adwebSite
-     * @return
-     */
-    private boolean startSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
-        // 站点启动
-        String cmd = "/home/ci-user/shell/start_site " + adwebSite.getCode() + " ";
-        shellService.exceShellByPwd(
-                cmd,
-                host,
-                port,
-                username,
-                password,
-                new ShellSSH2Util.StdoutListener() {
-                    @Override
-                    public void stdout(String line) {
-                        log.info("标准 :" + line);
-                        if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
-                            // TODO ----
-                            log.error("恢复测试站点异常:" + line);
-                        }
-                    }
-
-                    @Override
-                    public void stderr(String line) {
-                        log.info("错误 :" + line);
-                    }
-                });
-        return siteStatusUpdate(sysUser, adwebSite, 0);
     }
-
-    /**
-     * 站点停止脚本调用(未发布)
-     *
-     * @param sysUser
-     * @param adwebSite
-     * @return
-     */
-    private boolean stopSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
-        String cmd = "/home/ci-user/shell/stop_site " + adwebSite.getCode() + " ";
-        shellService.exceShellByPwd(
-                cmd,
-                host,
-                port,
-                username,
-                password,
-                new ShellSSH2Util.StdoutListener() {
-                    @Override
-                    public void stdout(String line) {
-                        log.info("标准 :" + line);
-                        if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
-                            // TODO ----
-                            log.error("停止测试站点异常:" + line);
-                        }
-                    }
-
-                    @Override
-                    public void stderr(String line) {
-                        log.info("错误 :" + line);
-                    }
-                });
-        return siteStatusUpdate(sysUser, adwebSite, 3);
+  }
+
+  /**
+   * 当执行Shell命令失败时调用此方法记录错误信息
+   *
+   * @param cmd 执行的Shell命令,用于标识操作
+   * @param adwebSite 发生错误的广告网站实例,包含站点信息
+   * @param errorMsg 错误信息描述,详细说明执行失败的原因
+   */
+  private void exceShellFailed(String cmd, AdwebSite adwebSite, String errorMsg) {
+    SysException sysException = new SysException();
+
+    sysException.setType(1);
+    sysException.setFunctionModule(cmd);
+    sysException.setExceptionDetail(
+        String.format(
+            "站点code:%s, 站点名称:%s,临时连接:%s",
+            adwebSite.getCode(), adwebSite.getName(), adwebSite.getDomain()));
+    sysException.setExceptionDescription(errorMsg);
+
+    sysExceptionService.save(sysException);
+  }
+
+  /**
+   * 处理临时站点创建失败的逻辑 当临时站点创建失败时,此方法会被调用,更新站点状态并记录错误信息
+   *
+   * @param adwebSite 代表临时站点的对象,包含站点的相关信息
+   * @param errorMsg 描述创建失败的错误信息
+   */
+  private void createSiteFailed(AdwebSite adwebSite, String errorMsg, int status) {
+    adwebSite.setStatus(status); // 临时站点创建失败 或者正式站点创建失败
+    siteService.updateById(adwebSite);
+
+    SysException sysException = new SysException();
+
+    sysException.setType(1); // 业务错误
+    sysException.setFunctionModule("拉取站点错误");
+    sysException.setExceptionDetail(
+        String.format(
+            "站点code:%s, 站点名称:%s,临时连接:%s",
+            adwebSite.getCode(), adwebSite.getName(), adwebSite.getDomain()));
+    sysException.setExceptionDescription(errorMsg);
+
+    sysExceptionService.save(sysException);
+  }
+
+  /**
+   * 处理临时站点创建失败的逻辑 当临时站点创建失败时,此方法会被调用,更新站点状态并记录错误信息
+   *
+   * @param adwebTheme 代表临时站点的对象,包含站点的相关信息
+   * @param errorMsg 描述创建失败的错误信息
+   */
+  private void createThemeFailed(AdwebTheme adwebTheme, String errorMsg, int status) {
+    adwebTheme.setStatus(status); // 临时站点创建失败 或者正式站点创建失败
+    themeService.updateById(adwebTheme);
+
+    SysException sysException = new SysException();
+
+    sysException.setType(1); // 业务错误
+    sysException.setFunctionModule("创建模板错误");
+    sysException.setExceptionDetail(
+        String.format(
+            "模板站点code:%s, 模板站点名称:%s,临时连接:%s",
+            adwebTheme.getCode(), adwebTheme.getName(), adwebTheme.getDomain()));
+    sysException.setExceptionDescription(errorMsg);
+
+    sysExceptionService.save(sysException);
+  }
+
+  /**
+   * 发布站点到生产环境
+   *
+   * @param user 当前登录用户
+   * @param serverId 服务器ID,未在方法体内使用
+   * @param domain 域名,用于站点发布
+   * @param siteCode 站点代码,标识特定的站点
+   */
+  @Async
+  public void releaseSite(LoginUser user, String serverId, String domain, String siteCode) {
+    log.info("===== releaseSite domain:{},siteCode:{} ====", domain, siteCode);
+    StringBuilder statusSuccess = new StringBuilder();
+    StringBuilder statusFail = new StringBuilder();
+    AdwebSite adwebSite = siteService.getSiteByCode(siteCode);
+    AdwebServer adwebServer = serverService.getById(serverId);
+
+    if (adwebServer == null) {
+      log.error("发布生产环境时未指定服务器");
+      return;
     }
 
-    /**
-     * 站点启动脚本调用(生产环境)
-     *
-     * @param sysUser
-     * @param adwebSite
-     * @return
-     */
-    private boolean startSite(LoginUser sysUser, AdwebSite adwebSite, AdwebServer serverInfo) {
-        // 站点启动
-        String cmd =
-                "./shell/start_site " + serverInfo.getServerIp() + " " + adwebSite.getCode() + " ";
-        shellService.exceShell(
-                cmd,
-                new ShellSSH2Util.StdoutListener() {
-                    @Override
-                    public void stdout(String line) {
-                        log.info("MJJ控制台 :" + line);
-                        if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
-                            // TODO ----
-                            log.error("恢复站点异常:" + line);
-                        }
-                    }
-
-                    @Override
-                    public void stderr(String line) {
-                        log.info("错误 :" + line);
-                    }
-                },
-                serverInfo);
-        return siteStatusUpdate(sysUser, adwebSite, 0);
-    }
+    String serverShellPath = "/opt/adweb3/shell";
 
-    /**
-     * 站点停止脚本调用(生产环境)
-     *
-     * @param sysUser
-     * @param adwebSite
-     * @return
-     */
-    private boolean stopSite(LoginUser sysUser, AdwebSite adwebSite, AdwebServer serverInfo) {
-        String cmd =
-                "./shell/stop_site " + serverInfo.getServerIp() + " " + adwebSite.getCode() + " ";
-        shellService.exceShell(
-                cmd,
-                new ShellSSH2Util.StdoutListener() {
-                    @Override
-                    public void stdout(String line) {
-                        log.info("MJJ控制台 :" + line);
-                        if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
-                            // TODO ----
-                            log.error("停止站点异常:" + line);
-                        }
-                    }
-
-                    @Override
-                    public void stderr(String line) {
-                        log.info("错误 :" + line);
-                    }
-                },
-                serverInfo);
-        return siteStatusUpdate(sysUser, adwebSite, 3);
+    // 原始域名
+    String originDomain = domain;
+    // 检验域名是否以www开头
+    if (domain.startsWith("www.")) {
+      domain = domain.replace("www.", "");
     }
+    String dbName = domain.replaceAll("[^a-zA-Z0-9]", "") + "_" + adwebSite.getCode();
+
+    log.info(
+        "===== releaseSite domain:{}, siteCode:{},originDomain:{},domain:{},dbName:{} ====",
+        domain,
+        siteCode,
+        originDomain,
+        domain,
+        dbName);
+
+    String cmd =
+        "sudo sh "
+            + serverShellPath
+            + "/publish_wp_site.sh "
+            + adwebSite.getCode()
+            + " "
+            + domain
+            + " "
+            + dbName;
+
+    log.info(
+        "===== releaseSite originDomain:{},domain:{},siteCode:{},cmd:{} ====",
+        originDomain,
+        domain,
+        siteCode,
+        cmd);
+
+    try {
+      if (StringUtils.isBlank(adwebServer.getServerPem())) {
+        String[] userIds = {user.getId()};
+        // 给该站点所属的用户发送消息
+        log.info("生产服务器:{},未配置连接秘钥", adwebServer.getServerName());
+        webSocketService.sendMessage(
+            userIds, "站点发布失败通知", "该站点发布失败,请联系管理员配置服务器连接秘钥", WebsocketConst.CMD_MANAGE_SITE);
+        return;
+      }
+
+      adwebSite.setStatus(5); // 正式站点正在创建
+      siteService.updateById(adwebSite);
+
+      String pemPath = adwebServer.getServerPem().replace("..", "").replace("../", "");
+      if (pemPath.endsWith(SymbolConstant.COMMA)) {
+        pemPath = pemPath.substring(0, pemPath.length() - 1);
+      }
+
+      String filePath = uploadpath + File.separator + pemPath;
+      adwebServer.setServerPem(filePath); // 设置秘钥绝对路径
+
+      shellService.exceShell(
+          cmd,
+          new ShellSSH2Util.StdoutListener() {
+            @Override
+            public void stdout(String line) {
+              log.info("标准 :{}", line);
+
+              if ("[Creation completed]".equals(line)) {
+                log.info("======网站上线成功======");
+                statusSuccess.append("ok");
+              }
+            }
 
-    /**
-     * 站点状态更改
-     *
-     * @param sysUser
-     * @param adwebSite
-     * @param runStatus
-     * @return
-     */
-    private boolean siteStatusUpdate(LoginUser sysUser, AdwebSite adwebSite, Integer runStatus) {
-        if (runStatus.equals(3)) {
-            adwebSite.setStopTime(new Date());
-            adwebSite.setStopUid(sysUser.getId());
-        }
-        adwebSite.setRunStatus(runStatus);
-        return siteService.updateById(adwebSite);
+            @Override
+            public void stderr(String line) {
+              log.info("错误 :{}", line);
+              statusFail.append(line);
+            }
+          },
+          adwebServer);
+
+      // 正式域名
+      log.info(
+          "===== releaseSite originDomain:{},domain:{},siteCode:{},statusSuccess:{} ====",
+          originDomain,
+          domain,
+          siteCode,
+          statusSuccess);
+      log.info(
+          "===== releaseSite originDomain:{},domain:{},siteCode:{},statusFail:{} ====",
+          originDomain,
+          domain,
+          siteCode,
+          statusFail);
+      if (StringUtils.isNotEmpty(statusFail.toString())) {
+        String title = "网站域名:" + originDomain + " 站点发布失败";
+        String message = "**站点CODE:** " + siteCode + "\n";
+        message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
+        message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
+        message += "**错误信息:** " + statusFail.toString() + "\n";
+        sendAdWebV3FeiShuMsg(title, message);
+
+        // 站点发布失败
+        createSiteFailed(adwebSite, statusFail.toString(), 6);
+
+      } else {
+        String title = "网站域名:" + originDomain + " 站点发布成功";
+        String message = "**站点CODE:** " + siteCode + "\n";
+        message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
+        message += "**服务器IP:** " + adwebSite.getDevServerIp() + "\n";
+        sendAdWebV3FeiShuMsg(title, message); // 发送飞书消息
+
+        String[] userIds = {user.getId()};
+        // 给该站点所属的用户发送消息
+        log.info("发布站点成功通知");
+        webSocketService.sendMessage(
+            userIds, "站点发布完成通知", "您的站点已经发布成功,请在站点管理中查看该站点详细信息", WebsocketConst.CMD_MANAGE_SITE);
+
+        // 创建站点完成-操作
+        adwebSite.setDomain(originDomain);
+        adwebSite.setIsDomain(1);
+        // 添加发布时间
+        adwebSite.setIssueTime(new Date());
+        // 发布成功后修改状态为发布成功状态 :1
+        adwebSite.setStatus(1);
+        adwebSite.setProdServerIp(adwebServer.getServerIp());
+        siteService.updateById(adwebSite);
+      }
+    } catch (Exception e) {
+      log.error("站点发布失败,退出执行;{}", e.getMessage(), e);
+      createSiteFailed(adwebSite, e.getMessage(), 6);
     }
-
-    /**
-     * @param msgTitle
-     * @param message
-     */
-    public void sendAdWebV3FeiShuMsg(String msgTitle, String message) {
-        try {
-            openFeishuMsgService.sendAdWebV3FeiShuMsg(msgTitle, message);
-        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
-            throw new RuntimeException(e);
-        }
+  }
+
+  /**
+   * 删除发布失败的站点(生产环境)
+   *
+   * @param domain 新域名
+   * @param siteId 站点ID
+   */
+  public Result<?> delReleaseWebsite(String domain, Integer siteId) {
+    log.info("===== delReleaseWebsite domain:{},siteId:{} ====", domain, siteId);
+    StringBuilder delSuccess = new StringBuilder();
+    StringBuilder delFail = new StringBuilder();
+    AdwebSite adwebSite = siteService.getById(siteId);
+    String usWest118ServerShellPath = "/home/ci-user/shell";
+    // 检验域名是否以www开头
+    if (domain.startsWith("www.")) {
+      domain = domain.replace("www.", "");
+    }
+    // 删除已发布的站点,重新发布
+    if (adwebSite.getStatus() == 5) {
+      String cmd = "sudo sh " + usWest118ServerShellPath + "/adweb-remove_prod_site.sh " + domain;
+      log.info("===== delReleaseWebsite domain:{},siteId:{},cmd:{} ====", domain, siteId, cmd);
+      try {
+        String finalDomain = domain;
+        //                shellService.exceShellByUsWest118(cmd, new
+        // ShellSSH2Util.StdoutListener() {
+        //                    @Override
+        //                    public void stdout(String line) {
+        //                        log.info("标准 :" + line);
+        //                        if ("remove site success".equals(line) || "remove site
+        // nginx success".equals(line)) {
+        //                            log.info("======执行删除旧站点,成功通知======");
+        //                            String title = "网站域名:" + finalDomain + "
+        // 删除发布失败的旧站点成功";
+        //                            String message = "**站点ID:** " + siteId + "\n";
+        //                            message += "**临时域名:** " + adwebSite.getDomainDev() +
+        // "\n";
+        //                            message += "**服务器IP:** " + adwebSite.getDevServerIp()
+        // + "\n";
+        //                            sendAdWebV3FeiShuMsg(title, message);
+        //
+        //                            delSuccess.append(line);
+        //                        }
+        //
+        //                        if ("remove site failed".equals(line) || "remove site
+        // nginx failed".equals(line)) {
+        //                            log.info("======执行删除旧站点,失败通知======");
+        //                            String title = "网站域名:" + finalDomain + "
+        // 删除发布失败的旧站点失败";
+        //                            String message = "**站点ID:** " + siteId + "\n";
+        //                            message += "**临时域名:** " + adwebSite.getDomainDev() +
+        // "\n";
+        //                            message += "**服务器IP:** " + adwebSite.getDevServerIp()
+        // + "\n";
+        //                            message += "**错误信息:** " + line + "\n";
+        //                            sendAdWebV3FeiShuMsg(title, message);
+        //
+        //                            delFail.append(line);
+        //                        }
+        //                    }
+        //
+        //                    @Override
+        //                    public void stderr(String line) {
+        //                        log.info("错误 :" + line);
+        //                        String title = "网站域名:" + finalDomain + " 删除发布失败的旧站点失败";
+        //                        String message = "**站点ID:** " + siteId + "\n";
+        //                        message += "**临时域名:** " + adwebSite.getDomainDev() + "\n";
+        //                        message += "**服务器IP:** " + adwebSite.getDevServerIp() +
+        // "\n";
+        //                        message += "**错误信息:** " + line + "\n";
+        //                        sendAdWebV3FeiShuMsg(title, message);
+        //
+        //                        delFail.append(line);
+        //                    }
+        //                });
+      } catch (Exception e) {
+        log.error("删除发布失败的旧站点失败,退出执行;" + e.getMessage(), e);
+        delFail.append(e.getMessage());
+      }
+
+      if (StringUtils.isNotBlank(delFail.toString())) {
+        return Result.error("旧站点删除失败,请重试!");
+      } else {
+        return Result.OK("旧站点删除成功!");
+      }
+    } else {
+      return Result.error("该站点状态不是发布失败,执行失败!");
+    }
+  }
+
+  /**
+   * 站点启动/停止
+   *
+   * @param sysUser
+   * @param siteId
+   * @param status
+   * @return
+   */
+  public boolean siteStartOrStop(LoginUser sysUser, Integer siteId, Integer status) {
+    AdwebSite adwebSite = siteService.getById(siteId);
+
+    // 获取站点所在生产服务器信息
+    AdwebServer serverInfo = new AdwebServer();
+    boolean flag = false;
+    switch (status) {
+      case 1:
+        flag = startSiteLocal(sysUser, adwebSite);
+        break;
+      case 2:
+        flag = stopSiteLocal(sysUser, adwebSite);
+        break;
+      case 3:
+        flag = startSite(sysUser, adwebSite, serverInfo);
+        break;
+      case 4:
+        flag = stopSite(sysUser, adwebSite, serverInfo);
+        break;
+    }
+    return flag;
+  }
+
+  /**
+   * 站点启动脚本调用(未发布)
+   *
+   * @param sysUser
+   * @param adwebSite
+   * @return
+   */
+  private boolean startSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
+    // 站点启动
+    String cmd = "/home/ci-user/shell/start_site " + adwebSite.getCode() + " ";
+    shellService.exceShellByPwd(
+        cmd,
+        host,
+        port,
+        username,
+        password,
+        new ShellSSH2Util.StdoutListener() {
+          @Override
+          public void stdout(String line) {
+            log.info("标准 :" + line);
+            if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
+              // TODO ----
+              log.error("恢复测试站点异常:" + line);
+            }
+          }
+
+          @Override
+          public void stderr(String line) {
+            log.info("错误 :" + line);
+          }
+        });
+    return siteStatusUpdate(sysUser, adwebSite, 0);
+  }
+
+  /**
+   * 站点停止脚本调用(未发布)
+   *
+   * @param sysUser
+   * @param adwebSite
+   * @return
+   */
+  private boolean stopSiteLocal(LoginUser sysUser, AdwebSite adwebSite) {
+    String cmd = "/home/ci-user/shell/stop_site " + adwebSite.getCode() + " ";
+    shellService.exceShellByPwd(
+        cmd,
+        host,
+        port,
+        username,
+        password,
+        new ShellSSH2Util.StdoutListener() {
+          @Override
+          public void stdout(String line) {
+            log.info("标准 :" + line);
+            if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
+              // TODO ----
+              log.error("停止测试站点异常:" + line);
+            }
+          }
+
+          @Override
+          public void stderr(String line) {
+            log.info("错误 :" + line);
+          }
+        });
+    return siteStatusUpdate(sysUser, adwebSite, 3);
+  }
+
+  /**
+   * 站点启动脚本调用(生产环境)
+   *
+   * @param sysUser
+   * @param adwebSite
+   * @return
+   */
+  private boolean startSite(LoginUser sysUser, AdwebSite adwebSite, AdwebServer serverInfo) {
+    // 站点启动
+    String cmd = "./shell/start_site " + serverInfo.getServerIp() + " " + adwebSite.getCode() + " ";
+    shellService.exceShell(
+        cmd,
+        new ShellSSH2Util.StdoutListener() {
+          @Override
+          public void stdout(String line) {
+            log.info("MJJ控制台 :" + line);
+            if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
+              // TODO ----
+              log.error("恢复站点异常:" + line);
+            }
+          }
+
+          @Override
+          public void stderr(String line) {
+            log.info("错误 :" + line);
+          }
+        },
+        serverInfo);
+    return siteStatusUpdate(sysUser, adwebSite, 0);
+  }
+
+  /**
+   * 站点停止脚本调用(生产环境)
+   *
+   * @param sysUser
+   * @param adwebSite
+   * @return
+   */
+  private boolean stopSite(LoginUser sysUser, AdwebSite adwebSite, AdwebServer serverInfo) {
+    String cmd = "./shell/stop_site " + serverInfo.getServerIp() + " " + adwebSite.getCode() + " ";
+    shellService.exceShell(
+        cmd,
+        new ShellSSH2Util.StdoutListener() {
+          @Override
+          public void stdout(String line) {
+            log.info("MJJ控制台 :" + line);
+            if ("ERROR:FILE_NAME IS EXISTS".equals(line)) {
+              // TODO ----
+              log.error("停止站点异常:" + line);
+            }
+          }
+
+          @Override
+          public void stderr(String line) {
+            log.info("错误 :" + line);
+          }
+        },
+        serverInfo);
+    return siteStatusUpdate(sysUser, adwebSite, 3);
+  }
+
+  /**
+   * 站点状态更改
+   *
+   * @param sysUser
+   * @param adwebSite
+   * @param runStatus
+   * @return
+   */
+  private boolean siteStatusUpdate(LoginUser sysUser, AdwebSite adwebSite, Integer runStatus) {
+    if (runStatus.equals(3)) {
+      adwebSite.setStopTime(new Date());
+      adwebSite.setStopUid(sysUser.getId());
+    }
+    adwebSite.setRunStatus(runStatus);
+    return siteService.updateById(adwebSite);
+  }
+
+  /**
+   * @param msgTitle
+   * @param message
+   */
+  public void sendAdWebV3FeiShuMsg(String msgTitle, String message) {
+    try {
+      openFeishuMsgService.sendAdWebV3FeiShuMsg(msgTitle, message);
+    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+      throw new RuntimeException(e);
     }
+  }
 }

+ 169 - 145
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/theme/controller/AdwebThemeController.java

@@ -1,21 +1,26 @@
 package org.jeecg.modules.adweb.theme.controller;
 
+import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
-
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-
+import java.util.Arrays;
 import lombok.extern.slf4j.Slf4j;
-
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.SecurityUtils;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.aspect.annotation.AutoLog;
 import org.jeecg.common.system.base.controller.JeecgController;
 import org.jeecg.common.system.query.QueryGenerator;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.modules.adweb.site.entity.AdwebSite;
+import org.jeecg.modules.adweb.site.service.IAdwebSiteService;
+import org.jeecg.modules.adweb.site.service.SelfWebSiteService;
+import org.jeecg.modules.adweb.theme.dto.param.AdwebThemeParam;
 import org.jeecg.modules.adweb.theme.entity.AdwebTheme;
 import org.jeecg.modules.adweb.theme.service.IAdwebThemeService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -23,155 +28,174 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.servlet.ModelAndView;
 
-import java.util.Arrays;
-
 /**
- * @Description: adweb主题库
- * @Author: jeecg-boot
- * @Date: 2024-09-30
- * @Version: V1.0
+ * @Description: adweb主题库 @Author: jeecg-boot @Date: 2024-09-30 @Version: V1.0
  */
 @Tag(name = "adweb主题库")
 @RestController
 @RequestMapping("/adweb/adwebTheme")
 @Slf4j
 public class AdwebThemeController extends JeecgController<AdwebTheme, IAdwebThemeService> {
-    @Autowired private IAdwebThemeService adwebThemeService;
-
-    /**
-     * 分页列表查询
-     *
-     * @param adwebTheme
-     * @param pageNo
-     * @param pageSize
-     * @param req
-     * @return
-     */
-    // @AutoLog(value = "adweb主题库-分页列表查询")
-    @Operation(summary = "adweb主题库-分页列表查询")
-    @GetMapping(value = "/list")
-    public Result<IPage<AdwebTheme>> queryPageList(
-            AdwebTheme adwebTheme,
-            @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
-            @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
-            HttpServletRequest req) {
-        QueryWrapper<AdwebTheme> queryWrapper =
-                QueryGenerator.initQueryWrapper(adwebTheme, req.getParameterMap());
-        Page<AdwebTheme> page = new Page<AdwebTheme>(pageNo, pageSize);
-        IPage<AdwebTheme> pageList = adwebThemeService.page(page, queryWrapper);
-        return Result.OK(pageList);
-    }
-
-    /**
-     * 添加
-     *
-     * @param adwebTheme
-     * @return
-     */
-    @AutoLog(value = "adweb主题库-添加")
-    @Operation(summary = "adweb主题库-添加")
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:add')")
-    @PostMapping(value = "/add")
-    public Result<String> add(@RequestBody AdwebTheme adwebTheme) {
-        adwebThemeService.save(adwebTheme);
-        return Result.OK("添加成功!");
-    }
-
-    /**
-     * 编辑
-     *
-     * @param adwebTheme
-     * @return
-     */
-    @AutoLog(value = "adweb主题库-编辑")
-    @Operation(summary = "adweb主题库-编辑")
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:edit')")
-    @RequestMapping(
-            value = "/edit",
-            method = {RequestMethod.PUT, RequestMethod.POST})
-    public Result<String> edit(@RequestBody AdwebTheme adwebTheme) {
-        adwebThemeService.updateById(adwebTheme);
-        return Result.OK("编辑成功!");
+  @Autowired private IAdwebThemeService adwebThemeService;
+
+  @Autowired private IAdwebSiteService adwebSiteService;
+
+  @Autowired private SelfWebSiteService selfWebSiteService;
+
+  /**
+   * 分页列表查询
+   *
+   * @param adwebTheme
+   * @param pageNo
+   * @param pageSize
+   * @param req
+   * @return
+   */
+  // @AutoLog(value = "adweb主题库-分页列表查询")
+  @Operation(summary = "adweb主题库-分页列表查询")
+  @GetMapping(value = "/list")
+  public Result<IPage<AdwebTheme>> queryPageList(
+      AdwebTheme adwebTheme,
+      @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
+      @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
+      HttpServletRequest req) {
+    QueryWrapper<AdwebTheme> queryWrapper =
+        QueryGenerator.initQueryWrapper(adwebTheme, req.getParameterMap());
+    Page<AdwebTheme> page = new Page<AdwebTheme>(pageNo, pageSize);
+    IPage<AdwebTheme> pageList = adwebThemeService.page(page, queryWrapper);
+    return Result.OK(pageList);
+  }
+
+  /**
+   * 添加
+   *
+   * @param adwebThemeParam
+   * @return
+   */
+  @AutoLog(value = "adweb主题库-添加")
+  @Operation(summary = "adweb主题库-添加")
+  @PostMapping(value = "/add")
+  public Result<String> add(@RequestBody AdwebThemeParam adwebThemeParam) {
+
+    AdwebTheme adwebTheme = new AdwebTheme();
+    BeanUtil.copyProperties(adwebThemeParam, adwebTheme);
+    adwebTheme.setCode(adwebThemeParam.getCode() + "tp");
+    adwebTheme.setPutaway(1);
+    adwebThemeService.save(adwebTheme);
+
+    if (StringUtils.isNotBlank(adwebThemeParam.getCode())) {
+      AdwebSite adwebSite =
+          adwebSiteService.getOne(
+              new QueryWrapper<AdwebSite>().eq("code", adwebThemeParam.getCode()));
+
+      if (adwebSite == null) {
+        return Result.error("要生成模板的临时站点不存在");
+      }
+
+      adwebTheme.setStatus(3); // 创建模板中
+      adwebThemeService.updateById(adwebTheme);
+      // 生成模板站点
+      LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
+      selfWebSiteService.createThemeBySite(sysUser, adwebTheme, adwebSite);
     }
 
-    /**
-     * 通过id删除
-     *
-     * @param id
-     * @return
-     */
-    @AutoLog(value = "adweb主题库-通过id删除")
-    @Operation(summary = "adweb主题库-通过id删除")
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:delete')")
-    @DeleteMapping(value = "/delete")
-    public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
-        adwebThemeService.removeById(id);
-        return Result.OK("删除成功!");
-    }
-
-    /**
-     * 批量删除
-     *
-     * @param ids
-     * @return
-     */
-    @AutoLog(value = "adweb主题库-批量删除")
-    @Operation(summary = "adweb主题库-批量删除")
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:deleteBatch')")
-    @DeleteMapping(value = "/deleteBatch")
-    public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
-        this.adwebThemeService.removeByIds(Arrays.asList(ids.split(",")));
-        return Result.OK("批量删除成功!");
-    }
-
-    /**
-     * 通过id查询
-     *
-     * @param id
-     * @return
-     */
-    // @AutoLog(value = "adweb主题库-通过id查询")
-    @Operation(summary = "adweb主题库-通过id查询")
-    @GetMapping(value = "/queryById")
-    public Result<AdwebTheme> queryById(@RequestParam(name = "id", required = true) String id) {
-        AdwebTheme adwebTheme = adwebThemeService.getById(id);
-        if (adwebTheme == null) {
-            return Result.error("未找到对应数据");
-        }
-        return Result.OK(adwebTheme);
-    }
-
-    /**
-     * 导出excel
-     *
-     * @param request
-     * @param adwebTheme
-     */
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:exportXls')")
-    @RequestMapping(value = "/exportXls")
-    public ModelAndView exportXls(HttpServletRequest request, AdwebTheme adwebTheme) {
-        return super.exportXls(request, adwebTheme, AdwebTheme.class, "adweb主题库");
-    }
-
-    /**
-     * 通过excel导入数据
-     *
-     * @param request
-     * @param response
-     * @return
-     */
-    @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:importExcel')")
-    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
-    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
-        return super.importExcel(request, response, AdwebTheme.class);
-    }
-
-    /**
-     * @return
-     */
-    @GetMapping(value = "/getTemplateTags")
-    public Result<?> getTemplateTags() {
-
-        return Result.OK("");
+    return Result.OK("添加成功!");
+  }
+
+  /**
+   * 编辑
+   *
+   * @param adwebTheme
+   * @return
+   */
+  @AutoLog(value = "adweb主题库-编辑")
+  @Operation(summary = "adweb主题库-编辑")
+  @RequestMapping(
+      value = "/edit",
+      method = {RequestMethod.PUT, RequestMethod.POST})
+  public Result<String> edit(@RequestBody AdwebTheme adwebTheme) {
+    adwebThemeService.updateById(adwebTheme);
+    return Result.OK("编辑成功!");
+  }
+
+  /**
+   * 通过id删除
+   *
+   * @param id
+   * @return
+   */
+  @AutoLog(value = "adweb主题库-通过id删除")
+  @Operation(summary = "adweb主题库-通过id删除")
+  @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:delete')")
+  @DeleteMapping(value = "/delete")
+  public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
+    adwebThemeService.removeById(id);
+    return Result.OK("删除成功!");
+  }
+
+  /**
+   * 批量删除
+   *
+   * @param ids
+   * @return
+   */
+  @AutoLog(value = "adweb主题库-批量删除")
+  @Operation(summary = "adweb主题库-批量删除")
+  @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:deleteBatch')")
+  @DeleteMapping(value = "/deleteBatch")
+  public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
+    this.adwebThemeService.removeByIds(Arrays.asList(ids.split(",")));
+    return Result.OK("批量删除成功!");
+  }
+
+  /**
+   * 通过id查询
+   *
+   * @param id
+   * @return
+   */
+  // @AutoLog(value = "adweb主题库-通过id查询")
+  @Operation(summary = "adweb主题库-通过id查询")
+  @GetMapping(value = "/queryById")
+  public Result<AdwebTheme> queryById(@RequestParam(name = "id", required = true) String id) {
+    AdwebTheme adwebTheme = adwebThemeService.getById(id);
+    if (adwebTheme == null) {
+      return Result.error("未找到对应数据");
     }
+    return Result.OK(adwebTheme);
+  }
+
+  /**
+   * 导出excel
+   *
+   * @param request
+   * @param adwebTheme
+   */
+  @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:exportXls')")
+  @RequestMapping(value = "/exportXls")
+  public ModelAndView exportXls(HttpServletRequest request, AdwebTheme adwebTheme) {
+    return super.exportXls(request, adwebTheme, AdwebTheme.class, "adweb主题库");
+  }
+
+  /**
+   * 通过excel导入数据
+   *
+   * @param request
+   * @param response
+   * @return
+   */
+  @PreAuthorize("@jps.requiresPermissions('adweb:adweb_theme:importExcel')")
+  @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
+  public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
+    return super.importExcel(request, response, AdwebTheme.class);
+  }
+
+  /**
+   * @return
+   */
+  @GetMapping(value = "/getTemplateTags")
+  public Result<?> getTemplateTags() {
+
+    return Result.OK("");
+  }
 }

+ 11 - 0
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/theme/dto/param/AdwebThemeParam.java

@@ -0,0 +1,11 @@
+package org.jeecg.modules.adweb.theme.dto.param;
+
+import lombok.Data;
+
+@Data
+public class AdwebThemeParam {
+  private String code;
+  private String devDomain;
+  private String images;
+  private String name;
+}

+ 73 - 92
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/adweb/theme/entity/AdwebTheme.java

@@ -5,19 +5,15 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
+import java.io.Serializable;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 import org.jeecgframework.poi.excel.annotation.Excel;
 import org.springframework.format.annotation.DateTimeFormat;
 
-import java.io.Serializable;
-
 /**
- * @Description: adweb主题库
- * @Author: jeecg-boot
- * @Date: 2024-09-30
- * @Version: V1.0
+ * @Description: adweb主题库 @Author: jeecg-boot @Date: 2024-09-30 @Version: V1.0
  */
 @Data
 @TableName("adweb_theme")
@@ -25,90 +21,75 @@ import java.io.Serializable;
 @EqualsAndHashCode(callSuper = false)
 @Schema(description = "adweb主题库")
 public class AdwebTheme implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * 主键
-     */
-    @TableId(type = IdType.ASSIGN_ID)
-    @Schema(description = "主键")
-    private java.lang.String id;
-    /**
-     * 创建人
-     */
-    @Schema(description = "创建人")
-    private java.lang.String createBy;
-    /**
-     * 创建日期
-     */
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Schema(description = "创建日期")
-    private java.util.Date createTime;
-    /**
-     * 更新人
-     */
-    @Schema(description = "更新人")
-    private java.lang.String updateBy;
-    /**
-     * 更新日期
-     */
-    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
-    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    @Schema(description = "更新日期")
-    private java.util.Date updateTime;
-    /**
-     * 模板名称
-     */
-    @Excel(name = "模板名称", width = 15)
-    @Schema(description = "模板名称")
-    private java.lang.String name;
-    /**
-     * 上架状态:0:未上架;1:已上架;默认0
-     */
-    @Excel(name = "上架状态:0:未上架;1:已上架;默认0", width = 15)
-    @Schema(description = "上架状态:0:未上架;1:已上架;默认0")
-    private java.lang.Integer putaway;
-    /**
-     * 图片路径
-     */
-    @Excel(name = "图片路径", width = 15)
-    @Schema(description = "图片路径")
-    private java.lang.String images;
-    /**
-     * 模板价格
-     */
-    @Excel(name = "模板价格", width = 15)
-    @Schema(description = "模板价格")
-    private java.math.BigDecimal templatePrice;
-    /**
-     * 模板标签
-     */
-    @Excel(name = "模板标签", width = 15)
-    @Schema(description = "模板标签")
-    private java.lang.String templateTags;
-    /**
-     * 主题颜色ID
-     */
-    @Excel(name = "主题颜色ID", width = 15)
-    @Schema(description = "主题颜色ID")
-    private java.lang.Integer templateColorId;
-    /**
-     * 站点域名
-     */
-    @Excel(name = "站点域名", width = 15)
-    @Schema(description = "站点域名")
-    private java.lang.String domain;
-    /**
-     * 站点备注
-     */
-    @Excel(name = "站点备注", width = 15)
-    @Schema(description = "站点备注")
-    private java.lang.String descirbe;
-    /**
-     * 站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一
-     */
-    @Excel(name = "站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一", width = 15)
-    @Schema(description = "站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一")
-    private java.lang.String code;
+  private static final long serialVersionUID = 1L;
+
+  /** 主键 */
+  @TableId(type = IdType.ASSIGN_ID)
+  @Schema(description = "主键")
+  private java.lang.String id;
+
+  /** 创建人 */
+  @Schema(description = "创建人")
+  private java.lang.String createBy;
+
+  /** 创建日期 */
+  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+  @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+  @Schema(description = "创建日期")
+  private java.util.Date createTime;
+
+  /** 更新人 */
+  @Schema(description = "更新人")
+  private java.lang.String updateBy;
+
+  /** 更新日期 */
+  @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
+  @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+  @Schema(description = "更新日期")
+  private java.util.Date updateTime;
+
+  /** 模板名称 */
+  @Excel(name = "模板名称", width = 15)
+  @Schema(description = "模板名称")
+  private java.lang.String name;
+
+  /** 上架状态:0:未上架;1:已上架;默认0 */
+  @Excel(name = "上架状态:0:未上架;1:已上架;默认0", width = 15)
+  @Schema(description = "上架状态:0:未上架;1:已上架;默认0")
+  private java.lang.Integer putaway;
+
+  /** 图片路径 */
+  @Excel(name = "图片路径", width = 15)
+  @Schema(description = "图片路径")
+  private java.lang.String images;
+
+  /** 模板价格 */
+  @Excel(name = "模板价格", width = 15)
+  @Schema(description = "模板价格")
+  private java.math.BigDecimal templatePrice;
+
+  /** 模板标签 */
+  @Excel(name = "模板标签", width = 15)
+  @Schema(description = "模板标签")
+  private java.lang.String templateTags;
+
+  /** 主题颜色ID */
+  @Excel(name = "模板创建状态", width = 15)
+  @Schema(description = "模板创建状态")
+  private java.lang.Integer status;
+
+  /** 站点域名 */
+  @Excel(name = "站点域名", width = 15)
+  @Schema(description = "站点域名")
+  private java.lang.String domain;
+
+  /** 站点备注 */
+  @Excel(name = "站点备注", width = 15)
+  @Schema(description = "站点备注")
+  private java.lang.String descirbe;
+
+  /** 站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一 */
+  @Excel(name = "站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一", width = 15)
+  @Schema(description = "站点code,生成6位长度随机码,取值范围[a-z0-9],保证系统唯一")
+  private java.lang.String code;
 }