scheme.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  2. import TickleBehavior, {
  3. getTickleContext,
  4. } from "../../../../core/behavior/tickle.behavior";
  5. // module/health/pages/scheme/scheme.ts
  6. import { healthSchemeMethod } from "../../request";
  7. import { toReportPage } from "../../router";
  8. Component({
  9. behaviors: [PageContainerBehavior, TickleBehavior],
  10. lifetimes: {
  11. attached() {
  12. this.getHealthScheme(this.data.id);
  13. },
  14. },
  15. properties: {
  16. id: { type: String, value: "" },
  17. },
  18. data: {
  19. dataset: null,
  20. schemeId: "",
  21. healthIndex: { data: [], loading: false, message: "" },
  22. showQrCodePopup: false,
  23. qrCodeImageUrl: "",
  24. },
  25. observers: {},
  26. methods: {
  27. async getHealthScheme(id: string) {
  28. wx.showLoading({ title: "加载中" });
  29. try {
  30. const dataset = await healthSchemeMethod(id);
  31. this.setData({ dataset });
  32. } catch (error) {
  33. console.log(error);
  34. getTickleContext
  35. .call(this)
  36. .showErrorMessage(error.errMsg || error.message, 0);
  37. }
  38. wx.hideLoading();
  39. },
  40. toReportPage() {
  41. toReportPage(this.data.id);
  42. },
  43. // 去购买
  44. goBuy(this: any, e: any) {
  45. const item = e.currentTarget.dataset.item || {};
  46. const type: string = (item.buyType || "").toLowerCase();
  47. const url: string = item.buyUrl || "";
  48. const shortImageUrl: string = item.shortImageUrl || "";
  49. console.log(item, "item", type, url);
  50. // 跳转小程序
  51. if (type === "miniprogram") {
  52. // 如果没有跳转链接,直接显示小程序码或提示错误
  53. if (!url) {
  54. if (shortImageUrl) {
  55. this.setData({
  56. showQrCodePopup: true,
  57. qrCodeImageUrl: shortImageUrl,
  58. });
  59. } else {
  60. getTickleContext.call(this).showWarnMessage("缺少小程序跳转参数");
  61. }
  62. return;
  63. }
  64. // 解析 miniprogram:// 格式的 URL
  65. let parsedAppId = "";
  66. let parsedPath = "";
  67. const isMiniprogramUrl = url.startsWith("miniprogram://");
  68. if (isMiniprogramUrl) {
  69. // 解析 miniprogram://?appid=xxx&path=xxx 格式
  70. try {
  71. // 提取查询参数字符串(去掉 miniprogram://? 前缀)
  72. const queryString = url.replace(/^miniprogram:\/\/(\?)?/, "");
  73. // 解析查询参数
  74. const params: Record<string, string> = {};
  75. queryString.split("&").forEach((param) => {
  76. const [key, value] = param.split("=");
  77. if (key && value) {
  78. params[key] = decodeURIComponent(value);
  79. }
  80. });
  81. parsedAppId = params.appid || "";
  82. parsedPath = params.path || "";
  83. } catch (error) {
  84. console.error("解析 miniprogram:// URL 失败:", error);
  85. }
  86. }
  87. // 统一的错误处理函数:显示小程序码或错误提示
  88. const showErrorOrQrCode = (errMsg?: string) => {
  89. if (shortImageUrl) {
  90. this.setData({
  91. showQrCodePopup: true,
  92. qrCodeImageUrl: shortImageUrl,
  93. });
  94. } else {
  95. getTickleContext
  96. .call(this)
  97. .showWarnMessage(errMsg || "跳转小程序失败");
  98. }
  99. };
  100. // 统一的跳转函数:使用 appId + path 方式跳转
  101. const navigateWithAppIdAndPath = (appId: string, path: string) => {
  102. wx.navigateToMiniProgram({
  103. appId: appId,
  104. path: path,
  105. envVersion: "release",
  106. fail: (pathErr) => {
  107. if (
  108. pathErr.errMsg.includes("navigateToMiniProgram:fail cancel")
  109. ) {
  110. console.log("用户取消appid小程序跳转");
  111. } else {
  112. showErrorOrQrCode(pathErr.errMsg);
  113. }
  114. },
  115. });
  116. };
  117. // 如果是 miniprogram:// 格式,直接使用 appId + path 方式跳转
  118. if (isMiniprogramUrl) {
  119. if (parsedAppId && parsedPath) {
  120. navigateWithAppIdAndPath(parsedAppId, parsedPath);
  121. }
  122. } else {
  123. // 短链接格式,优先使用短链接方式跳转
  124. wx.navigateToMiniProgram({
  125. shortLink: url,
  126. envVersion: "release",
  127. fail: (err) => {
  128. if (err.errMsg.includes("navigateToMiniProgram:fail cancel")) {
  129. console.log("用户取消短链跳转");
  130. } else {
  131. // 短链接失败,尝试使用 appId + path 方式跳转
  132. if (parsedAppId && parsedPath) {
  133. navigateWithAppIdAndPath(parsedAppId, parsedPath);
  134. } else {
  135. // 没有 appId 和 path,直接显示弹窗或错误提示
  136. showErrorOrQrCode(err.errMsg || "跳转小程序失败");
  137. }
  138. }
  139. },
  140. });
  141. }
  142. } else if (type === "url") {
  143. // h5链接
  144. if (!url) {
  145. getTickleContext.call(this).showWarnMessage("无有效链接");
  146. return;
  147. }
  148. wx.navigateTo({
  149. url: "/module/article/pages/science-info/science-info",
  150. success: (res) => {
  151. res.eventChannel?.emit?.("load", {
  152. title: item.title || "详情",
  153. url,
  154. });
  155. },
  156. fail: (err) => {
  157. getTickleContext
  158. .call(this)
  159. .showWarnMessage(err.errMsg || "打开页面失败");
  160. },
  161. });
  162. return;
  163. } else {
  164. // 无法识别
  165. getTickleContext.call(this).showWarnMessage("未识别的跳转类型");
  166. }
  167. },
  168. // 关闭小程序码弹窗
  169. closeQrCodePopup(e?: any) {
  170. // 如果 visible-change 事件触发且 visible 为 false,才关闭
  171. if (e === undefined || !e.detail?.visible) {
  172. this.setData({
  173. showQrCodePopup: false,
  174. qrCodeImageUrl: "",
  175. });
  176. }
  177. },
  178. },
  179. });