index.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /**
  2. * 获取当前页面路径
  3. * @returns 当前页面路径
  4. */
  5. export function getCurrentPath() {
  6. const pages = getCurrentPages()
  7. const currentPage = pages[pages.length - 1]
  8. return currentPage.route || ''
  9. }
  10. /**
  11. * 检测当前环境是否为微信小程序
  12. */
  13. export function isWxMiniProgram() {
  14. return new Promise((resolve, reject) => {
  15. const apltInfo = uni.getDeviceInfo()
  16. console.log(apltInfo, '当前环境=======================')
  17. if (apltInfo.platform === 'windows') {
  18. useGlobalToast().show('不支持电脑操作地址,请使用手机打开')
  19. reject(new Error('不支持电脑操作地址,请使用手机打开'))
  20. }
  21. resolve(1)
  22. })
  23. }
  24. /**
  25. * 将角度转换为弧度
  26. */
  27. function toRadians(degrees: number): number {
  28. return degrees * Math.PI / 180
  29. }
  30. /**
  31. * 将弧度转换为角度
  32. */
  33. function toDegrees(radians: number): number {
  34. return radians * 180 / Math.PI
  35. }
  36. /**
  37. * 计算两个经纬度的中心点(球面插值法)
  38. * 适用于任意距离,考虑地球曲率,更精确
  39. *
  40. * @param pointA 第一个经纬度坐标
  41. * @param pointB 第二个经纬度坐标
  42. * @returns 中心点经纬度坐标
  43. */
  44. export function calculateCenterPointSpherical(
  45. pointA: { lat: number, lng: number },
  46. pointB: { lat: number, lng: number },
  47. ): { lat: number, lng: number } {
  48. // 将经纬度转换为弧度
  49. const lat1 = toRadians(pointA.lat)
  50. const lng1 = toRadians(pointA.lng)
  51. const lat2 = toRadians(pointB.lat)
  52. const lng2 = toRadians(pointB.lng)
  53. // 计算纬度的差值
  54. const dLng = lng2 - lng1
  55. // 使用球面插值公式计算中心点
  56. const Bx = Math.cos(lat2) * Math.cos(dLng)
  57. const By = Math.cos(lat2) * Math.sin(dLng)
  58. const centerLat = Math.atan2(
  59. Math.sin(lat1) + Math.sin(lat2),
  60. Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By),
  61. )
  62. const centerLng = lng1 + Math.atan2(By, Math.cos(lat1) + Bx)
  63. // 将结果转换回角度
  64. return {
  65. lat: toDegrees(centerLat),
  66. lng: toDegrees(centerLng),
  67. }
  68. }
  69. /**
  70. * 订单统一枚举
  71. */
  72. export enum OrderStatus {
  73. /**
  74. * 待支付
  75. */
  76. PaddingPay = 0,
  77. /**
  78. * 订单已接单
  79. */
  80. OrderAccepted = 20,
  81. /**
  82. * 订单待配送
  83. */
  84. OrderWaitDelivery = 30,
  85. /**
  86. * 订单配送中
  87. */
  88. OrderDelivering = 40,
  89. /**
  90. * 订单取消审核
  91. */
  92. OrderCancelAudit = 50,
  93. /**
  94. * 订单取消
  95. */
  96. OrderCancel = 60,
  97. /**
  98. * 订单已过期
  99. */
  100. OrderExpired = 62,
  101. /**
  102. * 大健康退款
  103. */
  104. OrderRefund = 61,
  105. /**
  106. * 订单已送达
  107. */
  108. OrderArrived = 70,
  109. /**
  110. * 订单完成
  111. */
  112. OrderCompleted = 80,
  113. }
  114. /**
  115. * 把true转为数字true为1,false是0
  116. *
  117. * @param value
  118. */
  119. export function boolToNumber(value: boolean): number {
  120. return value ? 1 : 0
  121. }
  122. /**
  123. * 输入框格式校验工具类
  124. */
  125. export class InputFormatUtil {
  126. /**
  127. * 手机号校验
  128. * @param phone
  129. */
  130. static isPhone(phone: string) {
  131. return /^1[3-9]\d{9}$/.test(phone)
  132. }
  133. /**
  134. * QQ号校验
  135. * @param qq
  136. */
  137. static isQQ(qq: string) {
  138. return /^[1-9]\d{4,10}$/.test(qq)
  139. }
  140. }
  141. /**
  142. * 手机号*号
  143. */
  144. export function phoneFormat(phone: string) {
  145. return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
  146. }
  147. /**
  148. * 从 URL 中解析查询参数
  149. * 支持已编码和未编码的 URL
  150. * @param url URL 字符串,可以是完整 URL 或仅查询字符串部分
  151. * @returns 解析后的参数对象
  152. * @example
  153. */
  154. export function parseUrlParams(url: string): Record<string, string> {
  155. if (!url)
  156. return {}
  157. try {
  158. // 尝试解码(处理多次编码的情况)
  159. let decodedUrl = url
  160. while (decodedUrl.includes('%')) {
  161. const newDecoded = decodeURIComponent(decodedUrl)
  162. if (newDecoded === decodedUrl)
  163. break
  164. decodedUrl = newDecoded
  165. }
  166. // 提取查询字符串部分
  167. let queryString = decodedUrl
  168. const questionIndex = decodedUrl.indexOf('?')
  169. if (questionIndex !== -1) {
  170. queryString = decodedUrl.substring(questionIndex + 1)
  171. }
  172. // 移除可能存在的 hash 部分
  173. const hashIndex = queryString.indexOf('#')
  174. if (hashIndex !== -1) {
  175. queryString = queryString.substring(0, hashIndex)
  176. }
  177. if (!queryString)
  178. return {}
  179. // 解析参数
  180. const params: Record<string, string> = {}
  181. const pairs = queryString.split('&')
  182. pairs.forEach((pair) => {
  183. const equalIndex = pair.indexOf('=')
  184. if (equalIndex > 0) {
  185. const key = decodeURIComponent(pair.substring(0, equalIndex))
  186. const val = decodeURIComponent(pair.substring(equalIndex + 1))
  187. params[key] = val
  188. }
  189. else if (pair) {
  190. params[decodeURIComponent(pair)] = ''
  191. }
  192. })
  193. return params
  194. }
  195. catch {
  196. return {}
  197. }
  198. }
  199. /**
  200. *处理富文本图片溢出
  201. * @param html - 富文本字符串
  202. * @returns
  203. */
  204. export function fixImgStyle(html: string) {
  205. if (!html)
  206. return html
  207. // 处理已有 style 属性的 img 标签:将样式追加到现有 style 中
  208. let result = html.replace(/<img([^>]*)style\s*=\s*["']([^"']*)["']([^>]*)>/gi, (match, before, existingStyle, after) => {
  209. // 移除可能存在的 width/height 内联样式,然后添加防溢出样式
  210. const cleanedStyle = existingStyle.replace(/\bwidth\s*:[^;]*;?/gi, '').replace(/\bheight\s*:[^;]*;?/gi, '')
  211. const newStyle = `${cleanedStyle};max-width:100%;height:auto;display:block;`.replace(/^;+|;+$/g, '').replace(/;{2,}/g, ';')
  212. return `<img${before}style="${newStyle}"${after}>`
  213. })
  214. // 处理没有 style 属性的 img 标签:添加新的 style
  215. result = result.replace(/<img(?![^>]*style\s*=)([^>]*)>/gi, '<img style="max-width:100%;height:auto;display:block;"$1>')
  216. return result
  217. }
  218. // 从地址字符串中提取城市名称
  219. export function getCityName(address: string): string {
  220. if (!address)
  221. return ''
  222. // 安全正则,无 ESLint 警告
  223. const regex = /^[^省]+省([^市]+)/
  224. const match = address.match(regex)
  225. if (match) {
  226. return match[1]
  227. }
  228. // 兼容直辖市(北京 / 上海 / 重庆 / 天津)
  229. const municipality = address.match(/(北京|上海|重庆|天津)/)
  230. return municipality ? municipality[1] : ''
  231. }