select-goods.ts 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. import DictionariesBehavior from "../../../../core/behavior/dictionaries.behavior";
  2. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  3. import tickleBehavior, {
  4. getTickleContext,
  5. } from "../../../../core/behavior/tickle.behavior";
  6. import I18nBehavior from "../../../../i18n/behavior";
  7. import { getOfflineTreatmentListMethod } from "../../request";
  8. import { getFullImageUrl } from "../../../../utils/util";
  9. // module/order/pages/select-goods/select-goods.ts
  10. Component({
  11. behaviors: [PageContainerBehavior, DictionariesBehavior, tickleBehavior,I18nBehavior],
  12. lifetimes: {
  13. attached() {
  14. const healthAnalysisReportId = wx.getStorageSync('healthAnalysisReportId');
  15. if(healthAnalysisReportId){
  16. this.getOfflineTreatmentList(healthAnalysisReportId);
  17. }
  18. },
  19. },
  20. data: {
  21. goodsList: [] as Array<{
  22. category: string;
  23. goods: Array<{
  24. id: string;
  25. name: string;
  26. description?: string;
  27. image: string;
  28. price: number;
  29. quantity: number;
  30. checked: boolean;
  31. badge?: string;
  32. }>;
  33. }>,
  34. selectAll: true,
  35. selectedCount: 0,
  36. totalPrice: 0,
  37. i18n: {
  38. orderText: {
  39. selectGoods: '选择',
  40. payMeant:'确认'
  41. }
  42. }
  43. },
  44. observers: {
  45. 'goodsList': function () {
  46. this.calculateSummary();
  47. }
  48. },
  49. methods: {
  50. async getOfflineTreatmentList(healthAnalysisReportId: string) {
  51. const res = await getOfflineTreatmentListMethod(healthAnalysisReportId);
  52. const goodsList: any[] = [];
  53. Object.keys(res).forEach((categoryName: string) => {
  54. const categoryItems = res[categoryName] || [];
  55. if (categoryItems.length > 0) {
  56. const goods = categoryItems.map((item: any) => {
  57. return {
  58. id: item.id || '',
  59. name: item.name || '', //商品名称
  60. description: (() => {
  61. const dose = item?.cpFixedPricingRule?.convertDose ?? '';
  62. const unit = item?.cpFixedPricingRule?.convertUnit ?? '';
  63. return `${dose} ${unit}`;
  64. })(),
  65. image: getFullImageUrl(item.itemImgSecond) || '', //商品图片
  66. price: item.cpFixedPricingRule?.unitPrice || 0, //商品单价
  67. quantity: 1, //商品数量
  68. checked: true, //是否选中
  69. };
  70. });
  71. goodsList.push({
  72. category: categoryName,
  73. goods: goods,
  74. });
  75. }
  76. });
  77. this.setData({ goodsList });
  78. this.calculateSummary();
  79. },
  80. // 商品复选框变化
  81. onGoodsCheckChange(e: any) {
  82. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  83. const checked = e.detail.checked;
  84. const goodsList = this.data.goodsList;
  85. const goods = goodsList[categoryIndex].goods[goodsIndex];
  86. goods.checked = checked;
  87. // 如果勾选且数量为0,设置为1
  88. if (checked && goods.quantity === 0) {
  89. goods.quantity = 1;
  90. }
  91. // 单价为0的商品,如果勾选,数量固定为1
  92. if (goods.price === 0) {
  93. if (checked) {
  94. goods.quantity = 1;
  95. } else {
  96. goods.quantity = 0;
  97. }
  98. }
  99. this.setData({ goodsList });
  100. this.calculateSummary();
  101. },
  102. // 全选变化
  103. onSelectAllChange(e: any) {
  104. const checked = e.detail.checked;
  105. const goodsList = this.data.goodsList.map(category => ({
  106. ...category,
  107. goods: category.goods.map(goods => ({
  108. ...goods,
  109. checked: checked,
  110. // 0元商品:选中时数量为1,未选中时数量为0
  111. // 非0元商品:选中时如果数量为0则设为1,否则保持原数量
  112. quantity: goods.price === 0
  113. ? (checked ? 1 : 0)
  114. : (checked && goods.quantity === 0 ? 1 : goods.quantity)
  115. }))
  116. }));
  117. this.setData({
  118. goodsList,
  119. selectAll: checked
  120. });
  121. this.calculateSummary();
  122. },
  123. // 数量变化(加减按钮)
  124. onQuantityChange(e: any) {
  125. const { categoryIndex, goodsIndex, type } = e.currentTarget.dataset;
  126. const goodsList = this.data.goodsList;
  127. const goods = goodsList[categoryIndex].goods[goodsIndex];
  128. // 单价为0的商品数量固定为1(如果被选中)
  129. if (goods.price === 0) {
  130. // 0元商品数量固定为1,不允许通过按钮修改
  131. return;
  132. } else {
  133. // 非0价格商品的正常逻辑
  134. let newQuantity = goods.quantity;
  135. if (type === "plus") {
  136. newQuantity = goods.quantity + 1;
  137. } else if (type === "minus") {
  138. newQuantity = Math.max(0, goods.quantity - 1);
  139. }
  140. goods.quantity = newQuantity;
  141. // 如果数量为0,自动取消勾选
  142. if (newQuantity === 0) {
  143. goods.checked = false;
  144. } else if (!goods.checked) {
  145. // 如果数量大于0且未勾选,自动勾选
  146. goods.checked = true;
  147. }
  148. }
  149. this.setData({ goodsList });
  150. this.calculateSummary();
  151. },
  152. // 数量输入
  153. onQuantityInput(e: any) {
  154. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  155. const goodsList = this.data.goodsList;
  156. const goods = goodsList[categoryIndex].goods[goodsIndex];
  157. // 单价为0的商品数量固定为1,不允许修改
  158. if (goods.price === 0) {
  159. // 保持数量为1
  160. goods.quantity = 1;
  161. this.setData({ goodsList });
  162. return;
  163. }
  164. const value = parseInt(e.detail.value) || 0;
  165. goods.quantity = Math.max(0, value);
  166. this.setData({ goodsList });
  167. },
  168. // 数量输入失焦
  169. onQuantityBlur(e: any) {
  170. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  171. const goodsList = this.data.goodsList;
  172. const goods = goodsList[categoryIndex].goods[goodsIndex];
  173. // 单价为0的商品数量固定为1(如果被选中)
  174. if (goods.price === 0) {
  175. // 如果被选中,数量固定为1
  176. if (goods.checked) {
  177. goods.quantity = 1;
  178. } else {
  179. // 如果未选中,数量为0
  180. goods.quantity = 0;
  181. }
  182. } else {
  183. // 非0价格商品的逻辑
  184. if (goods.quantity === 0) {
  185. goods.checked = false;
  186. } else if (!goods.checked) {
  187. // 如果数量大于0且未勾选,自动勾选
  188. goods.checked = true;
  189. }
  190. }
  191. this.setData({ goodsList });
  192. this.calculateSummary();
  193. },
  194. // 计算汇总信息
  195. calculateSummary() {
  196. const goodsList = this.data.goodsList;
  197. let selectedCount = 0;
  198. let totalPrice = 0;
  199. let allChecked = true;
  200. goodsList.forEach((category: any) => {
  201. category.goods.forEach((goods: any) => {
  202. if (goods.checked && goods.quantity > 0) {
  203. selectedCount++; // 已选件数 = 选中的商品种类数
  204. totalPrice += goods.price * goods.quantity;
  205. }
  206. if (!goods.checked || goods.quantity === 0) {
  207. allChecked = false;
  208. }
  209. });
  210. });
  211. this.setData({
  212. selectedCount,
  213. totalPrice: totalPrice.toFixed(2),
  214. selectAll: allChecked
  215. });
  216. },
  217. // 结算
  218. onCheckout() {
  219. const goodsList = this.data.goodsList;
  220. // 过滤出选中的商品
  221. const selectedGoods = goodsList.map((category: any) => ({
  222. category: category.category,
  223. goods: category.goods.filter((goods: any) => goods.checked && goods.quantity > 0)
  224. })).filter((category: any) => category.goods.length > 0);
  225. if (selectedGoods.length === 0) {
  226. getTickleContext.call(this).showWarnMessage("请至少选择一件商品");
  227. return;
  228. }
  229. // 跳转到确认订单页面
  230. wx.setStorageSync('selectedGoods', selectedGoods);
  231. wx.setStorageSync('totalPrice', this.data.totalPrice);
  232. wx.navigateTo({
  233. url: `/module/order/pages/confirme-order/confirme-order`,
  234. fail: (err) => {
  235. getTickleContext.call(this).showWarnMessage(err.errMsg || "跳转失败");
  236. },
  237. });
  238. },
  239. }
  240. });