goods-evaluate.ts 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  2. import { EvaluateModel } from "../../model/evaluate.model";
  3. import { evaluateOrderGoodsMethod } from "../../request";
  4. import { upload } from "../../../../lib/request/upload";
  5. function withMediaType(url: string, type: "image" | "video") {
  6. if (!url) return url;
  7. const hasQuery = url.includes("?");
  8. const hasHash = url.includes("#");
  9. if (hasHash) {
  10. const [base, hash] = url.split("#");
  11. return `${base}${hasQuery ? "&" : "?"}type=${type}#${hash ?? ""}`;
  12. }
  13. return `${url}${hasQuery ? "&" : "?"}type=${type}`;
  14. }
  15. Page({
  16. behaviors: [PageContainerBehavior],
  17. data: {
  18. orderId: "",
  19. product: {} as { name: string; image: string; description?: string, patientConditioningRecordId?: number, patientConditioningProgramId?: number },
  20. score: 0,
  21. rateColor: "#F7BA2A",
  22. content: "",
  23. evaluateInfo: {} as EvaluateModel,
  24. mediaList: [] as { path: string; type: "image" | "video" }[],
  25. canPublish: false,
  26. videoFullscreen: false,
  27. },
  28. onLoad(options: Record<string, string>) {
  29. console.log(options, "options===");
  30. // const orderId = options.orderId || options.id || "";
  31. let product: { name: string; image: string; description?: string, patientConditioningRecordId?: number, patientConditioningProgramId?: number } = {
  32. name: "",
  33. image: "",
  34. description: "",
  35. patientConditioningRecordId: 0,
  36. patientConditioningProgramId: 0,
  37. };
  38. if (options.goodsInfo) {
  39. const goods = JSON.parse(decodeURIComponent(options.goodsInfo));
  40. console.log(goods, "goods===");
  41. product = {
  42. name: goods.name || "",
  43. image: goods.image || "",
  44. description: goods.description || "",
  45. patientConditioningRecordId: goods.patientConditioningRecordId || 0,
  46. patientConditioningProgramId: goods.id || 0,
  47. };
  48. }
  49. this.setData({
  50. // orderId,
  51. product,
  52. canPublish: this._checkCanPublish(0, ""),
  53. });
  54. },
  55. _checkCanPublish(score: number, _content: string): boolean {
  56. return score > 0;
  57. },
  58. onScoreChange(e: WechatMiniprogram.CustomEvent<{ value: number }>) {
  59. const score = e.detail?.value ?? 0;
  60. this.setData({
  61. score,
  62. canPublish: this._checkCanPublish(score, this.data.content),
  63. });
  64. },
  65. onContentInput(e: WechatMiniprogram.Input) {
  66. const content = e.detail?.value ?? "";
  67. this.setData({
  68. content,
  69. canPublish: this._checkCanPublish(this.data.score, content),
  70. });
  71. },
  72. onChooseMedia() {
  73. const current = this.data.mediaList.length;
  74. if (current >= 9) {
  75. wx.showToast({ title: "图片和视频总数不能超过9个", icon: "none" });
  76. return;
  77. }
  78. const remain = 9 - current;
  79. wx.chooseMedia({
  80. count: remain,
  81. mediaType: ["image", "video"],
  82. sourceType: ["album", "camera"],
  83. maxDuration: 30,
  84. camera: "back",
  85. success: (res) => {
  86. const list = res.tempFiles.map((f) => ({
  87. path: f.tempFilePath,
  88. type: (f.fileType === "video" ? "video" : "image") as "image" | "video",
  89. }));
  90. const oldLength = this.data.mediaList.length;
  91. const next = [...this.data.mediaList, ...list].slice(0, 9);
  92. this.setData({ mediaList: next });
  93. // 选取本地媒体后,调用上传接口上传到服务器
  94. list.forEach((item, idx) => {
  95. const index = oldLength + idx;
  96. upload<string, any>({
  97. params: { name: "file", file: item.path },
  98. transform({ data }: any): string {
  99. return (data as any)?.url || (data as any);
  100. },
  101. }).then(
  102. (url) => {
  103. const key = `mediaList[${index}].path`;
  104. this.setData({ [key]: url });
  105. },
  106. (error: any) => {
  107. wx.showToast({
  108. title: error?.errMsg || "上传失败",
  109. icon: "none",
  110. });
  111. const mediaList = this.data.mediaList.filter((_, i) => i !== index);
  112. this.setData({ mediaList });
  113. }
  114. );
  115. });
  116. },
  117. });
  118. },
  119. onRemoveMedia(e: WechatMiniprogram.TouchEvent) {
  120. const index = e.currentTarget.dataset.index as number;
  121. const mediaList = this.data.mediaList.filter((_, i) => i !== index);
  122. this.setData({ mediaList });
  123. },
  124. onPreviewImage(e: WechatMiniprogram.TouchEvent) {
  125. const url = e.currentTarget.dataset.url as string;
  126. const urls = this.data.mediaList.filter((m) => m.type === "image").map((m) => m.path);
  127. if (url && urls.length) {
  128. wx.previewImage({ current: url, urls });
  129. }
  130. },
  131. onPreviewVideo(e: WechatMiniprogram.TouchEvent) {
  132. const index = e.currentTarget.dataset.index as number;
  133. const videoContext = wx.createVideoContext("goods-video-" + index, this);
  134. videoContext.requestFullScreen({});
  135. },
  136. /** 点击图片/视频:原生全屏预览(类似 test 页) */
  137. onPreviewMedia(e: WechatMiniprogram.TouchEvent) {
  138. const index = e.currentTarget.dataset.index as number;
  139. const { mediaList } = this.data;
  140. if (index < 0 || index >= mediaList.length) return;
  141. const sources = mediaList.map((m) => ({
  142. url: m.path,
  143. type: m.type as "image" | "video",
  144. }));
  145. const previewMedia = (wx as any).previewMedia as
  146. | ((option: { sources: { url: string; type: "image" | "video" }[]; current: number }) => void)
  147. | undefined;
  148. if (typeof previewMedia === "function") {
  149. previewMedia({ sources, current: index });
  150. return;
  151. }
  152. // 低版本兜底:图片用 previewImage,视频用 requestFullScreen
  153. const current = mediaList[index];
  154. if (current.type === "image") {
  155. const urls = mediaList.filter((m) => m.type === "image").map((m) => m.path);
  156. wx.previewImage({ current: current.path, urls });
  157. return;
  158. }
  159. const ctx = wx.createVideoContext("goods-video-" + index, this);
  160. ctx.requestFullScreen({});
  161. },
  162. onVideoFullscreenChange(e: WechatMiniprogram.VideoFullScreenChange) {
  163. const fullScreen = !!(e.detail && e.detail.fullScreen);
  164. this.setData({ videoFullscreen: fullScreen });
  165. },
  166. onRemoveProduct() {
  167. this.setData({
  168. product: { name: "", image: "", description: "", patientConditioningRecordId: 0, patientConditioningProgramId: 0 },
  169. });
  170. },
  171. async onPublish() {
  172. if (!this.data.canPublish) {
  173. wx.showToast({ title: "请先完成评分", icon: "none" });
  174. return;
  175. }
  176. console.log(this.data.product,"90000")
  177. const data = {
  178. patientConditioningProgramId: this.data.product.patientConditioningProgramId,
  179. patientConditioningRecordId: this.data.product.patientConditioningRecordId,
  180. complianceScore: this.data.score,
  181. depict: this.data.content,
  182. imageVideos: this.data.mediaList.map((m) => withMediaType(m.path, m.type)),
  183. };
  184. console.log(data,"评价数据")
  185. try {
  186. wx.showLoading({ title: "发布中..." });
  187. await evaluateOrderGoodsMethod(data);
  188. wx.hideLoading();
  189. wx.showToast({ title: "发布成功", icon: "success" });
  190. wx.redirectTo({
  191. url: `/module/article/pages/order-list/order-list`,
  192. });
  193. } catch (error: any) {
  194. wx.hideLoading();
  195. wx.showToast({ title: error.errMsg || "发布失败", icon: "none" });
  196. }
  197. },
  198. });