Commit 5999c413 by chunhong.mu

refactor(*): 重构@common/sdk子包,新增多类工具与服务

parent 0b74decd
/**
* 平台条件执行器
* 用于在不同平台(微信/支付宝/抖音/快手小程序、H5、APP)下执行特定代码
*/
export class ActionInvoker {
/**
* 在微信小程序环境下执行
*/
public static execute(action: () => void, is = true) {
if (is) {
// #ifdef MP-WEIXIN
action()
// #endif
} else {
// #ifndef MP-WEIXIN
action()
// #endif
}
return this
}
/**
* 在小程序环境下执行
*/
public static executeMp(action: () => void, is = true) {
if (is) {
// #ifdef MP
action()
// #endif
} else {
// #ifndef MP
action()
// #endif
}
return this
}
/**
* 在头条小程序环境下执行
*/
public static executeToutiao(action: () => void, is = true) {
if (is) {
// #ifdef MP-TOUTIAO
action()
// #endif
} else {
// #ifndef MP-TOUTIAO
action()
// #endif
}
return this
}
/**
* 直播环境
*/
public static executeMPLive(action: () => void) {
// #ifdef MP-TOUTIAO || MP-KUAISHOU || MP-ALIPAY
action()
// #endif
return this
}
/**
* 在快手小程序环境下执行
*/
public static executeKuaishou(action: () => void, is = true) {
if (is) {
// #ifdef MP-KUAISHOU
action()
// #endif
} else {
// #ifndef MP-KUAISHOU
action()
// #endif
}
return this
}
/**
* 在支付宝小程序环境下执行
*/
public static executeAliPay(action: () => void, is = true) {
if (is) {
// #ifdef MP-ALIPAY
action()
// #endif
} else {
// #ifndef MP-ALIPAY
action()
// #endif
}
return this
}
/**
* 在 H5 环境下执行(包含 APP 环境)
*/
public static executeUnderH5(action: () => void, is = true) {
if (is) {
// #ifdef H5
action()
// #endif
} else {
// #ifndef H5
action()
// #endif
}
return this
}
}
import { isArray } from "lodash"
export interface UploadData {
url: string
fullUrl: string
fileName: string
}
export enum AppFileType {
image = ".jpg,.jpeg,.ico,.tiff,.gif,.svg,.webp,.png,.bmp,.pjpeg",
audio = ".opus,.flac,.webm,.weba,.wav,ogg,.mp3,.oga,.mid,.amr,.wma,.aac,.au,.m4a",
resume = ".doc,.docx,.pdf,.png,.jpg,.jpeg,.pjpeg",
video = ".mp4,.avi",
other = "other",
}
/**
* 选择图片
*/
export function chooseImage(
count = 9,
sizeType: "compressed" | "original" = "compressed",
): Promise<(UniApp.ChooseImageSuccessCallbackResultFile | File)[]> {
return new Promise((resolve, reject) => {
uni.chooseImage({
sizeType,
count,
success(data) {
let files: (
| UniApp.ChooseImageSuccessCallbackResultFile
| File
)[] = []
if (!isArray(data.tempFiles)) {
files = [data.tempFiles]
} else {
files = data.tempFiles
}
resolve(files)
},
fail(err) {
reject(err)
},
})
})
}
/**
* 下载文件
*/
export function downloadFile(path: string): Promise<string> {
return new Promise((resolve, reject) => {
uni.downloadFile({
url: path,
success: (res) => {
if (res.statusCode === 200) {
resolve(res.tempFilePath)
} else {
reject()
}
},
fail: err => reject(err),
})
})
}
/**
* 预览文档或图片/视频
*/
export function previewDocument(path: string): Promise<void> {
const documentFileType = ".doc,.txt,.xls,.ppt,.pdf,.docx,.xlsx,.pptx".split(
",",
)
const isDocument = documentFileType.some(i => path.includes(i))
if (isDocument) {
// #ifdef H5
window.location.href = path
return Promise.resolve()
// #endif
return downloadFile(path).then((temPath) => {
return openDocument(temPath, path)
})
}
const isVideo = path.includes(".mp4") || path.includes(".avi")
const urls = path.split(",").filter(Boolean)
return new Promise<void>((resolve, reject) => {
if (isVideo) {
// #ifdef MP-WEIXIN
wx.previewMedia({
sources: urls.map(e => ({ url: e, type: "video" })),
success: () => resolve(),
fail: () => reject(),
})
// #endif
} else {
uni.previewImage({
urls,
success: () => resolve(),
fail: () => reject(),
})
}
})
}
/**
* 打开文档
*/
function openDocument(filePath: string, path: string): Promise<void> {
const fileType = path.split(".").reverse()[0]
return new Promise<void>((resolve, reject) => {
// #ifndef MP-KUAISHOU
uni.openDocument({
filePath,
fileType,
// @ts-ignore
showMenu: true,
success: () => resolve(),
fail: err => reject(err),
})
// #endif
// #ifdef MP-KUAISHOU
// @ts-ignore
;(ks as any).openDocument({
filePath,
fileType,
success: () => resolve(),
fail: (err: any) => reject(err),
})
// #endif
})
}
import type { SdkCore } from "../sdk-core" import type { SdkCore } from "./sdk-core"
/** /**
* 基础请求服务类 * HTTP 请求服务
* 提供静态 get/post 方法,用于简单的 HTTP 请求 * 提供静态 get/post 方法,用于简单的 HTTP 请求
*/ */
export default class BaseService { export default class HttpRequest {
protected sdk!: SdkCore protected sdk!: SdkCore
public static get<T>(url: string, params?: any) { public static get<T>(url: string, params?: any) {
// 注意:此方法需要子类或实例提供 sdk 实例
throw new Error("sdk instance not set") throw new Error("sdk instance not set")
} }
...@@ -18,9 +17,9 @@ export default class BaseService { ...@@ -18,9 +17,9 @@ export default class BaseService {
} }
/** /**
* 增强版 BaseService,支持传入 sdk 实例 * 增强版 HttpRequest,支持传入 sdk 实例
*/ */
export class BaseServiceWithSdk { export class HttpRequestWithSdk {
constructor(protected sdk: SdkCore) {} constructor(protected sdk: SdkCore) {}
public get<T>(url: string, params?: any) { public get<T>(url: string, params?: any) {
......
import type { UniplatSdk } from "uniplat-sdk" import type { UniplatSdk } from "uniplat-sdk"
/**
* 构建图片 URL
*/
export function buildImage( export function buildImage(
sdk: UniplatSdk, sdk: UniplatSdk,
url?: string, url?: string,
...@@ -27,6 +30,9 @@ export function buildImage( ...@@ -27,6 +30,9 @@ export function buildImage(
return url return url
} }
/**
* 构建文件下载 URL
*/
export function buildFilePath( export function buildFilePath(
sdk: UniplatSdk, sdk: UniplatSdk,
url: string, url: string,
......
// Auth 相关 // 平台条件执行器
export { getAuthHandlers, registerAuthHandlers } from "./auth/auth-handlers" export { ActionInvoker } from "./action-invoker"
export type { AuthHandlers } from "./auth/auth-handlers" // 认证处理器
export { decodeToken, PassportTokenController } from "./auth/token-manager" export { getAuthHandlers, registerAuthHandlers } from "./auth-handlers"
export { LoginApiName } from "./auth/token-manager"
// 配置 export type { AuthHandlers } from "./auth-handlers"
export { ClientId, Environment, UICore, wxDistributerUrlConfig } from "./config/ui-core" // 文件操作(上传/下载/预览)
export {
AppFileType,
chooseImage,
downloadFile,
previewDocument,
} from "./file-operations"
export type { UploadData } from "./file-operations"
// HTTP 请求服务
export { HttpRequestWithSdk } from "./http-request"
export { default as HttpRequest } from "./http-request"
// 图片/文件 URL 构建
export { buildFilePath, buildImage } from "./image-builder"
// 小程序工具
export {
MiniProgramVersion,
navigateBackMiniProgram,
navigateToMiniProgram,
} from "./mini-program"
export type { MiniProgramNavConfig } from "./mini-program"
// HTTP 相关
export { uniAdapter } from "./http/adapter"
// 监控 // 监控
export { monitor, Product } from "./monitor/controller" export { monitor, Product } from "./monitor"
export type { SdkMonitorOption } from "./monitor"
// SDK 控制器
export { SdkController } from "./sdk-controller"
export type { SdkMonitorOption } from "./monitor/controller"
// SDK 核心 // SDK 核心
export { SdkCore } from "./sdk-core" export { SdkCore } from "./sdk-core"
export type { SdkConfig, SdkInitOptions } from "./sdk-types" export type { SdkConfig, SdkInitOptions } from "./sdk-types"
// 服务层 // 分享
export { BaseServiceWithSdk } from "./services/base-service" export { createShareMixin, finalShareData, setShareData } from "./share"
export { default as BaseService } from "./services/base-service" // Token 管理
export { decodeToken, PassportTokenController } from "./token-manager"
export { LoginApiName } from "./token-manager"
// 核心配置
export { ClientId, Environment, UICore, wxDistributerUrlConfig } from "./ui-core"
// 工具 // HTTP 适配器
export { buildFilePath, buildImage } from "./utils/image-builder" export { uniAdapter } from "./uni-adapter"
export { SdkController } from "./utils/sdk-controller" // 小程序版本更新
export { updateManager } from "./update-manager"
/**
* 小程序版本枚举
*/
export enum MiniProgramVersion {
Develop = "develop",
Trial = "trial",
Release = "release",
}
/**
* 小程序导航配置
*/
export interface MiniProgramNavConfig {
appId: string
path: string
envVersion?: MiniProgramVersion
}
/**
* 跳转到其他小程序
*/
export function navigateToMiniProgram(config: MiniProgramNavConfig): Promise<void> {
return new Promise((resolve, reject) => {
uni.navigateToMiniProgram({
appId: config.appId,
path: config.path,
envVersion: config.envVersion || MiniProgramVersion.Release,
success: () => resolve(),
fail: err => reject(err),
})
})
}
/**
* 返回上一个小程序
*/
export function navigateBackMiniProgram(extraData?: Record<string, any>): Promise<void> {
return new Promise((resolve, reject) => {
uni.navigateBackMiniProgram({
extraData,
success: () => resolve(),
fail: err => reject(err),
})
})
}
...@@ -11,8 +11,8 @@ import { ...@@ -11,8 +11,8 @@ import {
UniplatSdkExtender, UniplatSdkExtender,
} from "uniplat-sdk" } from "uniplat-sdk"
import { Tree } from "uniplat-sdk/build/main/model/tree/tree" import { Tree } from "uniplat-sdk/build/main/model/tree/tree"
import { uniAdapter } from "./http/adapter" import { buildFilePath, buildImage } from "./image-builder"
import { buildFilePath, buildImage } from "./utils/image-builder" import { uniAdapter } from "./uni-adapter"
export class SdkCore { export class SdkCore {
private uniplatSdk!: UniplatSdk private uniplatSdk!: UniplatSdk
......
import { last } from "lodash"
import { ref } from "vue"
const defaultShareData = {
title: "亲亲创客",
path: "/pages/home/index",
imageUrl: "",
}
export const finalShareData = ref<{
[key: string]: {
title: string
path: string
imageUrl: string
}
}>({})
/**
* 设置当前页面分享
*/
export function setShareData(shareData: {
title?: string
path?: string
imageUrl?: string
}) {
const p = last(getCurrentPages())
finalShareData.value = {
...finalShareData.value,
[p!.route]: {
...defaultShareData,
...shareData,
},
}
}
/**
* 创建全局分享 mixin,所有页面默认携带 shareAppMessage 配置
*/
export function createShareMixin() {
return {
onShareAppMessage() {
const p = last(getCurrentPages())
return finalShareData.value[p!.route] || defaultShareData
},
}
}
import type { AxiosAdapter } from "axios" import type { AxiosAdapter } from "axios"
import type { Index } from "uniplat-sdk" import type { Index } from "uniplat-sdk"
import { decodeJwt, UniplatSdk } from "uniplat-sdk" import { decodeJwt, UniplatSdk } from "uniplat-sdk"
import { UICore } from "../config/ui-core" import { UICore } from "./ui-core"
/** /**
* 登录 API 名称枚举 * 登录 API 名称枚举
......
import { ActionInvoker } from "./action-invoker"
/**
* 小程序版本更新管理器
*/
export function updateManager(contentText: string) {
ActionInvoker.executeMp(() => {
const updateManager = wx.getUpdateManager()
updateManager.onCheckForUpdate((res) => {
if (res.hasUpdate) {
updateManager.onUpdateReady(() => {
wx.showModal({
title: "更新提示",
content: contentText || "",
success(res) {
if (res.confirm) {
updateManager.applyUpdate()
}
},
})
})
updateManager.onUpdateFailed(() => {
wx.showModal({
title: "已经有新版本",
content: "请您删除当前小程序,重新搜索打开",
})
})
}
})
})
}
import type { SdkConfig } from "@common/sdk" import type { ClientId, Product, SdkConfig } from "@common/sdk"
import type { App } from "@vue/runtime-core"
import packageConfig from "../../package.json"
export enum Environment { export enum Environment {
Dev = "dev", Dev = "dev",
...@@ -7,21 +9,90 @@ export enum Environment { ...@@ -7,21 +9,90 @@ export enum Environment {
Stage = "stage", Stage = "stage",
} }
export const config: SdkConfig = { export interface MpConfig extends SdkConfig {
appName?: string
appSourceId?: string
officialAccountName?: string
uniplatApi: string
h5Url?: string
collectionUrl?: string
selfH5?: string
imgBaseUrl: string
clientId: ClientId
uniplatSocketUrl: string
clientSecret: string
logEnv?: Environment
version: string
mpAccountAppid?: string
mpAppid?: string
officialAccountMpH5?: string
mapKey?: string
customFn?: { chooseImage: typeof uni.chooseImage }
shareConfig: {
title: string
img?: string
path: string
forceUse?: boolean
hideshareBy?: boolean
}
shareFixed?: boolean
monitorProductKey?: Product
rootEntrance: string
domainService: {
subProjectName: string
serviceName: string
}
domainService4CitySelector?: {
subProjectName?: string
serviceName?: string
get_lbs?: string
}
cityCodeLength: number | 6
fastCity: any
testAccount?: string
testPassport?: string
sharePcRefConfig?: {
path: string
id: string
}[]
registerConfig?: any
hideshareBy?: boolean
qqxbH5Url?: string
applicationKey?: any
[key: string]: any
}
export const config: MpConfig = {
appName: "亲亲企服",
uniplatApi: import.meta.env.VITE_API_BASE_URL || "https://api.example.com", uniplatApi: import.meta.env.VITE_API_BASE_URL || "https://api.example.com",
rootEntrance: "qqqf-mp", rootEntrance: "qqqf-mp",
imgBaseUrl: `${import.meta.env.VITE_APP_LAND_PAGE || ""}/img/`,
clientId: import.meta.env.VITE_APP_CLIENT_ID || "qqqf-mp-client",
uniplatSocketUrl: import.meta.env.VITE_APP_UNIPLAT_WEBSOCKET_URI || "",
clientSecret: import.meta.env.VITE_APP_CLIENT_SECRET || "",
logEnv: import.meta.env.VITE_ENV || "development", logEnv: import.meta.env.VITE_ENV || "development",
clientId: "qqqf-mp-client", version: packageConfig.version,
domainService: { domainService: {
subProjectName: "qqqf", subProjectName: "qqqf",
serviceName: "api", serviceName: "api",
}, },
shareConfig: {
title: "亲亲企服",
path: "/pages/home/index",
},
cityCodeLength: 6,
fastCity: {},
} }
export const noNeedAuthPages = [ export const noNeedAuthPages = [
"pages/home/index", "pages/home/index",
] ]
export function initCommon(app: App): App {
// Vue3 不再需要 filters 和 mixins
return app
}
export class CoreEnvir { export class CoreEnvir {
private static currentEnv: Environment | null = null private static currentEnv: Environment | null = null
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment