戴志强1
Published on 2026-09-20 / 56 Visits
0
0

imom移动端打包部署

imom移动端打包部署

1. 安装nexus中央仓库

添加PVC:

image-CSog.png

创建deployment和svc:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nexus3
  namespace: common
  labels:
    app: nexus3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nexus3
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nexus3
      annotations:
        kubesphere.io/creator: admin
        kubesphere.io/restartedAt: '2024-09-03T03:02:34.074Z'
        logging.kubesphere.io/logsidecar-config: '{}'
    spec:
      volumes:
        - name: volume-c8wdzv
          persistentVolumeClaim:
            claimName: nexus3-pvc
      containers:
        - name: container-nexus3-rtsexq
          image: '192.168.168.207:30002/public/sonatype/nexus3'
          ports:
            - name: tcp-8081
              containerPort: 8081
              protocol: TCP
          resources:
            requests:
              memory: 2Gi
          volumeMounts:
            - name: volume-c8wdzv
              mountPath: /nexus-data
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext: {}
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
kind: Service
apiVersion: v1
metadata:
  name: nexus3-svc
  namespace: common
  labels:
    app: nexus3-svc
spec:
  ports:
    - name: http-nexus3
      protocol: TCP
      port: 8081
      targetPort: 8081
      nodePort: 31001
  selector:
    app: nexus3
  type: NodePort
  sessionAffinity: None
  externalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster

2. nexus配置

首次admin登录时,从容器的指定位置获取admin的登录密码。

image-cRSZ.png

然后在页面重置admin的密码。

按照下面的配置添加前端相关的npm仓库。

npm-hosted库:

image-dGRo.png

npm-taobao, npm-tencent 库:

image-Yfum.png

image-xVJx.png

npm-dev 代理库:

这里注意要配置公司的nexus的外网库,可以拉取定制开发的软件包:

image-llGF.png

npm-group 库:

将npm-dev, npm-taobao, npm-tencent, npm-hosted 添加到当前组

image-aRdw.png

配置完毕后,检查npm仓库列表:

image-CjAF.png

3. 安装devops-biz

3.1 配置

添加 devops-conf 配置:

kind: ConfigMap
apiVersion: v1
metadata:
  name: devops-conf
  namespace: imom
  annotations:
    kubesphere.io/creator: daizhiqiang
data:
  generate-apk.sh: >
    #!/bin/bash


    env=${1:-dev}

    templateType=${2:-dme}

    appCode=${3:-nationstar2024092711337449}

    appid=${4:-__UNI__477F3DB}

    appName=${5:-MBM}

    packageName=${6:-com.nationstar.smt.dme.sie}

    versionName=${7:-1.0.0}

    versionCode=${8:-1}

    site=${9:-http://localhost:8090}

    storeFileUrl=${10:-http://localhost:8090/api/app/__UNI__477F3DB/package/keystore}

    appKey=${11:-ed0fec369ec40d26871f2503441f2baf}

    checkUpdateHost=${12:-http://localhost:8090}

    #nexusUrl=${13:-http://192.168.181.114:8081}

    nexusUrl=${13:-http://192.168.168.207:30998}

    tenantId=${14:-hwstaff_p_apsimes}

    updateMode=${15:-0}

    rememberUsersLimit=${16:-1}

    cliId=${17:-imom}


    logPath="/var/log/apk/$appCode.log" # 日志路径


    bakLogPath="/var/log/apk/$appCode.bak_$(date +"%Y%m%d_%H%M%S").log" #
    备份日志文件路径

    # 重新打包时,备份日志文件后覆盖

    if [ -f "$logPath" ]; then
      mv "$logPath" "$bakLogPath"
    fi


    uniTemplateDir="uni-$appCode" # 临时项目模板文件夹名称

    apkTemplateDir="apk-$appCode" # 临时打包模板文件夹名称


    # 设置陷阱,在脚本退出时执行 sync

    trap 'sync' EXIT

    # 全局异常处理函数

    handler_error() {
      rm -rf /Android/code/$uniTemplateDir/ /Android/code/$apkTemplateDir/
            local exit_code=$?
            local error_msg="发生异常,错误码:$exit_code"
            echo "exec fail!"       | tee -a "$logPath"
            #exit $exit_code # 由于 set -e 开启了错误检查,所以不需要再干预退出脚本
    }

    # 全局异常捕获

    trap handler_error ERR

    # 将脚本的执行命令和输出都写入日志

    exec > >(while IFS= read -r line; do echo "[$(date +"%Y-%m-%d %H:%M:%S")]
    $line"; done | tee -a "$logPath") 2>&1

    # 开启错误检查,命令执行返回非零的退出状态码时,直接退出脚本

    set -e

    # 打开命令追踪

    set -x


    # 安装并查看脚手架版本

    if [[ $cliId == "dme" ]]; then
        npm install -g sie-cli@1.13.0-alpha.2 --registry=$nexusUrl/repository/npm-group/ --no-cache
        cliCmd="sie-cli"
    else
        npm install -g @imom/mobile-cli@0.1.2-alpha.14 --registry=$nexusUrl/repository/npm-group/
        cliCmd="imom-cli"
    fi

    $cliCmd -V


    # 使用脚手架生成移动端底座

    echo "project generating..."

    cd /Android/code

    if [[ $checkUpdateHost == "" ]] || [[ $checkUpdateHost == " " ]]; then
        checkUpdateHost="/devops"
    fi

    $cliCmd init -auto 是 -n $uniTemplateDir -$templateType -appCode $appCode
    -site $site -checkUpdateHost $checkUpdateHost -tenantId $tenantId
    -updateMode $updateMode -rememberUsersLimit $rememberUsersLimit

    cd $uniTemplateDir


    # 替换 APK 打包环境

    sed -i "s/const env = process.env?.VUE_APP_ENV .*/const env =
    process.env?.VUE_APP_ENV || \"$env\";/"
    /Android/code/$uniTemplateDir/src/config/index.js


    # 安装依赖

    sed -i "s|http://192.168.181.114:8081|${nexusUrl}|g"  yarn.lock

    echo "installing..."

    yarn install --registry=$nexusUrl/repository/npm-group/

    cd src

    yarn install --registry=$nexusUrl/repository/npm-group/

    cd ..

    ls


    # 构建项目h5

    mkdir -p /Android/code/h5-release/

    echo "building..."

    yarn run build:h5:$env

    tar -cvzf ${appCode}-dist.tar.gz dist

    cp -rf ${appCode}-dist.tar.gz /Android/code/h5-release/

    # 构建项目app-plus

    yarn run build:app-plus:$env

    rm -rf $appid

    mkdir $appid

    cp -r dist/build/app-plus $appid/www


    # 将生成的安卓格式的代码移入生成 APK 的模板中

    echo "android source moving..."

    rm -rf /Android/code/apk-template/simpleDemo/src/main/assets/apps/*

    # 复制打包模板用于打包生成 APK

    cp -r /Android/code/apk-template /Android/code/$apkTemplateDir

    cp -r $appid /Android/code/$apkTemplateDir/simpleDemo/src/main/assets/apps/


    # 替换版本号等基础信息

    sed -i "s/<app appid=.*/<app appid=\"$appid\" appver=\"\"\/>/"
    /Android/code/$apkTemplateDir/simpleDemo/src/main/assets/data/dcloud_control.xml

    sed -i "s/<string name=.*/<string name=\"app_name\">$appName<\/string>/"
    /Android/code/$apkTemplateDir/simpleDemo/src/main/res/values/strings.xml

    sed -i
    "s/outputFileName=.*/outputFileName=\"$appName-\${variant.name}-V\${variant.versionName}.apk\"/"
    /Android/code/$apkTemplateDir/simpleDemo/build.gradle

    sed -i "s/applicationId .*/applicationId \"$packageName\"/"
    /Android/code/$apkTemplateDir/simpleDemo/build.gradle

    sed -i "s/namespace .*/namespace \"$packageName\"/"
    /Android/code/$apkTemplateDir/simpleDemo/build.gradle

    sed -i "s/versionName \".*\"/versionName \"$versionName\"/"
    /Android/code/$apkTemplateDir/simpleDemo/build.gradle

    sed -i "s/versionCode .*/versionCode $versionCode/"
    /Android/code/$apkTemplateDir/simpleDemo/build.gradle

    sed -i "s/android:value=.*/android:value=\"$appKey\" \/>/"
    /Android/code/$apkTemplateDir/simpleDemo/src/main/AndroidManifest.xml

    sed -i
    "s/android:authorities=.*/android:authorities=\"$packageName.dc.fileprovider\"/"
    /Android/code/$apkTemplateDir/simpleDemo/src/main/AndroidManifest.xml


    # 下载对应的签名证书,一个 appid 对应一个 keystore 文件

    rm -f /Android/code/$apkTemplateDir/simpleDemo/sie-dme.keystore

    wget -O /Android/code/$apkTemplateDir/simpleDemo/sie-dme.keystore
    $storeFileUrl


    # 生成 APK

    echo "apk generating..."

    cd /Android/code/$apkTemplateDir

    ./gradlew assembleRelease


    # 复制 APK 留档

    apkName=$(find
    "/Android/code/$apkTemplateDir/simpleDemo/build/outputs/apk/release"
    -maxdepth 1 -type f -name "*.apk" | sort | head -n 1 | xargs -I {} basename
    {})

    cp
    /Android/code/$apkTemplateDir/simpleDemo/build/outputs/apk/release/$apkName
    /Android/code/apk-release/


    # 打包完成后删除模板

    rm -rf /Android/code/$uniTemplateDir/ /Android/code/$apkTemplateDir/


    echo "exec success! target path: /Android/code/apk-release/$apkName" | tee
    -a "$logPath"


    # 关闭命令追踪

    #set +x

    # 关闭错误检查

    #set +e

biz-conf 添加devops-biz.yml 一项:

注意mysql与nexus的配置。

security:
  oauth2:
    client:
      client-id: ENC(LcjZms1vqs1po+G3mQk17g==)
      client-secret: ENC(LcjZms1vqs1po+G3mQk17g==)
      scope: server
      ignore-urls:
        - /error
        - /druid/**
        - /actuator/**
        - /v2/api-docs

spring:
  http:
    multipart:
      encoding: UTF-8
  autoconfigure:
    exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration

mybatis-flex:
  datasource:
    #imom-kernel主库
    imom-kernel:
      username: ${MYSQL_USER:root}
      password: ${MYSQL_PWD:TODO_PASSWORD}
      url: jdbc:mysql://10.0.0.27:3306/imom_devops?serverTimezone=UTC&characterEncoding=utf8
      type: com.alibaba.druid.pool.DruidDataSource
      druid:
        max-wait: 10000
        stat-view-servlet:
          enabled: true
          url-pattern: /druid/*
          login-username: admin
          login-password: Sie123456
        filter:
          stat:
            enabled: true
            log-slow-sql: true
          wall:
            config:
              multi-statement-allow: true

logging:
  level:
    com.sie.mbm.mom.admin.upms.biz.mapper: debug

apilog:
  interfaceFlag: false # 默认是true,是否打印接口日志,这个是总开关

mom:
  tenant:
    column: tenant_id
    tables:
      - sys_user
      - sys_role
      - sys_menu
      - sys_dept
      - sys_log
      - sys_social_details
      - sys_dict
      - sys_dict_item
      - sys_public_param
      - sys_log
      - sys_file
      - sys_oauth_client_details
      - sys_post
      - sys_module
      - mes_import_sol
      - mes_import_sol_dtl
      - mes_prod_feed_station_list
      - mes_prod_feed_station_list_dtl
  api:
    api-source: class
    publish-type: private
    contextPath: /sie
    app-module: sie.site.smt
    permission-type: 3
    enabled: false

delegator:
  host: ${HUAWEI_API_URL:http://mbm-api-gateway.mbm:9090}

#----------------DME config begin------------------------
application:
  appId: 0fa023ca177341a89eec915d43c86ad9
  tenantId: -1

soa:
  token:
    url: https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens

hw:
  auth:
    loginAccount: sieadmin
    loginPwd: Mbm@2023.
    tenantId: hwstaff_p_apsimes

nexus:
  url: http://nexus3-svc.common:8081
  username: admin
  password: TODO_PASSWORD
  repository: npm-hosted

app:
  list:
    - appid: __UNI__6155926
      appName: 标品SMT
      packageName: com.smt.dme.sie
      appKey: d46270d1021856fecc13ea5d810f0ffd
    - appid: __UNI__477F3DB
      appName: 国星SMT
      packageName: com.nationstar.smt.dme.sie
      appKey: ed0fec369ec40d26871f2503441f2baf
    - appid: __UNI__E97732D
      appName: 国星LED
      packageName: com.nationstar.led.dme.sie
      appKey: 311cf0b4a49524674b0c79353ae42723
    - appid: __UNI__6155926
      appName: 赛意IMOM标品
      packageName: com.sie.imom.standard
      appKey: d46270d1021856fecc13ea5d810f0ffd
  envs:
    - id: lmdev
      label: 联明电源开发环境
      host: http://10.0.0.23:32555/imomapi
      # 检查更新接口(非必要不填)
      checkUpdateHost: 
      tenantId: 067cfa58c8404a908780bda7e934e1b1
    - id: lmprod
      label: 联明电源生产环境
      host: http://10.0.0.10:32555/imomapi
      # 检查更新接口(非必要不填)
      checkUpdateHost: 
      tenantId: 067cfa58c8404a908780bda7e934e1b1
    - id: gnddev
      label: 广能达开发环境
      host: http://10.0.0.23:31555/imomapi
      # 检查更新接口(非必要不填)
      checkUpdateHost: 
      tenantId: 067cfa58c8404a908780bda7e934e1b1
    - id: gndprod
      label: 广能达生产环境
      host: http://10.168.1.232:32555/imomapi
      # 检查更新接口(非必要不填)
      checkUpdateHost: 
      tenantId: 067cfa58c8404a908780bda7e934e1b1

  #调用脚手架时的打包参数
  package:
    templateType: dme
    shellCommend: /Android/code/generate-apk.sh
    maxRunning: 2
  appCode:
    prefix: nationstar
3.2 存储PVC

添加devops-biz-log:

image-mfDV.png

3.3 工作负载与服务

工作负载:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: devops-biz
  namespace: imom
  labels:
    app: devops-biz
    component: devops-biz
    tier: backend
  annotations:
    deployment.kubernetes.io/revision: '1'
    kubesphere.io/creator: daizhiqiang
spec:
  replicas: 1
  selector:
    matchLabels:
      app: devops-biz
      component: devops-biz
      tier: backend
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: devops-biz
        component: devops-biz
        tier: backend
      annotations:
        kubesphere.io/creator: daizhiqiang
    spec:
      volumes:
        - name: volume-apk-log
          persistentVolumeClaim:
            claimName: devops-biz-log
        - name: volume-biz-conf
          configMap:
            name: biz-conf
            items:
              - key: common.yml
                path: common.yml
              - key: devops-biz.yml
                path: devops-biz.yml
            defaultMode: 420
        - name: volume-v4ewp7
          persistentVolumeClaim:
            claimName: devops-biz-log
        - name: volume-generate-apk
          configMap:
            name: devops-conf
            items:
              - key: generate-apk.sh
                path: generate-apk.sh
            defaultMode: 365
      containers:
        - name: devops-biz
          image: 'swr.cn-south-1.myhuaweicloud.com/imom-release/imom-devops:20260920.0-dev-release'
          ports:
            - name: http-0
              containerPort: 80
              protocol: TCP
          env:
            - name: GATEWAY_HOST
              value: dev.api.dme.com
            - name: GATEWAY_PORT
              value: '80'
            - name: NACOS_HOST
              value: '192.168.168.207:30848'
            - name: PROFILES_ACTIVE
              value: dev
          resources:
            requests:
              memory: 1536Mi
          volumeMounts:
            - name: volume-apk-log
              mountPath: /var/log/apk/
            - name: volume-biz-conf
              readOnly: true
              mountPath: /springboot_config
            - name: volume-generate-apk
              mountPath: /Android/code/generate-apk.sh
              subPath: generate-apk.sh
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 80
              scheme: HTTP
            initialDelaySeconds: 60
            timeoutSeconds: 1
            periodSeconds: 5
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 80
              scheme: HTTP
            initialDelaySeconds: 30
            timeoutSeconds: 3
            periodSeconds: 5
            successThreshold: 1
            failureThreshold: 3
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      securityContext: {}
      imagePullSecrets:
        - name: swr
      schedulerName: default-scheduler
  strategy:
    type: Recreate
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

服务:

kind: Service
apiVersion: v1
metadata:
  name: devops-biz
  namespace: imom
  labels:
    app: devops-biz
    component: devops-biz
spec:
  ports:
    - name: http-80
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: devops-biz
    component: devops-biz
    tier: backend
  type: NodePort
  sessionAffinity: None
  externalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  internalTrafficPolicy: Cluster

nginx-gateway转发配置:

image-SCCc.png

location /devops/ {
              # 包含跨域配置
              add_header 'Access-Control-Allow-Origin' '*' always;
              add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
              add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,renterid,siteid' always;
              if ($request_method = 'OPTIONS') { return 204; }

              proxy_pass http://devops-biz/;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header X-Forwarded-Proto $scheme;
    }

移动端打包前端使用public-ui, 确保镜像比以下的镜像要新:

192.168.168.207:30002/imom/imom-public-ui-dev:20260915.1419

imom-public-ui 加入移动端外壳配置VITE_MOBILE_PATH:

企业微信截图_17920315566646.png

企业微信截图_17920359605506.png

栏目加入菜单配置.

业务包管理文根路径: imom-public/devops/#/appBusinessPackage

企业微信截图_17920313982178.png

APP版本管理文根路径: imom-public/devops/#/appVersion

企业微信截图_17920321712263.png

4. devops使用配置

4.1 导出npm包

从历史选择业务包

image-nChM.png

将勾选的包一个个下载:

image-gtUT.png

4.2 导入npm包

image-NxKq.png

4.3 生成APK

image-uZxP.png

在"APP管理"中观察打包进度, 打包完成后,点击"下载":

image-TNYy.png


Comment