前端发布接入jenkins

最原始的前端发布,会经过本地打包、压个 zip 包、通过工具手动上传、找到 leader 帮忙解压到对应的服务器上、同步文件服务器等等的步骤。每一个环节都是人工操作,发个版非常的繁琐。接入jenkins有助于我们简化CI/CD流程,实现前端发布自动化。

1. jenkins 安装部署(docker)

1-1 前置条件

安装 git、docker、配置 ssh

  1. git 安装
    # enter 到底
    yum install -y git
    # 查看git版本号 验证git安装成功
    # git version 1.8.3.1
    git --version
  2. docker 安装
    # docker-ce                             Docker社区版
    # docker-ce-cli                     Docker命令行界面(CLI)
    # containerd.io                     Docker插件,直接调用 Docker Compose
    # docker-compose-plugin     Docker插件,直接调用 Docker Compose
    yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
  3. 配置 ssh
    # Enter到底,最终会生成以下文件
    # /root/.ssh/authorized_keys 允许无密码登录的公钥列表
    # /root/.ssh/id_rsa 私钥文件
    # /root/.ssh/id_rsa.pub 公钥文件  注意该文件里的内容是接下来要用的
    ssh-keygen -t rsa -C "root"
    # 复制公钥文件的内容,添加到GitHub 的 SSH keys 或 任意其他远程仓库
    vim /root/.ssh/id_rsa.pub

1-2 jenkins 安装

docker 拉取镜像

# 拉取nginx
docker pull nginx
# 拉取jenkins
docker pull jenkins/jenkins:lts
# 查看镜像是否安装成功
docker images
# REPOSITORY        TAG       IMAGE ID       CREATED         SIZE
# jenkins/jenkins   lts       6a44d1dd2d60   3 weeks ago   468MB
# nginx             latest    53a18edff809   7 weeks ago   192MB

创建 docker 相关目录

# 创建docker的相关目录
mkdir -p ./docker/{compose,jenkins_home,nginx/conf,html/origin/{master,dev}}

# 创建docker-compose.yml配置文件
cd ./docker/compose
# 具体配置内容见下面
touch docker-compose.yml

# 创建nginx.conf配置文件
cd ./docker/nginx/conf
# 具体配置内容见下面
touch nginx.conf

最终目录结构如下

./docker/
├── compose/
│   └── docker-compose.yml  # 空的 docker-compose 配置文件
└── html/
       └── origin/
              ├── master/         # 预留的 master 版本 HTML 目录(为空)
             └── dev/            # 预留的 dev 版本 HTML 目录(为空)
├── jenkins_home/           # Jenkins 数据存储目录(为空)
├── nginx/
│   └── conf/
│          └── nginx.conf      # 空的 Nginx 配置文件

nginx 配置,其中 pamirs 代理的后端地址根据实际情况修改

# nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;

    #这里两个环境使用一个nginx.conf文件,也可以单独分开来
    #master环境
    server {
        #监听的端口
        listen  8001;
        server_name  localhost;
        #设置日志
        #access_log  logs/dev.access.log  main;

        #定位到index.html
           location / {
                #linux下HTML文件夹,就是你的前端项目文件夹
                root  /usr/share/nginx/html/origin/master/dist;
                #root  /home/html/dev/dist;
                #输入网址(server_name:port)后,默认的访问页面
                index  index.html;
                try_files $uri $uri/ /index.html;
           }

            location /pamirs {
                # 根据实际详情修改(后端接口地址)
                proxy_pass http://xxx.xxx.xxx;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
    }

    #dev环境
    server {
        #监听的端口
        listen  8002;
        server_name  localhost;
        #设置日志
        #access_log  logs/sit.access.log  main;

        #定位到index.html
           location / {
                #linux下HTML文件夹,就是你的前端项目文件夹
                root  /usr/share/nginx/html/origin/dev/dist;
                #root  /home/html/dev/dist;
                #输入网址(server_name:port)后,默认的访问页面
                index  index.html;
                try_files $uri $uri/ /index.html;
           }

            location /pamirs {
                # 根据实际详情修改(后端接口地址)
                proxy_pass http://xxx.xxx.xxx;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
    }

#    include /etc/nginx/conf.d/*.conf;
}

docker-compose 配置

# 新版docker-compose不用写自动引用最新版本
# version: '3'

networks:
  frontend:
    external: true

services:                                      # 容器

  docker_jenkins:
    user: root                                 # root权限
    restart: always                            # 重启方式
    image: jenkins/jenkins:lts                 # 使用的镜像
    container_name: jenkins                    # 容器名称
    environment:
      - TZ=Asia/Shanghai
      - "JENKINS_OPTS=--prefix=/jenkins_home" ## 自定义 jenkins 访问前缀(上下文context)
    ports:                                     # 对外暴露的端口定义
      - 8080:8080
      - 50000:50000
    volumes:                                   # 卷挂载路径
      - ../jenkins_home/:/var/jenkins_home     # 挂载到容器内的jenkins_home目录
      - /usr/local/bin/docker-compose:/usr/local/bin/docker-compose

  docker_nginx_pro:                            # nginx-pro环境
    restart: always
    image: nginx
    container_name: nginx_pro
    ports:
      - 8001:8001
    volumes:
      - ../nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ../html:/usr/share/nginx/html    # 宿主机./docker/html 映射docker容器内的/usr/share/nginx/html
      - ../nginx/logs:/var/log/nginx

  docker_nginx_dev:                            # nginx-dev环境
    restart: always
    image: nginx
    container_name: nginx_dev
    ports:
      - 8002:8002
    volumes:
      - ../nginx/conf/nginx.conf:/etc/nginx/nginx.conf
      - ../html:/usr/share/nginx/html        # 宿主机./docker/html 映射docker容器内的/usr/share/nginx/html
      - ../nginx/logs:/var/log/nginx

1-3 启动 docker

# 启动docker
systemctl start docker
# 启动docker-compose
# 这里我们使用docker-compose.yml配置文件启动,所以不需要另外手动创建容器里,这也是为什么使用docker-compose.yml配置文件的原因
cd /docker/compose/
docker-compose up -d

# 输出以下内容
[+] Building 0.0s (0/0)                       docker:desktop-linux
[+] Running 3/3
Container nginx_pro  Started                               0.1s
Container jenkins    Started                                 0.1s
Container nginx_dev  Started                               0.1s

1-4 检查 nginx 配置

测试 nginx 配置是否正确

# 目录下创建index.html文件
cd ./docker/html/origin/dev/dist
# 黏贴下面的html内容
vim index.html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>welcome to Nginx</h1>
  </body>
</html>

浏览器打开 localhost:8002 可以看到 welcome to Nginx 页面,证明 nginx 配置正确。

1-5 登录 jenkins web 端

  1. 登录 服务器地址 localhost:8080/jenkins_home 进入jenkins 的web端
  2. 去服务器上 vim ./docker/jenkins_home/secrets/initialAdminPassword 复制初始密码
  3. 回到 jenkins 的 web 端,输入初始密码。
  4. 登录后,安装推荐的插件(不要选择自定义插件)。
  5. 注册管理员账号完成登录

2. jenkins 配置

2-1 安装必要插件

这一步如果插件有报错的话可以尝试重启下容器
dashbord => Manage Jenkins(系统管理) => plugin(插件) => Available plugins

  • Publish Over SSH 配置远程服务器
  • NodeJS 服务端打包
  • Git Parameter 参数化构建

2-2 Publish Over SSH 配置远程服务器

dashbord => Manage Jenkins(系统管理) => 系统配置 => ctrl f Publish over SSH

  1. 找到 SSH Servers 并新增
  2. 填写 name 自定义填写名称(示例:jenkins_node)
  3. 填写 Hostname 服务器ip地址
  4. 填写 Username 服务器登录名称
  5. 填写 Remote Directory 登录后访问的地址
  6. 点击 高级 弹出额外配置
  7. 勾选 Use password authentication, or use a different key。
  8. 出现 Passphrase / Password,输入服务器登录密码
  9. 检查默认 port 是否为22 。一般不用修改
  10. 点击 Test Configuration,显示 success 则 jenkins 配置 SSH 远程服务器成功
  11. 点击 应用按钮 点击 保存按钮

2-3 NodeJs 配置

dashbord => Manage Jenkins(系统管理) => 全局工具配置 => ctrl F NodeJS 安装

  1. 新增 NodeJS
  2. 填写 别名 自定义填写名称,可以照抄下面的版本号
  3. 选择 NodeJS版本,之前已经下载好插件,这里应该自动跳出来的
  4. 点击 应用按钮 点击 保存按钮

前端发布接入jenkins

2-4 凭据配置

dashbord => Manage Jenkins(系统管理) => 凭据管理 => 全局 按钮下拉选择 添加凭据
此处添加 github 仓库和 npm 令牌

  1. 添加 github 仓库

    • 填写 用户名 github用户名
    • 填写 密码 github密码
    • 填写 描述 github 登录凭证
    • 点击 创建 按钮
  2. 添加 npm 令牌

    • 类型选择「Secret text」
    • Secret 字段填入你用于 Nexus 仓库的认证 authToken
    • ID 填写一个易于识别的值,比如:KUNLUN_NPM_TOKEN
    • 点击 创建 按钮
    • tips
      # 登录数式 npm 仓库
      npm login --registry=http://nexus.shushi.pro/repository/kunlun/
      # 查看登录令牌
      cat ~/.npmrc

2-5 创建任务

dashbord => 点击屏幕中间 create a job

  1. 名称填写 你的项目名字(示例:React_PC)
  2. 点击 构建一个自由风格的软件项目
  3. 点击 确定按钮
  4. 点击 github项目 填写项目URL
  5. 源码管理 勾选git
  6. 填写 Repository URL 这里用github仓库的http地址
  7. Credentials 选择之前配置的凭证
  8. 指定分支暂时填写 */dev
  9. 点击 应用按钮 点击 保存按钮
  10. 点击立即构建按钮,观察是否通过

2-6 Github webHooks 配置

github代码仓库 => Settings => Webhooks

填写 Payload URL http://ip:8080/jenkins_home/github-webhook/
选择 Content type application/json
点击 add webbhook 按钮
jenkins => dashbord => 点击之前创建的项目 => 配置

点击 构建触发器
勾选 GitHub hook trigger for GITScm polling

2-7 构建环境

`ctrl f` 构建环境

  1. 点击 构建环境
  2. 勾选「Use secret text(s) or file(s)」→「Add」→ 把 npm 令牌添加成环境变量
  3. 变量填 KUNLUN_NPM_TOKEN,凭据选我们添加的 npm 令牌(ID 是 KUNLUN_NPM_TOKEN)
  4. 勾选 Provide Node & npm bin/ folder to PATH
  5. 选择 我们刚刚配置过的nodejs版本
  6. 点击 应用按钮

2-8 Build Steps

`ctrl f` Build Steps

  1. 增加构建步骤
  2. 选择 Execute NodeJS script
  3. 选择 我们刚刚配置过的nodejs版本
  4. 点击 应用、保存按钮
  5. 构建项目测试目前为止步骤是否正确,并学会手动构建流程

2-9 执行 shell

dashbord => 点击之前创建的项目 => 配置 => ctrl F Build Steps

  1. 增加构建步骤
  2. 选择 执行 shell
  3. 填写下面 bash 指令
  4. 点击 应用、保存按钮
  5. 构建项目测试,控制台输出应该能看到安装成功和构建成功
#!/bin/bash
node -v
npm -v

npm install -g pnpm || { echo "pnpm 安装失败"; exit 1; }
echo "pnpm 安装成功"

echo "" >> .npmrc
echo "//nexus.shushi.pro/repository/kunlun/:_authToken=${KUNLUN_NPM_TOKEN}" >> .npmrc

pnpm install || { echo "依赖安装失败"; exit 1; }
echo "依赖安装成功"

pnpm --filter ss-boot build || { echo "构建失败"; exit 1; }
echo "构建成功"

2-10 自动部署到对应环境

  1. 修改下 bash 指令,打包出 ./dist 后,将 ./dist 压缩
    dashbord => 点击之前创建的项目 => 配置 => ctrl F 执行shell
#!/bin/bash

# 查看信息
echo "当前打包项目 Github 仓库分支:"
echo "GIT_BRANCH" $GIT_BRANCH

node -v
npm -v

npm install -g pnpm || { echo "pnpm 安装失败"; exit 1; }
echo "pnpm 安装成功"

echo "" >> .npmrc
echo "//nexus.shushi.pro/repository/kunlun/:_authToken=${KUNLUN_NPM_TOKEN}" >> .npmrc

pnpm install || { echo "依赖安装失败"; exit 1; }
echo "依赖安装成功"

pnpm --filter ss-boot build || { echo "构建失败"; exit 1; }
echo "构建成功"

cd ./packages/ss-boot
if [ ! -d "./dist" ]; then
    echo "构建未生成 dist 目录"
    exit 1
fi

echo "开始打包..."

rm -rf dist.tar     # 每次构建删除已存在的dist压缩包
tar -zcvf dist.tar ./dist  # 将dist文件压缩成dist.tar
if [ $? -eq 0 ]; then
    echo "打包成功"
else
    echo "打包失败"
    exit 1
fi

echo "构建和打包完成"
echo $PATH

点击应用

  1. 增加构建步骤,将 dist 压缩包通过 ssh 传到服务器上,用 nginx 代理

    • 选择 Send files or execute commands over SSH
    • 填写 服务名称 Name 为 jenkins_node
    • 填写 源文件Source 为 dist.tar
    • 填写 目标路径Remote directory 为 /Users/ember/docker/html/origin/dev (根据实际nginx代理的目录修改)
    • 填写 执行脚本Exec command 如下
      ```shell
      cd /Users/ember/docker/html/origin/dev
      rm -rf dist/
      tar zxvf dist.tar
      rm dist.tar

Oinone社区 作者:银时原创文章,如若转载,请注明出处:https://doc.oinone.top/other/20839.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
银时's avatar银时数式员工
Previous 2025年5月8日 pm2:03
Next 2025年5月15日 am10:40

相关推荐

  • 如何实现业务表格跳转页面设计器设计器页面

    后端实现 代理继承界面设计器视图模型 @Model.model(MyView.MODEL_MODEL) @Model(displayName = "视图代理") @Model.Advanced(type = ModelTypeEnum.PROXY) public class MyView extends UiDesignerViewProxy { public static final String MODEL_MODEL = "hr.simple.MyView"; @Field.Integer @Field(displayName = "页面布局ID") private Long uiDesignerViewLayoutId; } 重写查询接口,返回页面布局ID,重写创建接口,实现创建页面逻辑。 package pro.shushi.pamirs.top.core.action; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.base.constants.ViewConstants; import pro.shushi.pamirs.boot.base.enmu.ActionTargetEnum; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxAction; import pro.shushi.pamirs.boot.base.ux.annotation.action.UxRoute; import pro.shushi.pamirs.boot.base.ux.annotation.button.UxRouteButton; import pro.shushi.pamirs.framework.connectors.data.sql.Pops; import pro.shushi.pamirs.framework.connectors.data.sql.query.LambdaQueryWrapper; import pro.shushi.pamirs.meta.annotation.Action; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.dto.condition.Pagination; import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.constant.FunctionConstants; import pro.shushi.pamirs.meta.enmu.*; import pro.shushi.pamirs.top.api.model.MyView; import pro.shushi.pamirs.ui.designer.api.designe.UiDesignerViewLayoutService; import pro.shushi.pamirs.ui.designer.model.UiDesignerViewLayout; import pro.shushi.pamirs.ui.designer.pmodel.UiDesignerViewLayoutProxy; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @author Yexiu at 20:39 on 2025/3/27 */ @Component @Model.model(MyView.MODEL_MODEL) public class MyViewAction { @Autowired private UiDesignerViewLayoutService uiDesignerViewLayoutService; @Action.Advanced(name = FunctionConstants.create, managed = true) @Action(displayName = "创建", summary = "添加", bindingType = ViewTypeEnum.FORM) @Function(name = FunctionConstants.create) @Function.fun(FunctionConstants.create) public MyView create(MyView data) { UiDesignerViewLayoutProxy uiDesignerViewLayoutProxy = new UiDesignerViewLayoutProxy(); uiDesignerViewLayoutProxy.setBizType(data.getBizType()); uiDesignerViewLayoutProxy.setDesignerActionBarType(data.getDesignerActionBarType()); uiDesignerViewLayoutProxy.setViewType(data.getType()); uiDesignerViewLayoutProxy.setModel(data.getModel()); uiDesignerViewLayoutProxy.setModule(PamirsSession.getServApp()); uiDesignerViewLayoutProxy.setViewTitle(data.getTitle()); uiDesignerViewLayoutProxy.setUsingDefaultView(data.getLoadLayout()); UiDesignerViewLayoutProxy saveUiDesigner = uiDesignerViewLayoutService.create(uiDesignerViewLayoutProxy); data.setDesignerViewId(saveUiDesigner.getId()); return data; } @Function.Advanced(type = FunctionTypeEnum.QUERY, displayName = "查询列表") @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.API, FunctionOpenEnum.LOCAL}) public Pagination<MyView> queryPage(Pagination<MyView> page, IWrapper<MyView> queryWrapper) { LambdaQueryWrapper<MyView> wrapper = Pops.<MyView>lambdaQuery().from(MyView.MODEL_MODEL) .eq(MyView::getSys, Boolean.FALSE) .eq(MyView::getSystemSource, SystemSourceEnum.UI); Pagination<MyView> myViewPagination = new MyView().queryPage(page, wrapper); List<MyView> content…

    2025年3月31日
    71600
  • 模版名称如何翻译

    导出翻译项: mutation { excelExportTaskMutation { createExportTask( data: { workbookDefinition: { model: "file.ExcelWorkbookDefinition" name: "excelLocationTemplate" } } ) { name } } } { "path": "/file", "lang": "en-US" } 导入翻译项: mutation { excelImportTaskMutation { createImportTask( data: { workbookDefinition: { model: "file.ExcelWorkbookDefinition" name: "excelLocationTemplate" } file: { url: "https://minio.oinone.top/pamirs/upload/zbh/test/2024/06/03/导出国际化配置模板_1717390304285_1717391684633.xlsx" } } ) { name } } } PS:导入自行修改url进行导入

    2025年2月7日
    1.3K00
  • 后端脚手架生成工程

    后端脚手架生成工程 脚手架版本 6.2.x(6.3.x/6.4.x)版本的脚手架,修改脚本(参考下节内容)中脚手架版本: # 新项目的pamirs platform version pamirsVersion=6.2.8 …… # mvn archetype:generate执行片段中 -DarchetypeVersion=6.2.8 7.0.x版本的脚手架,修改脚本(参考下节内容)中脚手架版本: # 新项目的pamirs platform version pamirsVersion=7.0.5 …… # mvn archetype:generate执行片段中 -DarchetypeVersion=7.0.5 后端脚手架生成工程 后端单工程脚手架 1、使用如下命令来用项目脚手架生成工程:新建archetype-project-generate.sh(bat) 脚本 archetype-project-generate.sh #!/bin/bash # 项目生成脚手架 # 用于新项目的构建 # 脚手架使用目录 # 本地 local # 本地脚手架信息存储路径 ~/.m2/repository/archetype-catalog.xml archetypeCatalog=local # 以下参数以pamirs-demo为例 # 新项目的groupId groupId=pro.shushi.pamirs.demo # 新项目的artifactId artifactId=pamirs-demo # 新项目的version version=1.0.0-SNAPSHOT # Java包名前缀 packagePrefix=pro.shushi # Java包名后缀 packageSuffix=pamirs.demo # 新项目的pamirs platform version;根据上个章节中的版本介绍进行修改 pamirsVersion=6.2.8 # Java类名称前缀 javaClassNamePrefix=Demo # 项目名称 module.displayName projectName=OinoneDemo # 模块 MODULE_MODULE 常量 moduleModule=demo_core # 模块 MODULE_NAME 常量 moduleName=DemoCore # spring.application.name applicationName=pamirs-demo # tomcat server address serverAddress=0.0.0.0 # tomcat server port serverPort=8090 # redis host redisHost=127.0.0.1 # redis port redisPort=6379 # 数据库名 db=demo # zookeeper connect string zkConnectString=127.0.0.1:2181 # zookeeper rootPath zkRootPath=/demo mvn archetype:generate \ -DinteractiveMode=false \ -DarchetypeCatalog=${archetypeCatalog} \ -DarchetypeGroupId=pro.shushi.pamirs.archetype \ -DarchetypeArtifactId=pamirs-project-archetype \ -DarchetypeVersion=6.2.8 \ #根据上个章节中的版本介绍进行修改 -DgroupId=${groupId} \ -DartifactId=${artifactId} \ -Dversion=${version} \ -DpamirsVersion=${pamirsVersion} \ -Dpackage=${packagePrefix}.${packageSuffix} \ -DpackagePrefix=${packagePrefix} \ -DpackageSuffix=${packageSuffix} \ -DjavaClassNamePrefix=${javaClassNamePrefix} \ -DprojectName="${projectName}" \ -DmoduleModule=${moduleModule} \ -DmoduleName=${moduleName} \ -DapplicationName=${applicationName} \ -DserverAddress=${serverAddress} \ -DserverPort=${serverPort} \ -DredisHost=${redisHost} \ -DredisPort=${redisPort} \ -Ddb=${db} \ -DzkConnectString=${zkConnectString} \ -DzkRootPath=${zkRootPath} archetype-project-generate.bat @echo off :: 项目生成脚手架 set archetypeCatalog=local set groupId=pro.shushi.pamirs.demo set artifactId=pamirs-demo set version=1.0.0-SNAPSHOT set…

    2025年8月22日
    1.1K00
  • IP黑白名单实现拦截三方用户

    已知厂商IP为10.139.0.1,经系统检测122.233.24.28、138.122.12.9为风险IP,需要禁止访问。 白名单配置:10.139.0.1 黑名单配置:122.233.24.28、138.122.12.9 厂商请求到Oinone开放平台请求头需携带X-Forwarded-For和X-Real-IP,例如: X-Forwarded-For 122.233.24.28 X-Real-IP 122.233.24.28 经Nginx代理后,oinone获取的请求头内容: X-Forwarded-For 122.233.24.28, 10.139.0.1 # 代理追加厂商IP到末尾 X-Real-IP 122.233.24.28 # 保持客户端原始值,Nginx不处理 效果:厂商10.139.0.1发送的请求且用户X-Real-IP不在黑名单内才放行。 注意事项 Nginx如果配置X-Real-IP需关闭,否则拿到的永远是厂商IP。 proxy_set_header X-Real-IP $remote_addr; 相关文章 开放应用中的ip黑白名单

    2025年5月15日
    69700
  • Excel导出模块翻译值

    由于目前翻译资源导出只可以导出应用资源,无法导出模块资源,所以暂时提供以下方法导出模块资源。6.2.11、5.7.4.20 之前版本验证 方案一: 导出环境覆盖以下类 package pro.shushi.pamirs.translate.template.imports; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import pro.shushi.pamirs.file.api.context.ExcelDefinitionContext; import pro.shushi.pamirs.file.api.entity.ExcelExportFetchDataContext; import pro.shushi.pamirs.file.api.extpoint.impl.DefaultExcelExportFetchDataExtPoint; import pro.shushi.pamirs.file.api.model.ExcelExportTask; import pro.shushi.pamirs.framework.connectors.data.sql.Pops; import pro.shushi.pamirs.framework.connectors.data.sql.query.LambdaQueryWrapper; import pro.shushi.pamirs.framework.connectors.data.sql.query.QueryWrapper; import pro.shushi.pamirs.meta.annotation.Ext; import pro.shushi.pamirs.meta.annotation.ExtPoint; import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j; import pro.shushi.pamirs.meta.api.Models; import pro.shushi.pamirs.meta.api.dto.wrapper.IWrapper; import pro.shushi.pamirs.meta.common.lambda.LambdaUtil; import pro.shushi.pamirs.meta.common.util.PStringUtils; import pro.shushi.pamirs.meta.constant.SqlConstants; import pro.shushi.pamirs.meta.domain.module.ModuleDefinition; import pro.shushi.pamirs.resource.api.enmu.TranslationApplicationScopeEnum; import pro.shushi.pamirs.resource.api.model.ResourceTranslation; import pro.shushi.pamirs.resource.api.model.ResourceTranslationItem; import pro.shushi.pamirs.translate.constant.TranslateConstants; import pro.shushi.pamirs.translate.proxy.TranslationItemExportProxy; import pro.shushi.pamirs.translate.service.TranslationDslNodeVisitor; import pro.shushi.pamirs.translate.template.TranslateTemplate; import pro.shushi.pamirs.translate.utils.UniversalParser; import java.util.*; import java.util.stream.Collectors; import static pro.shushi.pamirs.translate.constant.TranslateConstants.FIELD_TO_EXCLUDE; /** * @author Adamancy Zhang * @date 2020-11-04 18:09 */ @Slf4j @Component @Ext(ExcelExportTask.class) @SuppressWarnings({"unchecked"}) public class ResourceTranslationExportExtPoint extends DefaultExcelExportFetchDataExtPoint { private String resLangCodeColumn = PStringUtils.fieldName2Column(LambdaUtil.fetchFieldName(ResourceTranslationItem::getResLangCode)); private String langCodeColumn = PStringUtils.fieldName2Column(LambdaUtil.fetchFieldName(ResourceTranslationItem::getLangCode)); private String moduleColumn = PStringUtils.fieldName2Column(LambdaUtil.fetchFieldName(ResourceTranslationItem::getModule)); @Override @ExtPoint.Implement(expression = "context.name=="" + TranslateTemplate.TEMPLATE_NAME + "" && context.model=="" + ResourceTranslation.MODEL_MODEL + """) public List<Object> fetchExportData(ExcelExportTask exportTask, ExcelDefinitionContext context) { ArrayList<Object> objects = new ArrayList<>(); Map<String, Object> queryData = exportTask.getConditionWrapper().getQueryData(); TranslationItemExportProxy data = JSON.parseObject(JSON.toJSONString(queryData), TranslationItemExportProxy.class); LambdaQueryWrapper<TranslationItemExportProxy> queryWrapper = Pops.<TranslationItemExportProxy>lambdaQuery() .from(TranslationItemExportProxy.MODEL_MODEL) .eq(StringUtils.isNotBlank(data.getModule()), ResourceTranslationItem::getModule, data.getModule()) .eq(ResourceTranslationItem::getResLangCode, TranslateConstants.RES_LANG_CODE) .eq(StringUtils.isNotBlank(data.getLangCode()), ResourceTranslationItem::getLangCode, data.getLangCode()) .eq(data.getState() != null, ResourceTranslationItem::getState, data.getState()) .like(StringUtils.isNotBlank(data.getResLangInclude()), ResourceTranslationItem::getOrigin, data.getResLangInclude()) .like(StringUtils.isNotBlank(data.getTargetInclude()), ResourceTranslationItem::getTarget, data.getResLangInclude()); Map<String, String> moduleNameMap = Models.origin().queryListByWrapper(Pops.<ModuleDefinition>lambdaQuery() .from(ModuleDefinition.MODEL_MODEL) .eq(StringUtils.isNotBlank(data.getModule()), ModuleDefinition::getModule, data.getModule())) .stream() .collect(Collectors.toMap(ModuleDefinition::getModule, ModuleDefinition::getDisplayName, (_a, _b)…

    2025年8月21日
    68300

Leave a Reply

Please Login to Comment