li.shaoyi 2 anos atrás
pai
commit
dcf4581818
77 arquivos alterados com 1062 adições e 846 exclusões
  1. 7 6
      src/business/bank/index.ts
  2. 4 4
      src/business/common/index.ts
  3. 3 2
      src/business/credit/index.ts
  4. 3 2
      src/business/goods/index.ts
  5. 14 8
      src/business/login/index.ts
  6. 3 2
      src/business/market/index.ts
  7. 3 2
      src/business/trade/index.ts
  8. 3 2
      src/business/user/account.ts
  9. 3 2
      src/business/user/address.ts
  10. 3 2
      src/business/user/invoice.ts
  11. 2 2
      src/constants/account.ts
  12. 2 2
      src/constants/bank.ts
  13. 2 2
      src/constants/certificate.ts
  14. 2 2
      src/constants/client.ts
  15. 2 2
      src/constants/credit.ts
  16. 2 2
      src/constants/market.ts
  17. 2 2
      src/constants/menu.ts
  18. 2 2
      src/constants/order.ts
  19. 2 2
      src/constants/receipt.ts
  20. 2 2
      src/constants/unit.ts
  21. 3 2
      src/hooks/echarts/candlestick/index.ts
  22. 3 2
      src/hooks/echarts/candlestick/options.ts
  23. 3 2
      src/hooks/echarts/line/options.ts
  24. 3 2
      src/hooks/echarts/smoothedline/index.ts
  25. 3 2
      src/hooks/echarts/smoothedline/options.ts
  26. 3 2
      src/hooks/echarts/timeline/index.ts
  27. 3 2
      src/hooks/echarts/timeline/options.ts
  28. 4 2
      src/hooks/menu/index.ts
  29. 3 3
      src/packages/mobile/components/base/tabbar/index.vue
  30. 3 3
      src/packages/mobile/components/layouts/navbar/index.vue
  31. 4 3
      src/packages/mobile/main.ts
  32. 3 3
      src/packages/mobile/router/index.ts
  33. 2 2
      src/packages/mobile/views/bank/wallet/components/deposit/index.vue
  34. 3 4
      src/packages/mobile/views/bank/wallet/components/withdraw/index.vue
  35. 4 4
      src/packages/mobile/views/credit/signin/index.vue
  36. 3 3
      src/packages/mobile/views/home/index.vue
  37. 4 4
      src/packages/mobile/views/mine/generalize/index.vue
  38. 9 8
      src/packages/mobile/views/mine/main/index.vue
  39. 3 3
      src/packages/mobile/views/mine/order/detail/transfer/index.vue
  40. 5 5
      src/packages/mobile/views/purchase/detail/index.vue
  41. 3 3
      src/packages/mobile/views/supply-demand/add/components/sell/index.vue
  42. 6 6
      src/packages/mobile/views/supply-demand/detail/components/delisting/index.vue
  43. 5 5
      src/packages/mobile/views/supply-demand/detail/components/listing/index.vue
  44. 5 4
      src/packages/mobile/views/user/avatar/index.vue
  45. 3 3
      src/packages/pc/App.vue
  46. 7 7
      src/packages/pc/components/layouts/header/index.vue
  47. 3 2
      src/packages/pc/components/layouts/navbar/index.vue
  48. 3 2
      src/packages/pc/components/layouts/page/index.vue
  49. 8 8
      src/packages/pc/components/layouts/sidebar/index.vue
  50. 4 3
      src/packages/pc/main.ts
  51. 3 2
      src/packages/pc/router/dynamicRouter.ts
  52. 4 4
      src/packages/pc/router/index.ts
  53. 3 2
      src/packages/pc/views/auth/login/index.vue
  54. 6 6
      src/packages/pc/views/member/index.vue
  55. 3 2
      src/services/api/bank/index.ts
  56. 3 2
      src/services/api/common/index.ts
  57. 3 2
      src/services/api/credit/index.ts
  58. 3 2
      src/services/api/goods/index.ts
  59. 3 2
      src/services/api/order/index.ts
  60. 3 2
      src/services/api/user/index.ts
  61. 4 2
      src/services/http/index.ts
  62. 3 2
      src/services/socket/index.ts
  63. 6 6
      src/services/socket/quote/index.ts
  64. 6 5
      src/services/socket/trade/index.ts
  65. 0 0
      src/stores/dev.ts
  66. 9 9
      src/stores/index.ts
  67. 56 60
      src/stores/modules/account.ts
  68. 73 61
      src/stores/modules/enum.ts
  69. 28 25
      src/stores/modules/errorInfo.ts
  70. 280 273
      src/stores/modules/futures.ts
  71. 94 86
      src/stores/modules/global.ts
  72. 22 23
      src/stores/modules/language.ts
  73. 34 32
      src/stores/modules/login.ts
  74. 20 22
      src/stores/modules/menu.ts
  75. 68 58
      src/stores/modules/user.ts
  76. 110 0
      src/stores/store.ts
  77. 31 0
      src/stores/types.ts

+ 7 - 6
src/business/bank/index.ts

@@ -1,11 +1,12 @@
 import { reactive, shallowRef, computed } from 'vue'
-import { loginStore, userStore } from '@/stores'
+import { useLoginStore, useUserStore } from '@/stores'
 import { t2bBankWithdraw, queryBankAccountSign, t2bBankDeposit, queryCusBankSignBank, t2bBankSign, t2bBankCancelSign, accountFundInfoReq } from '@/services/api/bank'
 import { SignStatus } from '@/constants/bank'
 import { decryptAES } from '@/utils/websocket/crypto'
 import moment from "moment"
 
-const { userId, firstAccountId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId, firstAccountId } = loginStore.$toRefs()
 
 // 提现请求
 export function useDoWithdraw() {
@@ -112,7 +113,7 @@ export function useDoDeposit() {
 
 /// 银行签约请求
 export function useDoBankSign() {
-    const { userInfo } = userStore.$mapGetters()
+    const { userInfo } = useUserStore()
     const loading = shallowRef(false)
     const bankInfo = shallowRef<Model.BankAccountSignRsp>()
 
@@ -159,9 +160,9 @@ export function useDoBankSign() {
         BankAccountType: 1,
         Extend_Info: JSON.stringify({ "sex": 1 }),
         AccountCode: firstAccountId.value.toString(),
-        CertID: decryptAES(userInfo.value?.cardnum ?? ''),
-        CertType: userInfo.value?.cardtypeid.toString(),
-        BankAccountName: userInfo.value?.customername,
+        CertID: decryptAES(userInfo?.cardnum ?? ''),
+        CertType: userInfo?.cardtypeid.toString(),
+        BankAccountName: userInfo?.customername,
     })
 
     const onSubmit = async () => {

+ 4 - 4
src/business/common/index.ts

@@ -1,5 +1,5 @@
 import { timerTask } from '@/utils/timer'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { tokenCheck } from '@/services/api/account'
 import eventBus from '@/services/bus'
 
@@ -8,10 +8,10 @@ import eventBus from '@/services/bus'
  */
 export async function checkToken() {
     try {
-        const { loginId, token } = loginStore.$mapGetters()
+        const { loginId, token } = useLoginStore()
         return await tokenCheck({
-            LoginID: loginId.value,
-            Token: token.value,
+            LoginID: loginId,
+            Token: token,
         })
     } catch {
         eventBus.$emit('LogoutNotify')

+ 3 - 2
src/business/credit/index.ts

@@ -2,11 +2,12 @@ import { shallowRef } from 'vue'
 import { v4 } from 'uuid'
 import { ClientType } from '@/constants/client'
 import { ScoreConfigType } from '@/constants/credit'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { queryUserAccount } from '@/services/api/account'
 import { queryUserScoreLog, queryTHJScoreConfig, thjRedPacketLottery } from '@/services/api/credit'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 // 积分抽奖
 export function useCreditLottery() {

+ 3 - 2
src/business/goods/index.ts

@@ -4,9 +4,10 @@ import { EchartsDataset } from '@/hooks/echarts/line/interface'
 import { BuyOrSell } from '@/constants/order'
 import { queryTHJinvesotrdeposit } from '@/services/api/common'
 import { queryOrderQuoteDetail, queryWrMarketTradeConfig, queryTHJWrstandardDetail, addUserFavoriteGoods, removeUserFavoriteGoods, queryMarketRun } from '@/services/api/goods'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 export type OptionalType<T, K extends keyof T> = Omit<T, K> & { [key in K]: Partial<T[K]> } // 指定某个属性为可选
 

+ 14 - 8
src/business/login/index.ts

@@ -5,7 +5,7 @@ import { timerTask } from '@/utils/timer'
 import { ClientType } from '@/constants/client'
 import { queryLoginId, login } from '@/services/api/account'
 import { sessionData, localData } from '@/stores/storage'
-import { loginStore, enumStore, errorInfoStore, userStore, futuresStore, accountStore } from '@/stores'
+import { useLoginStore, useEnumStore, useErrorInfoStore, useUserStore, useFuturesStore, useAccountStore } from '@/stores'
 import { checkToken, checkTokenLoop } from '@/business/common'
 import service from '@/services'
 import socket from '@/services/socket'
@@ -13,8 +13,14 @@ import eventBus from '@/services/bus'
 import cryptojs from 'crypto-js'
 
 export function useLogin() {
-    const { logining } = loginStore.$mapState()
-    const { token } = loginStore.$mapGetters()
+    const enumStore = useEnumStore()
+    const errorInfoStore = useErrorInfoStore()
+    const loginStore = useLoginStore()
+    const userStore = useUserStore()
+    const accountStore = useAccountStore()
+    const futuresStore = useFuturesStore()
+
+    const { logining, token } = loginStore.$toRefs()
 
     const formData = reactive<Proto.LoginReq>({
         LoginID: localStorage.getItem('thj_loginId') ?? '',
@@ -29,16 +35,16 @@ export function useLogin() {
     const loadBaseData = async () => {
         await service.onReady() // 等待服务初始化
         await Promise.all([
-            errorInfoStore.actions.getErrorInfoList(),
-            enumStore.actions.getAllEnumList(),
+            errorInfoStore.getErrorInfoList(),
+            enumStore.getAllEnumList(),
         ])
     }
 
     const loadUserData = async () => {
         await checkToken() // 令牌校验
-        await userStore.actions.getUserData()
-        futuresStore.actions.getGoodsList()
-        accountStore.actions.getAccountList()
+        await userStore.getUserData()
+        futuresStore.getGoodsList()
+        accountStore.getAccountList()
         checkTokenLoop()
     }
 

+ 3 - 2
src/business/market/index.ts

@@ -1,10 +1,11 @@
 import { computed } from 'vue'
-import { futuresStore } from '@/stores'
+import { useFuturesStore } from '@/stores'
 import quote from '@/services/socket/quote'
 
 // 期货行情列表
 export function useFuturesList() {
-    const dataList = computed(() => futuresStore.getters.quoteList.filter((e) => e.marketid === 99201))
+    const futuresStore = useFuturesStore()
+    const dataList = computed(() => futuresStore.quoteList.filter((e) => e.marketid === 99201))
     const quoteSubscribe = quote.addSubscribe(dataList.value.map((e) => e.goodscode))
 
     return {

+ 3 - 2
src/business/trade/index.ts

@@ -1,7 +1,7 @@
 import { reactive, ref, shallowRef, computed } from 'vue'
 import { v4 } from 'uuid'
 import { ClientType, OrderSrc } from '@/constants/client'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import {
     spotPresaleDestingOrder,
     spotPresaleTransferCancel,
@@ -21,7 +21,8 @@ import { formatDate } from "@/filters";
 import Long from 'long'
 import { BuyOrSell } from '@/constants/order'
 
-const { loginId, userId, firstAccountId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { loginId, userId, firstAccountId } = loginStore.$toRefs()
 
 // 采购摘牌
 export function usePurchaseOrderDesting() {

+ 3 - 2
src/business/user/account.ts

@@ -1,9 +1,10 @@
 import { shallowRef, reactive } from 'vue'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { investorDel, modifyPassword, requestAddAuth } from '@/services/api/account'
 import cryptojs from 'crypto-js'
 
-const { loginId, userId, firstAccountId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { loginId, userId, firstAccountId } = loginStore.$toRefs()
 
 // 用户实名认证
 export function addAuthReq() {

+ 3 - 2
src/business/user/address.ts

@@ -1,8 +1,9 @@
 import { shallowRef, reactive, computed } from 'vue'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { userReceiveInfo, delUserReceiveInfo, userReceiveIsDefault } from '@/services/api/user'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 export function useAddressForm(selectedRow?: Model.UserReceiveInfoRsp) {
     const loading = shallowRef(false)

+ 3 - 2
src/business/user/invoice.ts

@@ -1,9 +1,10 @@
 import { shallowRef, reactive } from 'vue'
 import { userReceiptInfo, delUserReceiptInfo } from '@/services/api/user'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { getCertificateTypeList } from '@/constants/certificate'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 export function useInvoiceForm(selectedRow?: Model.WrUserReceiptInfoRsp) {
     const loading = shallowRef(false)

+ 2 - 2
src/constants/account.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName, getEnumTypeValue } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName, getEnumTypeValue } = useEnumStore()
 
 /**
  * 实名认证状态

+ 2 - 2
src/constants/bank.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 签约状态

+ 2 - 2
src/constants/certificate.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 获取证件类型列表

+ 2 - 2
src/constants/client.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList } = enumStore.actions
+const { getEnumTypeList } = useEnumStore()
 
 /**
  * 客户端类型

+ 2 - 2
src/constants/credit.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 积分配置类型

+ 2 - 2
src/constants/market.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 获取铁合金市场列表

+ 2 - 2
src/constants/menu.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeName } = enumStore.actions
+const { getEnumTypeName } = useEnumStore()
 
 /**
  * 权限类型

+ 2 - 2
src/constants/order.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 买卖方向

+ 2 - 2
src/constants/receipt.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeName } = enumStore.actions
+const { getEnumTypeName } = useEnumStore()
 
 /**
  * 发票类型

+ 2 - 2
src/constants/unit.ts

@@ -1,6 +1,6 @@
-import { enumStore } from '@/stores'
+import { useEnumStore } from '@/stores'
 
-const { getEnumTypeList, getEnumTypeName } = enumStore.actions
+const { getEnumTypeList, getEnumTypeName } = useEnumStore()
 
 /**
  * 获取商品单位列表

+ 3 - 2
src/hooks/echarts/candlestick/index.ts

@@ -2,12 +2,13 @@ import { ref, computed, watch } from 'vue'
 //import { timerInterceptor } from '@/utils/timer'
 import { ChartCycleType } from '@/constants/chart'
 import { queryHistoryDatas } from '@/services/api/quote'
-import { futuresStore } from '@/stores'
+import { useFuturesStore } from '@/stores'
 import { useDataset } from './dataset'
 import { useOptions } from './options'
 import moment from 'moment'
 
 export function useCandlestickChart(goodscode: string) {
+    const futuresStore = useFuturesStore()
     const { dataset, handleData, clearData, calcIndicator } = useDataset();
     const { options, initOptions, updateOptions } = useOptions(dataset);
 
@@ -15,7 +16,7 @@ export function useCandlestickChart(goodscode: string) {
     const isEmpty = ref(true);
     const dataIndex = ref(-1); // 当前数据索引值
     const cycleType = ref(ChartCycleType.Minutes);
-    const quote = futuresStore.actions.getQuoteDayInfoByCode(goodscode); // 实时行情
+    const quote = futuresStore.getQuoteDayInfoByCode(goodscode); // 实时行情
 
     // 当前选中的数据项
     const selectedItem = computed(() => {

+ 3 - 2
src/hooks/echarts/candlestick/options.ts

@@ -1,11 +1,12 @@
 import { reactive, watch } from 'vue'
 import { ECOption } from '@/components/base/echarts/core'
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 import moment from 'moment'
 
-const { appTheme } = globalStore.$mapState()
+const globalStore = useGlobalStore()
+const { appTheme } = globalStore.$toRefs()
 
 function getColors() {
     // 默认主题色配置

+ 3 - 2
src/hooks/echarts/line/options.ts

@@ -1,9 +1,10 @@
 import { reactive, watch } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 
-const { appTheme } = globalStore.$mapState()
+const globalStore = useGlobalStore()
+const { appTheme } = globalStore.$toRefs()
 
 function getColors() {
     // 默认主题色配置

+ 3 - 2
src/hooks/echarts/smoothedline/index.ts

@@ -1,18 +1,19 @@
 import { ref, computed, watch } from 'vue'
-import { futuresStore } from '@/stores'
+import { useFuturesStore } from '@/stores'
 import { formatDate } from '@/filters'
 import { queryHistoryTikDatas } from '@/services/api/quote'
 import { useDataset } from './dataset'
 import { useOptions } from './options'
 
 export function useSmoothedLineChart(goodscode: string) {
+    const futuresStore = useFuturesStore()
     const { dataset, clearData } = useDataset()
     const { options, initOptions, updateOptions } = useOptions(dataset)
 
     const loading = ref(false)
     const isEmpty = ref(false)
     const dataIndex = ref(-1); // 当前数据索引值
-    const quote = futuresStore.actions.getQuoteDayInfoByCode(goodscode) // 实时行情
+    const quote = futuresStore.getQuoteDayInfoByCode(goodscode) // 实时行情
 
     // 当前选中的数据项
     const selectedItem = computed(() => {

+ 3 - 2
src/hooks/echarts/smoothedline/options.ts

@@ -1,9 +1,10 @@
 import { reactive, watch } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 
-const { appTheme } = globalStore.$mapState()
+const globalStore = useGlobalStore()
+const { appTheme } = globalStore.$toRefs()
 
 function getColors() {
     // 默认主题色配置

+ 3 - 2
src/hooks/echarts/timeline/index.ts

@@ -1,19 +1,20 @@
 import { ref, computed, watch } from 'vue'
 //import { timerInterceptor } from '@/utils/timer'
 import { queryTSData } from '@/services/api/quote'
-import { futuresStore } from '@/stores'
+import { useFuturesStore } from '@/stores'
 import { useDataset } from './dataset'
 import { useOptions } from './options'
 import moment from 'moment';
 
 export function useTimelineChart(goodscode: string) {
+    const futuresStore = useFuturesStore()
     const { dataset, handleData, clearData, calcIndicator } = useDataset();
     const { options, initOptions, updateOptions } = useOptions(dataset);
 
     const loading = ref(false);
     const isEmpty = ref(false);
     const dataIndex = ref(-1); // 当前数据索引值
-    const quote = futuresStore.actions.getQuoteDayInfoByCode(goodscode); // 实时行情
+    const quote = futuresStore.getQuoteDayInfoByCode(goodscode); // 实时行情
 
     // 当前选中的数据项
     const selectedItem = computed(() => {

+ 3 - 2
src/hooks/echarts/timeline/options.ts

@@ -1,10 +1,11 @@
 import { reactive, watch } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import { echarts } from '@/components/base/echarts/core'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 
-const { appTheme } = globalStore.$mapState()
+const globalStore = useGlobalStore()
+const { appTheme } = globalStore.$toRefs()
 
 function getColors() {
     // 默认主题色配置

+ 4 - 2
src/hooks/menu/index.ts

@@ -1,10 +1,12 @@
 import { defineAsyncComponent, Component } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-import { menuStore } from '@/stores'
+import { useMenuStore } from '@/stores'
 import { AuthType } from '@/constants/menu'
 
 export function useMenu(authCode?: string) {
-    const { userRoutes } = menuStore.$mapState()
+    const menuStore = useMenuStore()
+    const { userRoutes } = menuStore.$toRefs()
+
     const route = useRoute()
     const router = useRouter()
     const componentMap = new Map<string, Component>()

+ 3 - 3
src/packages/mobile/components/base/tabbar/index.vue

@@ -27,7 +27,7 @@
 <script lang="ts" setup>
 import { PropType, computed } from 'vue'
 import { Tabbar } from './interface'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import AppIconfont from '@mobile/components/base/iconfont/index.vue'
 
 const emit = defineEmits(['click'])
@@ -50,11 +50,11 @@ const props = defineProps({
   }
 })
 
-const { clientWidth } = globalStore.$mapState()
+const globalStore = useGlobalStore()
 
 const styles = computed(() => ({
   position: props.fixed ? 'fixed' : 'static',
-  width: clientWidth.value + 'px',
+  width: globalStore.clientWidth + 'px',
 }))
 
 const onClick = (index: number) => {

+ 3 - 3
src/packages/mobile/components/layouts/navbar/index.vue

@@ -31,7 +31,7 @@
 <script lang="ts" setup>
 import { useAttrs, computed } from 'vue'
 import { useRouter } from 'vue-router'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 
 const emit = defineEmits<{ (event: string, ...args: unknown[]): void }>()
 
@@ -49,11 +49,11 @@ const props = defineProps({
 
 const router = useRouter();
 const attrs = useAttrs();
-const { clientWidth } = globalStore.$mapState();
+const globalStore = useGlobalStore()
 
 const styles = computed(() => ({
   position: props.fixed ? 'fixed' : 'static',
-  width: clientWidth.value + 'px',
+  width: globalStore.clientWidth + 'px',
 }))
 
 // 返回按钮事件

+ 4 - 3
src/packages/mobile/main.ts

@@ -11,7 +11,7 @@ import 'vant/lib/index.css'
 import './assets/iconfont/iconfont.js'
 import './assets/themes/style.less' // 主题样式
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 // import Vconsole from 'vconsole'
 // new Vconsole()
 
@@ -23,8 +23,9 @@ app.mount('#app')
 
 // 等待 html 加载完成
 document.addEventListener('DOMContentLoaded', () => {
+    const { screenAdapter } = useGlobalStore()
     // 适配客户端
-    globalStore.actions.screenAdapter(true)
+    screenAdapter(true)
     // 监听窗口大小变化
-    window.addEventListener('resize', timerInterceptor.setDebounce(() => globalStore.actions.screenAdapter(true)))
+    window.addEventListener('resize', timerInterceptor.setDebounce(() => screenAdapter(true)))
 }, false)

+ 3 - 3
src/packages/mobile/router/index.ts

@@ -1,11 +1,11 @@
 import { createWebHashHistory, RouteRecordRaw } from "vue-router";
-import { loginStore } from "@/stores";
+import { useLoginStore } from "@/stores";
 import { clearPending } from "@/services/http/pending";
 import service from "@/services";
 import Page from "@mobile/components/layouts/page/index.vue";
 import animateRouter from "./animateRouter";
 
-const { token } = loginStore.$mapGetters();
+const loginStore = useLoginStore()
 
 const routes: Array<RouteRecordRaw> = [
   {
@@ -565,7 +565,7 @@ router.beforeEach((to, from, next) => {
   clearPending()
   // 判断服务是否加载完成
   if (service.isReady) {
-    if (to.meta.ignoreAuth || token.value) {
+    if (to.meta.ignoreAuth || loginStore.token) {
       next();
     } else {
       next({

+ 2 - 2
src/packages/mobile/views/bank/wallet/components/deposit/index.vue

@@ -67,13 +67,13 @@ import { Form, Field, CellGroup, Button, FieldRule, FormInstance, showFailToast,
 import { useDoDeposit } from '@/business/bank'
 import { fullloading, dialog } from '@/utils/vant'
 import { useNavigation } from '@/hooks/navigation'
-import { userStore } from '@/stores'
+import { useUserStore } from '@/stores'
 import AppUploader from '@mobile/components/base/uploader/index.vue'
 
 const formRef = shallowRef<FormInstance>()
 const { formData, onSubmit, extendInfo } = useDoDeposit()
 const { router } = useNavigation()
-const { getSystemParamValue } = userStore.actions
+const { getSystemParamValue } = useUserStore()
 const start = getSystemParamValue('012')
 const end = getSystemParamValue('013')
 

+ 3 - 4
src/packages/mobile/views/bank/wallet/components/withdraw/index.vue

@@ -2,8 +2,7 @@
     <app-view class="g-form bank-wallet-withdraw">
         <Form ref="formRef" class="g-form__container" @submit="formSubmit">
             <CellGroup inset>
-                <Field class="form-field" type="number" label="提现金额" v-model="formData.Amount"
-                    :rules="formRules.Amount">
+                <Field class="form-field" type="number" label="提现金额" v-model="formData.Amount" :rules="formRules.Amount">
                     <template #input>
                         <input v-model="formData.Amount" placeholder="请填写提现金额" />
                         <span class="form-field__tips">可出金额:{{ fund.AvailableOutMoney }}</span>
@@ -48,14 +47,14 @@ import { Form, Field, CellGroup, FormInstance, Button, FieldRule, showFailToast
 import { shallowRef } from 'vue'
 import { fullloading, dialog } from '@/utils/vant'
 import { useNavigation } from '@/hooks/navigation'
-import { userStore } from '@/stores'
+import { useUserStore } from '@/stores'
 
 const { formData, onSubmit, sign } = useDoWithdraw()
 /// 资金账户信息
 const { fund } = useAccountFundInfo()
 const { router } = useNavigation()
 const formRef = shallowRef<FormInstance>()
-const { getSystemParamValue } = userStore.actions
+const { getSystemParamValue } = useUserStore()
 const start = getSystemParamValue('012')
 const end = getSystemParamValue('013')
 

+ 4 - 4
src/packages/mobile/views/credit/signin/index.vue

@@ -110,15 +110,15 @@
 import { shallowRef, onActivated } from 'vue'
 import { showSuccessToast, showFailToast, Button } from 'vant'
 import { fullloading } from '@/utils/vant'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { queryUserAccount } from '@/services/api/account'
 import { queryTHJScoreConfig } from '@/services/api/credit'
 import { signin } from '@/services/api/common'
 import { useNavigation } from '@/hooks/navigation'
 import AppRegisterCode from '@mobile/components/modules/register-code/index.vue'
 
-const { userId } = loginStore.$mapGetters()
 const { routerTo, routerBack } = useNavigation()
+const loginStore = useLoginStore()
 const headerRef = shallowRef<HTMLDivElement>()
 const userAccount = shallowRef<Partial<Model.UserAccount>>({})
 const scoreConfig = shallowRef<Model.THJScoreConfigRsp[]>([])
@@ -143,7 +143,7 @@ const navigationBack = (index: number) => {
 const userSignin = () => {
     fullloading(() => {
         signin({
-            userid: userId.value
+            userid: loginStore.userId
         }).then((res) => {
             if (res.data.signinstatus === 1) {
                 getUserAccount()
@@ -159,7 +159,7 @@ const userSignin = () => {
 
 const getUserAccount = () => {
     queryUserAccount({
-        userID: userId.value
+        userID: loginStore.userId
     }).then((res) => {
         userAccount.value = res.data
     })

+ 3 - 3
src/packages/mobile/views/home/index.vue

@@ -19,14 +19,14 @@ import { Tabbar } from '@mobile/components/base/tabbar/interface'
 import { GetAppUpdateInfo } from '@/services/api/common'
 import { useNavigation } from '@/hooks/navigation'
 import { useLogin } from '@/business/login'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import plus from '@/utils/h5plus'
 import AppTabbar from '@mobile/components/base/tabbar/index.vue'
 import RouterTransition from '@mobile/components/base/router-transition/index.vue'
 
-const { token } = loginStore.$mapGetters()
 const { route, routerTo, getGlobalUrlParams } = useNavigation()
 const { autoLogin } = useLogin()
+const loginStore = useLoginStore()
 const cssTransition = shallowRef(true) // 是否使用css动画
 const currentTab = shallowRef(0)
 
@@ -61,7 +61,7 @@ const onTabClick = (index: number) => {
   const { name } = tabList[index]
   cssTransition.value = false
 
-  if (name === 'home-index' || token.value) {
+  if (name === 'home-index' || loginStore.token) {
     currentTab.value = index
     routerTo(name, true)
   } else {

+ 4 - 4
src/packages/mobile/views/mine/generalize/index.vue

@@ -57,7 +57,7 @@
 <script lang="ts" setup>
 import { shallowRef, computed } from 'vue'
 import { DropdownItem, DropdownMenu, Progress } from 'vant'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { queryUserLevelInfo } from '@/services/api/common'
 import { queryUserAccount } from '@/services/api/account'
 import AppRegisterCode from '@mobile/components/modules/register-code/index.vue'
@@ -65,7 +65,7 @@ import TradeData from './components/tradedata/index.vue'
 import Promotion from './components/promotion/index.vue'
 import { getTHJMarketList } from '@/constants/market'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
 const showQRCode = shallowRef(false)
 const selectedMenu = shallowRef(0)
 const selectedType = shallowRef(64201)
@@ -110,13 +110,13 @@ const onMenuChange = () => {
 }
 
 queryUserAccount({
-    userID: userId.value
+    userID: loginStore.userId
 }).then((res) => {
     userAccount.value = res.data
 })
 
 queryUserLevelInfo({
-    userid: userId.value
+    userid: loginStore.userId
 }).then((res) => {
     userLevelInfo.value = res.data
 })

+ 9 - 8
src/packages/mobile/views/mine/main/index.vue

@@ -14,12 +14,12 @@
               <div>
                 <Tag :type="authStatus ? 'success' : 'primary'">{{ getAuthStatusName(authStatus) }}</Tag>
               </div>
-              <span>{{ loginId }}</span>
+              <span>{{ loginStore.loginId }}</span>
             </div>
           </div>
           <div class="profile-account">
             <span>正常</span>
-            <span>{{ firstAccountId }}</span>
+            <span>{{ loginStore.firstAccountId }}</span>
           </div>
         </div>
         <div class="bank" v-if="accountInfo">
@@ -126,7 +126,7 @@ import { Cell, CellGroup, Button, Tag, showFailToast } from 'vant'
 import { fullloading, dialog } from '@/utils/vant'
 import { getFileUrl } from '@/filters'
 import { useNavigation } from '@/hooks/navigation'
-import { loginStore, accountStore, userStore } from '@/stores'
+import { useLoginStore, useAccountStore, useUserStore } from '@/stores'
 import { localData } from '@/stores/storage'
 import AppIconfont from '@mobile/components/base/iconfont/index.vue'
 import { queryBankAccountSign } from '@/services/api/bank'
@@ -136,9 +136,10 @@ import eventBus from '@/services/bus'
 import AppRegisterCode from '@mobile/components/modules/register-code/index.vue'
 
 const { router, routerTo } = useNavigation()
-const { userId, loginId, firstAccountId } = loginStore.$mapGetters()
-const { userInfo } = userStore.$mapGetters()
-const { accountInfo, freezeMargin, avaiableMoney } = accountStore.$mapGetters()
+const loginStore = useLoginStore()
+const userStore = useUserStore()
+const accountStore = useAccountStore()
+const { accountInfo, freezeMargin, avaiableMoney } = accountStore.$toRefs()
 
 const authStatus = shallowRef(AuthStatus.Uncertified) // 实名认证状态
 const registerCode = shallowRef('') // 注册编码
@@ -147,7 +148,7 @@ const showQRCode = shallowRef(false)
 
 // 用户头像
 const userAvatar = computed(() => {
-  const file = userInfo.value?.headurl
+  const file = userStore.userInfo?.headurl
   return file ? getFileUrl(file) : ''
 })
 
@@ -204,7 +205,7 @@ onActivated(() => {
   if (authStatus.value !== AuthStatus.Certified) {
     // 获取用户账号信息
     queryUserAccount({
-      userID: userId.value
+      userID: loginStore.userId
     }).then((res) => {
       authStatus.value = res.data.hasauth
       registerCode.value = res.data.refernum

+ 3 - 3
src/packages/mobile/views/mine/order/detail/transfer/index.vue

@@ -29,7 +29,7 @@
                 <Cell title="合同单号" :value="details.transferid" :is-link="!!details.contractaddr"
                     @click="openPDF(details?.contractaddr)" />
             </CellGroup>
-            <CellGroup title="点价信息" v-if="details.pointflag && userId === details.firstbuyuserid">
+            <CellGroup title="点价信息" v-if="details.pointflag && loginStore.userId === details.firstbuyuserid">
                 <Cell title="已点价格" :value="details.pointprice" />
                 <Cell title="已点收益" :value="details.pointincome" />
             </CellGroup>
@@ -55,11 +55,11 @@ import { useRequest } from '@/hooks/request'
 import { queryTHJPurchaseTransferOrderDetail } from '@/services/api/order'
 import { useSpotPresaleTransferCancel } from "@/business/trade"
 import { handleNumberValue, parsePercent, formatDate } from '@/filters'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import plus from '@/utils/h5plus'
 
+const loginStore = useLoginStore()
 const { router, getQueryString } = useNavigation()
-const { userId } = loginStore.$mapGetters()
 const { transferCancelSubmit } = useSpotPresaleTransferCancel()
 const { data: details } = useRequest(queryTHJPurchaseTransferOrderDetail, {
     params: {

+ 5 - 5
src/packages/mobile/views/purchase/detail/index.vue

@@ -50,7 +50,8 @@
                 </Field>
                 <Field label="预付款(含定金)" name="PreAmount" :rules="formRules.PreAmount" v-if="selectedDate">
                     <template #input>
-                        <span style="color:#999">{{ `${totalAmount.toFixed(2)}(≤${avaiableMoney.toFixed(2)}元)` }}</span>
+                        <span style="color:#999">{{ `${totalAmount.toFixed(2)}(≤${accountStore.avaiableMoney.toFixed(2)}元)`
+                        }}</span>
                     </template>
                 </Field>
                 <Field label="收货信息" name="AddressInfo" :rules="formRules.AddressInfo" @click="openComponent('address')"
@@ -110,7 +111,7 @@ import { getFileUrl, parsePercent } from '@/filters'
 import { getGoodsUnitName } from '@/constants/unit'
 import { useComponent } from '@/hooks/component'
 import { useNavigation } from '@/hooks/navigation'
-import { accountStore, } from '@/stores'
+import { useAccountStore, } from '@/stores'
 import { useWrstandardDetails } from '@/business/goods'
 import { usePurchaseOrderDesting } from '@/business/trade'
 import Long from 'long'
@@ -122,10 +123,9 @@ const componentMap = new Map<string, unknown>([
     ['chart', defineAsyncComponent(() => import('@mobile/components/modules/echarts-line/index.vue'))],
 ])
 
-const { avaiableMoney } = accountStore.$mapGetters()
 const { componentRef, componentId, openComponent, closeComponent } = useComponent()
 const { router, getQueryStringToNumber } = useNavigation()
-
+const accountStore = useAccountStore()
 const wrstandardid = getQueryStringToNumber('wrstandardid')
 const formRef = shallowRef<FormInstance>()
 const showDialog = shallowRef(false)
@@ -254,7 +254,7 @@ const formRules: { [key in keyof Proto.SpotPresaleDestingOrderReq | 'AddressInfo
     PreAmount: [{
         message: '可用资金不足',
         validator: () => {
-            return avaiableMoney.value >= totalAmount.value
+            return accountStore.avaiableMoney >= totalAmount.value
         }
     }],
 }

+ 3 - 3
src/packages/mobile/views/supply-demand/add/components/sell/index.vue

@@ -42,7 +42,7 @@
                 </Field>
                 <Field label="可用资金">
                     <template #input>
-                        <span>{{ avaiableMoney.toFixed(2) }}</span>
+                        <span>{{ accountStore.avaiableMoney.toFixed(2) }}</span>
                     </template>
                 </Field>
             </CellGroup>
@@ -64,12 +64,12 @@ import { useNavigation } from '@/hooks/navigation'
 import { useRequest } from '@/hooks/request'
 import { queryFtDeliveryGoods, queryWrStandardFactoryItem } from '@/services/api/goods'
 import { useHdWROrder } from '@/business/trade'
-import { accountStore } from '@/stores'
+import { useAccountStore } from '@/stores'
 import AppSelect from '@mobile/components/base/select/index.vue'
 
-const { avaiableMoney } = accountStore.$mapGetters()
 const { routerBack } = useNavigation()
 const { formData, listingSubmit, amount } = useHdWROrder()
+const accountStore = useAccountStore()
 const formRef = shallowRef<FormInstance>()
 
 const { dataList: ftDeliveryGoodsList } = useRequest(queryFtDeliveryGoods)

+ 6 - 6
src/packages/mobile/views/supply-demand/detail/components/delisting/index.vue

@@ -41,7 +41,7 @@
             </Field>
             <Field label="可用资金" v-if="buyorsell === BuyOrSell.Buy">
                 <template #input>
-                    <span>{{ avaiableMoney.toFixed(2) }}</span>
+                    <span>{{ accountStore.avaiableMoney.toFixed(2) }}</span>
                 </template>
             </Field>
         </Form>
@@ -55,7 +55,7 @@
 import { shallowRef, PropType, computed } from 'vue'
 import { Form, Field, Stepper, Button, showFailToast, FieldRule, FormInstance } from 'vant'
 import { fullloading, dialog } from '@/utils/vant'
-import { loginStore, accountStore } from '@/stores'
+import { useLoginStore, useAccountStore } from '@/stores'
 import { BuyOrSell } from '@/constants/order'
 import { queryHoldLB } from '@/services/api/order'
 import { useHdWRDealOrder } from '@/business/trade'
@@ -78,9 +78,9 @@ const props = defineProps({
     }
 })
 
-const { firstAccountId } = loginStore.$mapGetters()
-const { avaiableMoney } = accountStore.$mapGetters()
 const { formData, formSubmit } = useHdWRDealOrder()
+const loginStore = useLoginStore()
+const accountStore = useAccountStore()
 const formRef = shallowRef<FormInstance>()
 const refresh = shallowRef(false) // 是否刷新父组件数据
 const showModal = shallowRef(true)
@@ -139,7 +139,7 @@ const onSubmit = () => {
     const { wrtradeorderid = '0', marketid } = props.quoteDetail ?? {}
 
     formData.Header = {
-        AccountID: firstAccountId.value,
+        AccountID: loginStore.firstAccountId,
         MarketID: marketid
     }
     formData.BuyOrSell = props.buyorsell
@@ -164,7 +164,7 @@ const onSubmit = () => {
 }
 
 queryHoldLB({
-    accountid: firstAccountId.value,
+    accountid: loginStore.firstAccountId,
     wrfactortypeid: props.quoteItem.wrfactortypeid
 }).then((res) => {
     selectedRow.value = res.data[0]

+ 5 - 5
src/packages/mobile/views/supply-demand/detail/components/listing/index.vue

@@ -32,7 +32,7 @@
             </Field>
             <Field label="可用资金" v-if="buyorsell === BuyOrSell.Buy">
                 <template #input>
-                    <span>{{ avaiableMoney.toFixed(2) }}</span>
+                    <span>{{ accountStore.avaiableMoney.toFixed(2) }}</span>
                 </template>
             </Field>
         </Form>
@@ -46,7 +46,7 @@
 import { shallowRef, PropType } from 'vue'
 import { Form, Field, Stepper, Button, showFailToast, FieldRule, FormInstance } from 'vant'
 import { fullloading, dialog } from '@/utils/vant'
-import { loginStore, accountStore } from '@/stores'
+import { useLoginStore, useAccountStore } from '@/stores'
 import { BuyOrSell } from '@/constants/order'
 import { queryHoldLB } from '@/services/api/order'
 import { useHdWROrder } from '@/business/trade'
@@ -65,9 +65,9 @@ const props = defineProps({
     }
 })
 
-const { firstAccountId } = loginStore.$mapGetters()
-const { avaiableMoney } = accountStore.$mapGetters()
 const { formData, listingSubmit, amount } = useHdWROrder()
+const loginStore = useLoginStore()
+const accountStore = useAccountStore()
 const formRef = shallowRef<FormInstance>()
 const refresh = shallowRef(false) // 是否刷新父组件数据
 const showModal = shallowRef(true)
@@ -145,7 +145,7 @@ const onSubmit = () => {
 }
 
 queryHoldLB({
-    accountid: firstAccountId.value,
+    accountid: loginStore.firstAccountId,
     wrfactortypeid: props.quoteItem.wrfactortypeid
 }).then((res) => {
     selectedRow.value = res.data[0]

+ 5 - 4
src/packages/mobile/views/user/avatar/index.vue

@@ -26,15 +26,16 @@ import { CellGroup, Button, Field, Form, FormInstance, FieldRule, showFailToast
 import { fullloading } from '@/utils/vant'
 import { useNavigation } from '@/hooks/navigation'
 import { updateUserHeadUrl } from '@/services/api/user'
-import { loginStore, userStore } from '@/stores'
+import { useLoginStore, useUserStore } from '@/stores'
 import AppUploader from '@mobile/components/base/uploader/index.vue'
 
-const { userId } = loginStore.$mapGetters()
 const { router } = useNavigation()
+const loginStore = useLoginStore()
+const userStore = useUserStore()
 
 const formRef = shallowRef<FormInstance>()
 const formData = reactive<Model.UserHeadUrlReq>({
-    userid: userId.value, // 用户ID
+    userid: loginStore.userId, // 用户ID
     headurl: '', // 头像地址
 })
 
@@ -56,7 +57,7 @@ const onSubmit = () => {
     fullloading((hideLoading) => {
         updateUserHeadUrl(formData).then(() => {
             hideLoading()
-            userStore.actions.getUserData()
+            userStore.getUserData()
             router.back()
         }).catch((err) => {
             showFailToast(err)

+ 3 - 3
src/packages/pc/App.vue

@@ -16,12 +16,12 @@ import { ref, watch } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import { ElMessageBox } from 'element-plus'
 import { useLogin } from '@/business/login'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import zhCn from 'element-plus/lib/locale/lang/zh-cn'
 import eventBus from '@/services/bus'
 
-const { token } = loginStore.$mapGetters()
 const { userLogout } = useLogin()
+const loginStore = useLoginStore()
 const route = useRoute()
 const router = useRouter()
 const hasLogin = ref(false)
@@ -37,7 +37,7 @@ eventBus.$on('LogoutNotify', (msg) => {
 })
 
 watch(() => route.name, (routeName) => {
-  if (routeName === 'boot' || routeName === 'login' || !token.value) {
+  if (routeName === 'boot' || routeName === 'login' || !loginStore.token) {
     hasLogin.value = false
   } else {
     hasLogin.value = true

+ 7 - 7
src/packages/pc/components/layouts/header/index.vue

@@ -2,7 +2,7 @@
     <div class="app-header">
         <div class="app-header__left">
             <slot name="left"></slot>
-            <el-breadcrumb :separator-icon="ArrowRight" v-show="!isMobile">
+            <el-breadcrumb :separator-icon="ArrowRight" v-show="!globalStore.isMobile">
                 <template v-for="(item, index) in $route.matched" :key="index">
                     <el-breadcrumb-item :to="{ path: item.path }">
                         <!--<i :class="item.meta.icon" v-if="item.meta.icon"></i>-->
@@ -19,8 +19,8 @@
             </div>
             <el-dropdown class="user-dropdown" trigger="click">
                 <span class="user-dropdown__link">
-                    <img class="g-image--avatar" :title="accountName" :src="userAvatar" />
-                    <span v-if="!isMobile">{{ accountName }}</span>
+                    <img class="g-image--avatar" :title="userStore.accountName" :src="userAvatar" />
+                    <span v-if="!globalStore.isMobile">{{ userStore.accountName }}</span>
                     <app-icon class="el-icon--right" icon="ArrowDown" />
                 </span>
                 <template #dropdown>
@@ -38,17 +38,17 @@
 import { ref, onMounted, computed } from 'vue'
 import { ArrowRight, SwitchButton } from '@element-plus/icons-vue'
 import { getFileUrl } from '@/filters'
-import { userStore, globalStore } from '@/stores'
+import { useUserStore, useGlobalStore } from '@/stores'
 import eventBus from '@/services/bus'
 import AppIcon from '@pc/components/base/icon/index.vue'
 
-const { isMobile } = globalStore.$mapState()
-const { userInfo, accountName } = userStore.$mapGetters()
+const globalStore = useGlobalStore()
+const userStore = useUserStore()
 const fullScreen = ref(false)
 
 // 用户头像
 const userAvatar = computed(() => {
-    const file = userInfo.value?.headurl
+    const file = userStore.userInfo?.headurl
     return file ? getFileUrl(file) : ''
 })
 

+ 3 - 2
src/packages/pc/components/layouts/navbar/index.vue

@@ -26,10 +26,11 @@
 <script lang="ts" setup>
 import { computed, ref, watch } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import historyRouter from '../../../router/historyRouter'
 
 const { state, removeHistory } = historyRouter;
+const globalStore = useGlobalStore()
 
 const route = useRoute(),
     router = useRouter(),
@@ -40,7 +41,7 @@ const route = useRoute(),
 
 const isMobile = computed(() => {
     scrollTab();
-    return globalStore.state.isMobile;
+    return globalStore.isMobile;
 })
 
 // 选择标签

+ 3 - 2
src/packages/pc/components/layouts/page/index.vue

@@ -34,13 +34,14 @@
 <script lang="ts" setup>
 import { ref } from 'vue'
 import { RouteRecordNormalized, RouteRecordName } from 'vue-router'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import AppHeader from '../header/index.vue'
 import AppFooter from '../footer/index.vue'
 import AppNavbar from '../navbar/index.vue'
 import AppSidebar from '../sidebar/index.vue'
 
-const isCollapse = ref(globalStore.state.isMobile);
+const globalStore = useGlobalStore()
+const isCollapse = ref(globalStore.isMobile);
 
 // 手动给组件添加 name 属性,处理缓存 exclude 无效的问题
 const handleComponent = (component: Record<'type', { name: RouteRecordName | undefined }>, route: RouteRecordNormalized) => {

+ 8 - 8
src/packages/pc/components/layouts/sidebar/index.vue

@@ -1,22 +1,22 @@
 <template>
   <el-scrollbar :class="['app-sidebar', collapse && 'is-hide']" view-class="app-sidebar__view">
-    <div :class="['app-sidebar__header', isMobile ? 'is-show' : collapse && 'is-hide']">
+    <div :class="['app-sidebar__header', globalStore.isMobile ? 'is-show' : collapse && 'is-hide']">
       <span class="logo">推广查询系统</span>
     </div>
     <div class="app-sidebar__menu">
-      <app-sidemenu :collapse="isMobile ? false : collapse" @select="routerTo" />
+      <app-sidemenu :collapse="globalStore.isMobile ? false : collapse" @select="routerTo" />
     </div>
-    <div :class="['app-sidebar__copyright', isMobile ? 'is-show' : collapse && 'is-hide']">
+    <div :class="['app-sidebar__copyright', globalStore.isMobile ? 'is-show' : collapse && 'is-hide']">
       <span>&copy;{{ year }} Muchinfo</span>
     </div>
-    <div :class="['app-sidebar__mask', collapse && 'is-hide']" @click="hideSidebar()" v-if="isMobile"></div>
+    <div :class="['app-sidebar__mask', collapse && 'is-hide']" @click="hideSidebar()" v-if="globalStore.isMobile"></div>
   </el-scrollbar>
 </template>
 
 <script lang="ts" setup>
 import { watch } from 'vue'
 import { useRouter } from 'vue-router'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 import AppSidemenu from '../sidemenu/index.vue'
 
 const emit = defineEmits(['update:collapse'])
@@ -26,12 +26,12 @@ defineProps({
   collapse: Boolean,
 })
 
-const { isMobile } = globalStore.$mapState()
+const globalStore = useGlobalStore()
 const router = useRouter()
 const year = new Date().getFullYear()
 
 const hideSidebar = () => {
-  emit('update:collapse', isMobile.value)
+  emit('update:collapse', globalStore.isMobile)
 }
 
 // 菜单跳转
@@ -41,7 +41,7 @@ const routerTo = (active: string) => {
 }
 
 // 监听设备变化
-watch(isMobile, () => hideSidebar())
+watch(() => globalStore.isMobile, () => hideSidebar())
 </script>
 
 <style lang="less">

+ 4 - 3
src/packages/pc/main.ts

@@ -9,7 +9,7 @@ import * as ElementIcons from '@element-plus/icons-vue'
 import 'element-plus/dist/index.css'
 import './assets/themes/style.less' // 主题样式
 import { timerInterceptor } from '@/utils/timer'
-import { globalStore } from '@/stores'
+import { useGlobalStore } from '@/stores'
 
 const app = createApp(App)
 app.use(router)
@@ -20,10 +20,11 @@ app.mount('#app')
 
 // 等待 html 加载完成
 document.addEventListener('DOMContentLoaded', () => {
+    const { screenAdapter } = useGlobalStore()
     // 适配客户端
-    globalStore.actions.screenAdapter()
+    screenAdapter()
     // 监听窗口大小变化
-    window.addEventListener('resize', timerInterceptor.setDebounce(() => globalStore.actions.screenAdapter()))
+    window.addEventListener('resize', timerInterceptor.setDebounce(() => screenAdapter()))
 }, false)
 
 // 注册全局图标

+ 3 - 2
src/packages/pc/router/dynamicRouter.ts

@@ -1,6 +1,6 @@
 import { RouteRecordRaw } from 'vue-router'
 import { AuthType } from '@/constants/menu'
-import { menuStore } from '@/stores'
+import { useMenuStore } from '@/stores'
 import router from '../router'
 
 export default new (class {
@@ -65,8 +65,9 @@ export default new (class {
      * @returns 
      */
     registerRoutes() {
+        const menuStore = useMenuStore()
         this.addNotFound();
-        this.addRoutes(menuStore.state.userRoutes);
+        this.addRoutes(menuStore.userRoutes);
         this.isReady = true;
     }
 })

+ 4 - 4
src/packages/pc/router/index.ts

@@ -1,15 +1,15 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import dynamicRouter from './dynamicRouter'
 import historyRouter from './historyRouter'
 import service from '@/services'
 
-const { token } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
 
 const routes: Array<RouteRecordRaw> = [
     {
         path: '/',
-        redirect: () => token.value ? '/member' : '/login', // 重定向到默认页面
+        redirect: () => loginStore.token ? '/member' : '/login', // 重定向到默认页面
     },
     {
         path: '/login',
@@ -44,7 +44,7 @@ router.beforeEach((to, from, next) => {
 
     // 判断服务是否加载完成
     if (service.isReady) {
-        if (token.value) {
+        if (loginStore.token) {
             if (dynamicRouter.isReady) {
                 if (isLoginOrRegister) {
                     next('/')

+ 3 - 2
src/packages/pc/views/auth/login/index.vue

@@ -29,12 +29,13 @@ import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 import { ClientType } from '@/constants/client'
 import { useLogin } from '@/business/login'
-import { menuStore } from '@/stores'
+import { useMenuStore } from '@/stores'
 import SignLayout from '../components/layout/index.vue'
 
 const { formData, userLogin } = useLogin()
 const route = useRoute()
 const router = useRouter()
+const menuStore = useMenuStore()
 const formRef = shallowRef<FormInstance>()
 const loading = shallowRef(false)
 //const remember = shallowRef(false) // 记住账号
@@ -54,7 +55,7 @@ const formSubmit = () => {
       try {
         loading.value = true
         await userLogin(ClientType.Web)
-        await menuStore.actions.getUserMenuList()
+        await menuStore.getUserMenuList()
         const redirect = route.query.redirect
         if (redirect) {
           router.replace(redirect.toString())

+ 6 - 6
src/packages/pc/views/member/index.vue

@@ -50,7 +50,7 @@ import { formatDate } from '@/filters'
 import { useRequest } from '@/hooks/request'
 import { useDataFilter } from '@/hooks/datatable'
 import { queryTHJFriends, queryInvestorLevelGroup } from '@/services/api/common'
-import { loginStore, userStore } from '@/stores'
+import { useLoginStore, useUserStore } from '@/stores'
 import { decryptAES } from '@/utils/websocket/crypto'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppFilter from '@pc/components/base/table-filter/index.vue'
@@ -62,15 +62,15 @@ interface TreeData {
     children?: TreeData[];
 }
 
-const { userId } = loginStore.$mapGetters()
-const { accountName } = userStore.$mapGetters()
 const { filterOptons, getQueryParams } = useDataFilter<Model.THJFriendsReq>()
+const loginStore = useLoginStore()
+const userStore = useUserStore()
 const treeRef = shallowRef<InstanceType<typeof ElTree>>()
 const filterText = shallowRef('')
-const selectedId = shallowRef(userId.value) // 当前选中用户ID
+const selectedId = shallowRef(loginStore.userId) // 当前选中用户ID
 
 const treeList = reactive<TreeData[]>([{
-    label: accountName.value ?? '登录用户',
+    label: userStore.accountName ?? '登录用户',
     userid: selectedId.value,
     children: []
 }])
@@ -140,7 +140,7 @@ const getAuthStatusName = (status: number) => {
 // 获取手机号码
 const getPhoneNumber = (value: string) => {
     const phoneNumber = decryptAES(value)
-    if (selectedId.value == userId.value) {
+    if (selectedId.value == loginStore.userId) {
         return phoneNumber
     }
     const reg = /^(\d{3})\d{4}(\d{4})$/

+ 3 - 2
src/services/api/bank/index.ts

@@ -1,8 +1,9 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 import tradeServer from '@/services/socket/trade'
 
-const { userId, firstAccountId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId, firstAccountId } = loginStore.$toRefs()
 
 /**
  * 账户资金信息请求

+ 3 - 2
src/services/api/common/index.ts

@@ -1,8 +1,9 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import service from '@/services'
 import http from '@/services/http'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 /**
  * 获取应用配置信息

+ 3 - 2
src/services/api/credit/index.ts

@@ -1,8 +1,9 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 import tradeServer from '@/services/socket/trade'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 /**
  * 查询我的积分流水

+ 3 - 2
src/services/api/goods/index.ts

@@ -1,7 +1,8 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 /**
  * 查询企业风管期货商品信息

+ 3 - 2
src/services/api/order/index.ts

@@ -1,7 +1,8 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 
-const { userId, firstAccountId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId, firstAccountId } = loginStore.$toRefs()
 
 /**
  * 查询仓单成交明细

+ 3 - 2
src/services/api/user/index.ts

@@ -1,8 +1,9 @@
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import http from '@/services/http'
 import tradeServer from '@/services/socket/trade'
 
-const { userId } = loginStore.$mapGetters()
+const loginStore = useLoginStore()
+const { userId } = loginStore.$toRefs()
 
 /**
  * 查询收货地址信息

+ 4 - 2
src/services/http/index.ts

@@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig } from 'axios'
 //import qs from 'qs'
 //import cryptojs from 'crypto-js'
 //import { addPending, removePending } from './pending'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { CommonResult, ResultCode } from './interface'
 import service from '@/services'
 
@@ -12,13 +12,15 @@ export default new (class {
     })
 
     constructor() {
+        const loginStore = useLoginStore()
+
         // 请求拦截器
         this.axiosInstance.interceptors.request.use(
             (config) => {
                 //addPending(config) //将当前请求添加到列表中
                 //请求头签名
                 const sign = {
-                    token: loginStore.getters.token,
+                    token: loginStore.token,
                     signsecret: 'qz7qWOMXKTMT5JlDs5w4NTPwWeR3xhF1v6wqbZ9cExmP6cc3spvNAp1wJJ1SqRI5',
                     timestamp: new Date().getTime(),
                 }

+ 3 - 2
src/services/socket/index.ts

@@ -6,7 +6,7 @@ import { FunCode } from '@/constants/funcode'
 import { parseReceivePush } from './quote/build/decode'
 import protobuf from './trade/protobuf'
 import { checkToken, stopCheckToken, checkTokenLoop } from '@/business/common'
-import { errorInfoStore } from '@/stores'
+import { useErrorInfoStore } from '@/stores'
 import { localData } from '@/stores/storage'
 import service from '@/services'
 import eventBus from '@/services/bus'
@@ -43,7 +43,8 @@ export default new (class {
                 case FunCode.LogoutRsp: {
                     // 通知上层 用户登出
                     protobuf.responseDecode<Proto.LogoutRsp>(FunCode[funCode], content).then(({ RetCode, RetDesc }) => {
-                        const msg = errorInfoStore.actions.getErrorInfoByCode(RetCode)
+                        const { getErrorInfoByCode } = useErrorInfoStore()
+                        const msg = getErrorInfoByCode(RetCode)
                         const error = (RetDesc || RetCode).toString();
                         localData.reset('autoLoginEncryptedData'); // 清除自动登录数据
                         eventBus.$emit('LogoutNotify', msg ?? error);

+ 6 - 6
src/services/socket/quote/index.ts

@@ -1,7 +1,7 @@
 import { v4 } from 'uuid'
 import { Package40 } from '@/utils/websocket/package'
 import { FunCode } from '@/constants/funcode'
-import { loginStore } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { subscribeListToByteArrary } from './build/encode'
 import { parseSubscribeRsp } from './build/decode'
 import Long from 'long'
@@ -25,8 +25,8 @@ export default new (class {
      * @returns 
      */
     private send(params: Proto.QuoteReq[]) {
-        const { loginId, token } = loginStore.$mapGetters()
-        const content = subscribeListToByteArrary(params, token.value, Long.fromNumber(loginId.value));
+        const { loginId, token } = useLoginStore()
+        const content = subscribeListToByteArrary(params, token, Long.fromNumber(loginId));
 
         return new Promise<Proto.QuoteRsp[]>((resolve, reject) => {
             socket.sendQuoteServer({
@@ -96,12 +96,12 @@ export default new (class {
      * @returns 
      */
     addSubscribe = (goodsCodes: string[], key?: string) => {
-        const { token } = loginStore.$mapGetters()
+        const { token } = useLoginStore()
         const uuid = key ?? v4()
         const value = this.quoteSubscribeMap.get(uuid) ?? []
 
         const start = () => {
-            if (token.value) {
+            if (token) {
                 // 对相同 key 订阅的商品进行合并处理
                 this.quoteSubscribeMap.set(uuid, [...value, ...goodsCodes])
                 this.quoteSubscribe()
@@ -116,7 +116,7 @@ export default new (class {
                 if (flag) {
                     console.log('删除订阅', uuid)
                 }
-                if (token.value) {
+                if (token) {
                     this.quoteSubscribe()
                 }
                 return flag

+ 6 - 5
src/services/socket/trade/index.ts

@@ -1,7 +1,7 @@
 import { v4 } from 'uuid'
 import { Package50 } from '@/utils/websocket/package'
 import { FunCode } from '@/constants/funcode'
-import { loginStore, errorInfoStore } from '@/stores'
+import { useLoginStore, useErrorInfoStore } from '@/stores'
 import { TradeResponse, TradeRequestConfig } from './interface'
 import cryptojs from 'crypto-js'
 import Protobuf from './protobuf'
@@ -14,17 +14,17 @@ export default new (class {
      * @returns 
      */
     private send<T>({ params, reqName, rspName, marketId = 0 }: TradeRequestConfig) {
-        const { userId, firstAccountId } = loginStore.$mapGetters()
+        const { userId, firstAccountId } = useLoginStore()
         const reqCode = FunCode[reqName]
         const rspCode = FunCode[rspName]
 
         // 默认请求头
         params.Header = {
-            AccountID: firstAccountId.value,
+            AccountID: firstAccountId,
             MarketID: marketId,
             FunCode: reqCode,
             UUID: v4(),
-            UserID: userId.value,
+            UserID: userId,
             ...params.Header
         }
 
@@ -83,7 +83,8 @@ export default new (class {
                 if (res.Status === 0 || res.Status == 6007) {
                     return Promise.resolve(res)
                 }
-                const msg = errorInfoStore.actions.getErrorInfoByCode(res.RetCode)
+                const { getErrorInfoByCode } = useErrorInfoStore()
+                const msg = getErrorInfoByCode(res.RetCode)
                 const error = String(res.RetDesc || res.RetCode)
                 return Promise.reject(msg ?? error)
             }

+ 0 - 0
src/stores/base.ts → src/stores/dev.ts


+ 9 - 9
src/stores/index.ts

@@ -1,9 +1,9 @@
-export { loginStore } from './modules/login'
-export { userStore } from './modules/user'
-export { globalStore } from './modules/global'
-export { menuStore } from './modules/menu'
-export { accountStore } from './modules/account'
-export { futuresStore } from './modules/futures'
-//export { languageStore } from './modules/language'
-export { enumStore, enumMap } from './modules/enum'
-export { errorInfoStore } from './modules/errorInfo'
+export { useLoginStore } from './modules/login'
+export { useUserStore } from './modules/user'
+export { useGlobalStore } from './modules/global'
+export { useMenuStore } from './modules/menu'
+export { useAccountStore } from './modules/account'
+export { useFuturesStore } from './modules/futures'
+//export { i18n, useLanguageStore } from './modules/language'
+export { useEnumStore } from './modules/enum'
+export { useErrorInfoStore } from './modules/errorInfo'

+ 56 - 60
src/stores/modules/account.ts

@@ -1,71 +1,67 @@
+import { toRefs, computed, reactive } from 'vue'
 import { queryTaAccounts } from '@/services/api/account'
-import { loginStore } from './login'
-import { createStore } from '../base'
+import { defineStore } from '../store'
+import { useLoginStore } from './login'
 import eventBus from '@/services/bus'
 
 /**
  * 账号存储对象
+ * @returns 
  */
-export const accountStore = createStore({
-    state() {
-        return {
-            loading: false,
-            accountList: <Model.TaAccountsRsp[]>[],
-            accountId: 0,
-        }
-    },
-    getters: {
-        // 当前资金账户信息
-        accountInfo() {
-            return this.state.accountList.find((e) => e.accountid === this.state.accountId)
-        },
-        // 冻结资金
-        freezeMargin() {
-            const { freezecharge = 0, freezemargin = 0, otherfreezemargin = 0, outamountfreeze = 0 } = this.getters.accountInfo ?? {}
-            return freezecharge + freezemargin + otherfreezemargin + outamountfreeze
-        },
-        // 可用资金
-        avaiableMoney() {
-            const { currentbalance = 0 } = this.getters.accountInfo ?? {}
-            return currentbalance - this.getters.freezeMargin
-        }
-    },
-    actions: {
-        // 获取资金账户列表
-        async getAccountList() {
-            this.state.loading = true
-            try {
-                const res = await queryTaAccounts({
-                    loginID: loginStore.getters.loginId
-                })
-                const dataList = res.data
-                if (dataList.length) {
-                    this.state.accountList = dataList
-                    // 查找当前选中的资金账户
-                    const account = dataList.find((e) => e.accountid === this.state.accountId)
-                    if (account) {
-                        this.state.loading = false
-                    } else {
-                        // 如果不存在,默认选中第一个账户
-                        this.state.accountId = dataList[0].accountid
-                    }
-                } else {
-                    this.state.loading = false
-                    this.actions.reset()
-                }
-            } catch {
-                this.state.loading = false
+export const useAccountStore = defineStore(() => {
+    const loginStore = useLoginStore()
+
+    const state = reactive({
+        loading: false,
+        accountList: <Model.TaAccountsRsp[]>[],
+        accountId: 0,
+    })
+
+    // 当前资金账户信息
+    const accountInfo = computed(() => {
+        return state.accountList.find((e) => e.accountid === state.accountId)
+    })
+
+    // 冻结资金
+    const freezeMargin = computed(() => {
+        const { freezecharge = 0, freezemargin = 0, otherfreezemargin = 0, outamountfreeze = 0 } = accountInfo.value ?? {}
+        return freezecharge + freezemargin + otherfreezemargin + outamountfreeze
+    })
+
+    // 可用资金
+    const avaiableMoney = computed(() => {
+        const { currentbalance = 0 } = accountInfo.value ?? {}
+        return currentbalance - freezeMargin.value
+    })
+
+    // 获取资金账户列表
+    const getAccountList = async () => {
+        try {
+            state.loading = true
+            const res = await queryTaAccounts({
+                loginID: loginStore.loginId
+            })
+            const data = res.data
+            state.accountList = data
+
+            // 查找当前选中的资金账户
+            if (!data.every((e) => e.accountid === state.accountId)) {
+                state.accountId = data[0]?.accountid ?? 0
             }
-        },
-        // 重置数据
-        reset() {
-            this.state.accountList = []
-            this.state.accountId = 0
+        } finally {
+            state.loading = false
         }
     }
-})
 
-// 接收资金变动通知
-export const moneyChangedNotify = eventBus.$on('MoneyChangedNotify', () => {
-    accountStore.actions.getAccountList()
+    // 接收资金变动通知
+    const moneyChangedNotify = eventBus.$on('MoneyChangedNotify', () => getAccountList())
+
+    return {
+        ...toRefs(state),
+        accountInfo,
+        freezeMargin,
+        avaiableMoney,
+        moneyChangedNotify,
+        getAccountList,
+    }
 })

+ 73 - 61
src/stores/modules/enum.ts

@@ -1,6 +1,6 @@
 import { shallowRef, ShallowRef } from 'vue'
 import { queryAllEnums } from '@/services/api/common'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { sessionData } from '../storage'
 
 /**
@@ -14,7 +14,7 @@ export interface EnumType {
 
 const enumKeys = ['clientType', 'scoreConfigType', 'accountBusinessCode', 'certificatetype', 'signstatus', 'thjOrderStatus', 'THJDeliveryMode', 'goodsunit', 'WROutInApplyStatus2', 'THJTransferStatus', 'WRTradeOrderStatus', 'THJMarket', 'THJProfitRoleType'] as const
 
-export const enumMap = new Map<typeof enumKeys[number], ShallowRef<Model.EnumRsp[]>>()
+const enumMap = new Map<typeof enumKeys[number], ShallowRef<Model.EnumRsp[]>>()
 
 // 初始化枚举列表
 for (const key of enumKeys) {
@@ -24,68 +24,80 @@ for (const key of enumKeys) {
 /**
  * 枚举存储对象
  */
-export const enumStore = createStore({
-    state() {
-        return {
-            loading: false,
-            allEnums: sessionData.getRef('allEnums'),
+export const useEnumStore = defineStore(() => {
+    const loading = shallowRef(false)
+    const allEnums = sessionData.getRef('allEnums')
+
+    // 获取所有枚举列表
+    const getAllEnumList = async () => {
+        if (!allEnums.value.length) {
+            loading.value = true
+            await queryAllEnums().then((res) => {
+                allEnums.value = res.data
+            }).finally(() => {
+                loading.value = false
+            })
         }
-    },
-    actions: {
-        // 获取所有枚举列表
-        async getAllEnumList() {
-            if (!this.state.allEnums.length) {
-                this.state.loading = true
-                await queryAllEnums().then((res) => {
-                    this.state.allEnums = res.data
-                }).finally(() => {
-                    this.state.loading = false
-                })
-            }
-            // 清空列表数据
-            for (const item of enumMap.values()) {
-                item.value = []
+
+        // 清空列表数据
+        for (const item of enumMap.values()) {
+            item.value = []
+        }
+
+        allEnums.value.forEach((e) => {
+            const mapKey = enumKeys.find((key) => key === e.enumdiccode)
+            if (mapKey && e.enumitemstatus === 1) {
+                const enumRef = enumMap.get(mapKey)
+                enumRef?.value.push(e)
             }
-            this.state.allEnums.forEach((e) => {
-                const mapKey = enumKeys.find((key) => key === e.enumdiccode)
-                if (mapKey && e.enumitemstatus === 1) {
-                    const enumRef = enumMap.get(mapKey)
-                    enumRef?.value.push(e)
+        })
+    }
+
+    // 获取枚举信息
+    const getEnumTypeInfo = (enumKey: typeof enumKeys[number], value: number) => {
+        const enums = enumMap.get(enumKey)
+        return enums?.value.find((e) => e.enumitemname === value)
+    }
+
+    // 获取枚举列表
+    const getEnumTypeList = (enumKey: typeof enumKeys[number], propertys?: (keyof Model.EnumRsp)[]) => {
+        const enums = enumMap.get(enumKey)
+        if (enums) {
+            return enums.value.map((e) => {
+                const props = propertys?.reduce((res, prop) => {
+                    const value = e[prop]
+                    if (value) res.push(value)
+                    return res
+                }, [] as unknown[])
+                return {
+                    label: props?.length ? props.join('-') : e.enumdicname,
+                    value: e.enumitemname,
                 }
             })
-        },
-        // 获取枚举信息
-        getEnumTypeInfo(enumKey: typeof enumKeys[number], value: number) {
-            const enums = enumMap.get(enumKey)
-            return enums?.value.find((e) => e.enumitemname === value)
-        },
-        // 获取枚举列表
-        getEnumTypeList: (enumKey: typeof enumKeys[number], propertys?: (keyof Model.EnumRsp)[]) => {
-            const enums = enumMap.get(enumKey)
-            if (enums) {
-                return enums.value.map((e) => {
-                    const props = propertys?.reduce((res, prop) => {
-                        const value = e[prop]
-                        if (value) res.push(value)
-                        return res
-                    }, [] as unknown[])
-                    return {
-                        label: props?.length ? props.join('-') : e.enumdicname,
-                        value: e.enumitemname,
-                    }
-                })
-            }
-            return []
-        },
-        // 根据枚举值获取枚举名称
-        getEnumTypeName(enums: EnumType[], value?: number) {
-            const item = enums.find((e) => e.value === value)
-            return item?.label ?? value?.toString() ?? '无效枚举'
-        },
-        // 根据枚举名称获取对应的值
-        getEnumTypeValue(enums: EnumType[], label?: string) {
-            const item = enums.find((e) => e.label === label)
-            return item?.value ?? label
         }
-    },
+        return []
+    }
+
+    // 根据枚举值获取枚举名称
+    const getEnumTypeName = (enums: EnumType[], value?: number) => {
+        const item = enums.find((e) => e.value === value)
+        return item?.label ?? value?.toString() ?? '无效枚举'
+    }
+
+    // 根据枚举名称获取对应的值
+    const getEnumTypeValue = (enums: EnumType[], label?: string) => {
+        const item = enums.find((e) => e.label === label)
+        return item?.value ?? label
+    }
+
+    return {
+        loading,
+        allEnums,
+        enumMap,
+        getAllEnumList,
+        getEnumTypeInfo,
+        getEnumTypeList,
+        getEnumTypeName,
+        getEnumTypeValue
+    }
 })

+ 28 - 25
src/stores/modules/errorInfo.ts

@@ -1,36 +1,39 @@
+import { shallowRef } from 'vue'
 import { queryErrorInfos } from '@/services/api/common'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { sessionData } from '../storage'
 
 /**
  * 错误信息存储对象
  */
-export const errorInfoStore = createStore({
-    state() {
-        return {
-            loading: false,
-            errorInfos: sessionData.getRef('errorInfos'),
-        }
-    },
-    actions: {
-        // 获取系统错误信息
-        async getErrorInfoList() {
-            if (this.state.errorInfos.length) {
+export const useErrorInfoStore = defineStore(() => {
+    const loading = shallowRef(false)
+    const errorInfos = sessionData.getRef('errorInfos')
+
+    // 获取系统错误信息
+    const getErrorInfoList = async () => {
+        try {
+            if (errorInfos.value.length) {
                 return Promise.resolve()
             }
-            this.state.loading = true
-            try {
-                const res = await queryErrorInfos()
-                this.state.errorInfos = res.data
-            } finally {
-                this.state.loading = false
-            }
-        },
-        // 根据 code 获取错误信息
-        getErrorInfoByCode(code: number) {
-            const errorInfos = this.state.errorInfos
-            const error = errorInfos.find((e) => e.errorid === code)
-            return error?.description
+            loading.value = true
+            const res = await queryErrorInfos()
+            errorInfos.value = res.data
+        } finally {
+            loading.value = false
         }
     }
+
+    // 根据 code 获取错误信息
+    const getErrorInfoByCode = (code: number) => {
+        const error = errorInfos.value.find((e) => e.errorid === code)
+        return error?.description
+    }
+
+    return {
+        loading,
+        errorInfos,
+        getErrorInfoList,
+        getErrorInfoByCode,
+    }
 })

+ 280 - 273
src/stores/modules/futures.ts

@@ -1,300 +1,307 @@
-import { computed } from 'vue'
+import { reactive, computed, toRefs } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
 import { queryErmcpGoods, queryQuoteDay } from '@/services/api/goods'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { timerTask } from '@/utils/timer'
 import eventBus from '@/services/bus'
 import moment from 'moment'
 
 /**
  * 期货存储对象
+ * @returns 
  */
-export const futuresStore = createStore({
-    state() {
-        return {
-            loading: false,
-            quotes: <Proto.Quote[]>[], // 行情数据
-            goodsList: <Model.GoodsRsp[]>[], // 商品列表
-            quoteDayList: <Model.QuoteDayRsp[]>[], // 盘面列表
-        }
-    },
-    getters: {
-        quoteList() {
-            return this.state.goodsList.reduce((res, cur) => {
-                const { goodscode, goodsname, goodsgroupid, marketid, decimalplace } = cur
-                const {
-                    last = 0,
-                    bid = 0,
-                    ask = 0,
-                    bidvolume = 0,
-                    askvolume = 0,
-                    totalvolume = 0,
-                    lastvolume = 0,
-                    holdvolume = 0,
-                    holdincrement = 0,
-                    presettle = 0,
-                    totalturnover = 0,
-                    opened = 0,
-                    highest = 0,
-                    lowest = 0,
-                    lasttime = '',
-                } = this.actions.getQuoteDayInfoByCode(goodscode).value ?? {}
+export const useFuturesStore = defineStore(() => {
+    const state = reactive({
+        loading: false,
+        quotes: <Proto.Quote[]>[], // 行情数据
+        goodsList: <Model.GoodsRsp[]>[], // 商品列表
+        quoteDayList: <Model.QuoteDayRsp[]>[], // 盘面列表
+    })
 
-                const change = last === 0 ? 0 : last - presettle // 涨跌额/涨跌: 最新价 - 昨结价
+    // 行情列表
+    const quoteList = computed(() => {
+        return state.goodsList.reduce((res, cur) => {
+            const { goodscode, goodsname, goodsgroupid, marketid, decimalplace } = cur
+            const {
+                last = 0,
+                bid = 0,
+                ask = 0,
+                bidvolume = 0,
+                askvolume = 0,
+                totalvolume = 0,
+                lastvolume = 0,
+                holdvolume = 0,
+                holdincrement = 0,
+                presettle = 0,
+                totalturnover = 0,
+                opened = 0,
+                highest = 0,
+                lowest = 0,
+                lasttime = '',
+            } = getQuoteDayInfoByCode(goodscode).value ?? {}
 
-                const item: Model.Futures = {
-                    marketid,
-                    goodsgroupid,
-                    goodscode,
-                    goodsname,
-                    decimalplace,
-                    last,
-                    lasttime,
-                    amplitude: change === 0 ? 0 : change / presettle, // 涨跌幅/幅度: (最新价 - 昨结价) / 昨结价
-                    change,
-                    bid,
-                    ask,
-                    bidvolume,
-                    askvolume,
-                    totalvolume,
-                    lastvolume,
-                    holdvolume,
-                    holdincrement,
-                    presettle,
-                    totalturnover,
-                    opened,
-                    highest,
-                    lowest,
-                }
-                res.push(item)
-                return res
-            }, [] as Model.Futures[])
-        }
-    },
-    actions: {
-        // 获取商品列表
-        async getGoodsList() {
-            this.state.loading = true
-            try {
-                const res = await queryErmcpGoods()
-                const codes = res.data.map((e) => e.goodscode)
-                this.state.goodsList = res.data
+            const change = last === 0 ? 0 : last - presettle // 涨跌额/涨跌: 最新价 - 昨结价
 
-                // 获取商品盘面信息
-                const getQuoteDay = async () => {
-                    try {
-                        const res_1 = await queryQuoteDay({
-                            goodsCodes: codes.join(',')
-                        })
-                        this.state.quoteDayList = res_1.data
-                    } finally {
-                        // 每5分钟获取一次盘面
-                        timerTask.setTimeout(() => getQuoteDay(), 5 * 60 * 1000, 'quoteDay')
-                    }
-                }
+            const item: Model.Futures = {
+                marketid,
+                goodsgroupid,
+                goodscode,
+                goodsname,
+                decimalplace,
+                last,
+                lasttime,
+                amplitude: change === 0 ? 0 : change / presettle, // 涨跌幅/幅度: (最新价 - 昨结价) / 昨结价
+                change,
+                bid,
+                ask,
+                bidvolume,
+                askvolume,
+                totalvolume,
+                lastvolume,
+                holdvolume,
+                holdincrement,
+                presettle,
+                totalturnover,
+                opened,
+                highest,
+                lowest,
+            }
+            res.push(item)
+            return res
+        }, [] as Model.Futures[])
+    })
 
-                if (codes.length) {
-                    getQuoteDay()
+    // 获取商品列表
+    const getGoodsList = async () => {
+        state.loading = true
+        try {
+            const res = await queryErmcpGoods()
+            const codes = res.data.map((e) => e.goodscode)
+            state.goodsList = res.data
+
+            // 获取商品盘面信息
+            const getQuoteDay = async () => {
+                try {
+                    const res_1 = await queryQuoteDay({
+                        goodsCodes: codes.join(',')
+                    })
+                    state.quoteDayList = res_1.data
+                } finally {
+                    // 每5分钟获取一次盘面
+                    timerTask.setTimeout(() => getQuoteDay(), 5 * 60 * 1000, 'quoteDay')
                 }
-            } finally {
-                this.state.loading = false
             }
-        },
-        // 通过 goodscode 获取盘面实时行情
-        getQuoteDayInfoByCode(goodscode: string) {
-            return computed(() => this.state.quoteDayList.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase()))
-        },
-        // 通过 goodscode 获取商品实时报价
-        getGoodsPriceByCode(goodscode: string) {
-            return computed(() => {
-                const quote = this.actions.getQuoteDayInfoByCode(goodscode)
-                return quote.value?.last ?? 0
-            })
+
+            if (codes.length) {
+                getQuoteDay()
+            }
+        } finally {
+            state.loading = false
         }
     }
-})
 
-// 接收行情推送通知
-export const quotePushNotify = eventBus.$on('QuotePushNotify', (res) => {
-    const { quotes } = futuresStore.$mapState()
-    const data = res as Proto.Quote[]
-    data.forEach((item) => {
-        const index = quotes.value.findIndex((e) => e.goodscode === item.goodscode)
-        if (index > -1) {
-            quotes.value[index] = item
-        } else {
-            quotes.value.push(item)
-        }
-    })
-    handleQuote()
-})
+    // 通过 goodscode 获取盘面实时行情
+    const getQuoteDayInfoByCode = (goodscode: string) => {
+        return computed(() => state.quoteDayList.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase()))
+    }
 
-// 处理行情数据
-const handleQuote = timerInterceptor.setThrottle(() => {
-    const { quotes, goodsList, quoteDayList, } = futuresStore.$mapState()
-    quotes.value.forEach((item) => {
-        const goods = goodsList.value.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
-        const quote = quoteDayList.value.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
-        const lasttime = (item.date && item.time) ? moment(item.date + item.time, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss') : ''
+    // 通过 goodscode 获取商品实时报价
+    const getGoodsPriceByCode = (goodscode: string) => {
+        return computed(() => {
+            const quote = getQuoteDayInfoByCode(goodscode)
+            return quote.value?.last ?? 0
+        })
+    }
 
-        // 处理报价小数位
-        const last = (() => {
-            const decimal = goods?.decimalplace ?? 0
-            const num = Math.pow(10, decimal)
-            if (item.last) {
-                return item.last / num
-            }
-            return 0
-        })()
+    // 处理行情数据
+    const handleQuote = timerInterceptor.setThrottle(() => {
+        state.quotes.forEach((item) => {
+            const goods = state.goodsList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
+            const quote = state.quoteDayList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
+            const lasttime = (item.date && item.time) ? moment(item.date + item.time, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss') : ''
 
-        if (quote) {
-            Object.entries(item).forEach(([key, value]) => {
-                // 只更新存在的属性
-                if (Reflect.has(quote, key)) {
-                    Object.defineProperty(quote, key, { value })
+            // 处理报价小数位
+            const last = (() => {
+                const decimal = goods?.decimalplace ?? 0
+                const num = Math.pow(10, decimal)
+                if (item.last) {
+                    return item.last / num
                 }
-            })
-            quote.last = last
-            // 处理最高最低价
-            if (last) {
-                if (last > quote.highest) {
-                    quote.highest = last
+                return 0
+            })()
+
+            if (quote) {
+                Object.entries(item).forEach(([key, value]) => {
+                    // 只更新存在的属性
+                    if (Reflect.has(quote, key)) {
+                        Object.defineProperty(quote, key, { value })
+                    }
+                })
+                quote.last = last
+                // 处理最高最低价
+                if (last) {
+                    if (last > quote.highest) {
+                        quote.highest = last
+                    }
+                    if (last < quote.lowest) {
+                        quote.lowest = last
+                    }
                 }
-                if (last < quote.lowest) {
-                    quote.lowest = last
+                // 处理最新时间
+                if (lasttime) {
+                    quote.lasttime = lasttime
                 }
+            } else {
+                console.warn('行情推送的商品 ' + item.goodscode + ' 缺少盘面信息')
+                state.quoteDayList.push({
+                    ask: item.ask ?? 0,
+                    ask2: item.ask2 ?? 0,
+                    ask3: item.ask3 ?? 0,
+                    ask4: item.ask4 ?? 0,
+                    ask5: item.ask5 ?? 0,
+                    ask6: 0,
+                    ask7: 0,
+                    ask8: 0,
+                    ask9: 0,
+                    ask10: 0,
+                    askorderid: 0,
+                    askorderid2: 0,
+                    askorderid3: 0,
+                    askorderid4: 0,
+                    askorderid5: 0,
+                    askordervolume: 0,
+                    askordervolume2: 0,
+                    askordervolume3: 0,
+                    askordervolume4: 0,
+                    askordervolume5: 0,
+                    askordervolume6: 0,
+                    askordervolume7: 0,
+                    askordervolume8: 0,
+                    askordervolume9: 0,
+                    askordervolume10: 0,
+                    askqueueinfo: "",
+                    askvolume: item.askvolume ?? 0,
+                    askvolume2: item.askvolume2 ?? 0,
+                    askvolume3: item.askvolume3 ?? 0,
+                    askvolume4: item.askvolume4 ?? 0,
+                    askvolume5: item.askvolume5 ?? 0,
+                    askvolume6: 0,
+                    askvolume7: 0,
+                    askvolume8: 0,
+                    askvolume9: 0,
+                    askvolume10: 0,
+                    averageprice: 0,
+                    bid: item.bid ?? 0,
+                    bid2: item.bid2 ?? 0,
+                    bid3: item.bid3 ?? 0,
+                    bid4: item.bid4 ?? 0,
+                    bid5: item.bid5 ?? 0,
+                    bid6: 0,
+                    bid7: 0,
+                    bid8: 0,
+                    bid9: 0,
+                    bid10: 0,
+                    bidorderid: 0,
+                    bidorderid2: 0,
+                    bidorderid3: 0,
+                    bidorderid4: 0,
+                    bidorderid5: 0,
+                    bidordervolume: 0,
+                    bidordervolume2: 0,
+                    bidordervolume3: 0,
+                    bidordervolume4: 0,
+                    bidordervolume5: 0,
+                    bidordervolume6: 0,
+                    bidordervolume7: 0,
+                    bidordervolume8: 0,
+                    bidordervolume9: 0,
+                    bidordervolume10: 0,
+                    bidqueueinfo: "",
+                    bidvolume: item.bidvolume ?? 0,
+                    bidvolume2: item.bidvolume2 ?? 0,
+                    bidvolume3: item.bidvolume3 ?? 0,
+                    bidvolume4: item.bidvolume4 ?? 0,
+                    bidvolume5: item.bidvolume5 ?? 0,
+                    bidvolume6: 0,
+                    bidvolume7: 0,
+                    bidvolume8: 0,
+                    bidvolume9: 0,
+                    bidvolume10: 0,
+                    calloptionpremiums: item.calloptionpremiums ?? 0,
+                    calloptionpremiums2: item.calloptionpremiums2 ?? 0,
+                    calloptionpremiums3: item.calloptionpremiums3 ?? 0,
+                    calloptionpremiums4: item.calloptionpremiums4 ?? 0,
+                    calloptionpremiums5: item.calloptionpremiums5 ?? 0,
+                    cleartime: 0,
+                    exchangecode: item.exchangecode ?? 0,
+                    exchangedate: item.exchangedate ?? 0,
+                    goodscode: item.goodscode ?? '',
+                    grepmarketprice: 0,
+                    highest: item.highest ?? 0,
+                    holdincrement: 0,
+                    holdvolume: item.holdvolume ?? 0,
+                    iep: 0,
+                    iev: 0,
+                    inventory: item.inventory ?? 0,
+                    iscleared: 0,
+                    issettled: 0,
+                    last,
+                    lastlot: 0,
+                    lasttime,
+                    Lastturnover: 0,
+                    lastvolume: item.lastvolume ?? 0,
+                    limitdown: item.limitlow ?? 0,
+                    limitup: item.limithigh ?? 0,
+                    lowest: item.lowest ?? 0,
+                    nontotalholdervolume: 0,
+                    nontotallot: 0,
+                    nontotalturnover: 0,
+                    nontotalvolume: 0,
+                    opened: item.opened ?? 0,
+                    opentime: '',
+                    orderid: 0,
+                    preclose: item.preclose ?? 0,
+                    preholdvolume: item.preholdvolume ?? 0,
+                    presettle: item.presettle ?? 0,
+                    publictradetype: '',
+                    putoptionpremiums: item.putoptionpremiums ?? 0,
+                    putoptionpremiums2: item.putoptionpremiums2 ?? 0,
+                    putoptionpremiums3: item.putoptionpremiums3 ?? 0,
+                    putoptionpremiums4: item.putoptionpremiums4 ?? 0,
+                    putoptionpremiums5: item.putoptionpremiums5 ?? 0,
+                    settle: item.settle ?? 0,
+                    strikeprice: 0,
+                    totalaskvolume: 0,
+                    totalbidvolume: 0,
+                    totallot: 0,
+                    totalturnover: item.totalturnover ?? 0,
+                    totalvolume: item.totalvolume ?? 0,
+                    utclasttime: ''
+                })
             }
-            // 处理最新时间
-            if (lasttime) {
-                quote.lasttime = lasttime
+        })
+    }, 200)
+
+    // 接收行情推送通知
+    const quotePushNotify = eventBus.$on('QuotePushNotify', (res) => {
+        const data = res as Proto.Quote[]
+        data.forEach((item) => {
+            const index = state.quotes.findIndex((e) => e.goodscode === item.goodscode)
+            if (index > -1) {
+                state.quotes[index] = item
+            } else {
+                state.quotes.push(item)
             }
-        } else {
-            console.warn('行情推送的商品 ' + item.goodscode + ' 缺少盘面信息')
-            quoteDayList.value.push({
-                ask: item.ask ?? 0,
-                ask2: item.ask2 ?? 0,
-                ask3: item.ask3 ?? 0,
-                ask4: item.ask4 ?? 0,
-                ask5: item.ask5 ?? 0,
-                ask6: 0,
-                ask7: 0,
-                ask8: 0,
-                ask9: 0,
-                ask10: 0,
-                askorderid: 0,
-                askorderid2: 0,
-                askorderid3: 0,
-                askorderid4: 0,
-                askorderid5: 0,
-                askordervolume: 0,
-                askordervolume2: 0,
-                askordervolume3: 0,
-                askordervolume4: 0,
-                askordervolume5: 0,
-                askordervolume6: 0,
-                askordervolume7: 0,
-                askordervolume8: 0,
-                askordervolume9: 0,
-                askordervolume10: 0,
-                askqueueinfo: "",
-                askvolume: item.askvolume ?? 0,
-                askvolume2: item.askvolume2 ?? 0,
-                askvolume3: item.askvolume3 ?? 0,
-                askvolume4: item.askvolume4 ?? 0,
-                askvolume5: item.askvolume5 ?? 0,
-                askvolume6: 0,
-                askvolume7: 0,
-                askvolume8: 0,
-                askvolume9: 0,
-                askvolume10: 0,
-                averageprice: 0,
-                bid: item.bid ?? 0,
-                bid2: item.bid2 ?? 0,
-                bid3: item.bid3 ?? 0,
-                bid4: item.bid4 ?? 0,
-                bid5: item.bid5 ?? 0,
-                bid6: 0,
-                bid7: 0,
-                bid8: 0,
-                bid9: 0,
-                bid10: 0,
-                bidorderid: 0,
-                bidorderid2: 0,
-                bidorderid3: 0,
-                bidorderid4: 0,
-                bidorderid5: 0,
-                bidordervolume: 0,
-                bidordervolume2: 0,
-                bidordervolume3: 0,
-                bidordervolume4: 0,
-                bidordervolume5: 0,
-                bidordervolume6: 0,
-                bidordervolume7: 0,
-                bidordervolume8: 0,
-                bidordervolume9: 0,
-                bidordervolume10: 0,
-                bidqueueinfo: "",
-                bidvolume: item.bidvolume ?? 0,
-                bidvolume2: item.bidvolume2 ?? 0,
-                bidvolume3: item.bidvolume3 ?? 0,
-                bidvolume4: item.bidvolume4 ?? 0,
-                bidvolume5: item.bidvolume5 ?? 0,
-                bidvolume6: 0,
-                bidvolume7: 0,
-                bidvolume8: 0,
-                bidvolume9: 0,
-                bidvolume10: 0,
-                calloptionpremiums: item.calloptionpremiums ?? 0,
-                calloptionpremiums2: item.calloptionpremiums2 ?? 0,
-                calloptionpremiums3: item.calloptionpremiums3 ?? 0,
-                calloptionpremiums4: item.calloptionpremiums4 ?? 0,
-                calloptionpremiums5: item.calloptionpremiums5 ?? 0,
-                cleartime: 0,
-                exchangecode: item.exchangecode ?? 0,
-                exchangedate: item.exchangedate ?? 0,
-                goodscode: item.goodscode ?? '',
-                grepmarketprice: 0,
-                highest: item.highest ?? 0,
-                holdincrement: 0,
-                holdvolume: item.holdvolume ?? 0,
-                iep: 0,
-                iev: 0,
-                inventory: item.inventory ?? 0,
-                iscleared: 0,
-                issettled: 0,
-                last,
-                lastlot: 0,
-                lasttime,
-                Lastturnover: 0,
-                lastvolume: item.lastvolume ?? 0,
-                limitdown: item.limitlow ?? 0,
-                limitup: item.limithigh ?? 0,
-                lowest: item.lowest ?? 0,
-                nontotalholdervolume: 0,
-                nontotallot: 0,
-                nontotalturnover: 0,
-                nontotalvolume: 0,
-                opened: item.opened ?? 0,
-                opentime: '',
-                orderid: 0,
-                preclose: item.preclose ?? 0,
-                preholdvolume: item.preholdvolume ?? 0,
-                presettle: item.presettle ?? 0,
-                publictradetype: '',
-                putoptionpremiums: item.putoptionpremiums ?? 0,
-                putoptionpremiums2: item.putoptionpremiums2 ?? 0,
-                putoptionpremiums3: item.putoptionpremiums3 ?? 0,
-                putoptionpremiums4: item.putoptionpremiums4 ?? 0,
-                putoptionpremiums5: item.putoptionpremiums5 ?? 0,
-                settle: item.settle ?? 0,
-                strikeprice: 0,
-                totalaskvolume: 0,
-                totalbidvolume: 0,
-                totallot: 0,
-                totalturnover: item.totalturnover ?? 0,
-                totalvolume: item.totalvolume ?? 0,
-                utclasttime: ''
-            })
-        }
+        })
+        handleQuote()
     })
-}, 200)
+
+    return {
+        ...toRefs(state),
+        quoteList,
+        getGoodsList,
+        getQuoteDayInfoByCode,
+        getGoodsPriceByCode,
+        quotePushNotify,
+    }
+})

+ 94 - 86
src/stores/modules/global.ts

@@ -1,103 +1,111 @@
+import { reactive, toRefs } from 'vue'
 import { AppTheme } from '@/constants/theme'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { localData } from '../storage'
 import plus from '@/utils/h5plus'
 
-export const globalStore = createStore({
-    state() {
-        return {
-            appTheme: localData.getRef('appTheme'),
-            clientWidth: 0, // 客户端宽度
-            isMobile: false, // 是否移动设备
-            animating: false, // 控制路由动画的状态
-        }
-    },
-    actions: {
-        // 设置状态栏主题色
-        setStatusBarTheme(theme: AppTheme) {
-            switch (theme) {
-                case AppTheme.Default:
-                case AppTheme.Dark: {
-                    plus.setStatusBarStyle('light')
-                    break
-                }
-                default: {
-                    plus.setStatusBarStyle('dark')
-                }
+export const useGlobalStore = defineStore(() => {
+    const appTheme = localData.getRef('appTheme')
+
+    const state = reactive({
+        clientWidth: 0, // 客户端宽度
+        isMobile: false, // 是否移动设备
+    })
+
+    // 设置状态栏主题色
+    const setStatusBarTheme = (theme: AppTheme) => {
+        switch (theme) {
+            case AppTheme.Default:
+            case AppTheme.Dark: {
+                plus.setStatusBarStyle('light')
+                break
+            }
+            default: {
+                plus.setStatusBarStyle('dark')
             }
-        },
-        // 设置主题
-        setTheme(key: keyof typeof AppTheme) {
-            const theme = AppTheme[key]
-            this.actions.setStatusBarTheme(theme)
-            document.documentElement.setAttribute('theme', theme)
-            this.state.appTheme = theme
-        },
-        // 适配客户端屏幕
-        screenAdapter(remsize = false) {
-            const { clientWidth, isMobile } = this.$mapState()
-            const { isPc } = this.actions.getClientAgent()
-            const el = document.documentElement
-            const body = document.body
-            let screenWidth = el.clientWidth
+        }
+    }
+
+    // 设置主题
+    const setTheme = (key: keyof typeof AppTheme) => {
+        const theme = AppTheme[key]
+        setStatusBarTheme(theme)
+        document.documentElement.setAttribute('theme', theme)
+        appTheme.value = theme
+    }
 
-            if (remsize) {
-                const designSize = 750
-                isMobile.value = true
+    // 适配客户端屏幕
+    const screenAdapter = (remsize = false) => {
+        const { isPc } = getClientAgent()
+        const el = document.documentElement
+        const body = document.body
+        let screenWidth = el.clientWidth
 
-                if (isPc) {
-                    screenWidth = designSize / 1.8
-                    body.style.setProperty('width', '540px')
-                } else {
-                    body.style.removeProperty('width')
-                }
+        if (remsize) {
+            const designSize = 750
+            state.isMobile = true
 
-                if (screenWidth > 0) {
-                    const fontSize = (screenWidth / designSize) * 100 + 'px'
-                    el.style.setProperty('font-size', fontSize)
-                }
+            if (isPc) {
+                screenWidth = designSize / 1.8
+                body.style.setProperty('width', '540px')
             } else {
-                if (screenWidth > 768) {
-                    isMobile.value = false
-                } else {
-                    isMobile.value = true
-                }
+                body.style.removeProperty('width')
+            }
 
-                el.setAttribute('screen', isMobile.value ? 'small' : 'normal')
+            if (screenWidth > 0) {
+                const fontSize = (screenWidth / designSize) * 100 + 'px'
+                el.style.setProperty('font-size', fontSize)
+            }
+        } else {
+            if (screenWidth > 768) {
+                state.isMobile = false
+            } else {
+                state.isMobile = true
             }
 
-            clientWidth.value = body.clientWidth
-        },
-        // 获取客户端平台
-        getClientAgent() {
-            const ua = navigator.userAgent,
-                isWindowsPhone = /(?:Windows Phone)/.test(ua),
-                isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
-                isAndroid = /(?:Android)/.test(ua),
-                isFireFox = /(?:Firefox)/.test(ua),
-                isChrome = /(?:Chrome|CriOS)/.test(ua),
-                isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
-                isiPhone = /(?:iPhone)/.test(ua) && !isTablet,
-                isPc = !isiPhone && !isAndroid && !isSymbian && !isTablet
+            el.setAttribute('screen', state.isMobile ? 'small' : 'normal')
+        }
 
-            return {
-                isTablet,
-                isiPhone,
-                isAndroid,
-                isChrome,
-                isPc,
-            }
+        state.clientWidth = body.clientWidth
+    }
+
+    // 获取客户端平台
+    const getClientAgent = () => {
+        const ua = navigator.userAgent,
+            isWindowsPhone = /(?:Windows Phone)/.test(ua),
+            isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
+            isAndroid = /(?:Android)/.test(ua),
+            isFireFox = /(?:Firefox)/.test(ua),
+            isChrome = /(?:Chrome|CriOS)/.test(ua),
+            isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
+            isiPhone = /(?:iPhone)/.test(ua) && !isTablet,
+            isPc = !isiPhone && !isAndroid && !isSymbian && !isTablet
+
+        return {
+            isTablet,
+            isiPhone,
+            isAndroid,
+            isChrome,
+            isPc,
         }
     }
-})
 
-// 加载主题
-const loadTheme = () => {
-    const theme = globalStore.state.appTheme
-    globalStore.actions.setStatusBarTheme(theme)
-    document.documentElement.setAttribute('theme', theme)
-    document.removeEventListener('DOMContentLoaded', loadTheme)
-}
+    // 加载主题
+    const loadTheme = () => {
+        setStatusBarTheme(appTheme.value)
+        document.documentElement.setAttribute('theme', appTheme.value)
+        document.removeEventListener('DOMContentLoaded', loadTheme)
+    }
 
-// 等待 dom 加载完毕
-document.addEventListener('DOMContentLoaded', loadTheme, false)
+    // 等待 dom 加载完毕
+    document.addEventListener('DOMContentLoaded', loadTheme, false)
+
+    return {
+        ...toRefs(state),
+        appTheme,
+        setStatusBarTheme,
+        setTheme,
+        screenAdapter,
+        getClientAgent,
+    }
+})

+ 22 - 23
src/stores/modules/language.ts

@@ -1,35 +1,34 @@
 import axios from 'axios'
 import { createI18n } from 'vue-i18n'
 import { Language } from '@/constants/language'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { localData } from '../storage'
 
 export const i18n = createI18n({})
 
-export const languageStore = createStore({
-    state() {
-        return {
-            lang: localData.getRef('appLanguage'),
-        }
-    },
-    actions: {
-        // 设置语言
-        async setLanguage(lang: Language) {
-            const locale = i18n.global.getLocaleMessage(lang)
+export const useLanguageStore = defineStore(() => {
+    const appLanguage = localData.getRef('appLanguage')
 
-            if (!Object.keys(locale).length) {
-                await axios(`./language/${lang}.json`).then((res) => {
-                    i18n.global.setLocaleMessage(lang, res.data)
-                }).catch(() => {
-                    // 默认语言
-                })
-            }
+    // 设置语言
+    const setLanguage = async (lang: Language) => {
+        const locale = i18n.global.getLocaleMessage(lang)
 
-            i18n.global.locale = lang
-            this.state.lang = lang
+        if (!Object.keys(locale).length) {
+            await axios(`./language/${lang}.json`).then((res) => {
+                i18n.global.setLocaleMessage(lang, res.data)
+            }).catch(() => {
+                // 默认语言
+            })
         }
+
+        i18n.global.locale = lang
+        appLanguage.value = lang
     }
-})
 
-const { actions, state } = languageStore
-actions.setLanguage(state.lang)
+    setLanguage(appLanguage.value)
+
+    return {
+        appLanguage,
+        setLanguage,
+    }
+})

+ 34 - 32
src/stores/modules/login.ts

@@ -1,39 +1,41 @@
-import { createStore } from '../base'
+import { computed, ref } from 'vue'
+import { defineStore } from '../store'
 import { sessionData } from '../storage'
 
 /**
  * 登录存储对象
  */
-export const loginStore = createStore({
-    state() {
-        return {
-            logining: false,
-            loginInfo: sessionData.getRef('loginInfo'),
-        }
-    },
-    getters: {
-        // 登录令牌
-        token() {
-            return this.state.loginInfo.Token
-        },
-        // 用户ID
-        userId() {
-            return this.state.loginInfo.UserID
-        },
-        // 登录ID
-        loginId() {
-            return this.state.loginInfo.LoginID
-        },
-        // 首个资金账户ID
-        firstAccountId() {
-            const accounts = this.state.loginInfo.AccountIDs
-            return accounts[0] ?? 0
-        },
-    },
-    actions: {
-        // 获取用户登录信息
-        getLoginInfo<K extends keyof Proto.LoginRsp>(key: K) {
-            return this.state.loginInfo[key]
-        },
+export const useLoginStore = defineStore(() => {
+    const logining = ref(false)
+    const loginInfo = sessionData.getRef('loginInfo')
+
+    // 登录令牌
+    const token = computed(() => loginInfo.value.Token)
+
+    // 用户ID
+    const userId = computed(() => loginInfo.value.UserID)
+
+    // 登录ID
+    const loginId = computed(() => loginInfo.value.LoginID)
+
+    // 首个资金账户ID
+    const firstAccountId = computed(() => {
+        const accounts = loginInfo.value.AccountIDs
+        return accounts[0] ?? 0
+    })
+
+    // 获取用户登录信息
+    const getLoginInfo = <K extends keyof Proto.LoginRsp>(key: K) => {
+        return loginInfo.value[key]
+    }
+
+    return {
+        logining,
+        loginInfo,
+        token,
+        userId,
+        loginId,
+        firstAccountId,
+        getLoginInfo,
     }
 })

+ 20 - 22
src/stores/modules/menu.ts

@@ -1,28 +1,26 @@
+import { shallowRef } from 'vue'
 import { queryAccountMenu } from '@/services/api/account'
-import { createStore } from '../base'
+import { defineStore } from '../store'
 import { sessionData } from '../storage'
 
-export const menuStore = createStore({
-    state() {
-        return {
-            loading: false,
-            userRoutes: sessionData.getRef('userRoutes'),
-        }
-    },
-    actions: {
-        /** 获取用户菜单列表 */
-        async getUserMenuList() {
-            try {
-                this.state.loading = true
-                const res = await queryAccountMenu()
-                this.state.userRoutes = res.data
-            } finally {
-                this.state.loading = false
-            }
-        },
-        /** 重置数据 */
-        reset() {
-            this.state.userRoutes = []
+export const useMenuStore = defineStore(() => {
+    const loading = shallowRef(false)
+    const userRoutes = sessionData.getRef('userRoutes')
+
+    /** 获取用户菜单列表 */
+    const getUserMenuList = async () => {
+        try {
+            loading.value = true
+            const res = await queryAccountMenu()
+            userRoutes.value = res.data
+        } finally {
+            loading.value = false
         }
     }
+
+    return {
+        loading,
+        userRoutes,
+        getUserMenuList,
+    }
 })

+ 68 - 58
src/stores/modules/user.ts

@@ -1,69 +1,79 @@
+import { reactive, computed, toRefs } from 'vue'
 import { queryLoginData } from '@/services/api/account'
-import { loginStore } from './login'
-import { createStore } from '../base'
+import { useLoginStore } from './login'
+import { defineStore } from '../store'
 import eventBus from '@/services/bus'
 
 /**
  * 用户存储对象
+ * @returns 
  */
-export const userStore = createStore({
-    state() {
-        return {
-            loading: false,
-            userData: <Model.LoginQueryRsp>{
-                arearole: [],
-                externalExchanges: [],
-                goodsgroups: [],
-                markets: [],
-                systemParams: []
-            },
-        }
-    },
-    getters: {
-        // 用户信息
-        userInfo() {
-            const { userInfo } = this.state.userData
-            return userInfo
-        },
-        // 登录机构名称
-        accountName() {
-            const { userAccount } = this.state.userData
-            return userAccount?.accountname
-        },
-        // 是否已实名认证
-        hasAuth() {
-            const { userAccount } = this.state.userData
-            return userAccount?.hasauth === 1
-        }
-    },
-    actions: {
-        // 获取用户数据
-        async getUserData() {
-            try {
-                this.state.loading = true
-                const res = await queryLoginData({
-                    loginID: loginStore.getters.loginId
-                })
-                this.state.userData = res.data
-            } finally {
-                this.state.loading = false
-            }
-        },
-        // 获取用户数据
-        getUserDataInfo<K extends keyof Model.LoginQueryRsp>(key: K) {
-            return this.state.userData[key]!
+export const useUserStore = defineStore(() => {
+    const loginStore = useLoginStore()
+
+    const state = reactive({
+        loading: false,
+        userData: <Model.LoginQueryRsp>{
+            arearole: [],
+            externalExchanges: [],
+            goodsgroups: [],
+            markets: [],
+            systemParams: []
         },
-        // 获取对应系统参数的对应值
-        getSystemParamValue(paramcode: string) {
-            const { systemParams } = this.state.userData
-            return systemParams.find(obj => {
-                return obj.paramcode === paramcode
-            })?.paramvalue
+    })
+
+    // 用户信息
+    const userInfo = computed(() => state.userData.userInfo)
+
+    // 登录机构名称
+    const accountName = computed(() => {
+        const { userAccount } = state.userData
+        return userAccount?.accountname
+    })
+
+    // 是否已实名认证
+    const hasAuth = computed(() => {
+        const { userAccount } = state.userData
+        return userAccount?.hasauth === 1
+    })
+
+    // 获取用户数据
+    const getUserData = async () => {
+        try {
+            state.loading = true
+            const res = await queryLoginData({
+                loginID: loginStore.loginId
+            })
+            state.userData = res.data
+        } finally {
+            state.loading = false
         }
     }
-})
 
-// 接收账户变更通知
-export const userChangeNtf = eventBus.$on('UserChangeNtf', () => {
-    userStore.actions.getUserData()
+    // 获取用户数据
+    const getUserDataInfo = <K extends keyof Model.LoginQueryRsp>(key: K) => {
+        return state.userData[key]!
+    }
+
+    // 获取对应系统参数的对应值
+    const getSystemParamValue = (paramcode: string) => {
+        const { systemParams } = state.userData
+        return systemParams.find(obj => {
+            return obj.paramcode === paramcode
+        })?.paramvalue
+    }
+
+    // 接收账户变更通知
+    const userChangeNtf = eventBus.$on('UserChangeNtf', () => getUserData())
+
+    return {
+        ...toRefs(state),
+        userInfo,
+        accountName,
+        hasAuth,
+        getUserData,
+        getUserDataInfo,
+        getSystemParamValue,
+        userChangeNtf,
+    }
 })

+ 110 - 0
src/stores/store.ts

@@ -0,0 +1,110 @@
+import { reactive, isRef, isReactive, toRaw, ComputedRef, toRef, effectScope, unref } from 'vue'
+import { v4 } from 'uuid'
+import { Store, StoreState, StoreToRefs } from './types'
+
+/**
+ * 判断是否 ComputedRef 类型
+ * @param obj 
+ * @returns 
+ */
+function isComputed(obj: unknown): obj is ComputedRef {
+    return !!(isRef(obj) && Reflect.has(obj, 'effect'))
+}
+
+/**
+ * 定义一个 store 对象
+ * @param createStore 
+ * @param id 
+ * @returns 
+ */
+export function defineStore<T extends object>(createStore: () => T, id = v4()) {
+    const scope = effectScope()
+    const store = scope.run(() => createStore()) as T
+
+    // 将 store 中的响应式属性转化为 ref 属性
+    const $toRefs = () => {
+        const result = Object.create(null)
+
+        for (const key in store) {
+            const value = store[key]
+            if (isRef(value)) {
+                result[key] = value
+            } else if (isReactive(value)) {
+                result[key] = toRef(store, key)
+            }
+        }
+
+        return result as StoreToRefs<T>
+    }
+
+    // 更新 state 状态
+    const $setState = (callback: (state: StoreState<T>) => void) => {
+        const state = Object.create(null)
+
+        for (const key in store) {
+            const value = store[key]
+            if (!isComputed(value) && (isRef(value) || isReactive(value))) {
+                state[key] = value
+            }
+        }
+
+        callback(reactive(state))
+    }
+
+    // 将 state 重设为初始状态
+    const $reset = () => {
+        const newScope = effectScope()
+        const newStore = scope.run(() => createStore()) as T
+
+        for (const key in store) {
+            const item = store[key]
+            if (!isComputed(item) && isRef(item)) {
+                item.value = unref(newStore[key])
+            }
+            if (isReactive(item)) {
+                for (const prop in item) {
+                    item[prop] = newStore[key][prop]
+                }
+            }
+        }
+
+        newScope.stop()
+    }
+
+    // 销毁当前的 store
+    const $dispose = () => {
+        scope.stop()
+    }
+
+    const $store: Store<T> = reactive({
+        $id: id,
+        $toRefs,
+        $setState,
+        $reset,
+        $dispose,
+        ...store
+    })
+
+    return () => $store
+}
+
+/**
+ * 将 store 中的响应式属性转化为 ref 属性
+ * @param store 
+ * @returns 
+ */
+export function storeToRefs<T extends object>(store: Store<T>) {
+    const raw = toRaw(store)
+    const result = Object.create(null)
+
+    for (const key in raw) {
+        const value = raw[key]
+        if (isRef(value)) {
+            result[key] = value
+        } else if (isReactive(value)) {
+            result[key] = toRef(raw, key)
+        }
+    }
+
+    return result as StoreToRefs<T>
+}

+ 31 - 0
src/stores/types.ts

@@ -0,0 +1,31 @@
+import { Ref, UnwrapNestedRefs, ComputedRef } from 'vue'
+
+// type Method = (...args: unknown[]) => unknown
+
+/**
+ * 选取 Ref 类型的属性,Reactive 类型无法被选取
+ */
+export type StoreState<T> = UnwrapNestedRefs<{ [K in keyof T as T[K] extends ComputedRef ? never : T[K] extends Ref ? K : never]: T[K] }>
+
+/**
+ * 选取 Ref、ComputedRef 类型的属性,Reactive 类型无法被选取
+ */
+export type StoreToRefs<T> = { [K in keyof T as T[K] extends Ref ? K : never]: T[K] }
+
+/**
+ * 选取除 Function 类型外的所有属性,并转为 Ref 类型
+ */
+//export type StoreToRefs<T> = { [K in keyof T as T[K] extends Ref ? K : T[K] extends Method ? never : K]: T[K] extends ComputedRef ? T[K] : ToRef<T[K]> }
+
+interface StoreProps<T extends object> {
+    $id: string;
+    $toRefs(): StoreToRefs<T>;
+    $setState(callback: (state: StoreState<T>) => void): void;
+    $reset(): void;
+    $dispose(): void;
+}
+
+/**
+ * 存储对象
+ */
+export type Store<T extends object> = UnwrapNestedRefs<T & StoreProps<T>>