user.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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. }, isFreeShipping?: boolean): 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: any = {
  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. if (isFreeShipping) {
  247. orderData.isFreeShipping = 1
  248. }
  249. Apis.common.addOrder({
  250. data: orderData,
  251. }).then((res) => {
  252. resolve(res.data)
  253. uni.hideLoading()
  254. }).catch((err) => {
  255. uni.hideLoading()
  256. reject(err)
  257. })
  258. })
  259. },
  260. /**
  261. *
  262. * @param orderInfo
  263. * @returns 统一拉起微信支付
  264. * @param type 0是下单,1是列表下单
  265. */
  266. getWxCommonPayment(orderPay: wxpay) {
  267. uni.showLoading({ mask: true })
  268. return new Promise((resolve, reject) => {
  269. const orderInfo = {
  270. appid: orderPay.appId,
  271. timeStamp: orderPay.timeStamp,
  272. nonceStr: orderPay.nonceStr,
  273. package: orderPay.package,
  274. signType: orderPay.signType,
  275. paySign: orderPay.paySign,
  276. }
  277. uni.requestPayment({
  278. provider: 'wxpay',
  279. orderInfo,
  280. ...orderInfo,
  281. success: (res) => {
  282. resolve(res)
  283. },
  284. fail: (e) => {
  285. reject(e)
  286. },
  287. complete() {
  288. uni.hideLoading()
  289. },
  290. })
  291. })
  292. },
  293. /**
  294. *
  295. * 支付成功统一跳转
  296. * @param name 订单列表
  297. * @param idxPath 首页路径
  298. *
  299. */
  300. paySuccess(name: string, idxPath: string) {
  301. return new Promise((resolve) => {
  302. useSysStore().setPaySuccessPath(name, idxPath)
  303. router.replace({ name: 'common-paySuccess' })
  304. setTimeout(() => {
  305. resolve(1)
  306. }, 2000)
  307. })
  308. },
  309. /**
  310. *
  311. * 支付失败统一跳转
  312. * @param name 订单列表
  313. * @param idxPath 首页路径
  314. */
  315. payError(name: string, idxPath: string) {
  316. return new Promise((resolve) => {
  317. useSysStore().setPaySuccessPath(name, idxPath)
  318. router.replace({ name: 'common-payError' })
  319. setTimeout(() => {
  320. resolve(1)
  321. }, 2000)
  322. })
  323. }, /**
  324. * 支付成功清空购买的商品的购物车
  325. */
  326. clearCart(skuList: Api.CartSkuVo[]) {
  327. uni.showLoading({ mask: true })
  328. return new Promise((resolve) => {
  329. const skuids = skuList.map(item => item.id).join(',')
  330. if (skuids.length) {
  331. console.log(skuids, '执行中')
  332. Apis.common.deleteShoppingCart({
  333. pathParams: {
  334. ids: skuids,
  335. },
  336. }).then(async (res) => {
  337. resolve(res)
  338. await useSmqjhCartStore().getCartList('XSB')
  339. uni.hideLoading()
  340. }).finally(() => resolve(1))
  341. }
  342. else {
  343. resolve(1)
  344. uni.hideLoading()
  345. }
  346. })
  347. },
  348. /**
  349. * 统一确认收货
  350. * @param order
  351. * @returns
  352. */
  353. handleCommonOrderReceive(order: Api.xsbOrderList) {
  354. return new Promise((resolve, reject) => {
  355. useGlobalMessage().confirm({
  356. title: '确认收货',
  357. msg: '确定要确认收货吗?',
  358. zIndex: 99999999999999,
  359. success: async () => {
  360. uni.showLoading({ mask: true })
  361. await Apis.xsb.confirmReceipt({
  362. data: {
  363. orderNumber: String(order.orderNumber),
  364. },
  365. })
  366. resolve(1)
  367. },
  368. fail: err => reject(err),
  369. })
  370. })
  371. },
  372. /**
  373. * 统一删除订单
  374. * @param order
  375. * @returns
  376. */
  377. handleCommonDeleteOrder(order: Api.xsbOrderList) {
  378. return new Promise((resolve, reject) => {
  379. useGlobalMessage().confirm({
  380. title: '删除订单',
  381. msg: '确定要删除该订单吗?',
  382. zIndex: 99999999999999,
  383. success: async () => {
  384. uni.showLoading({ mask: true })
  385. Apis.xsb.deleteOrder({
  386. pathParams: {
  387. ids: String(order.orderId),
  388. },
  389. }).then(res => resolve(res)).catch(err => reject(err)).finally(() => uni.hideLoading())
  390. },
  391. fail: async (err) => {
  392. reject(err)
  393. },
  394. })
  395. })
  396. },
  397. /**
  398. * 统一取消订单
  399. * @param order
  400. * @returns
  401. */
  402. handleCommonCancelOrder(order: Api.xsbOrderList) {
  403. return new Promise((resolve, reject) => {
  404. useGlobalMessage().confirm({
  405. title: '取消订单',
  406. msg: '确定要取消订单吗?',
  407. zIndex: 99999999999999,
  408. success: async () => {
  409. uni.showLoading({ mask: true })
  410. Apis.xsb.cancelOrder({
  411. data: {
  412. orderNo: String(order.orderNumber),
  413. },
  414. }).then(res => resolve(res)).catch(err => reject(err)).finally(() => uni.hideLoading())
  415. },
  416. fail: async (err) => {
  417. reject(err)
  418. },
  419. })
  420. })
  421. },
  422. handleXSBCommonOrderStatusText(order: Api.xsbOrderList): any {
  423. if (order.hbOrderStatus === OrderStatus.PaddingPay) {
  424. const endTime = dayjs(order.createTime).add(16, 'minutes')
  425. const remaining = dayjs(endTime).valueOf() - dayjs().valueOf()
  426. return Math.max(0, remaining) // 确保不会返回负数
  427. }
  428. if (order.hbOrderStatus === OrderStatus.OrderAccepted) {
  429. return '订单已接单'
  430. }
  431. if (order.hbOrderStatus === OrderStatus.OrderWaitDelivery) {
  432. return '订单待配送'
  433. }
  434. if (order.hbOrderStatus === OrderStatus.OrderDelivering) {
  435. return '订单配送中'
  436. }
  437. if (order.hbOrderStatus === OrderStatus.OrderCancelAudit) {
  438. return '订单取消审核'
  439. }
  440. if (order.hbOrderStatus === OrderStatus.OrderCancel) {
  441. return '订单取消'
  442. }
  443. if (order.hbOrderStatus === OrderStatus.OrderArrived) {
  444. return '订单已送达'
  445. }
  446. if (order.hbOrderStatus === OrderStatus.OrderCompleted) {
  447. return '订单完成'
  448. }
  449. return '未知订单状态'
  450. },
  451. handleFilmCommonOrderStatusText(order: Api.xsbOrderList): any {
  452. if (order.hbOrderStatus === OrderStatus.PaddingPay) {
  453. const endTime = dayjs(order.createTime).add(16, 'minutes')
  454. const remaining = dayjs(endTime).valueOf() - dayjs().valueOf()
  455. return Math.max(0, remaining) // 确保不会返回负数
  456. }
  457. if (order.hbOrderStatus === OrderStatus.OrderAccepted) {
  458. return '待出票'
  459. }
  460. if (order.hbOrderStatus === OrderStatus.OrderWaitDelivery) {
  461. return '订单待配送'
  462. }
  463. if (order.hbOrderStatus === OrderStatus.OrderDelivering) {
  464. return '出票中'
  465. }
  466. if (order.hbOrderStatus === OrderStatus.OrderCancelAudit) {
  467. return '订单取消审核'
  468. }
  469. if (order.hbOrderStatus === OrderStatus.OrderCancel) {
  470. return '订单取消'
  471. }
  472. if (order.hbOrderStatus === OrderStatus.OrderArrived) {
  473. return '订单完成'
  474. }
  475. if (order.hbOrderStatus === OrderStatus.OrderCompleted) {
  476. return '订单完成'
  477. }
  478. return '未知订单状态'
  479. },
  480. handleDjkCommonOrderStatusText(order: Api.xsbOrderList) {
  481. const textMap = {
  482. [OrderStatus.OrderAccepted]: '待使用',
  483. [OrderStatus.OrderCompleted]: '已完成',
  484. [OrderStatus.OrderCancel]: '已取消',
  485. [OrderStatus.OrderRefund]: '已退款',
  486. [OrderStatus.OrderExpired]: '已过期',
  487. }
  488. return textMap[order.hbOrderStatus as keyof typeof textMap] || '未知订单状态'
  489. },
  490. async getOrderNode(orderNumber: string) {
  491. uni.showLoading({
  492. mask: true,
  493. })
  494. return new Promise((resolve, reject) => {
  495. Apis.xsb.deliveryNode({
  496. data: {
  497. orderNumber,
  498. },
  499. }).then((res) => {
  500. // NodeList.value = res.data
  501. resolve(res.data)
  502. }).catch((err) => {
  503. reject(err)
  504. }).finally(() => uni.hideLoading())
  505. })
  506. },
  507. /**
  508. *
  509. * @param _item 兑换的券 加油
  510. */
  511. async handleExchange(_item: any) {
  512. uni.showLoading({ mask: true })
  513. try {
  514. const res = await Apis.app.get_smqjh_system_app_api_coupon_exchangepoints({ params: { couponId: _item.id } })
  515. uni.hideLoading()
  516. // 兑换成功,跳转成功页
  517. router.push({
  518. name: 'exchangeSuccess',
  519. params: {
  520. couponId: res.data?.id || _item.id,
  521. batchNo: res.data?.batchId || '',
  522. expireDays: res.data?.expirationDate || _item.expirationDate,
  523. discountMoney: res.data?.discountMoney || _item.discountMoney,
  524. amountMoney: res.data?.amountMoney || _item.amountMoney,
  525. },
  526. })
  527. }
  528. catch (error: any) {
  529. console.log(error)
  530. uni.hideLoading()
  531. // 兑换失败,跳转失败页
  532. router.push({
  533. name: 'exchangeFail',
  534. params: {
  535. failReason: error?.message || '兑换失败,请稍后重试',
  536. },
  537. })
  538. }
  539. },
  540. /**
  541. * 拉起小橘支付
  542. * @param path
  543. */
  544. handleCommonPath(path: string) {
  545. uni.showLoading({ mask: true })
  546. const url = REDIRECT_URL
  547. window.location.href = `${path}&redirectUrl=${url}`
  548. uni.hideLoading()
  549. },
  550. async handleCommonGoXiaoJuPay(orderNumber: string) {
  551. try {
  552. const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_findbypayurl({ params: { orderNumber } })
  553. this.handleCommonPath(res.data as string)
  554. }
  555. catch (error) {
  556. console.log(error)
  557. useGlobalToast().show('获取支付信息失败')
  558. }
  559. },
  560. /**
  561. * 加油统一取消订单
  562. * @param orderNumber
  563. * @returns
  564. */
  565. async handleCommonCancelOrderJY(orderNumber: string) {
  566. try {
  567. const res = await Apis.xsb.cancelOrder({ data: { orderNo: orderNumber } })
  568. return res
  569. }
  570. catch (error) {
  571. console.log(error)
  572. useGlobalToast().show('取消订单失败')
  573. }
  574. },
  575. /**
  576. * h5专属。小程序不可调用
  577. * h5第三方统一拉起微信支付跳转路径及参数
  578. * @param orderNumber
  579. */
  580. handleCommonWechatPay(orderNumber: string, model: string = 'mixture') {
  581. // #ifdef H5
  582. uni.showLoading({ mask: true })
  583. const query = {
  584. orderNumber,
  585. phone: String(this.userInfo.mobile),
  586. model,
  587. tenantCode: useSysStore().tenantCode,
  588. }
  589. const queryString = Object.entries(query)
  590. .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
  591. .join('&')
  592. const path = 'subPack-common/threePay/index'
  593. // const env = 'develop'
  594. // const env = 'trial'
  595. const env = 'release'
  596. window.location.href = `weixin://dl/business/?appid=wx43b5b906cc30ed0b&path=${path}&query=${encodeURIComponent(queryString)}&env_version=${env}`
  597. uni.hideLoading()
  598. // #endif
  599. },
  600. async getPayMent(orderNumber: string): Promise<{ payType: 'point' | 'hybrid' | 'wx' }> {
  601. return new Promise((resolve, reject) => {
  602. Apis.common.hybridPaymentType({ data: { orderNumber } })
  603. .then((res) => {
  604. resolve(res.data)
  605. })
  606. .catch((err) => {
  607. reject(err)
  608. })
  609. })
  610. },
  611. },
  612. })