diff --git a/doc/google/google.md b/doc/google/google.md index 3cf7e3c8..f77a8bba 100644 --- a/doc/google/google.md +++ b/doc/google/google.md @@ -21,17 +21,17 @@ gcloud beta publicca external-account-keys create ```shell Created an external account key -[b64MacKey: xxxxxxxxxxxxx -keyId: xxxxxxxxx] +[b64MacKey: xxxxxxxxxxxxxxxx +keyId: xxxxxxxxxxxxx] ``` -记录以上信息备用 +记录以上信息备用(注意keyId是不带中括号的) ## 3、 创建证书流水线 选择证书提供商为google, 开启使用代理 ## 4、 将key信息作为EAB授权信息 -google证书需要EAB授权, 使用第二步中的 keyId 和 b64MacKey 信息创建一条EAB授权记录 - +google证书需要EAB授权, 使用第二步中的 keyId 和 b64MacKey 信息创建一条EAB授权记录 +注意:keyId没有`]`结尾,不要把`]`也复制了 ## 5、 其他就跟正常申请证书一样了 diff --git a/packages/core/acme-client/src/crypto/index.js b/packages/core/acme-client/src/crypto/index.js index 53599f5d..79c59859 100644 --- a/packages/core/acme-client/src/crypto/index.js +++ b/packages/core/acme-client/src/crypto/index.js @@ -67,11 +67,11 @@ function getKeyInfo(keyPem) { * ``` */ -async function createPrivateRsaKey(modulusLength = 2048) { +async function createPrivateRsaKey(modulusLength = 2048, encodingType = 'pkcs8') { const pair = await generateKeyPair('rsa', { modulusLength, privateKeyEncoding: { - type: 'pkcs8', + type: encodingType, format: 'pem', }, }); @@ -106,11 +106,11 @@ exports.createPrivateKey = createPrivateRsaKey; * ``` */ -exports.createPrivateEcdsaKey = async (namedCurve = 'P-256') => { +exports.createPrivateEcdsaKey = async (namedCurve = 'P-256', encodingType = 'pkcs8') => { const pair = await generateKeyPair('ec', { namedCurve, privateKeyEncoding: { - type: 'pkcs8', + type: encodingType, format: 'pem', }, }); diff --git a/packages/core/acme-client/src/index.js b/packages/core/acme-client/src/index.js index 5c82b3f9..4e83c9f6 100644 --- a/packages/core/acme-client/src/index.js +++ b/packages/core/acme-client/src/index.js @@ -32,7 +32,7 @@ exports.directory = { */ exports.crypto = require('./crypto'); -// exports.forge = require('./crypto/forge'); +exports.forge = require('./crypto/forge'); /** * Axios diff --git a/packages/core/acme-client/types/index.d.ts b/packages/core/acme-client/types/index.d.ts index 406b546a..b0fc9657 100644 --- a/packages/core/acme-client/types/index.d.ts +++ b/packages/core/acme-client/types/index.d.ts @@ -155,16 +155,16 @@ export interface EcdsaPublicJwk { } export interface CryptoInterface { - createPrivateKey(keySize?: number): Promise; - createPrivateRsaKey(keySize?: number): Promise; - createPrivateEcdsaKey(namedCurve?: 'P-256' | 'P-384' | 'P-521'): Promise; + createPrivateKey(keySize?: number,encodingType?:string): Promise; + createPrivateRsaKey(keySize?: number,encodingType?:string): Promise; + createPrivateEcdsaKey(namedCurve?: 'P-256' | 'P-384' | 'P-521',encodingType?:string): Promise; getPublicKey(keyPem: PrivateKeyBuffer | PrivateKeyString | PublicKeyBuffer | PublicKeyString): PublicKeyBuffer; getJwk(keyPem: PrivateKeyBuffer | PrivateKeyString | PublicKeyBuffer | PublicKeyString): RsaPublicJwk | EcdsaPublicJwk; splitPemChain(chainPem: CertificateBuffer | CertificateString): string[]; getPemBodyAsB64u(pem: CertificateBuffer | CertificateString): string; readCsrDomains(csrPem: CsrBuffer | CsrString): CertificateDomains; readCertificateInfo(certPem: CertificateBuffer | CertificateString): CertificateInfo; - createCsr(data: CsrOptions, keyPem?: PrivateKeyBuffer | PrivateKeyString): Promise<[PrivateKeyBuffer, CsrBuffer]>; + createCsr(data: CsrOptions, keyPem?: PrivateKeyBuffer | PrivateKeyString,encodingType?:string): Promise<[PrivateKeyBuffer, CsrBuffer]>; createAlpnCertificate(authz: Authorization, keyAuthorization: string, keyPem?: PrivateKeyBuffer | PrivateKeyString): Promise<[PrivateKeyBuffer, CertificateBuffer]>; isAlpnCertificateAuthorizationValid(certPem: CertificateBuffer | CertificateString, keyAuthorization: string): boolean; } diff --git a/packages/core/pipeline/build.md b/packages/core/pipeline/build.md index f852c9ed..af5df441 100644 --- a/packages/core/pipeline/build.md +++ b/packages/core/pipeline/build.md @@ -1 +1 @@ -17:29 +02:32 diff --git a/packages/core/pipeline/package.json b/packages/core/pipeline/package.json index 963fe489..ad92f09b 100644 --- a/packages/core/pipeline/package.json +++ b/packages/core/pipeline/package.json @@ -17,6 +17,8 @@ "@certd/plus": "1.22.1", "axios": "^1.7.2", "fix-path": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", "lodash-es": "^4.17.21", "node-forge": "^1.3.1", "nodemailer": "^6.9.3", diff --git a/packages/core/pipeline/src/access/api.ts b/packages/core/pipeline/src/access/api.ts index 5343b30d..15a5339d 100644 --- a/packages/core/pipeline/src/access/api.ts +++ b/packages/core/pipeline/src/access/api.ts @@ -12,7 +12,7 @@ export type AccessDefine = Registrable & { }; }; export interface IAccessService { - getById(id: any): Promise; + getById(id: any): Promise; } // eslint-disable-next-line @typescript-eslint/no-empty-interface diff --git a/packages/core/pipeline/src/core/handler.ts b/packages/core/pipeline/src/core/handler.ts new file mode 100644 index 00000000..8180a627 --- /dev/null +++ b/packages/core/pipeline/src/core/handler.ts @@ -0,0 +1,33 @@ +import _ from "lodash-es"; +import { HttpClient, ILogger } from "../utils"; + +export type PluginRequest = { + type: "plugin" | "access"; + typeName: string; + action: string; + input: any; + data: any; +}; + +export type RequestHandleContext = { + http: HttpClient; + logger: ILogger; +}; + +export class RequestHandler { + async onRequest(req: PluginRequest, ctx: RequestHandleContext) { + if (!req.action) { + throw new Error("action is required"); + } + + const methodName = `on${_.upperFirst(req.action)}`; + + // @ts-ignore + const method = this[methodName]; + if (method) { + // @ts-ignore + return await this[methodName](req.data, ctx); + } + throw new Error(`action ${req.action} not found`); + } +} diff --git a/packages/core/pipeline/src/core/index.ts b/packages/core/pipeline/src/core/index.ts index ea038be6..6059e858 100644 --- a/packages/core/pipeline/src/core/index.ts +++ b/packages/core/pipeline/src/core/index.ts @@ -4,3 +4,4 @@ export * from "./context.js"; export * from "./storage.js"; export * from "./file-store.js"; export * from "./license.js"; +export * from "./handler.js"; diff --git a/packages/core/pipeline/src/dt/pipeline.ts b/packages/core/pipeline/src/dt/pipeline.ts index c9532327..f436d30a 100644 --- a/packages/core/pipeline/src/dt/pipeline.ts +++ b/packages/core/pipeline/src/dt/pipeline.ts @@ -46,6 +46,7 @@ export type Stage = Runnable & { tasks: Task[]; concurrency: ConcurrencyStrategy; next: NextStrategy; + maxTaskCount?: number; }; export type Trigger = { diff --git a/packages/core/pipeline/src/utils/util.request.ts b/packages/core/pipeline/src/utils/util.request.ts index 12e841fd..c76c6b79 100644 --- a/packages/core/pipeline/src/utils/util.request.ts +++ b/packages/core/pipeline/src/utils/util.request.ts @@ -1,7 +1,9 @@ import axios, { AxiosRequestConfig } from "axios"; import { logger } from "./util.log.js"; import { Logger } from "log4js"; -import { ProxyAgent, ProxyAgentOptions } from "proxy-agent"; +import { HttpProxyAgent } from "http-proxy-agent"; +import { HttpsProxyAgent } from "https-proxy-agent"; +import nodeHttp from "http"; export class HttpError extends Error { status?: number; statusText?: string; @@ -55,9 +57,10 @@ export function createAxiosService({ logger }: { logger: Logger }) { } let agents = defaultAgents; if (config.skipSslVerify) { - agents = createAgent({ rejectUnauthorized: config.rejectUnauthorized }); + logger.info("跳过SSL验证"); + agents = createAgent({ rejectUnauthorized: false } as any); } - + delete config.skipSslVerify; config.httpsAgent = agents.httpsAgent; config.httpAgent = agents.httpAgent; @@ -118,7 +121,9 @@ export function createAxiosService({ logger }: { logger: Logger }) { `请求出错:status:${error.response?.status},statusText:${error.response?.statusText},url:${error.config?.url},method:${error.config?.method}。` ); logger.error("返回数据:", JSON.stringify(error.response?.data)); - + if (error.response?.data) { + error.message = error.response.data.message || error.response.data.msg || error.response.data.error || error.response.data; + } if (error instanceof AggregateError) { logger.error("AggregateError", error); } @@ -138,10 +143,19 @@ export type HttpClient = { request(config: HttpRequestConfig): Promise>; }; -export function createAgent(opts: ProxyAgentOptions = {}) { - const httpAgent = new ProxyAgent(opts); +export function createAgent(opts: nodeHttp.AgentOptions = {}) { + let httpAgent, httpsAgent; + const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy; + if (httpProxy) { + httpAgent = new HttpProxyAgent(httpProxy, opts as any); + } + const httpsProxy = process.env.HTTPS_PROXY || process.env.https_proxy; + if (httpsProxy) { + httpsAgent = new HttpsProxyAgent(httpsProxy, opts as any); + } + return { httpAgent, - httpsAgent: httpAgent, + httpsAgent, }; } diff --git a/packages/libs/lib-iframe/package.json b/packages/libs/lib-iframe/package.json index 7483d506..fa3c9085 100644 --- a/packages/libs/lib-iframe/package.json +++ b/packages/libs/lib-iframe/package.json @@ -13,6 +13,7 @@ "preview": "vite preview" }, "dependencies": { + "nanoid": "^4.0.0" }, "devDependencies": { "@rollup/plugin-commonjs": "^23.0.4", diff --git a/packages/libs/lib-iframe/src/lib/iframe.client.ts b/packages/libs/lib-iframe/src/lib/iframe.client.ts index 2be6f8a0..527f8dcd 100644 --- a/packages/libs/lib-iframe/src/lib/iframe.client.ts +++ b/packages/libs/lib-iframe/src/lib/iframe.client.ts @@ -1,55 +1,109 @@ import { nanoid } from 'nanoid'; -export type IframeMessageData = { +export type IframeMessageData = { action: string; id: string; - data: any; + data?: T; replyId?: string; + errorCode?: number; //0为成功 + message?: string; }; -export type IframeMessageReq = { - req: IframeMessageData; - onReply: (data: IframeMessageData) => void; +export type IframeMessageReq = { + req: IframeMessageData; + onReply: (data: IframeMessageData) => void; }; +export class IframeException extends Error { + code?: number = 0; + constructor(data: IframeMessageData) { + super(data.message); + this.code = data.errorCode; + } +} + export class IframeClient { - messageBucket: Record = {}; + requestQueue: Record = {}; //当前客户端是否是父级页面 iframe?: HTMLIFrameElement; - constructor(iframe?: HTMLIFrameElement) { + onError?: any; + + handlers: Record) => Promise> = {}; + constructor(iframe?: HTMLIFrameElement, onError?: (e: any) => void) { this.iframe = iframe; - window.addEventListener('message', (event: MessageEvent) => { + this.onError = onError; + window.addEventListener('message', async (event: MessageEvent>) => { const data = event.data; - if (data.replyId) { - const req = this.messageBucket[data.replyId]; - if (req) { - req.onReply(data); - delete this.messageBucket[data.replyId]; + if (data.action) { + console.log(`收到消息[isSub:${this.isInFrame()}]`, data); + try { + const handler = this.handlers[data.action]; + if (handler) { + const res = await handler(data); + if (data.id && data.action !== 'reply') { + await this.send('reply', res, data.id); + } + } else { + throw new Error(`action:${data.action} 未注册处理器,可能版本过低`); + } + } catch (e: any) { + console.error(e); + await this.send('reply', {}, data.id, 500, e.message); } } }); + + this.register('reply', async data => { + const req = this.requestQueue[data.replyId!]; + if (req) { + req.onReply(data); + delete this.requestQueue[data.replyId!]; + } + }); } isInFrame() { return window.self !== window.top; } - async send(action: string, data?: any, replyId?: string) { - const reqMessageData: IframeMessageData = { + register(action: string, handler: (data: IframeMessageData) => Promise) { + this.handlers[action] = handler; + } + + async send(action: string, data?: T, replyId?: string, errorCode?: number, message?: string): Promise> { + try { + return await this.doSend(action, data, replyId, errorCode, message); + } catch (e) { + if (this.onError) { + this.onError(e); + } + throw e; + } + } + + async doSend(action: string, data?: T, replyId?: string, errorCode?: number, message?: string): Promise> { + const reqMessageData: IframeMessageData = { id: nanoid(), action, data, replyId, + errorCode, + message, }; return new Promise((resolve, reject) => { - const onReply = async (reply: IframeMessageData) => { + const onReply = (reply: IframeMessageData) => { + if (reply.errorCode && reply.errorCode > 0) { + reject(new IframeException(reply)); + return; + } resolve(reply); }; - this.messageBucket[reqMessageData.id] = { + this.requestQueue[reqMessageData.id] = { req: reqMessageData, onReply, }; try { + console.log(`send message[isSub:${this.isInFrame()}]:`, reqMessageData); if (!this.iframe) { if (!window.parent) { reject('当前页面不在 iframe 中'); diff --git a/packages/libs/lib-jdcloud/.eslintrc b/packages/libs/lib-jdcloud/.eslintrc new file mode 100644 index 00000000..a591578c --- /dev/null +++ b/packages/libs/lib-jdcloud/.eslintrc @@ -0,0 +1,23 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "prettier" + ], + "env": { + "mocha": true + }, + "rules": { + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-ts-ignore": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-function": "off", +// "no-unused-expressions": "off", + "max-len": [0, 160, 2, { "ignoreUrls": true }] + } +} diff --git a/packages/libs/lib-jdcloud/.gitignore b/packages/libs/lib-jdcloud/.gitignore new file mode 100644 index 00000000..b59eedaa --- /dev/null +++ b/packages/libs/lib-jdcloud/.gitignore @@ -0,0 +1,28 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +test/user.secret.ts + +.rollup.cache diff --git a/packages/libs/lib-jdcloud/.npmignore b/packages/libs/lib-jdcloud/.npmignore new file mode 100644 index 00000000..ec6e82b7 --- /dev/null +++ b/packages/libs/lib-jdcloud/.npmignore @@ -0,0 +1,3 @@ +node_modules +src +.rollup.cache diff --git a/packages/libs/lib-jdcloud/.prettierrc b/packages/libs/lib-jdcloud/.prettierrc new file mode 100644 index 00000000..1d96ee86 --- /dev/null +++ b/packages/libs/lib-jdcloud/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 160 +} \ No newline at end of file diff --git a/packages/libs/lib-jdcloud/CHANGELOG.md b/packages/libs/lib-jdcloud/CHANGELOG.md new file mode 100644 index 00000000..5bfc76f3 --- /dev/null +++ b/packages/libs/lib-jdcloud/CHANGELOG.md @@ -0,0 +1,27 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.24.3](https://github.com/certd/certd/compare/v1.24.2...v1.24.3) (2024-09-06) + +**Note:** Version bump only for package @certd/lib-huawei + +## [1.24.2](https://github.com/certd/certd/compare/v1.24.1...v1.24.2) (2024-09-06) + +**Note:** Version bump only for package @certd/lib-huawei + +## [1.24.1](https://github.com/certd/certd/compare/v1.24.0...v1.24.1) (2024-09-02) + +**Note:** Version bump only for package @certd/lib-huawei + +## [1.22.1](https://github.com/certd/certd/compare/v1.22.0...v1.22.1) (2024-07-20) + +**Note:** Version bump only for package @certd/lib-huawei + +# [1.22.0](https://github.com/certd/certd/compare/v1.21.2...v1.22.0) (2024-07-19) + +### Features + +* 升级midway,支持esm ([485e603](https://github.com/certd/certd/commit/485e603b5165c28bc08694997726eaf2a585ebe7)) +* 支持postgresql ([3b19bfb](https://github.com/certd/certd/commit/3b19bfb4291e89064b3b407a80dae092d54747d5)) diff --git a/packages/libs/lib-jdcloud/README.md b/packages/libs/lib-jdcloud/README.md new file mode 100644 index 00000000..30b15e21 --- /dev/null +++ b/packages/libs/lib-jdcloud/README.md @@ -0,0 +1,16 @@ +# Vue 3 + TypeScript + Vite + +This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 ` diff --git a/packages/ui/certd-client/src/components/vip-button/index.vue b/packages/ui/certd-client/src/components/vip-button/index.vue index 8d44ee5e..28dfa923 100644 --- a/packages/ui/certd-client/src/components/vip-button/index.vue +++ b/packages/ui/certd-client/src/components/vip-button/index.vue @@ -18,6 +18,7 @@ import dayjs from "dayjs"; import { message, Modal } from "ant-design-vue"; import * as api from "./api"; import { useSettingStore } from "/@/store/modules/settings"; +import { useRouter } from "vue-router"; const props = withDefaults( defineProps<{ @@ -90,6 +91,7 @@ const formState = reactive({ code: "" }); +const router = useRouter(); async function doActive() { if (!formState.code) { message.error("请输入激活码"); @@ -100,7 +102,19 @@ async function doActive() { await userStore.reInit(); Modal.success({ title: "激活成功", - content: `您已成功激活专业版,有效期至:${dayjs(userStore.plusInfo.expireTime).format("YYYY-MM-DD")}` + content: `您已成功激活专业版,有效期至:${dayjs(userStore.plusInfo.expireTime).format("YYYY-MM-DD")}`, + onOk() { + if (!(settingStore.installInfo.bindUserId > 0)) { + //未绑定账号 + Modal.confirm({ + title: "是否绑定袖手账号", + content: "绑定账号后,可以避免专业版License丢失,强烈建议绑定", + onOk() { + router.push("/sys/account"); + } + }); + } + } }); } } @@ -132,7 +146,7 @@ function openUpgrade() {
  • 可加VIP群,需求优先实现
  • 证书流水线数量无限制(免费版限制10条)
  • 免配置发邮件功能
  • -
  • FTP上传、cdnfly、宝塔、易盾等部署插件
  • +
  • FTP上传、cdnfly、宝塔、易盾、群晖等部署插件
  • 更多特权敬请期待
  • @@ -143,7 +157,6 @@ function openUpgrade() {
    站点ID: -
    注意保存好数据库,暂不支持换绑(默认数据库路径/data/certd/db.sqlite)
    diff --git a/packages/ui/certd-client/src/layout/layout-outside.vue b/packages/ui/certd-client/src/layout/layout-outside.vue index 0dc736fa..34ef6f24 100644 --- a/packages/ui/certd-client/src/layout/layout-outside.vue +++ b/packages/ui/certd-client/src/layout/layout-outside.vue @@ -57,7 +57,7 @@ export default { .container { .main { max-width: 368px; - width: 98%; + width: 96%; } } } @@ -136,16 +136,15 @@ export default { } .main { - min-width: 260px; - width: 368px; - margin: 0 auto; + min-width: 300px; + width: 94%; } .footer { // position: absolute; width: 100%; bottom: 0; - margin: 48px 0 24px; + margin: 24px 0 24px; text-align: center; .links { @@ -163,6 +162,7 @@ export default { color: rgba(0, 0, 0, 0.45); font-size: 14px; display: flex; + flex-wrap: wrap; justify-content: center; align-items: center; span { diff --git a/packages/ui/certd-client/src/router/source/modules/sys.ts b/packages/ui/certd-client/src/router/source/modules/sys.ts index 29261481..9dfebff1 100644 --- a/packages/ui/certd-client/src/router/source/modules/sys.ts +++ b/packages/ui/certd-client/src/router/source/modules/sys.ts @@ -65,6 +65,16 @@ export const sysResources = [ }, path: "/sys/settings", component: "/sys/settings/index.vue" + }, + { + title: "账号绑定", + name: "account", + meta: { + icon: "ion:golf-outline", + permission: "sys:settings:view" + }, + path: "/sys/account", + component: "/sys/account/index.vue" } ] } diff --git a/packages/ui/certd-client/src/store/modules/settings.ts b/packages/ui/certd-client/src/store/modules/settings.ts index 397b2560..4c43d564 100644 --- a/packages/ui/certd-client/src/store/modules/settings.ts +++ b/packages/ui/certd-client/src/store/modules/settings.ts @@ -1,11 +1,13 @@ import { defineStore } from "pinia"; -import { theme } from "ant-design-vue"; +import { Modal, theme } from "ant-design-vue"; import _ from "lodash-es"; // @ts-ignore import { LocalStorage } from "/src/utils/util.storage"; import * as basicApi from "/@/api/modules/api.basic"; import { SysInstallInfo, SysPublicSetting } from "/@/api/modules/api.basic"; +import { useUserStore } from "/@/store/modules/user"; +import { mitter } from "/@/utils/util.mitt"; export type ThemeToken = { token: { @@ -23,6 +25,17 @@ export interface SettingState { sysPublic?: SysPublicSetting; installInfo?: { siteId: string; + installTime?: number; + bindUserId?: number; + bindUrl?: string; + accountServerBaseUrl?: string; + appKey?: string; + }; + siteInfo?: { + TITLE: string; + SLOGAN: string; + LOGO: string; + ICP_NO: string; }; } @@ -44,7 +57,17 @@ export const useSettingStore = defineStore({ managerOtherUserPipeline: false }, installInfo: { - siteId: "" + siteId: "", + bindUserId: null, + bindUrl: "", + accountServerBaseUrl: "", + appKey: "" + }, + siteInfo: { + TITLE: "", + SLOGAN: "", + LOGO: "", + ICP_NO: "" } }), getters: { @@ -63,9 +86,59 @@ export const useSettingStore = defineStore({ const settings = await basicApi.getSysPublicSettings(); _.merge(this.sysPublic, settings); + const siteInfo = await basicApi.getSiteInfo(); + _.merge(this.siteInfo, siteInfo); + + await this.loadInstallInfo(); + + await this.checkUrlBound(); + }, + async loadInstallInfo() { const installInfo = await basicApi.getInstallInfo(); _.merge(this.installInfo, installInfo); }, + async checkUrlBound() { + const userStore = useUserStore(); + if (!userStore.isAdmin || !userStore.isPlus) { + return; + } + + const bindUrl = this.installInfo.bindUrl; + + function getBaseUrl() { + let url = window.location.href; + //只要hash前面的部分 + url = url.split("#")[0]; + return url; + } + + const doBindUrl = async (url: string) => { + await basicApi.bindUrl({ url }); + await this.loadInstallInfo(); + }; + const baseUrl = getBaseUrl(); + if (!bindUrl) { + //绑定url + await doBindUrl(baseUrl); + } else { + //检查当前url 是否与绑定的url一致 + const url = window.location.href; + if (!url.startsWith(bindUrl)) { + Modal.confirm({ + title: "URL地址有变化", + content: "以后都用这个新地址访问本系统吗?", + onOk: async () => { + await doBindUrl(baseUrl); + }, + okText: "是的,继续", + cancelText: "不是,回到原来的地址", + onCancel: () => { + window.location.href = bindUrl; + } + }); + } + } + }, persistThemeConfig() { LocalStorage.set(SETTING_THEME_KEY, this.getThemeConfig); }, @@ -108,3 +181,7 @@ export const useSettingStore = defineStore({ } } }); + +mitter.on("app.login", async () => { + await useSettingStore().init(); +}); diff --git a/packages/ui/certd-client/src/utils/util.env.ts b/packages/ui/certd-client/src/utils/util.env.ts index ac124983..621a4a97 100644 --- a/packages/ui/certd-client/src/utils/util.env.ts +++ b/packages/ui/certd-client/src/utils/util.env.ts @@ -1,37 +1,25 @@ // @ts-ignore import _ from "lodash-es"; -export function getEnvValue(key: string) { - // @ts-ignore - return import.meta.env["VITE_APP_" + key]; -} export class EnvConfig { - API: string; - MODE: string; - STORAGE: string; - TITLE: string; - SLOGAN: string; - COPYRIGHT_YEAR: string; - COPYRIGHT_NAME: string; - COPYRIGHT_URL: string; - LOGO_PATH: string; - PM_ENABLED: string; - ICP_NO: string; - constructor() { - this.init(); - } + MODE: string = import.meta.env.MODE; + API: string = import.meta.env.VITE_APP_API; + STORAGE: string = import.meta.env.VITE_APP_STORAGE; + TITLE: string = import.meta.env.VITE_APP_TITLE; + SLOGAN: string = import.meta.env.VITE_APP_SLOGAN; + COPYRIGHT_YEAR: string = import.meta.env.VITE_APP_COPYRIGHT_YEAR; + COPYRIGHT_NAME: string = import.meta.env.VITE_APP_COPYRIGHT_NAME; + COPYRIGHT_URL: string = import.meta.env.VITE_APP_COPYRIGHT_URL; + LOGO: string = import.meta.env.VITE_APP_LOGO; + PM_ENABLED: string = import.meta.env.VITE_APP_PM_ENABLED; + ICP_NO: string = import.meta.env.VITE_APP_ICP_NO; - init() { - // @ts-ignore - _.forEach(import.meta.env, (value, key) => { - if (key.startsWith("VITE_APP")) { - key = key.replace("VITE_APP_", ""); - // @ts-ignore - this[key] = value; + init(env: any) { + for (const key in this) { + if (this.hasOwnProperty(key)) { + this[key] = env[key]; } - }); - // @ts-ignore - this.MODE = import.meta.env.MODE; + } } get(key: string, defaultValue: string) { diff --git a/packages/ui/certd-client/src/views/certd/access/api.ts b/packages/ui/certd-client/src/views/certd/access/api.ts index ab87aff2..e282881b 100644 --- a/packages/ui/certd-client/src/views/certd/access/api.ts +++ b/packages/ui/certd-client/src/views/certd/access/api.ts @@ -1,55 +1,55 @@ import { request } from "/src/api/service"; const apiPrefix = "/pi/access"; -export function GetList(query: any) { - return request({ +export async function GetList(query: any) { + return await request({ url: apiPrefix + "/page", method: "post", data: query }); } -export function AddObj(obj: any) { - return request({ +export async function AddObj(obj: any) { + return await request({ url: apiPrefix + "/add", method: "post", data: obj }); } -export function UpdateObj(obj: any) { - return request({ +export async function UpdateObj(obj: any) { + return await request({ url: apiPrefix + "/update", method: "post", data: obj }); } -export function DelObj(id: number) { - return request({ +export async function DelObj(id: number) { + return await request({ url: apiPrefix + "/delete", method: "post", params: { id } }); } -export function GetObj(id: number) { - return request({ +export async function GetObj(id: number) { + return await request({ url: apiPrefix + "/info", method: "post", params: { id } }); } -export function GetProviderDefine(type: string) { - return request({ +export async function GetProviderDefine(type: string) { + return await request({ url: apiPrefix + "/define", method: "post", params: { type } }); } -export function GetProviderDefineByAccessType(type: string) { - return request({ +export async function GetProviderDefineByAccessType(type: string) { + return await request({ url: apiPrefix + "/defineByAccessType", method: "post", params: { type } diff --git a/packages/ui/certd-client/src/views/certd/access/common.tsx b/packages/ui/certd-client/src/views/certd/access/common.tsx index 9bf080bb..29a8f27a 100644 --- a/packages/ui/certd-client/src/views/certd/access/common.tsx +++ b/packages/ui/certd-client/src/views/certd/access/common.tsx @@ -3,7 +3,8 @@ import { ColumnCompositionProps, dict, compute } from "@fast-crud/fast-crud"; import * as api from "./api"; // @ts-ignore import _ from "lodash-es"; -import { toRef } from "vue"; +import { computed, ref, toRef } from "vue"; +import { useReference } from "/@/use/use-refrence"; export function getCommonColumnDefine(crudExpose: any, typeRef: any) { const AccessTypeDictRef = dict({ @@ -32,19 +33,10 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) { ...value, key }; - let column = _.merge({ title: key }, defaultPluginConfig, field); + const column = _.merge({ title: key }, defaultPluginConfig, field); //eval - if (column.mergeScript) { - const ctx = { - compute - }; - const script = column.mergeScript; - delete column.mergeScript; - const func = new Function("ctx", script); - const merged = func(ctx); - column = _.merge(column, merged); - } + useReference(column); //设置默认值 if (column.value != null && _.get(form, key) == null) { @@ -56,6 +48,8 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) { }); } + const currentDefine = ref(); + return { type: { title: "类型", @@ -84,13 +78,21 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) { return; } const define = await api.GetProviderDefine(value); + currentDefine.value = define; console.log("define", define); if (!immediate) { form.access = {}; } buildDefineFields(define, form); } - } + }, + helper: computed(() => { + const define = currentDefine.value; + if (define == null) { + return ""; + } + return define.desc; + }) }, addForm: { value: typeRef diff --git a/packages/ui/certd-client/src/views/certd/account/index.vue b/packages/ui/certd-client/src/views/certd/account/index.vue deleted file mode 100644 index 98adeef0..00000000 --- a/packages/ui/certd-client/src/views/certd/account/index.vue +++ /dev/null @@ -1,8 +0,0 @@ - diff --git a/packages/ui/certd-client/src/views/certd/history/api.ts b/packages/ui/certd-client/src/views/certd/history/api.ts index bd6a11de..eae98960 100644 --- a/packages/ui/certd-client/src/views/certd/history/api.ts +++ b/packages/ui/certd-client/src/views/certd/history/api.ts @@ -2,56 +2,56 @@ import { request } from "/src/api/service"; const apiPrefix = "/pi/history"; -export function GetList(query: any) { - return request({ +export async function GetList(query: any) { + return await request({ url: apiPrefix + "/page", method: "post", data: query }); } -export function AddObj(obj: any) { - return request({ +export async function AddObj(obj: any) { + return await request({ url: apiPrefix + "/add", method: "post", data: obj }); } -export function UpdateObj(obj: any) { - return request({ +export async function UpdateObj(obj: any) { + return await request({ url: apiPrefix + "/update", method: "post", data: obj }); } -export function DelObj(id: any) { - return request({ +export async function DelObj(id: any) { + return await request({ url: apiPrefix + "/delete", method: "post", params: { id } }); } -export function GetObj(id: any) { - return request({ +export async function GetObj(id: any) { + return await request({ url: apiPrefix + "/info", method: "post", params: { id } }); } -export function GetDetail(id: any) { - return request({ +export async function GetDetail(id: any) { + return await request({ url: apiPrefix + "/detail", method: "post", params: { id } }); } -export function DeleteBatch(ids: any[]) { - return request({ +export async function DeleteBatch(ids: any[]) { + return await request({ url: apiPrefix + "/deleteByIds", method: "post", data: { ids } diff --git a/packages/ui/certd-client/src/views/certd/mine/api.ts b/packages/ui/certd-client/src/views/certd/mine/api.ts index fc8f492e..75a163cc 100644 --- a/packages/ui/certd-client/src/views/certd/mine/api.ts +++ b/packages/ui/certd-client/src/views/certd/mine/api.ts @@ -1,14 +1,14 @@ import { request } from "/src/api/service"; export async function getMineInfo() { - return request({ + return await request({ url: "/mine/info", method: "POST" }); } export async function changePassword(form: any) { - return request({ + return await request({ url: "/mine/changePassword", method: "POST", data: form diff --git a/packages/ui/certd-client/src/views/certd/pipeline/api.ts b/packages/ui/certd-client/src/views/certd/pipeline/api.ts index e10c2433..22abab61 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/api.ts +++ b/packages/ui/certd-client/src/views/certd/pipeline/api.ts @@ -3,72 +3,72 @@ import { request } from "/src/api/service"; const apiPrefix = "/pi/pipeline"; const historyApiPrefix = "/pi/history"; -export function GetList(query: any) { - return request({ +export async function GetList(query: any) { + return await request({ url: apiPrefix + "/page", method: "post", data: query }); } -export function AddObj(obj: any) { - return request({ +export async function AddObj(obj: any) { + return await request({ url: apiPrefix + "/add", method: "post", data: obj }); } -export function UpdateObj(obj: any) { - return request({ +export async function UpdateObj(obj: any) { + return await request({ url: apiPrefix + "/update", method: "post", data: obj }); } -export function DelObj(id: any) { - return request({ +export async function DelObj(id: any) { + return await request({ url: apiPrefix + "/delete", method: "post", params: { id } }); } -export function GetObj(id: any) { - return request({ +export async function GetObj(id: any) { + return await request({ url: apiPrefix + "/info", method: "post", params: { id } }); } -export function GetDetail(id: any) { - return request({ +export async function GetDetail(id: any) { + return await request({ url: apiPrefix + "/detail", method: "post", params: { id } }); } -export function Save(pipelineEntity: any) { - return request({ +export async function Save(pipelineEntity: any) { + return await request({ url: apiPrefix + "/save", method: "post", data: pipelineEntity }); } -export function Trigger(id: any, stepId?: string) { - return request({ +export async function Trigger(id: any, stepId?: string) { + return await request({ url: apiPrefix + "/trigger", method: "post", params: { id, stepId } }); } -export function Cancel(historyId: any) { - return request({ +export async function Cancel(historyId: any) { + return await request({ url: apiPrefix + "/cancel", method: "post", params: { historyId } @@ -76,7 +76,7 @@ export function Cancel(historyId: any) { } export async function GetFiles(pipelineId: number) { - return request({ + return await request({ url: historyApiPrefix + "/files", method: "post", params: { pipelineId } diff --git a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/crud.tsx index 4512b3da..879e3933 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/certd-form/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/certd-form/crud.tsx @@ -84,7 +84,8 @@ export default function (certPluginGroup: PluginGroup, formWrapperRef: any): Cre vModel: "modelValue", placeholder: "0 0 4 * * *" }, - helper: "点击上面的按钮,选择每天几点几分定时执行, 例如:0 0 4 * * *,每天凌晨4点0分0秒触发\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行", + helper: + "点击上面的按钮,选择每天几点几分定时执行,后面的分秒都要选择0。\n例如:0 0 4 * * *,每天凌晨4点0分0秒触发\n建议设置为每天触发一次,证书未到期之前任务会跳过,不会重复执行", order: 100 } }, diff --git a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx index eaf59228..b1563744 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/pipeline/crud.tsx @@ -113,6 +113,7 @@ export default function ({ crudExpose, context: { certdFormRef } }: CreateCrudOp stages: [ { title: "证书申请阶段", + maxTaskCount: 1, tasks: [ { title: "证书申请任务", diff --git a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/notification-form/index.vue b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/notification-form/index.vue index c0c0d837..9d4f8988 100644 --- a/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/notification-form/index.vue +++ b/packages/ui/certd-client/src/views/certd/pipeline/pipeline/component/notification-form/index.vue @@ -8,10 +8,12 @@ @after-open-change="notificationDrawerOnAfterVisibleChange" >