offline-evaluate.ts 6.8 KB

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