create.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. const _Http = getApp().globalData.http;
  2. Page({
  3. data: {
  4. loading: false,
  5. disabled: false,
  6. showAll: false,
  7. activeTab: 0,
  8. productList: [],
  9. form: [{
  10. label: "客户",
  11. error: false,
  12. errMsg: "",
  13. type: "route",
  14. url: "/CRM/customer/index?selectMode=true",
  15. params: {},
  16. value: "",
  17. placeholder: "客户名称",
  18. valueName: "name",
  19. required: false,
  20. checking: "base",
  21. interrupt: true
  22. },
  23. {
  24. label: "门店",
  25. error: false,
  26. errMsg: "",
  27. type: "text",
  28. value: "",
  29. placeholder: "门店名称",
  30. valueName: "storename",
  31. required: false,
  32. checking: "base",
  33. disabled: true
  34. },
  35. {
  36. label: "开单日期",
  37. error: false,
  38. errMsg: "",
  39. type: "date",
  40. value: "",
  41. placeholder: "请选择开单日期",
  42. valueName: "billdate",
  43. required: false,
  44. checking: "base"
  45. },
  46. {
  47. label: "订单数量",
  48. error: false,
  49. errMsg: "",
  50. type: "number",
  51. value: "0",
  52. placeholder: "订单数量",
  53. valueName: "orderCount",
  54. required: false,
  55. checking: "base",
  56. disabled: true
  57. },
  58. {
  59. label: "订单金额",
  60. error: false,
  61. errMsg: "",
  62. type: "number",
  63. value: "0",
  64. placeholder: "订单金额",
  65. valueName: "amount",
  66. required: false,
  67. checking: "base",
  68. disabled: true
  69. },
  70. {
  71. label: "备注",
  72. error: false,
  73. errMsg: "",
  74. type: "textarea",
  75. value: "",
  76. placeholder: "请输入备注",
  77. valueName: "remarks",
  78. required: false,
  79. checking: "base"
  80. }
  81. ],
  82. "content": {
  83. "sa_custorderid": 0,
  84. "sa_customersid": 0,
  85. }
  86. },
  87. onLoad(options) {
  88. getApp().globalData.setCustomer = this.setCustomer.bind(this);
  89. // 如果传递了客户信息,填充到表单
  90. try {
  91. const customerInfo = getCurrentPages().find(v => v.__route__ == 'CRM/customer/detail').data.detail;
  92. let form = this.data.form;
  93. // 填充客户信息到表单
  94. form.forEach(item => {
  95. if (item.valueName === 'name' && customerInfo.name) {
  96. item.value = [customerInfo.name, [customerInfo.sa_customersid]];
  97. item.disabled = true;
  98. }
  99. if (item.valueName === 'storename' && customerInfo.storename) {
  100. item.value = customerInfo.storename;
  101. }
  102. });
  103. this.setData({
  104. form,
  105. "content.sa_storeid": customerInfo.sa_storeid,
  106. "content.storeno": customerInfo.storeno,
  107. "content.sa_customersid": customerInfo.sa_customersid,
  108. });
  109. } catch (error) {
  110. console.error("解析客户信息失败", error);
  111. // 从订单列表页面跳转过来,需要选择客户
  112. this.selectCustomer();
  113. }
  114. // 设置默认开单日期为当天
  115. const today = new Date().toISOString().split('T')[0];
  116. let form = this.data.form;
  117. form.forEach(item => {
  118. if (item.valueName === 'billdate') {
  119. item.value = today;
  120. this.setData({
  121. "content.billdate": today
  122. });
  123. }
  124. });
  125. this.setData({
  126. form
  127. });
  128. },
  129. // 选择客户
  130. selectCustomer() {
  131. // 设置全局回调函数
  132. wx.navigateTo({
  133. url: "/CRM/customer/index?selectMode=true"
  134. });
  135. },
  136. // 设置客户信息
  137. setCustomer(customerInfo) {
  138. this.setData({
  139. "content.sa_storeid": customerInfo.sa_storeid,
  140. "content.storeno": customerInfo.storeno,
  141. "content.sa_customersid": customerInfo.sa_customersid,
  142. "content.name": customerInfo.name || '',
  143. "content.storename": customerInfo.storename || ''
  144. });
  145. // 更新表单数据
  146. let form = this.data.form;
  147. form.forEach(item => {
  148. if (item.valueName === 'name') {
  149. item.value = [customerInfo.name, [customerInfo.sa_customersid]];
  150. }
  151. if (item.valueName === 'storename') {
  152. item.value = customerInfo.storename || '';
  153. }
  154. });
  155. this.setData({
  156. form
  157. });
  158. },
  159. // 切换客户
  160. switchCustomer() {
  161. this.selectCustomer();
  162. },
  163. submit() {
  164. // 检查是否有商品
  165. if (this.data.productList.length === 0) {
  166. this.addProduct();
  167. wx.showToast({
  168. title: '请先添加商品',
  169. icon: 'none'
  170. });
  171. return;
  172. }
  173. this.setData({
  174. loading: true
  175. });
  176. let formData = this.selectComponent("#Form").submit();
  177. delete formData.name
  178. if (!formData) {
  179. this.setData({
  180. loading: false
  181. });
  182. return;
  183. }
  184. let content = {
  185. ...this.data.content,
  186. ...formData
  187. };
  188. // 先创建订单
  189. _Http.basic({
  190. "id": "2026031309441701", // 创建订单的接口ID
  191. content
  192. }).then(res => {
  193. console.log("保存订单", res);
  194. if (res.code == 1) {
  195. const orderId = res.data;
  196. console.log("订单ID", orderId);
  197. // 显示加载提示
  198. wx.showLoading({
  199. title: '正在处理...',
  200. mask: true
  201. });
  202. // 准备绑定操作
  203. const promises = [];
  204. // 绑定商品
  205. if (this.data.productList.length > 0) {
  206. promises.push(this.bindProductsWithPromise(orderId));
  207. }
  208. // 绑定附件
  209. const attachmentids = this.selectComponent("#Yl_files").getFiles().attachmentids;
  210. if (attachmentids && attachmentids.length > 0) {
  211. promises.push(this.bindAttachmentsWithPromise(orderId, attachmentids));
  212. }
  213. // 使用Promise.all处理所有绑定操作
  214. Promise.all(promises).then(() => {
  215. // 所有绑定完成,跳转到订单详情
  216. this.navigateToOrderDetail(orderId);
  217. }).catch(() => {
  218. // 绑定失败,跳转到订单详情
  219. this.navigateToOrderDetail(orderId);
  220. });
  221. } else {
  222. this.setData({
  223. loading: false
  224. });
  225. wx.showToast({
  226. title: res.msg || '保存失败',
  227. icon: 'none'
  228. });
  229. }
  230. }).catch(err => {
  231. this.setData({
  232. loading: false
  233. });
  234. console.error("保存订单失败", err);
  235. wx.showToast({
  236. title: '网络错误',
  237. icon: 'none'
  238. });
  239. });
  240. },
  241. // 使用Promise.all绑定商品
  242. bindProductsWithPromise(orderId) {
  243. const productList = this.data.productList;
  244. // 创建商品绑定的Promise数组
  245. const bindPromises = productList.map(product => {
  246. return new Promise((resolve, reject) => {
  247. _Http.basic({
  248. "id": "2026031415462301", // 绑定商品接口ID
  249. content: {
  250. sa_custorderid: orderId,
  251. sa_custorderitemsid: 0,
  252. sys_enterprise_itemid: product.sys_enterprise_itemid || product.itemid,
  253. qty: product.qty,
  254. oldprice: product.originalPrice || product.price,
  255. discountrate: product.discount,
  256. price: product.price,
  257. amount: product.amount,
  258. remarks: product.remarks || ""
  259. }
  260. }).then(res => {
  261. if (res.code != 1) {
  262. console.error("绑定商品失败", res);
  263. }
  264. resolve(res);
  265. }).catch(err => {
  266. console.error("绑定商品失败", err);
  267. resolve(null); // 即使失败也继续处理
  268. });
  269. });
  270. });
  271. // 处理附件绑定(预留接口)
  272. const attachmentPromise = this.bindAttachmentsWithPromise(orderId);
  273. // 合并所有Promise
  274. const allPromises = [...bindPromises, attachmentPromise];
  275. // 使用Promise.all处理所有请求
  276. return Promise.all(allPromises);
  277. },
  278. // 绑定附件
  279. bindAttachmentsWithPromise(orderId, attachmentids) {
  280. return new Promise((resolve) => {
  281. if (!attachmentids || attachmentids.length === 0) {
  282. resolve(null);
  283. return;
  284. }
  285. _Http.basic({
  286. "classname": "system.attachment.Attachment",
  287. "method": "createFileLink",
  288. id: 10020501,
  289. "content": {
  290. ownertable: "sa_custorder",
  291. ownerid: orderId,
  292. usetype: 'default',
  293. attachmentids
  294. }
  295. }).then(res => {
  296. console.log('绑定附件', res);
  297. if (res.code == 1) {
  298. resolve(res.data);
  299. } else {
  300. console.error('绑定附件失败', res);
  301. resolve(); // 绑定失败也继续执行
  302. }
  303. }).catch(err => {
  304. console.error('绑定附件错误', err);
  305. resolve(); // 错误也继续执行
  306. });
  307. });
  308. },
  309. // 跳转到订单详情
  310. navigateToOrderDetail(orderId) {
  311. // 隐藏加载提示
  312. wx.hideLoading();
  313. this.setData({
  314. loading: false
  315. });
  316. wx.redirectTo({
  317. url: `/CRM/order/detail?id=${orderId}`,
  318. success: () => {
  319. // 跳转到订单详情页面
  320. wx.showToast({
  321. title: "开单成功",
  322. icon: "none",
  323. duration: 1500,
  324. });
  325. }
  326. });
  327. },
  328. interrupt({
  329. detail
  330. }) {
  331. // 处理中断逻辑,如果需要的话
  332. },
  333. /* 表单必填项是否完成 */
  334. onConfirm({
  335. detail
  336. }) {
  337. this.setData({
  338. disabled: detail
  339. });
  340. },
  341. onChange(e) {
  342. this.setData({
  343. showAll: e.detail
  344. });
  345. },
  346. closePage() {
  347. wx.navigateBack({
  348. delta: 1
  349. });
  350. },
  351. // tab切换
  352. onTabChange(e) {
  353. this.setData({
  354. activeTab: e.detail
  355. });
  356. },
  357. // 打开添加商品面板
  358. addProduct() {
  359. // 直接跳转到产品选择页面
  360. wx.navigateTo({
  361. url: `/CRM/customer/modules/orderCreate/productSelect/index?params=${JSON.stringify({
  362. "id": "2026031312441901",
  363. "content": {
  364. "pageNumber": 1,
  365. "pageSize": 20,
  366. "where": {
  367. "tablefilter": {
  368. "itemname": null,
  369. "itemno": null,
  370. "model": null,
  371. "guid_price": null,
  372. "guid_price_cus": null,
  373. "packageqty": null
  374. }
  375. }
  376. }
  377. })}&butText=添加商品`
  378. });
  379. // 设置全局回调函数
  380. getApp().globalData.handleSelect = this.handleSelect.bind(this);
  381. },
  382. // 处理选择商品回调
  383. handleSelect(detail) {
  384. if (detail && detail.list) {
  385. const existingItemIds = this.data.productList.map(item => item.sys_enterprise_itemid);
  386. // 过滤掉已经存在的商品
  387. const newProducts = detail.list.filter(item => !existingItemIds.includes(item.sys_enterprise_itemid)).map(item => {
  388. // 处理价格字段,去除格式化符号
  389. const priceStr = item.guid_price_cus || item.price || "0";
  390. const price = parseFloat(priceStr.toString().replace(/[¥,]/g, '')) || 0;
  391. const qty = parseInt(item.qty) || 1;
  392. return {
  393. itemid: item.itemid,
  394. sys_enterprise_itemid: item.sys_enterprise_itemid,
  395. itemname: item.itemname,
  396. itemno: item.itemno,
  397. model: item.model,
  398. originalPrice: price,
  399. price: price,
  400. discount: 1,
  401. qty: qty,
  402. amount: parseFloat((price * qty * 1).toFixed(2)),
  403. remarks: item.remarks || ''
  404. };
  405. });
  406. if (newProducts.length > 0) {
  407. this.setData({
  408. productList: [...this.data.productList, ...newProducts]
  409. });
  410. // 更新订单金额
  411. this.updateOrderAmount();
  412. } else {
  413. wx.showToast({
  414. title: '所选商品已在列表中',
  415. icon: 'none'
  416. });
  417. }
  418. // 返回页面
  419. wx.navigateBack();
  420. }
  421. },
  422. // 处理字段编辑
  423. onFieldBlur(e) {
  424. const index = e.currentTarget.dataset.index;
  425. const field = e.currentTarget.dataset.field;
  426. const value = e.detail.value;
  427. const productList = [...this.data.productList];
  428. const product = productList[index];
  429. // 处理不同字段的编辑
  430. switch (field) {
  431. case 'price':
  432. product.price = parseFloat(value) || 0;
  433. // 重新计算金额,保留两位小数,折扣1=100%
  434. product.amount = parseFloat((product.price * product.qty * product.discount).toFixed(2));
  435. break;
  436. case 'discount':
  437. product.discount = parseFloat(value) || 1;
  438. // 重新计算金额,保留两位小数,折扣1=100%
  439. product.amount = parseFloat((product.price * product.qty * product.discount).toFixed(2));
  440. break;
  441. case 'qty':
  442. let qty = parseInt(value) || 1;
  443. // 数量不能为0
  444. qty = Math.max(1, qty);
  445. product.qty = qty;
  446. // 重新计算金额,保留两位小数,折扣1=100%
  447. product.amount = parseFloat((product.price * product.qty * product.discount).toFixed(2));
  448. break;
  449. case 'amount':
  450. product.amount = parseFloat(value) || 0;
  451. // 重新计算单价(假设数量和折扣不变),保留两位小数,折扣1=100%
  452. if (product.qty > 0 && product.discount > 0) {
  453. product.price = parseFloat((product.amount / (product.qty * product.discount)).toFixed(2));
  454. }
  455. break;
  456. case 'remarks':
  457. product.remarks = value;
  458. break;
  459. }
  460. this.setData({
  461. productList
  462. });
  463. // 更新订单金额
  464. this.updateOrderAmount();
  465. },
  466. // 删除商品
  467. deleteProduct(e) {
  468. wx.showModal({
  469. title: '提示',
  470. content: '确定要删除这个商品吗?',
  471. confirmText: '确定',
  472. cancelText: '取消',
  473. success: (res) => {
  474. if (res.confirm) {
  475. const index = e.currentTarget.dataset.index;
  476. const productList = [...this.data.productList];
  477. productList.splice(index, 1);
  478. this.setData({
  479. productList
  480. });
  481. // 更新订单金额
  482. this.updateOrderAmount();
  483. }
  484. }
  485. });
  486. },
  487. // 更新订单金额
  488. updateOrderAmount() {
  489. // 计算总金额,确保不是NaN,默认0
  490. const totalAmount = parseFloat(this.data.productList.reduce((sum, item) => {
  491. const amount = parseFloat(item.amount) || 0;
  492. return sum + amount;
  493. }, 0)) || 0;
  494. // 计算总数量,所有商品数量的总计
  495. const totalQty = this.data.productList.reduce((sum, item) => {
  496. const qty = parseInt(item.qty) || 0;
  497. return sum + qty;
  498. }, 0);
  499. const form = [...this.data.form];
  500. form.forEach(item => {
  501. if (item.valueName === 'amount') {
  502. item.value = totalAmount.toString();
  503. this.setData({
  504. "content.amount": totalAmount
  505. });
  506. }
  507. if (item.valueName === 'orderCount') {
  508. item.value = totalQty.toString();
  509. this.setData({
  510. "content.orderCount": totalQty
  511. });
  512. }
  513. });
  514. this.setData({
  515. form
  516. });
  517. },
  518. // 处理上传状态
  519. changeState({
  520. detail
  521. }) {
  522. this.setData({
  523. loading: detail
  524. });
  525. },
  526. // 处理文件上传回调
  527. handleFileUpload({
  528. detail
  529. }) {
  530. console.log("detail", detail)
  531. Promise.all(detail.map(attachmentid => {
  532. return _Http.basic({
  533. "id": 2024061710590401,
  534. "content": {
  535. "pageSize": 1,
  536. "pageNumber": 1,
  537. "attachmentid": attachmentid
  538. }
  539. })
  540. })).then(res => {
  541. console.log('获取文件详情', res);
  542. this.selectComponent("#Yl_files").handleFiles(res.map(v => v.data[0]))
  543. })
  544. },
  545. });