uni-tool.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /**
  2. * 模态框配置选项接口
  3. */
  4. export interface IModalOptions {
  5. /** 标题 */
  6. title?: string;
  7. /** 内容 */
  8. content: string;
  9. /** 是否显示取消按钮 */
  10. showCancel?: boolean;
  11. /** 是否显示确认按钮 */
  12. showConfirm?: boolean;
  13. /** 确认按钮文字 */
  14. confirmText?: string;
  15. /** 取消按钮文字 */
  16. cancelText?: string;
  17. /** 取消按钮颜色 */
  18. cancelColor?: string;
  19. /** 确认按钮颜色 */
  20. confirmColor?: string;
  21. }
  22. /**
  23. * 工具函数接口
  24. */
  25. export interface IeTool {
  26. /** 是否显示加载提示 */
  27. loading: boolean,
  28. /** 加载提示开始时间 */
  29. loadingStartTime: number,
  30. /** 最小显示时间 */
  31. minLoadingTime: number,
  32. /**
  33. * 显示普通提示
  34. * @param title - 提示内容,默认为空字符串
  35. */
  36. showToast(title?: string): void;
  37. /**
  38. * 显示成功提示
  39. * @param title - 提示内容,默认为空字符串
  40. */
  41. showSuccess(title?: string): void;
  42. /**
  43. * 显示错误提示
  44. * @param title - 提示内容,默认为空字符串
  45. */
  46. showError(title?: string): void;
  47. /**
  48. * 显示加载提示
  49. * @param title - 提示内容,默认为空字符串
  50. */
  51. showLoading(title?: string): void;
  52. /**
  53. * 隐藏加载提示
  54. */
  55. hideLoading(): void;
  56. /**
  57. * 显示模态对话框
  58. * @param params - 模态框配置选项
  59. * @returns Promise<boolean> - 用户点击确认返回 true,点击取消返回 false
  60. */
  61. showModal(params: IModalOptions): Promise<boolean>;
  62. /*
  63. * 显示模态对话框, 与showModal的差异在于,确认时命中resolve, 取消时命中reject.
  64. * // NOTE: 没有直接在showModal里改,是因为使用的地方太多,避免直接修改影响太广 2026.1.8
  65. * @param params - 模态框配置选项
  66. * @returns Promise<boolean> - 用户点击确认返回 true,点击取消返回 false
  67. * */
  68. showConfirm(params: IModalOptions): Promise<boolean>;
  69. /**
  70. * 复制内容
  71. * @param content - 要复制的内容
  72. */
  73. copy(content: string): void;
  74. /* 打开网址 */
  75. openBrowser(url: string): void;
  76. }
  77. const defaultModalOptions: IModalOptions = {
  78. title: '',
  79. content: '',
  80. showCancel: true,
  81. showConfirm: true,
  82. cancelColor: '#000000',
  83. confirmColor: '#31a0fc',
  84. cancelText: '取消',
  85. confirmText: '确认'
  86. };
  87. const tool: IeTool = {
  88. loading: false,
  89. loadingStartTime: 0,
  90. minLoadingTime: 500, // 最小显示时间,单位毫秒
  91. async showToast(title: string = '') {
  92. // 先立即隐藏,避免上一个 toast存在导致下次的 toast 很快关闭
  93. uni.hideToast();
  94. await sleep(100);
  95. uni.showToast({
  96. title,
  97. icon: 'none'
  98. });
  99. },
  100. showSuccess(title: string = '') {
  101. uni.showToast({
  102. title,
  103. icon: 'success'
  104. });
  105. },
  106. showError(title: string = '') {
  107. uni.showToast({
  108. title,
  109. icon: 'error'
  110. });
  111. },
  112. showLoading(title: string = '') {
  113. this.loadingStartTime = Date.now();
  114. uni.showLoading({
  115. title,
  116. mask: true,
  117. success: () => { }
  118. });
  119. },
  120. hideLoading() {
  121. const currentTime = Date.now();
  122. const elapsedTime = currentTime - this.loadingStartTime;
  123. const remainingTime = Math.max(0, this.minLoadingTime - elapsedTime);
  124. if (remainingTime > 0) {
  125. setTimeout(() => {
  126. uni.hideLoading();
  127. }, remainingTime);
  128. } else {
  129. uni.hideLoading();
  130. }
  131. },
  132. showModal(params: IModalOptions) {
  133. const { title, content, showCancel, confirmText, cancelText, cancelColor, confirmColor } = Object.assign(defaultModalOptions, params);
  134. return new Promise((resolve, reject) => {
  135. uni.showModal({
  136. title,
  137. content,
  138. showCancel,
  139. confirmText,
  140. cancelText,
  141. cancelColor,
  142. confirmColor,
  143. success: (res) => {
  144. resolve(res.confirm);
  145. },
  146. fail: reject
  147. });
  148. });
  149. },
  150. showConfirm(params: IModalOptions) {
  151. const { title, content, showCancel, confirmText, cancelText, cancelColor, confirmColor } = Object.assign(defaultModalOptions, params);
  152. return new Promise((resolve, reject) => {
  153. uni.showModal({
  154. title,
  155. content,
  156. showCancel,
  157. confirmText,
  158. cancelText,
  159. cancelColor,
  160. confirmColor,
  161. success: (res) => {
  162. /* 这里不要动,就是这样的。形成await showConfirm的效果 2026.1.13 */
  163. /* 如果有必须接收true/false的写法,请使用showModal */
  164. if (res.confirm) (resolve(true))
  165. else reject(false)
  166. },
  167. fail: reject
  168. });
  169. });
  170. },
  171. copy(content: string) {
  172. uni.setClipboardData({
  173. data: content,
  174. success: () => { }
  175. });
  176. },
  177. openBrowser(url: string) {
  178. const handleCopy = function () {
  179. uni.setClipboardData({
  180. data: url,
  181. success: () => {
  182. uni.showModal({
  183. title: '提示',
  184. content: '链接已复制,请在浏览器中打开',
  185. showCancel: false
  186. })
  187. }
  188. })
  189. }
  190. // 判断平台
  191. // #ifdef APP-PLUS
  192. plus.runtime.openURL(url)
  193. // #endif
  194. // #ifdef H5
  195. window.open(url, '_blank')
  196. // #endif
  197. // #ifdef MP-WEIXIN
  198. // 微信小程序
  199. try {
  200. if (url.toLowerCase().startsWith('https://mp.weixin.qq.com/')) {
  201. uni.openOfficialAccountArticle({
  202. url,
  203. fail: handleCopy
  204. })
  205. } else {
  206. handleCopy()
  207. }
  208. } catch (e){
  209. console.log('小程序打开链接降级处理', e)
  210. handleCopy()
  211. }
  212. // #endif
  213. // 其他平台,如App、快应用等,可以根据需要补充
  214. // 对于不支持直接打开浏览器的平台,使用降级方案
  215. // #ifndef H5 || MP-WEIXIN
  216. handleCopy()
  217. // #endif
  218. }
  219. };
  220. const sleep = (ms: number) => {
  221. return new Promise(resolve => setTimeout(resolve, ms));
  222. }
  223. export default tool;