# ISV 专项

# 简介

ISV框架是为客开人员提供的一套插件类工程的项目模版。目前提供 PCH5 两种类型模版,可配合 wat3 进行快速构建。

# 安装

npm install -g @esign/wat3

# 初始化项目
wat3 init plugin-demo

创建项目流程如下:
CLI 预览

服务运行后展示效果如下: isv效果图

# 脚本命令

# 查看最新的打包工具版本(如果模版里面版本落后的话请升级到最新); 要求pnpm版本6.35.1
npm view @esign/plugin-build versions --registry https://registry-npm.tsign.cn/

# 全局安装
npm i -g @esign/plugin-build@latest --registry https://registry-npm.tsign.cn/

# 项目升级最新的版本
pnpm add -Dw @esign/plugin-build@latest --registry https://registry-npm.tsign.cn/

# 运行服务指令
yarn serve

# 构建业务代码指令
yarn build:base

# 构建插件代码指令
yarn build:plugin

# 构建插件及业务代码指令
yarn build

# 快速创建插件模版指令

# 创建 template 插件模版
yarn create:plugin <插件名称>

# 构建插件指令

# 初始化插件配置
yarn plugin:init

# 构建插件 (打包所有插件)
yarn build:plugin

# 构建插件 (打包单独某个插件) 未开放
# 例如,打包 hello-world-plugin 插件
# yarn build:plugin-module @base/hello-world-plugin
# yarn build:plugin-module 插件的包名(package.name)

创建插件流程如下:
CLI 预览

# 开发工具

# 开发规范

# 目录

+-- _templates -------------------------------------------------> 插件模版目录
|
+-- dist -------------------------------------------------------> 构建后的源码目录
|   |
|   +-- base ---------------------------------------------------> 业务源码目录
|   |
|   +-- plugins ------------------------------------------------> 插件源码目录
|   
+-- config -----------------------------------------------------> 配置文件
|   |
|   +-- verifyCommitMsg.js -------------------------------------> git提交规范
|
+-- thirdSDK ---------------------------------------------------> 三方业务测试SDK目录
|   |
|   +-- index.ts -----------------------------------------------> SDK包
|   |
|   +-- README.md ----------------------------------------------> SDK 说明文档
|
+-- build ------------------------------------------------------> 扩展指令目录(可选)
|
+-- moduleComponents -------------------------------------------> 公用业务组件目录(可选)
|
+-- plugins ----------------------------------------------------> 插件目录(必选)
|   |
|   +-- base ---------------------------------------------------> 业务域目录
|   |   | 
|   |   +-- hello-world-plugin ---------------------------------> 插件目录
|   |   |   |
|   |   |   +-- package.json -----------------------------------> 插件的 package.json (用于插件单独单包)
|   |   |   |
|   |   |   +-- src --------------------------------------------> 插件源文件目录
|   |   |   |   |
|   |   |   |   +-- index.ts -----------------------------------> 插件入口文件
|   |   |   |   |
|   |   |   |   +-- components ---------------------------------> UI组件目录(可选)
|   |   |   |   |
|   |   |   |   +-- logic --------------------------------------> 逻辑目录(可选)
|   |   |   |   |
|   |   |   |   +-- plugin -------------------------------------> 插件源码目录
|   |   |   |   |   |
|   |   |   |   |   +-- index.js -------------------------------> 插件源码    
|   |  
|   +-- ......
|   |
|   +-- config.json --------------------------------------------> 插件配置文件目录
|
+-- pluginManager ----------------------------------------------> 插件引用方式管理目录
|
+-- src(demo) --------------------------------------------------> demo 目录(vue项目目录结构)
|
+-- .eslintrc.js -----------------------------------------------> eslint 配置文件
|
+-- .npmrc -----------------------------------------------------> npm 源配置文件
|
+-- babel.config.js --------------------------------------------> babel 配置文件
|
+-- tsconfig.json ----------------------------------------------> ts 配置文件
|
+-- package.json -----------------------------------------------> package.json
|
+-- vue.config.js ----------------------------------------------> vue 配置文件
|
+-- README.md --------------------------------------------------> 说明文档

# 国际化

如果你的项目需要使用多语言,我们的模板已提供了简单的vue-i18n的集成能力,如下:

提示

当然,如果项目中不需要使用多语言,删除以下vue-i18n依赖及引入文件即可

package.json

{
  "dependencies": {
    "vue-i18n": "8" // 8.x版本
  }
}

语言包位置public/static/locales/

目录

zh-CN.json

{
  "standard": "标准",
  "submitCounts": "提交次数",
  "plugins.helloword.developmentDocuments": "开发文档",
  "plugins.helloword.specificationDocument": "规范文档",
  "plugins.helloword.toolsDocumentation": "工具文档",
  "plugins.helloword.frontEndDevelopmentSpecification": "前端开发规范"
}

lib/i18n.ts

import VueI18n from 'vue-i18n'

const loadedLanguages: any = [] // 已加载的语言包
let i18n // VueI18n 实例
let langPrefix // 语言包前缀
let fallbackLocale = 'zh-CN' // 兜底语言
let beforeSetLanguage = (lang?: string) => {}
let afterSetLanguage = (lang?: string) => {}

// 解析 url 参数, 返回对象
function parseURL(url) {
  return url
    .slice(1)
    .split('&')
    .reduce((res, item) => {
      const [key, value] = item.split('=')
      res[key] = value

      return res
    }, {})
}

// url 中的语言标识
const langFromUrl = parseURL(window.location.search).lang

// 浏览器的语言设置
const langFromBrowser = window.navigator && window.navigator.language
let lang: string = langFromUrl || langFromBrowser || ''

// 浏览器设置语言环境为英文时, navigator.language 取出来的标识符可能是 en, en-us
lang = ['en', 'en-us', 'en-US'].includes(lang) ? 'en-US' : fallbackLocale // TODO: 现在就两种语言

// 异步加载语言包
function loadLanguageAsync(lang) {
  beforeSetLanguage(lang)

  return new Promise((resolve, reject) => {
    // 已经加载过, 返回
    if (loadedLanguages.includes(lang)) return resolve(setI18nLanguage(lang))
    if (window[`i18n_${lang}`]) {
      i18n.setLocaleMessage(lang, window[`i18n_${lang}`])
      loadedLanguages.push(lang)
      resolve(setI18nLanguage(lang))

      return
    }

    // Indicator.open()
    window.axios
      .get(`${langPrefix}${lang}.json?t=${new Date().getTime()}`, { withCredentials: false })
      .then(res => {
        // Indicator.close()
        i18n.setLocaleMessage(lang, res.data)
        loadedLanguages.push(lang)
        resolve(setI18nLanguage(lang))
      })
      .catch(e => {
        reject(e)
      })
      .finally(() => {
        afterSetLanguage(lang)
      })
  })
}

// 设置语言到关联语言的地方
function setI18nLanguage(lang) {
  i18n.locale = lang

  return lang
}

/**
 *
 * @param {*} Vue
 * @param {*} prefix 语言包地址前缀
 * @param {*} options 透传给 VueI18n 的参数
 */
function init(Vue, prefix, options): Promise<VueI18n> {
  const opt = options || {}
  langPrefix = prefix
  Vue.use(VueI18n)
  beforeSetLanguage = opt.beforeSetLanguage || beforeSetLanguage
  afterSetLanguage = opt.afterSetLanguage || afterSetLanguage
  fallbackLocale = opt.fallbackLocale || fallbackLocale
  i18n = new VueI18n({
    locale: lang || fallbackLocale, // set locale
    fallbackLocale,
    messages: {}, // set locale messages
    ...options,
  })

  return new Promise((resolve, reject) => {
    return loadLanguageAsync(lang)
      .catch(e => {
        console.error(`Load language ${lang} fail, use fallback language ${fallbackLocale} instead.`)
        loadLanguageAsync(fallbackLocale)
      })
      .catch(e => console.error('fallback language also faled. Use text key'))
      .finally(() => resolve(i18n))
  })
}
function text(...args) {
  return i18n.t(...args)
}
function getLanguage() {
  return i18n.locale
}
export { init, text as $t, getLanguage, loadLanguageAsync as setLanguage, i18n }

入口文件main.ts

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import { init as initI18n, $t, setLanguage, getLanguage } from './lib/i18n'
import axios from 'axios'

Vue.prototype.$t = $t
Vue.prototype.$setLanguage = setLanguage
Vue.prototype.$getLanguage = getLanguage

window.axios = axios

const prefix = '/static/locales/' // 字体包url前缀
initI18n(Vue, prefix, {}).then(async i18n => {
  new Vue({
    router,
    store,
    i18n,
    render: h => h(App),
  }).$mount('#app')
})

项目中使用

<template>
  <div class="hello-world">
    <h3>{{ $t('plugins.helloword.specificationDocument') }}</h3>
  </div>
</template>

效果如下:

i18n-2

# 注意事项

  • UI类组件使用/升级机制
    • 通用UI类组件: 通用组件会有专有的 npm 包,客开人员可自行安装使用。
    • 定制UI类组件: 定制组件会在项目开发前由主应用开发人员统一放在 moduleComponents 目录下,客开人员可自行使用。
  • src目录说明
    • src目录内容为开发的插件提供可预览的页面,便于插件开发时预览UI效果和业务逻辑。
  • 更多插件开发案例,可参考 esign-plugin-demo
    • esign-plugin-demo 仓库权限(或源码)可向 主应用开发人员 申请。
上次更新: 5/23/2023, 7:35:51 AM