user.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. import { defineStore } from 'pinia'
  2. import { dayjs } from 'wot-design-uni'
  3. import { REDIRECT_URL, StaticUrl } from '@/config'
  4. import router from '@/router'
  5. import type { wxpay } from '@/api/globals'
  6. interface userStroe {
  7. token: string
  8. /**
  9. * 重定向路由名称
  10. */
  11. redirectName: string
  12. /**
  13. * 用户登录信息
  14. */
  15. userInfo: Api.userInfo
  16. /**
  17. * 用户收货地址
  18. */
  19. addresses: Api.addressList[]
  20. /**
  21. * 星闪爆用户选择的收货地址
  22. *
  23. */
  24. selectedAddress: Api.addressList | null
  25. /**
  26. * 市民请集合购物车用户选中的收货地址
  27. */
  28. smqjhSelectedAddress: Api.addressList | null
  29. /**
  30. * 用户会员信息
  31. */
  32. userMemberInfo: Api.userMemberInfo
  33. }
  34. export const useUserStore = defineStore('user', {
  35. state: (): userStroe => ({
  36. token: '',
  37. redirectName: '',
  38. userInfo: {
  39. id: 0,
  40. channelId: 0,
  41. channelName: '',
  42. },
  43. addresses: [],
  44. selectedAddress: null,
  45. smqjhSelectedAddress: null,
  46. userMemberInfo: {
  47. active: false,
  48. isFirstLogin: false,
  49. expireTime: undefined,
  50. },
  51. }),
  52. getters: {
  53. getUserAvatar(): string {
  54. if (this.userInfo.avatarUrl) {
  55. return this.userInfo.avatarUrl
  56. }
  57. return `${StaticUrl}/avator.png`
  58. },
  59. },
  60. actions: {
  61. async getUserInfo() {
  62. if (this.token) {
  63. const { data } = await api.sys.userInfo({})
  64. this.userInfo = data
  65. await this.getUserMemberInfo()
  66. await this.getuserAddresslist()
  67. this.getSelectedAddress()
  68. await useSmqjhCartStore().getCartList('XSB')
  69. }
  70. },
  71. /**
  72. * 获取用户会员信息
  73. */
  74. async getUserMemberInfo() {
  75. if (this.token) {
  76. const { data } = await Apis.sys.userVipInfo({})
  77. this.userMemberInfo = data
  78. }
  79. },
  80. async updataUserInfo(data: Api.userInfo) {
  81. uni.showLoading({ mask: true })
  82. await Apis.sys.updateUserInfo({ pathParams: { memberId: data.id }, data })
  83. uni.hideLoading()
  84. useGlobalToast().show({ msg: '修改成功' })
  85. this.getUserInfo()
  86. },
  87. /**
  88. * 获取用户收货地址列表
  89. */
  90. async getuserAddresslist() {
  91. return new Promise((resolve, reject) => {
  92. uni.showLoading({ mask: true })
  93. Apis.sys.addresses({}).then((res) => {
  94. this.addresses = res.data || []
  95. resolve(res)
  96. }).catch(err => reject(err)).finally(() => uni.hideLoading())
  97. })
  98. },
  99. /**
  100. *
  101. * 更新用户选择的收货地址
  102. */
  103. updateSelectedAddress(address: Api.addressList) {
  104. this.selectedAddress = address
  105. },
  106. /**
  107. * 获取用户收货地址
  108. * @description 默认选择默认地址,如无默认地址则不选择
  109. */
  110. getSelectedAddress() {
  111. this.selectedAddress = this.addresses.find(it => it.defaulted === 1) ?? null
  112. },
  113. /**
  114. * 获取市民请集合购物车用户选择的收货地址
  115. * @description 默认选择默认地址,如无默认地址则不选择
  116. */
  117. getSmqjhSelectedAddress() {
  118. this.smqjhSelectedAddress = this.addresses.find(it => it.defaulted === 1) ?? null
  119. },
  120. /**
  121. * 更新市民请集合购物车用户选择的收货地址
  122. */
  123. updateSmqjhSelectedAddress(address: Api.addressList) {
  124. this.smqjhSelectedAddress = address
  125. },
  126. /**
  127. * 检测当前用户是否登录,如果没有登录弹窗提示未登录
  128. */
  129. checkLogin() {
  130. return new Promise((resolve, reject) => {
  131. if (!this.token) {
  132. useGlobalMessage().confirm({
  133. title: '提示',
  134. msg: '检测到当前状态未登录,是否登录',
  135. confirmButtonText: '登录',
  136. cancelButtonText: '取消',
  137. zIndex: 99999999999,
  138. success() {
  139. router.replace({ name: 'smqjh-login' })
  140. setTimeout(() => { // 延迟1秒后抛错,防止立马抛错之后用户立即点击按钮会重复跳转登录页面
  141. reject(new Error('未登录'))
  142. }, 1000)
  143. },
  144. fail() {
  145. reject(new Error('未登录'))
  146. },
  147. })
  148. }
  149. else {
  150. resolve(1)
  151. }
  152. })
  153. },
  154. /**
  155. * 通用支付逻辑
  156. * @param orderNumber
  157. * @returns
  158. */
  159. handleCommonPayMent(orderNumber: string): Promise<wxpay> {
  160. return new Promise((resolve, reject) => {
  161. if (!orderNumber) {
  162. useGlobalToast().show({ msg: '订单号为空!请联系管理员' })
  163. reject(new Error('订单号为空!请联系管理员'))
  164. return
  165. }
  166. uni.showLoading({ mask: true })
  167. Apis.common.hybridPayment({ data: { orderNumber } }).then((res) => {
  168. resolve(res.data)
  169. uni.hideLoading()
  170. }).catch((err) => {
  171. uni.hideLoading()
  172. reject(err)
  173. })
  174. })
  175. },
  176. /**
  177. * H5支付后轮询通用订单支付状态
  178. * @param orderNumber 订单号
  179. * @param interval 轮询间隔,默认3秒
  180. * @param timeout 超时时间,默认90秒
  181. */
  182. async pollOrderPaySuccess(orderNumber: string, interval = 3000, timeout = 90000): Promise<boolean> {
  183. if (!orderNumber) {
  184. useGlobalToast().show({ msg: '订单号为空!请联系管理员' })
  185. return false
  186. }
  187. const startedAt = Date.now()
  188. const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms))
  189. while (Date.now() - startedAt <= timeout) {
  190. try {
  191. const res = await Apis.xsb.orderInfo({
  192. data: {
  193. orderNo: orderNumber,
  194. },
  195. })
  196. const orderInfo = res.data
  197. if (orderInfo?.isPayed === 1 || (orderInfo?.hbOrderStatus !== undefined && orderInfo.hbOrderStatus !== OrderStatus.PaddingPay)) {
  198. return true
  199. }
  200. }
  201. catch (error) {
  202. console.error('轮询订单支付状态失败', error)
  203. }
  204. if (Date.now() - startedAt + interval > timeout)
  205. break
  206. await sleep(interval)
  207. }
  208. return false
  209. }, /**
  210. *
  211. * @param freightFee
  212. * @param businessType
  213. * @param dvyType 配送类型 1:快递 2:自提 3:及时配送
  214. * @param shopId
  215. * @param orderItemList
  216. * @param remarks
  217. * @param allowanceId
  218. * @returns 下单获取待支付订单号
  219. */
  220. getOrderPayMent(freightFee: number, businessType: string, dvyType: number, shopId: number, orderItemList: {
  221. prodCount?: number
  222. skuId?: number
  223. }[], remarks?: string, allowanceId?: string, pickupInfo?: {
  224. consigneeName?: string
  225. consigneeMobile?: string
  226. }): Promise<string> {
  227. uni.showLoading({ mask: true })
  228. return new Promise((resolve, reject) => {
  229. if (dvyType !== 2 && !this.selectedAddress) {
  230. uni.hideLoading()
  231. reject(new Error('请选择收货地址'))
  232. return
  233. }
  234. const orderData = {
  235. channelId: Number(this.userInfo.channelId),
  236. businessType,
  237. addressId: Number(this.selectedAddress?.id),
  238. dvyType,
  239. freightAmount: freightFee,
  240. shopId,
  241. orderItemList,
  242. remarks,
  243. allowanceIds: allowanceId ? [allowanceId] : [],
  244. ...pickupInfo,
  245. }
  246. Apis.common.addOrder({
  247. data: orderData,
  248. }).then((res) => {
  249. resolve(res.data)
  250. uni.hideLoading()
  251. }).catch((err) => {
  252. uni.hideLoading()
  253. reject(err)
  254. })
  255. })
  256. },
  257. /**
  258. *
  259. * @param orderInfo
  260. * @returns 统一拉起微信支付
  261. * @param type 0是下单,1是列表下单
  262. */
  263. getWxCommonPayment(orderPay: wxpay) {
  264. uni.showLoading({ mask: true })
  265. return new Promise((resolve, reject) => {
  266. const orderInfo = {
  267. appid: orderPay.appId,
  268. timeStamp: orderPay.timeStamp,
  269. nonceStr: orderPay.nonceStr,
  270. package: orderPay.package,
  271. signType: orderPay.signType,
  272. paySign: orderPay.paySign,
  273. }
  274. uni.requestPayment({
  275. provider: 'wxpay',
  276. orderInfo,
  277. ...orderInfo,
  278. success: (res) => {
  279. resolve(res)
  280. },
  281. fail: (e) => {
  282. reject(e)
  283. },
  284. complete() {
  285. uni.hideLoading()
  286. },
  287. })
  288. })
  289. },
  290. /**
  291. *
  292. * 支付成功统一跳转
  293. * @param name 订单列表
  294. * @param idxPath 首页路径
  295. *
  296. */
  297. paySuccess(name: string, idxPath: string) {
  298. return new Promise((resolve) => {
  299. useSysStore().setPaySuccessPath(name, idxPath)
  300. router.replace({ name: 'common-paySuccess' })
  301. setTimeout(() => {
  302. resolve(1)
  303. }, 2000)
  304. })
  305. },
  306. /**
  307. *
  308. * 支付失败统一跳转
  309. * @param name 订单列表
  310. * @param idxPath 首页路径
  311. */
  312. payError(name: string, idxPath: string) {
  313. return new Promise((resolve) => {
  314. useSysStore().setPaySuccessPath(name, idxPath)
  315. router.replace({ name: 'common-payError' })
  316. setTimeout(() => {
  317. resolve(1)
  318. }, 2000)
  319. })
  320. }, /**
  321. * 支付成功清空购买的商品的购物车
  322. */
  323. clearCart(skuList: Api.CartSkuVo[]) {
  324. uni.showLoading({ mask: true })
  325. return new Promise((resolve) => {
  326. const skuids = skuList.map(item => item.id).join(',')
  327. if (skuids.length) {
  328. console.log(skuids, '执行中')
  329. Apis.common.deleteShoppingCart({
  330. pathParams: {
  331. ids: skuids,
  332. },
  333. }).then(async (res) => {
  334. resolve(res)
  335. await useSmqjhCartStore().getCartList('XSB')
  336. uni.hideLoading()
  337. }).finally(() => resolve(1))
  338. }
  339. else {
  340. resolve(1)
  341. uni.hideLoading()
  342. }
  343. })
  344. },
  345. /**
  346. * 统一确认收货
  347. * @param order
  348. * @returns
  349. */
  350. handleCommonOrderReceive(order: Api.xsbOrderList) {
  351. return new Promise((resolve, reject) => {
  352. useGlobalMessage().confirm({
  353. title: '确认收货',
  354. msg: '确定要确认收货吗?',
  355. zIndex: 99999999999999,
  356. success: async () => {
  357. uni.showLoading({ mask: true })
  358. await Apis.xsb.confirmReceipt({
  359. data: {
  360. orderNumber: String(order.orderNumber),
  361. },
  362. })
  363. resolve(1)
  364. },
  365. fail: err => reject(err),
  366. })
  367. })
  368. },
  369. /**
  370. * 统一删除订单
  371. * @param order
  372. * @returns
  373. */
  374. handleCommonDeleteOrder(order: Api.xsbOrderList) {
  375. return new Promise((resolve, reject) => {
  376. useGlobalMessage().confirm({
  377. title: '删除订单',
  378. msg: '确定要删除该订单吗?',
  379. zIndex: 99999999999999,
  380. success: async () => {
  381. uni.showLoading({ mask: true })
  382. Apis.xsb.deleteOrder({
  383. pathParams: {
  384. ids: String(order.orderId),
  385. },
  386. }).then(res => resolve(res)).catch(err => reject(err)).finally(() => uni.hideLoading())
  387. },
  388. fail: async (err) => {
  389. reject(err)
  390. },
  391. })
  392. })
  393. },
  394. /**
  395. * 统一取消订单
  396. * @param order
  397. * @returns
  398. */
  399. handleCommonCancelOrder(order: Api.xsbOrderList) {
  400. return new Promise((resolve, reject) => {
  401. useGlobalMessage().confirm({
  402. title: '取消订单',
  403. msg: '确定要取消订单吗?',
  404. zIndex: 99999999999999,
  405. success: async () => {
  406. uni.showLoading({ mask: true })
  407. Apis.xsb.cancelOrder({
  408. data: {
  409. orderNo: String(order.orderNumber),
  410. },
  411. }).then(res => resolve(res)).catch(err => reject(err)).finally(() => uni.hideLoading())
  412. },
  413. fail: async (err) => {
  414. reject(err)
  415. },
  416. })
  417. })
  418. },
  419. handleXSBCommonOrderStatusText(order: Api.xsbOrderList): any {
  420. if (order.hbOrderStatus === OrderStatus.PaddingPay) {
  421. const endTime = dayjs(order.createTime).add(16, 'minutes')
  422. const remaining = dayjs(endTime).valueOf() - dayjs().valueOf()
  423. return Math.max(0, remaining) // 确保不会返回负数
  424. }
  425. if (order.hbOrderStatus === OrderStatus.OrderAccepted) {
  426. return '订单已接单'
  427. }
  428. if (order.hbOrderStatus === OrderStatus.OrderWaitDelivery) {
  429. return '订单待配送'
  430. }
  431. if (order.hbOrderStatus === OrderStatus.OrderDelivering) {
  432. return '订单配送中'
  433. }
  434. if (order.hbOrderStatus === OrderStatus.OrderCancelAudit) {
  435. return '订单取消审核'
  436. }
  437. if (order.hbOrderStatus === OrderStatus.OrderCancel) {
  438. return '订单取消'
  439. }
  440. if (order.hbOrderStatus === OrderStatus.OrderArrived) {
  441. return '订单已送达'
  442. }
  443. if (order.hbOrderStatus === OrderStatus.OrderCompleted) {
  444. return '订单完成'
  445. }
  446. return '未知订单状态'
  447. },
  448. handleFilmCommonOrderStatusText(order: Api.xsbOrderList): any {
  449. if (order.hbOrderStatus === OrderStatus.PaddingPay) {
  450. const endTime = dayjs(order.createTime).add(16, 'minutes')
  451. const remaining = dayjs(endTime).valueOf() - dayjs().valueOf()
  452. return Math.max(0, remaining) // 确保不会返回负数
  453. }
  454. if (order.hbOrderStatus === OrderStatus.OrderAccepted) {
  455. return '待出票'
  456. }
  457. if (order.hbOrderStatus === OrderStatus.OrderWaitDelivery) {
  458. return '订单待配送'
  459. }
  460. if (order.hbOrderStatus === OrderStatus.OrderDelivering) {
  461. return '出票中'
  462. }
  463. if (order.hbOrderStatus === OrderStatus.OrderCancelAudit) {
  464. return '订单取消审核'
  465. }
  466. if (order.hbOrderStatus === OrderStatus.OrderCancel) {
  467. return '订单取消'
  468. }
  469. if (order.hbOrderStatus === OrderStatus.OrderArrived) {
  470. return '订单完成'
  471. }
  472. if (order.hbOrderStatus === OrderStatus.OrderCompleted) {
  473. return '订单完成'
  474. }
  475. return '未知订单状态'
  476. },
  477. handleDjkCommonOrderStatusText(order: Api.xsbOrderList) {
  478. const textMap = {
  479. [OrderStatus.OrderAccepted]: '待使用',
  480. [OrderStatus.OrderCompleted]: '已完成',
  481. [OrderStatus.OrderCancel]: '已取消',
  482. [OrderStatus.OrderRefund]: '已退款',
  483. [OrderStatus.OrderExpired]: '已过期',
  484. }
  485. return textMap[order.hbOrderStatus as keyof typeof textMap] || '未知订单状态'
  486. },
  487. async getOrderNode(orderNumber: string) {
  488. uni.showLoading({
  489. mask: true,
  490. })
  491. return new Promise((resolve, reject) => {
  492. Apis.xsb.deliveryNode({
  493. data: {
  494. orderNumber,
  495. },
  496. }).then((res) => {
  497. // NodeList.value = res.data
  498. resolve(res.data)
  499. }).catch((err) => {
  500. reject(err)
  501. }).finally(() => uni.hideLoading())
  502. })
  503. },
  504. /**
  505. *
  506. * @param _item 兑换的券 加油
  507. */
  508. async handleExchange(_item: any) {
  509. uni.showLoading({ mask: true })
  510. try {
  511. const res = await Apis.app.get_smqjh_system_app_api_coupon_exchangepoints({ params: { couponId: _item.id } })
  512. uni.hideLoading()
  513. // 兑换成功,跳转成功页
  514. router.push({
  515. name: 'exchangeSuccess',
  516. params: {
  517. couponId: res.data?.id || _item.id,
  518. batchNo: res.data?.batchId || '',
  519. expireDays: res.data?.expirationDate || _item.expirationDate,
  520. discountMoney: res.data?.discountMoney || _item.discountMoney,
  521. amountMoney: res.data?.amountMoney || _item.amountMoney,
  522. },
  523. })
  524. }
  525. catch (error: any) {
  526. console.log(error)
  527. uni.hideLoading()
  528. // 兑换失败,跳转失败页
  529. router.push({
  530. name: 'exchangeFail',
  531. params: {
  532. failReason: error?.message || '兑换失败,请稍后重试',
  533. },
  534. })
  535. }
  536. },
  537. /**
  538. * 拉起小橘支付
  539. * @param path
  540. */
  541. handleCommonPath(path: string) {
  542. uni.showLoading({ mask: true })
  543. const url = REDIRECT_URL
  544. window.location.href = `${path}&redirectUrl=${url}`
  545. uni.hideLoading()
  546. },
  547. async handleCommonGoXiaoJuPay(orderNumber: string) {
  548. try {
  549. const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_findbypayurl({ params: { orderNumber } })
  550. this.handleCommonPath(res.data as string)
  551. }
  552. catch (error) {
  553. console.log(error)
  554. useGlobalToast().show('获取支付信息失败')
  555. }
  556. },
  557. /**
  558. * 加油统一取消订单
  559. * @param orderNumber
  560. * @returns
  561. */
  562. async handleCommonCancelOrderJY(orderNumber: string) {
  563. try {
  564. const res = await Apis.xsb.cancelOrder({ data: { orderNo: orderNumber } })
  565. return res
  566. }
  567. catch (error) {
  568. console.log(error)
  569. useGlobalToast().show('取消订单失败')
  570. }
  571. },
  572. /**
  573. * h5专属。小程序不可调用
  574. * h5第三方统一拉起微信支付跳转路径及参数
  575. * @param orderNumber
  576. */
  577. handleCommonWechatPay(orderNumber: string, model: string = 'mixture') {
  578. // #ifdef H5
  579. uni.showLoading({ mask: true })
  580. const query = {
  581. orderNumber,
  582. phone: String(this.userInfo.mobile),
  583. model,
  584. tenantCode: useSysStore().tenantCode,
  585. }
  586. const queryString = Object.entries(query)
  587. .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
  588. .join('&')
  589. const path = 'subPack-common/threePay/index'
  590. // const env = 'develop'
  591. // const env = 'trial'
  592. const env = 'release'
  593. window.location.href = `weixin://dl/business/?appid=wx43b5b906cc30ed0b&path=${path}&query=${encodeURIComponent(queryString)}&env_version=${env}`
  594. uni.hideLoading()
  595. // #endif
  596. },
  597. async getPayMent(orderNumber: string): Promise<{ payType: 'point' | 'hybrid' | 'wx' }> {
  598. return new Promise((resolve, reject) => {
  599. Apis.common.hybridPaymentType({ data: { orderNumber } })
  600. .then((res) => {
  601. resolve(res.data)
  602. })
  603. .catch((err) => {
  604. reject(err)
  605. })
  606. })
  607. },
  608. },
  609. })