select-goods.ts 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. // module/order/pages/select-goods/select-goods.ts
  7. Component({
  8. behaviors: [PageContainerBehavior, DictionariesBehavior, tickleBehavior],
  9. lifetimes: {
  10. attached() {
  11. // 初始化商品数据(示例数据,实际应从接口获取)
  12. this.initGoodsData();
  13. },
  14. },
  15. properties: {
  16. schemeId: { type: String, value: "" },
  17. },
  18. data: {
  19. goodsList: [] as Array<{
  20. category: string;
  21. goods: Array<{
  22. id: string;
  23. name: string;
  24. description?: string;
  25. image: string;
  26. price: number;
  27. quantity: number;
  28. checked: boolean;
  29. badge?: string;
  30. }>;
  31. }>,
  32. selectAll: true,
  33. selectedCount: 0,
  34. totalPrice: 0,
  35. },
  36. observers: {
  37. 'goodsList': function() {
  38. this.calculateSummary();
  39. }
  40. },
  41. methods: {
  42. // 初始化商品数据
  43. initGoodsData() {
  44. // 示例数据,实际应从接口获取
  45. const goodsList = [
  46. {
  47. category: "穴位贴敷",
  48. goods: [
  49. {
  50. id: "1",
  51. name: "肝血虚穴位贴",
  52. description: "20贴",
  53. image: "/assets/icon/icon_file@3x.png",
  54. price: 100,
  55. quantity: 1,
  56. checked: true,
  57. }
  58. ]
  59. },
  60. {
  61. category: "运动",
  62. goods: [
  63. {
  64. id: "2",
  65. name: "五禽戏",
  66. image: "/assets/icon/icon_file@3x.png",
  67. price: 0,
  68. quantity: 1,
  69. checked: true,
  70. badge: "1",
  71. },
  72. {
  73. id: "3",
  74. name: "颈椎操",
  75. image: "/assets/icon/icon_file@3x.png",
  76. price: 0,
  77. quantity: 1,
  78. checked: true,
  79. }
  80. ]
  81. },
  82. {
  83. category: "茶饮",
  84. goods: [
  85. {
  86. id: "4",
  87. name: "元气茶",
  88. description: "30包",
  89. image: "/assets/icon/icon_file@3x.png",
  90. price: 80,
  91. quantity: 1,
  92. checked: true,
  93. },
  94. {
  95. id: "5",
  96. name: "芡实米仁燕麦粥",
  97. description: "21袋",
  98. image: "/assets/icon/icon_file@3x.png",
  99. price: 1.5,
  100. quantity: 1,
  101. checked: true,
  102. }
  103. ]
  104. }
  105. ];
  106. this.setData({ goodsList });
  107. this.calculateSummary();
  108. },
  109. // 商品复选框变化
  110. onGoodsCheckChange(e: any) {
  111. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  112. const checked = e.detail.checked;
  113. const goodsList = this.data.goodsList;
  114. const goods = goodsList[categoryIndex].goods[goodsIndex];
  115. goods.checked = checked;
  116. // 如果勾选且数量为0,设置为1
  117. if (checked && goods.quantity === 0) {
  118. goods.quantity = 1;
  119. }
  120. // 单价为0的商品,如果勾选,确保数量为1
  121. if (checked && goods.price === 0 && goods.quantity !== 1) {
  122. goods.quantity = 1;
  123. }
  124. this.setData({ goodsList });
  125. this.calculateSummary();
  126. },
  127. // 全选变化
  128. onSelectAllChange(e: any) {
  129. const checked = e.detail.checked;
  130. const goodsList = this.data.goodsList.map(category => ({
  131. ...category,
  132. goods: category.goods.map(goods => ({
  133. ...goods,
  134. checked: checked,
  135. quantity: checked && goods.quantity === 0 ? 1 : goods.quantity
  136. }))
  137. }));
  138. this.setData({
  139. goodsList,
  140. selectAll: checked
  141. });
  142. this.calculateSummary();
  143. },
  144. // 数量变化(加减按钮)
  145. onQuantityChange(e: any) {
  146. const { categoryIndex, goodsIndex, type } = e.currentTarget.dataset;
  147. const goodsList = this.data.goodsList;
  148. const goods = goodsList[categoryIndex].goods[goodsIndex];
  149. // 单价为0的商品数量只能是1
  150. if (goods.price === 0) {
  151. if (type === "plus") {
  152. // 已经是1,不能再加
  153. return;
  154. } else if (type === "minus") {
  155. // 减到0时自动取消勾选,但不能小于1(如果已勾选)
  156. if (goods.quantity === 1) {
  157. goods.quantity = 0;
  158. goods.checked = false;
  159. } else {
  160. goods.quantity = 1; // 确保始终为1
  161. }
  162. }
  163. } else {
  164. // 非0价格商品的正常逻辑
  165. let newQuantity = goods.quantity;
  166. if (type === "plus") {
  167. newQuantity = goods.quantity + 1;
  168. } else if (type === "minus") {
  169. newQuantity = Math.max(0, goods.quantity - 1);
  170. }
  171. goods.quantity = newQuantity;
  172. // 如果数量为0,自动取消勾选
  173. if (newQuantity === 0) {
  174. goods.checked = false;
  175. } else if (!goods.checked) {
  176. // 如果数量大于0且未勾选,自动勾选
  177. goods.checked = true;
  178. }
  179. }
  180. this.setData({ goodsList });
  181. this.calculateSummary();
  182. },
  183. // 数量输入
  184. onQuantityInput(e: any) {
  185. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  186. const value = parseInt(e.detail.value) || 0;
  187. const goodsList = this.data.goodsList;
  188. const goods = goodsList[categoryIndex].goods[goodsIndex];
  189. // 单价为0的商品数量只能是1
  190. if (goods.price === 0) {
  191. if (value > 1) {
  192. goods.quantity = 1;
  193. } else if (value < 0) {
  194. goods.quantity = 0;
  195. } else {
  196. goods.quantity = value;
  197. }
  198. } else {
  199. goods.quantity = Math.max(0, value);
  200. }
  201. this.setData({ goodsList });
  202. },
  203. // 数量输入失焦
  204. onQuantityBlur(e: any) {
  205. const { categoryIndex, goodsIndex } = e.currentTarget.dataset;
  206. const goodsList = this.data.goodsList;
  207. const goods = goodsList[categoryIndex].goods[goodsIndex];
  208. // 单价为0的商品数量只能是1
  209. if (goods.price === 0) {
  210. if (goods.quantity > 1) {
  211. goods.quantity = 1;
  212. } else if (goods.quantity < 1 && goods.checked) {
  213. // 如果已勾选但数量小于1,设置为1
  214. goods.quantity = 1;
  215. } else if (goods.quantity === 0) {
  216. // 数量为0,取消勾选
  217. goods.checked = false;
  218. }
  219. } else {
  220. // 非0价格商品的逻辑
  221. if (goods.quantity === 0) {
  222. goods.checked = false;
  223. } else if (!goods.checked) {
  224. // 如果数量大于0且未勾选,自动勾选
  225. goods.checked = true;
  226. }
  227. }
  228. this.setData({ goodsList });
  229. this.calculateSummary();
  230. },
  231. // 计算汇总信息
  232. calculateSummary() {
  233. const goodsList = this.data.goodsList;
  234. let selectedCount = 0;
  235. let totalPrice = 0;
  236. let allChecked = true;
  237. goodsList.forEach((category: any) => {
  238. category.goods.forEach((goods: any) => {
  239. if (goods.checked && goods.quantity > 0) {
  240. selectedCount++; // 已选件数 = 选中的商品种类数
  241. totalPrice += goods.price * goods.quantity;
  242. }
  243. if (!goods.checked || goods.quantity === 0) {
  244. allChecked = false;
  245. }
  246. });
  247. });
  248. this.setData({
  249. selectedCount,
  250. totalPrice: totalPrice.toFixed(2),
  251. selectAll: allChecked
  252. });
  253. },
  254. // 结算
  255. onCheckout() {
  256. const goodsList = this.data.goodsList;
  257. const selectedGoods: any[] = [];
  258. // 收集选中的商品
  259. goodsList.forEach((category: any) => {
  260. category.goods.forEach((goods: any) => {
  261. if (goods.checked && goods.quantity > 0) {
  262. selectedGoods.push({
  263. ...goods,
  264. category: category.category
  265. });
  266. }
  267. });
  268. });
  269. if (selectedGoods.length === 0) {
  270. getTickleContext.call(this).showWarnMessage("请至少选择一件商品");
  271. return;
  272. }
  273. // 跳转到确认订单页面(需要创建该页面)
  274. // 暂时将选中的商品数据存储,供确认订单页面使用
  275. wx.setStorageSync('selectedGoods', selectedGoods);
  276. wx.setStorageSync('totalPrice', this.data.totalPrice);
  277. wx.navigateTo({
  278. url: `/module/order/pages/confirm-order/confirm-order`,
  279. fail: (err) => {
  280. // 如果确认订单页面不存在,提示用户
  281. getTickleContext.call(this).showWarnMessage("确认订单页面不存在,请先创建该页面");
  282. }
  283. });
  284. },
  285. // 隐私相关方法
  286. onPrivacySetting() {},
  287. onAgree() {},
  288. onDisagree() {},
  289. },
  290. });