shinnosuke
2026-09-18 ac374e5100c8e600f1b74ceb228cde49ebb1272c
rencaika/services/business.uts
@@ -5,11 +5,26 @@
export const createIdempotencyKey = (scope: string): string => scope + '-' + Date.now() + '-' + Math.floor(Math.random() * 1000000000)
export const sanitizeRichText = (html: string): string => {
   return html
   if (html == null) return ''
   const base = getApiBaseUrl().replace(/\/+$/, '')
   const content = ('' + html)
      .replace(/<script[\s\S]*?<\/script>/gi, '')
      .replace(/<style[\s\S]*?<\/style>/gi, '')
      .replace(/\son[a-z]+\s*=\s*(['"]).*?\1/gi, '')
      .replace(/\s(href|src)\s*=\s*(['"])(?!https:\/\/).*?\2/gi, '')
      // 危险协议(javascript: 等)直接去掉属性。
      .replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2/gi, '')
   if (base == '') return content
   // 后台富文本里的图片/链接存的是相对路径(/uploads/xxx.png)。小程序加载不了相对路径,
   // 而原来这里会把所有非 https 的 src 整条删掉,图片就变成破图(只显示 alt 文字)。
   // 这里统一补成接口域名下的绝对地址,http(s) 绝对地址原样保留。
   return content
      .replace(/(src|href)=(["'])\/\//gi, '$1=$2https://')
      .replace(/(\s(?:src|href)\s*=\s*(['"]))\/+/gi, '$1' + base + '/')
      .replace(/(\s(?:src|href)\s*=\s*(['"]))(?!https?:|\/\/|\/|data:|javascript:)/gi, '$1' + base + '/')
      // 小程序 rich-text 不继承页面样式:后台图片带的是原图尺寸,会撑出卡片。
      // 在图片标签上补内联样式,按容器宽度等比缩放并居中。
      .replace(/(<img\b[^>]*?\sstyle=(["']))([^"']*)(\2)/gi, '$1$3max-width:100%;height:auto;display:block;margin:10px auto;$4')
      .replace(/<img\b(?![^>]*\sstyle=)/gi, '<img style="max-width:100%;height:auto;display:block;margin:10px auto;"')
}
export const requestDynamicCode = (codeType: string, businessId: string, onSuccess: (data: any) => void, onError: (error: HttpError) => void) => {