Skip to content

system · 应用配置

ts
import { SystemDomain } from '@hfyidu/api/system';

系统领域负责应用全局配置(应用信息、支付渠道配置)、底部导航栏(Tabbar)拉取、文件上传,以及应用运行错误上报,服务前缀 system

用例总览

用例说明请求方式
SystemDomain.cases.appSetting获取应用设置GET system/appSetting
SystemDomain.cases.appTabbar获取应用底部导航栏GET system/appTabbar
SystemDomain.cases.report上报应用运行错误POST system/reportAppLog
SystemDomain.cases.upload上传文件或图片POST system/uploaduni.uploadFile

appSetting · 获取应用设置

ts
const { data } = await SystemDomain.cases.appSetting.run();

console.log(data); // SystemAppSettingDto

请求参数 SystemAppSettingQueryParams

该用例的请求参数类型固定为 null,即不需要任何查询参数,调用时可不传参数(或传 null)。

响应 SystemAppSettingDto

SystemAppSettingDto(不可变,@Freeze

字段类型后台原始字段说明
appKeystringapp_key应用 Key,默认 ''
appNamestringapp_name应用名称,默认 ''
appPackageNamestringapp_package应用包名,默认 ''
appVersionNamestringapp_version应用版本号,默认 '1.0.0'
appTypeAppTypeapp_type应用类型,默认 AppType.QA
appIdstringmini_app_id小程序 AppId,默认 ''
appSecretstringmini_app_secret小程序 AppSecret,默认 ''
configSystemAppSettingConfigDto应用扩展配置,默认新建一个 SystemAppSettingConfigDto 实例
domainsstringcall_domain请求域名列表的 JSON 字符串,默认 ''
requestDomainsany(getter)domainsJSON.parse 后的运行时求值属性,非后台原始字段

SystemAppSettingConfigDto(不可变,@Freeze

字段类型后台原始字段说明
appNamestringname应用展示名称,默认 ''
customerUrlstringcustomer_url客服链接,默认 ''
customerDouyinstringcustomer_dy抖音客服号,默认 '0'
customerWechatstring | nullcustomer_wechat微信客服号,默认 null
customerQQstring | nullcustomer_qqQQ 客服号,默认 null
customerPhonestring | nullcustomer_phone客服电话,默认 null
payOriginalTypenumberpay_original_type原生支付类型标识,默认 1
workingTimestringworking_time客服工作时间,默认 ''
workTypestringwork_type工作类型,默认 ''
arpunumberad_close_arpu关闭广告的 ARPU 阈值,默认 0
payTypeSystemAppSettingConfigPayTypeDto[]quickappAssignPay快应用指定支付渠道列表,默认 []
mpPayTypeSystemAppSettingConfigMpPayTypeDto[]wechatMiniAssignPay微信小程序指定支付渠道列表,默认 []
wechatOaPayTypeSystemAppSettingConfigWechatOaPayTypeDto[]wechatOaAssignPay微信公众号指定支付渠道列表,默认 []
h5PayListSystemAppSettingConfigH5PayListDto[]h5AssignPayH5 指定支付渠道列表,默认 []
servicesImagestringservices_image客服图片,默认 ''
readListAdGapsnumberad_section_num小说滑动翻页时插入广告的段数,默认 10
readAdGapsnumberpre_read_ad_gaps预留可配置字段:阅读间隔广告段数,默认 3
readAdCountnumberpre_read_ad_count预留可配置字段:阅读广告次数,默认 0
adDwellTimenumberpre_ad_dwell_time广告停留时间(秒),默认 3
payChannelstringpay_channel支付渠道标识,默认 'mhpay'

以下 4 个支付渠道子 DTO(payType / mpPayType / wechatOaPayType / h5PayList)字段结构完全一致,仅默认值不同,统一说明如下。其中 payType 字段与 payProvider 字段均引用 @hfyidu/api/order 领域(PayTypePayProvider)导出的枚举类型,非 system 领域自有类型,具体成员定义请查阅 order 领域文档。

SystemAppSettingConfigPayTypeDto(不可变,@Freeze,对应 quickappAssignPay

字段类型后台原始字段说明
typenumberassign_pay指定支付类型数值,默认 1
payTypePayTypeassign_pay指定支付类型枚举,默认 PayType.MH_WX
providerstringplatform支付平台代码,默认 'other'
payProviderPayProviderplatform支付平台枚举,默认 PayProvider.unknown
statusnumber状态标记,默认 0

SystemAppSettingConfigMpPayTypeDto(不可变,@Freeze,对应 wechatMiniAssignPay

字段类型后台原始字段说明
typenumberassign_pay指定支付类型数值,默认 1
payTypePayTypeassign_pay指定支付类型枚举,默认 PayType.MH_MP
providerstringplatform支付平台代码,默认 'mhpay'
payProviderPayProviderplatform支付平台枚举,默认 PayProvider.mhpay
statusnumber状态标记,默认 0

SystemAppSettingConfigWechatOaPayTypeDto(不可变,@Freeze,对应 wechatOaAssignPay

字段类型后台原始字段说明
typenumberassign_pay指定支付类型数值,默认 1
payTypePayTypeassign_pay指定支付类型枚举,默认 PayType.MH_JSAPI
providerstringplatform支付平台代码,默认 'mhpay'
payProviderPayProviderplatform支付平台枚举,默认 PayProvider.mhpay
statusnumber状态标记,默认 0

SystemAppSettingConfigH5PayListDto(不可变,@Freeze,对应 h5AssignPay

字段类型后台原始字段说明
typenumberassign_pay指定支付类型数值,默认 1
payTypePayTypeassign_pay指定支付类型枚举,默认 PayType.MH_WX
providerstringplatform支付平台代码,默认 'mhpay'
payProviderPayProviderplatform支付平台枚举,默认 PayProvider.mhpay
statusnumber状态标记,默认 0

appTabbar · 获取应用底部导航栏

ts
const { data } = await SystemDomain.cases.appTabbar.run({
  provider_code: 'wxapp',
});

console.log(data); // SystemAppTabbarDto[]

请求参数 SystemAppTabbarQueryParams

字段类型必填说明
provider_codestring广告/渠道平台代码

响应 SystemAppTabbarDto[]

SystemAppTabbarDto(支持 @List,即 SystemAppTabbarDto.toList 批量转换)

字段类型后台原始字段说明
namestringpagePath导航项标识(与 pagePath 同源),默认 ''
titlestringtext导航项标题(与 text 同源),默认 ''
iconstring图标,默认 ''
iconPathstring未选中态图标路径,默认 ''
selectedIconPathstring选中态图标路径,默认 ''
pagePathstring页面路径,默认 ''
textstring文案,默认 ''
pageParamsstring页面参数(JSON 字符串),默认 '{}'
renderboolean是否渲染,运行时状态字段,默认 false
activeboolean是否激活,运行时状态字段,默认 false
sortnumber排序值,默认 0
valuenumbersortsort 同源的唯一标识值,默认 0

report · 上报应用运行错误

ts
await SystemDomain.cases.report.run({
  title: '页面渲染异常',
  content: { stack: 'Error: xxx' },
  level: 'error',
});

请求参数 SystemReportBodyParams

字段类型必填说明
titleany上报标题
contentany上报内容详情
level'warn' | 'error'上报级别

响应

无格式化 DTO,直接透传后台原始返回(any)。

upload · 上传文件

该用例通过 uni-app 的 uni.uploadFile 发起 multipart/form-data 文件上传,而不是普通的 httpApi.request。上传请求会自动复用 httpApi 的请求地址和鉴权请求头。

ts
const { data } = await SystemDomain.cases.upload.run({
  file: tempFilePath,
  onProgress(progress) {
    console.log(`上传进度:${progress}%`);
  },
});

console.log(data?.url); // 服务端返回的远程文件地址

请求参数 SystemUploadBodyParams

字段类型必填说明
filestringuni-app 选择文件后返回的本地临时路径,传给 uni.uploadFile.filePath
namestring服务端接收文件的字段名,默认 'file'
onProgress(progress: number) => void上传进度回调,progress 取值范围为 0-100

响应 SystemUploadDto

字段类型后台原始字段说明
urlstringurl上传成功后的远程文件地址,必填

上传错误处理

HTTP 状态码不是 200、响应无法解析,或后台业务码不是成功状态时,run() 返回的 Promise 会被拒绝。建议在业务侧使用 try/catch 处理失败状态。上传进度由底层 UploadTask.onProgressUpdate 回传。

使用案例:wd-upload 多图逐张上传

下面的案例提炼自 playground 的个人档案页面。它通过 wd-upload 选择和预览多张图片,再由 SystemDomain.cases.upload 逐张上传:

  • 排队期间显示“待上传”,当前任务显示进度;
  • 每张图片上传完成后才开始下一张,避免并发上传;
  • file.url 保留本地临时地址,保证即时展示和预览;
  • 服务端返回的持久化地址保存在自定义属性 file.remote
  • 所有任务结束后统一提示成功和失败数量。

先创建可复用的上传工厂:

ts
import type { UploadFileItem, UploadMethod } from '@wot-ui/ui/components/wd-upload/types';
import { SystemDomain } from '@hfyidu/api/system';
import { ref } from 'vue';

type ImageFile = UploadFileItem & {
  remote?: string;
};

export function useFileUpload() {
  const uploadUseCase = SystemDomain.cases.upload;
  const uploadFiles = ref<ImageFile[]>([]);
  const queuedIds = new Set<number>();
  let uploadQueue = Promise.resolve();
  let queueVersion = 0;

  function watchQueueFinished() {
    const currentVersion = ++queueVersion;
    const currentQueue = uploadQueue;

    void currentQueue.finally(() => {
      // 后续仍有任务加入时,旧的队尾监听不触发完成提示。
      if (currentVersion !== queueVersion || currentQueue !== uploadQueue) return;

      const successCount = uploadFiles.value.filter(file => file.status === 'success').length;
      const failCount = uploadFiles.value.filter(file => file.status === 'fail').length;

      uni.showToast({
        icon: failCount > 0 ? 'none' : 'success',
        title:
          failCount > 0 ? `上传完成:成功 ${successCount} 张,失败 ${failCount} 张` : `成功上传 ${successCount} 张图片`,
      });
    });
  }

  const customUpload: UploadMethod = (file, formData, options) => {
    // wd-upload 可能重复扫描 pending 文件,避免同一文件多次入队。
    if (queuedIds.has(file.uid)) {
      file.status = 'pending';
      return;
    }

    queuedIds.add(file.uid);
    file.status = 'pending';

    const upload = uploadQueue.then(async () => {
      file.status = 'loading';
      options.onProgress({ progress: 0, totalBytesSent: 0, totalBytesExpectedToSend: 0 }, file);

      try {
        const { data } = await uploadUseCase.run({
          file: file.url,
          onProgress(progress) {
            options.onProgress({ progress, totalBytesSent: 0, totalBytesExpectedToSend: 0 }, file);
          },
        });

        if (!data?.url) throw new Error('服务端未返回图片地址');

        // 本地 url 继续用于预览,远程地址单独保存。
        const imageFile = file as ImageFile;
        imageFile.remote = data.url;
        options.onSuccess({ data: JSON.stringify(data), statusCode: 200, header: {} }, file, formData);
      } catch (error) {
        const errMsg = error instanceof Error ? error.message : '图片上传失败';
        options.onError({ errMsg }, file, formData);
      } finally {
        queuedIds.delete(file.uid);
      }
    });

    // 当前任务成为新队尾,下一张图片等待它结束后再执行。
    uploadQueue = upload.catch(() => undefined);
    watchQueueFinished();
    return upload;
  };

  function getUploadStatusText(file: UploadFileItem) {
    if (file.status === 'loading') return `上传中 ${file.percent ?? 0}%`;
    if (file.status === 'success') return '上传完成';
    if (file.status === 'fail') return '上传失败';
    return '待上传';
  }

  return { customUpload, getUploadStatusText, uploadFiles };
}

在页面中绑定上传工厂:

vue
<script setup lang="ts">
import { useFileUpload } from '@/composables/useFileUpload';

const { customUpload, getUploadStatusText, uploadFiles } = useFileUpload();
</script>

<template>
  <wd-upload
    v-model:file-list="uploadFiles"
    accept="image"
    image-mode="aspectFill"
    name="file"
    multiple
    :limit="9"
    :max-size="5 * 1024 * 1024"
    :upload-method="customUpload"
  >
    <template #preview-cover="{ file }">
      <view class="absolute inset-x-0 bottom-0 bg-black/55 py-1 text-center text-white">
        {{ getUploadStatusText(file) }}
      </view>
    </template>
  </wd-upload>
</template>

工厂必须在页面实例中调用

不要把 uploadFilesuploadQueue 或去重集合声明成模块级单例。通过 useFileUpload() 为每个页面实例创建独立状态,页面销毁后再次进入时才不会继承上一次的上传列表。

枚举

AppType 应用类型

枚举成员valuecode说明
H50H5网页端
WXGZH1WechatOa微信公众号网页
WXAPP2WechatApp微信小程序
QA3QuickApp快应用
Android4Android安卓 APP
IOS5IOS苹果 APP
DouyinApp6DouyinApp抖音小程序
KuaishouApp7KuaishouApp快手小程序

TabbarItem 导航项类型

该类型定义在 enum/tabbar_type.ts 中,实际是一个纯 TypeScript 接口(interface),并非继承 BaseEnumeration 的业务枚举,这里为保持目录归属完整性一并收录。它描述了单个 Tabbar 导航项的完整字段形态,与 SystemAppTabbarDto 字段基本一一对应,可用于业务侧自定义 Tabbar 状态管理时的类型标注。

字段类型说明
namestring导航项标识
valuenumber | null排序/唯一标识值
activeboolean是否激活
titlestring导航项标题
iconstring图标
pagePathstring页面路径
iconPathstring未选中态图标路径
selectedIconPathstring选中态图标路径
textstring文案
sortnumber排序值
renderboolean是否渲染

内部工具包 · 未开源授权,仅限公司内部授权团队使用