li.shaoyi 3 tahun lalu
induk
melakukan
06a912baae
72 mengubah file dengan 1321 tambahan dan 899 penghapusan
  1. 18 16
      src/business/account/index.ts
  2. 9 5
      src/business/bargain/index.ts
  3. 20 20
      src/business/common/index.ts
  4. 10 32
      src/business/favorite/index.ts
  5. 12 9
      src/business/goods/index.ts
  6. 4 4
      src/business/notice/index.ts
  7. 10 9
      src/business/order/index.ts
  8. 3 23
      src/business/search/index.ts
  9. 13 34
      src/business/sign/index.ts
  10. 3 3
      src/business/table/index.ts
  11. 16 16
      src/business/trade/desting.ts
  12. 10 23
      src/business/trade/list.ts
  13. 19 17
      src/business/trade/listing.ts
  14. 10 8
      src/business/user/index.ts
  15. 8 5
      src/business/warehouse/index.ts
  16. 2 1
      src/constants/certificate.ts
  17. 5 4
      src/constants/client.ts
  18. 5 4
      src/constants/diamond.ts
  19. 0 69
      src/constants/index.ts
  20. 3 1
      src/constants/menu.ts
  21. 5 4
      src/constants/order.ts
  22. 3 1
      src/constants/receipt.ts
  23. 6 6
      src/hooks/auth/index.ts
  24. 8 3
      src/hooks/datatable/index.ts
  25. 7 0
      src/hooks/datatable/interface.ts
  26. 3 2
      src/hooks/echarts/candlestick/index.ts
  27. 4 4
      src/hooks/echarts/candlestick/options.ts
  28. 3 2
      src/hooks/echarts/timeline/index.ts
  29. 4 5
      src/hooks/echarts/timeline/options.ts
  30. 4 4
      src/packages/mobile/router/index.ts
  31. 7 6
      src/packages/mobile/views/home/components/market/index.vue
  32. 3 2
      src/packages/pc/App.vue
  33. 1 1
      src/packages/pc/components/base/multiple/index.vue
  34. 4 4
      src/packages/pc/components/layouts/header/index.vue
  35. 3 3
      src/packages/pc/components/modules/address/index.vue
  36. 3 3
      src/packages/pc/components/modules/invoice/index.vue
  37. 4 2
      src/packages/pc/main.ts
  38. 3 3
      src/packages/pc/router/dynamicRouter.ts
  39. 5 3
      src/packages/pc/router/index.ts
  40. 8 10
      src/packages/pc/views/boot/index.vue
  41. 1 5
      src/packages/pc/views/favorite/main/index.vue
  42. 5 4
      src/packages/pc/views/search/diamond/index.vue
  43. 5 4
      src/packages/pc/views/search/fancy/index.vue
  44. 3 2
      src/packages/pc/views/trade/buy/components/details/index.vue
  45. 3 2
      src/packages/pc/views/trade/buy/index.vue
  46. 5 4
      src/packages/pc/views/trade/sell/index.vue
  47. 3 2
      src/packages/pc/views/warehousing/goods/components/details/index.vue
  48. 3 2
      src/services/http/index.ts
  49. 0 30
      src/services/language/index.ts
  50. 3 2
      src/services/socket/index.ts
  51. 3 3
      src/services/socket/quote/index.ts
  52. 6 3
      src/services/socket/trade/index.ts
  53. 3 2
      src/services/subscribe/index.ts
  54. 49 0
      src/stores/base.ts
  55. 41 9
      src/stores/index.ts
  56. 67 49
      src/stores/modules/account.ts
  57. 0 54
      src/stores/modules/common.ts
  58. 95 0
      src/stores/modules/enum.ts
  59. 55 0
      src/stores/modules/errorInfo.ts
  60. 54 0
      src/stores/modules/favorite.ts
  61. 58 50
      src/stores/modules/futures.ts
  62. 52 0
      src/stores/modules/language.ts
  63. 108 0
      src/stores/modules/login.ts
  64. 88 0
      src/stores/modules/menu.ts
  65. 46 0
      src/stores/modules/performance.ts
  66. 0 232
      src/stores/modules/storage.ts
  67. 46 0
      src/stores/modules/tableColumn.ts
  68. 65 0
      src/stores/modules/theme.ts
  69. 65 0
      src/stores/modules/user.ts
  70. 0 18
      src/types/store/globalStorage.d.ts
  71. 69 0
      src/utils/storage/base.ts
  72. 52 51
      src/utils/storage/index.ts

+ 18 - 16
src/business/account/index.ts

@@ -1,7 +1,7 @@
 import { shallowRef, reactive } from 'vue'
 import { decryptAES } from '@/utils/websocket/crypto'
 import { useDataTable } from '@/hooks/datatable'
-import { commonStore, accountStore, sessionData } from '@/stores'
+import { useUserStore, useAccountStore, useLoginStore } from '@/stores'
 import { modifyPassword } from '@/services/api/account'
 import { queryCusBankSignBank, queryAccountInOutApply, t2bBankSign, t2bBankCancelSign, queryBankAccountSign, t2bBankDeposit, t2bBankWithdraw } from '@/services/api/bank'
 import { getTableColumns } from '../table'
@@ -9,10 +9,10 @@ import { SignStatus } from '@/constants/bank'
 import cryptojs from 'crypto-js'
 
 export function useAccount() {
-    const { getLoginDataInfo } = commonStore
-    const { accountInfo } = accountStore
-    const loginInfo = getLoginDataInfo('loginAccount')
-    const userInfo = getLoginDataInfo('userInfo')
+    const { getUserDataInfo } = useUserStore()
+    const { currentAccountInfo } = useAccountStore()
+    const loginInfo = getUserDataInfo('loginAccount')
+    const userInfo = getUserDataInfo('userInfo')
     const bankInfo = shallowRef<Ermcp.BankAccountSignRsp>()
     const loading = shallowRef(false)
 
@@ -38,7 +38,7 @@ export function useAccount() {
         loading,
         loginInfo,
         userInfo,
-        accountInfo,
+        currentAccountInfo,
         bankInfo,
         getBankAccountSign,
     }
@@ -46,7 +46,8 @@ export function useAccount() {
 
 // 修改密码
 export function usePassword(ModifyPwdType: 0 | 1 | 2) {
-    const { LoginCode, LoginID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { loginInfo } = useLoginStore()
+    const { LoginCode, LoginID, AccountIDs } = loginInfo.value
     const loading = shallowRef(false)
     const checkPassword = shallowRef('')
 
@@ -85,9 +86,9 @@ export function usePassword(ModifyPwdType: 0 | 1 | 2) {
 
 // 银行签约相关
 export function useBank() {
-    const { getLoginDataInfo } = commonStore
-    const { accountId } = accountStore
-    const userInfo = getLoginDataInfo('userInfo')
+    const { getUserDataInfo } = useUserStore()
+    const { currentAccountId } = useAccountStore()
+    const userInfo = getUserDataInfo('userInfo')
     const loading = shallowRef(false)
     const custodianBanks = shallowRef<Ermcp.CusBankSignBankRsp[]>([]) // 托管银行列表
     const selectedCustodianBank = shallowRef<Ermcp.CusBankSignBankRsp>() // 已选中的托管银行
@@ -105,7 +106,7 @@ export function useBank() {
         BankAccountType: 1, // 银行账户类型
         AccountType: 1, // // 账户类型[1-对私; 2-对公]
         extend_info: JSON.stringify(extendInfo), //  扩展信息(JSON串,参考配置要求进行填充)
-        AccountCode: accountId.value.toString(), // 账户
+        AccountCode: currentAccountId.toString(), // 账户
         AccountName: userInfo.customername, // 客户名称
         BankAccountName: userInfo.customername,
         ExtOperatorID: new Date().getTime(), // 外部操作流水号
@@ -160,6 +161,7 @@ export function useBank() {
  * @returns 
  */
 export function useAccountInOut() {
+    const { getUserId } = useLoginStore()
     const { dataList, selectList, buttonList } = useDataTable<Ermcp.AccountOutInApplyRsp>()
     const columns = shallowRef(getTableColumns('mine_capital'))
     const loading = shallowRef(false)
@@ -187,7 +189,7 @@ export function useAccountInOut() {
         loading.value = true
         return queryAccountInOutApply({
             data: {
-                userid: sessionData.getLoginInfo('UserID')
+                userid: getUserId()
             },
             success: (res) => {
                 dataList.value = res.data
@@ -210,9 +212,9 @@ export function useAccountInOut() {
 
 // 入金
 export function useDeposit() {
-    const { getLoginDataInfo } = commonStore
-    const { accountInfo } = accountStore
-    const userInfo = getLoginDataInfo('userInfo')
+    const { getUserDataInfo } = useUserStore()
+    const { currentAccountInfo } = useAccountStore()
+    const userInfo = getUserDataInfo('userInfo')
     const loading = shallowRef(false)
 
     const formData = reactive<Partial<Proto.t2bBankDepositReq>>({
@@ -270,7 +272,7 @@ export function useDeposit() {
     return {
         loading,
         userInfo,
-        accountInfo,
+        currentAccountInfo,
         formData,
         formSubmit,
     }

+ 9 - 5
src/business/bargain/index.ts

@@ -6,7 +6,7 @@ import { useDataTable } from '@/hooks/datatable'
 import { FilterSelect, FilterButton } from '@/hooks/datatable/interface'
 import { getTableColumns } from '@/business/table'
 import { queryMyBargainApply, queryMyDelistingApply, zsBuyOrderDestingNegPriceOperate, zsSellOrderDestingApplyOperate } from '@/services/api/trade'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { BuyOrSell } from '@/constants/order'
 import Long from 'long'
 
@@ -14,6 +14,7 @@ import Long from 'long'
  * 我的询价
  */
 export function useBargain(type: 0 | 1) {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.MyBargainApplyRsp | Ermcp.MyDelistingApplyRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef<Ermcp.TableColumn[]>([])
@@ -60,7 +61,7 @@ export function useBargain(type: 0 | 1) {
             type,
             page: pageIndex.value,
             pagesize: pageSize.value,
-            userid: sessionData.getLoginInfo('UserID'),
+            userid: getUserId(),
             applystatus: applyStatus.selectedValue || undefined,
         }
 
@@ -114,6 +115,7 @@ export function useBargain(type: 0 | 1) {
  * 我的询价-求购
  */
 export function useBuyBargain(type: 0 | 1) {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.MyBargainApplyRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('bargain_buy'))
@@ -149,7 +151,7 @@ export function useBuyBargain(type: 0 | 1) {
                 type,
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 applystatus: selectList[0].selectedValue || undefined,
             },
             success: (res) => {
@@ -179,6 +181,7 @@ export function useBuyBargain(type: 0 | 1) {
  * 我的询价-出售
  */
 export function useSellBargain(type: 0 | 1) {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.MyDelistingApplyRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('bargain_sell'))
@@ -214,7 +217,7 @@ export function useSellBargain(type: 0 | 1) {
                 type,
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 applystatus: selectList[0].selectedValue || undefined,
             },
             success: (res) => {
@@ -245,7 +248,8 @@ export function useSellBargain(type: 0 | 1) {
  * @returns 
  */
 export function useBargainOperate(selectedRow: Ermcp.MyBargainApplyRsp | Ermcp.MyDelistingApplyRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { loginInfo } = useLoginStore()
+    const { UserID, AccountIDs } = loginInfo.value
     const loading = shallowRef(false)
 
     const formData = reactive<{ AuditRemark: string }>({

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

@@ -1,5 +1,5 @@
 import { timerTask } from '@/utils/timer'
-import { commonStore, accountStore, futuresStore, sessionData } from '@/stores'
+import { useStore } from '@/stores'
 import { tokenCheck } from '@/services/api/account'
 import eventBus from '@/services/bus'
 import socket from '@/services/socket'
@@ -8,9 +8,10 @@ import socket from '@/services/socket'
  * 退出登录
  */
 export function logout(callback?: () => void) {
+    const { loginStore, accountStore } = useStore()
     socket.closeAll()
     timerTask.clearAll()
-    sessionData.reset()
+    loginStore.reset()
     accountStore.reset()
     callback && callback()
 }
@@ -20,33 +21,32 @@ export function logout(callback?: () => void) {
  * @param callback 
  */
 export async function initBaseData(callback?: () => void) {
-    if (sessionData.getLoginInfo('Token')) {
-        checkTokenLoop()
+    checkTokenLoop()
 
-        const asyncTask = [
-            commonStore.getLoginData(),
-            futuresStore.getGoodsList(),
-            sessionData.getUserMenuList(),
-            sessionData.getPerformanceStepList(),
-            //sessionData.getTableColumnList(),
-        ]
+    const { userStore, futuresStore, menuStore, performanceStore, accountStore, favoriteStore } = useStore()
+    const asyncTask = [
+        userStore.getUserData(),
+        menuStore.getUserMenuList(),
+        futuresStore.getGoodsList(),
+        performanceStore.getPerformanceStepList(),
+        //useTableColumnStore.getTableColumnList(),
+    ]
 
-        await Promise.all(asyncTask).then(() => {
-            accountStore.getAccountList()
-            callback && callback()
-        }).catch(() => {
-            return Promise.reject('初始化失败')
-        })
-    } else {
+    await Promise.all(asyncTask).then(() => {
+        accountStore.getAccountList()
+        favoriteStore.getFavoriteList()
         callback && callback()
-    }
+    }).catch(() => {
+        return Promise.reject('初始化失败')
+    })
 }
 
 /**
  * 令牌效验
  */
 export function checkToken() {
-    const { LoginID, Token } = sessionData.getValue('loginInfo')
+    const { loginStore } = useStore()
+    const { LoginID, Token } = loginStore.loginInfo.value
     return tokenCheck({
         data: {
             LoginID,

+ 10 - 32
src/business/favorite/index.ts

@@ -1,13 +1,12 @@
-import { shallowRef } from 'vue'
+import { shallowRef, watch } from 'vue'
 import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
-import { queryMyFavorite } from '@/services/api/favorite'
 import { Category } from '@/constants/diamond'
-import { sessionData } from '@/stores'
+import { useFavoriteStore } from '@/stores'
 
 export function useFavorite() {
-    const { dataList, total, pageIndex, pageSize, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyFavoriteRsp>()
-    const loading = shallowRef(false)
+    const { loading, favoriteList, getFavoriteList } = useFavoriteStore()
+    const { dataList, total, pageIndex, pageSize, selectList, buttonList } = useDataTable<Ermcp.MyFavoriteRsp>({ pagination: true })
     const columns = shallowRef(getTableColumns('favorite'))
 
     selectList.value = [
@@ -21,33 +20,12 @@ export function useFavorite() {
         },
     ]
 
-    filterMethod.onReset = () => {
-        getFavoriteList()
-    }
-
-    filterMethod.onSearch = () => {
-        getFavoriteList()
-    }
-
-    const getFavoriteList = () => {
-        const param = getQueryParam()
-        loading.value = true
-        return queryMyFavorite({
-            data: {
-                page: pageIndex.value,
-                pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
-                zscategorys: param.zscategorydisplay,
-            },
-            success: (res) => {
-                total.value = res.total
-                dataList.value = res.data
-            },
-            complete: () => {
-                loading.value = false
-            }
-        })
-    }
+    watch(favoriteList, (data) => {
+        total.value = data.length
+        dataList.value = data
+    }, {
+        immediate: true
+    })
 
     return {
         loading,

+ 12 - 9
src/business/goods/index.ts

@@ -8,7 +8,7 @@ import { Market } from '@/constants/market'
 import { queryWarehouseInfo } from '@/services/api/warehouse'
 import { queryMyFavorite } from '@/services/api/favorite'
 import { addDiamond, queryDiamondList, queryDiamondDetails, goodsFavoriteOperate, receiptZSOutApply } from '@/services/api/goods'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import {
     Category,
     getCurrencyTypeList,
@@ -31,7 +31,7 @@ import Long from 'long'
 
 // 钻石列表相关
 export function useDiamond() {
-    const { UserID } = sessionData.getValue('loginInfo')
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, getQueryParam } = useDataTable<Ermcp.MyWRPositionRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('warehousing_diamond'))
@@ -67,7 +67,7 @@ export function useDiamond() {
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                wruserid: UserID,
+                wruserid: getUserId(),
                 zscategorys: param.zscategory ? param.zscategory.toString() : categoryList.map((e) => e.value).join(','),
                 zsallproperties: param.goodsno,
                 warehouseid: param.warehouseid,
@@ -101,7 +101,7 @@ export function useDiamond() {
     // 获取仓库列表
     queryWarehouseInfo({
         data: {
-            userid: UserID,
+            userid: getUserId(),
             status: 1,
             isincludeexchange: true,
         },
@@ -132,6 +132,7 @@ export function useDiamond() {
 
 // 钻石详情相关
 export function useDiamondDetails(goodsno: string) {
+    const { getUserId } = useLoginStore()
     const loading = shallowRef(false)
     const details = shallowRef<Ermcp.DiamondDetailsRsp>()
     const favoriteList = shallowRef<Ermcp.MyFavoriteRsp[]>([]) // 我的收藏列表
@@ -162,7 +163,7 @@ export function useDiamondDetails(goodsno: string) {
 
         const task2 = queryMyFavorite({
             data: {
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
             },
             success: (res) => {
                 favoriteList.value = res.data
@@ -186,7 +187,8 @@ export function useDiamondDetails(goodsno: string) {
 
 // 钻石上架相关
 export function useDiamondForm(category: Category) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { loginInfo } = useLoginStore()
+    const { UserID, AccountIDs } = loginInfo.value
     const loading = shallowRef(false)
     const warehouseList = shallowRef<Ermcp.WarehouseInfoRsp[]>([]) // 仓库列表
     const performanceId = shallowRef<number>() // 选中的履约模板ID
@@ -323,7 +325,7 @@ export function useDiamondForm(category: Category) {
 
 // 钻石收藏相关
 export function useDiamondFavorite(selectedRow: Ermcp.MyWRPositionRsp | Ermcp.SellOrderRsp) {
-    const { UserID } = sessionData.getValue('loginInfo')
+    const { getUserId } = useLoginStore()
     const loading = shallowRef(false)
 
     // 钻石收藏操作
@@ -331,7 +333,7 @@ export function useDiamondFavorite(selectedRow: Ermcp.MyWRPositionRsp | Ermcp.Se
         loading.value = true
         return goodsFavoriteOperate({
             data: {
-                UserID, // 用户ID,必填
+                UserID: getUserId(), // 用户ID,必填
                 WRTradeOrderID: Long.fromString(selectedRow.wrtradeorderid), // 委托单ID,必填
                 OperateType: operateType, // 操作类型,1:添加2:删除,必填
                 ClientType: ClientType.Web, // 终端类型
@@ -352,7 +354,8 @@ export function useDiamondFavorite(selectedRow: Ermcp.MyWRPositionRsp | Ermcp.Se
 
 // 钻石删除相关
 export function useDiamondDelete(selectedRow: Ermcp.MyWRPositionRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { loginInfo } = useLoginStore()
+    const { UserID, AccountIDs } = loginInfo.value
     const loading = shallowRef(false)
 
     const formSubmit = () => {

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

@@ -1,10 +1,10 @@
 import { shallowRef, computed } from 'vue'
 import { timerTask } from '@/utils/timer'
 import { queryNotice, postNoticeReaded } from '@/services/api/common'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 
 export function useNotice() {
-    const { LoginID } = sessionData.getValue('loginInfo')
+    const { getLoginId } = useLoginStore()
     const dataList = shallowRef<Ermcp.NoticeRsp[]>([])
     const loading = shallowRef(false)
 
@@ -19,7 +19,7 @@ export function useNotice() {
         loading.value = true
         return queryNotice({
             data: {
-                loginID: LoginID
+                loginID: getLoginId()
             },
             success: (res) => {
                 dataList.value = res.data
@@ -38,7 +38,7 @@ export function useNotice() {
     const updateNoticeReaded = (id: number) => {
         return postNoticeReaded({
             data: {
-                loginID: Number(LoginID),
+                loginID: Number(getLoginId()),
                 noticeID: id,
             },
         })

+ 10 - 9
src/business/order/index.ts

@@ -3,12 +3,13 @@ import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
 import { getReceiptTypeName } from '@/constants/receipt'
 import { queryMyPerformance, performanceManualConfirm, performanceDelayApply, performanceContractedApply, performanceModifyContact } from '@/services/api/order'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { BuyOrSell } from '@/constants/order'
 import Long from 'long'
 
 // 我的履约
 export function usePerformance(buyorsell?: BuyOrSell) {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize, inputList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyPerformancRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('order'))
@@ -42,7 +43,7 @@ export function usePerformance(buyorsell?: BuyOrSell) {
 
         return queryMyPerformance({
             data: {
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 page: pageIndex.value,
                 pagesize: pageSize.value,
                 buyorsell,
@@ -104,12 +105,12 @@ export function usePerformanceManual(selectedRow: Ermcp.MyPerformancRsp) {
 
 // 履约延期申请
 export function usePerformanceDelay(selectedRow: Ermcp.MyPerformancRsp) {
-    const { UserID } = sessionData.getValue('loginInfo')
+    const { getUserId } = useLoginStore()
     const loading = shallowRef(false)
 
     const formData = reactive<Proto.PerformanceDelayApplyReq>({
         PerformancePlanStepID: Long.fromString(selectedRow.curstepid), // uint64 履约计划步骤ID
-        applicant: UserID, // uint64 申请人
+        applicant: getUserId(), // uint64 申请人
     })
 
     const formSubmit = () => {
@@ -131,13 +132,13 @@ export function usePerformanceDelay(selectedRow: Ermcp.MyPerformancRsp) {
 
 // 履约违约申请
 export function usePerformanceContracted(selectedRow: Ermcp.MyPerformancRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
 
     const formData = reactive<Proto.PerformanceContractedApplyReq>({
         PerformancePlanID: Long.fromString(selectedRow.performanceplanid), // uint64 履约计划ID
-        BreachType: selectedRow.buyaccountid === AccountIDs[0] ? 2 : 1, // uint32 违约方类型
-        Applicant: UserID, // uint64 违约申请人
+        BreachType: selectedRow.buyaccountid === getFirstAccountId() ? 2 : 1, // uint32 违约方类型
+        Applicant: getUserId(), // uint64 违约申请人
     })
 
     const formSubmit = () => {
@@ -159,7 +160,7 @@ export function usePerformanceContracted(selectedRow: Ermcp.MyPerformancRsp) {
 
 // 履约修改联络信息
 export function usePerformanceModify(selectedRow: Ermcp.MyPerformancRsp) {
-    const { AccountIDs } = sessionData.getValue('loginInfo')
+    const { getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
     const formData = reactive<{ address?: Ermcp.UserReceiveInfoRsp, invoice?: Ermcp.WrUserReceiptInfoRsp, contactInfo?: string }>({})
 
@@ -221,7 +222,7 @@ export function usePerformanceModify(selectedRow: Ermcp.MyPerformancRsp) {
         return performanceModifyContact({
             data: {
                 PerformancePlanID: Long.fromString(selectedRow.performanceplanid), // uint64 履约计划ID
-                AccountID: AccountIDs[0], // uint64 账号
+                AccountID: getFirstAccountId(), // uint64 账号
                 ContactInfo: JSON.stringify(jsonParam), // string 联络信息
             },
             complete: () => {

+ 3 - 23
src/business/search/index.ts

@@ -2,8 +2,6 @@ import { ref, shallowRef, computed } from 'vue'
 import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
 import { searchSellOrder } from '@/services/api/trade'
-import { queryMyFavorite } from '@/services/api/favorite'
-import { sessionData } from '@/stores'
 import {
     Category,
     getCurrencyTypeList,
@@ -22,7 +20,6 @@ export function useSearch(category: Category) {
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.SellOrderRsp & { checked: boolean }>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_sellorder'))
-    const favoriteList = shallowRef<Ermcp.MyFavoriteRsp[]>([]) // 我的收藏列表
     const warehouseList = shallowRef<Ermcp.WarehouseInfoRsp[]>([]) // 仓库列表
 
     // 部分请求参数类型重定义
@@ -70,11 +67,10 @@ export function useSearch(category: Category) {
     }
 
     // 获取出售大厅委托单
-    const getSellOrderList = async () => {
+    const getSellOrderList = () => {
         const { zsshapetype, zscurrencytype, zscerttype, warehouseid, zsstyletype, ...param } = formData.value
         loading.value = true
-
-        const task1 = searchSellOrder({
+        return searchSellOrder({
             data: {
                 ...param,
                 page: pageIndex.value,
@@ -93,21 +89,6 @@ export function useSearch(category: Category) {
                 loading.value = false
             }
         })
-
-        const task2 = queryMyFavorite({
-            data: {
-                userid: sessionData.getLoginInfo('UserID'),
-            },
-            success: (res) => {
-                favoriteList.value = res.data
-            }
-        })
-
-        try {
-            return await Promise.all([task1, task2])
-        } finally {
-            loading.value = false
-        }
     }
 
     const onSearch = () => {
@@ -126,7 +107,7 @@ export function useSearch(category: Category) {
     // 获取仓库列表
     // queryWarehouseInfo({
     //     data: {
-    //         userid: sessionData.getLoginInfo('UserID'),
+    //         userid: getUserId(),
     //         status: 1,
     //         isincludeexchange: true,
     //     },
@@ -138,7 +119,6 @@ export function useSearch(category: Category) {
     return {
         loading,
         warehouseList,
-        favoriteList,
         formData,
         enums,
         dataList,

+ 13 - 34
src/business/sign/index.ts

@@ -1,13 +1,12 @@
 import { ref, reactive } from 'vue'
 import { v4 } from 'uuid'
 import { ClientType } from '@/constants/client'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { initBaseData } from '@/business/common'
-import { login, queryLoginId } from '@/services/api/account'
-import cryptojs from 'crypto-js'
 import eventBus from '@/services/bus'
 
 export function useSign() {
+    const { userLogin } = useLoginStore();
     const loading = ref(false);
     const user = reactive<Proto.LoginReq>({
         LoginID: '110000000001',
@@ -28,43 +27,23 @@ export function useSign() {
     const signIn = () => {
         loading.value = true
         return new Promise((resolve, reject) => {
-            queryLoginId({
-                data: {
-                    username: user.LoginID
-                },
-                success: (res) => {
-                    login({
-                        data: {
-                            ...user,
-                            LoginID: res.data,
-                            LoginPWD: cryptojs.SHA256(res.data + user.LoginPWD).toString(),
-                        },
-                        success: (res) => {
-                            sessionData.setValue('loginInfo', res);
-                            initBaseData(() => {
-                                resolve(res);
-                            }).catch((err) => {
-                                loading.value = false;
-                                reject(err);
-                            })
-                        },
-                        fail: (err) => {
-                            loading.value = false;
-                            reject(err);
-                        }
-                    })
-                },
-                fail: (err) => {
-                    loading.value = false;
-                    reject(err);
-                }
+            userLogin(user).then((res) => {
+                initBaseData(() => {
+                    resolve(res)
+                }).catch((err) => {
+                    loading.value = false
+                    reject(err)
+                })
+            }).catch((err) => {
+                loading.value = false
+                reject(err)
             })
         })
     }
 
     // 用户登出
     const signOut = () => {
-        eventBus.$emit('LogoutNotify');
+        eventBus.$emit('LogoutNotify')
     }
 
     return {

+ 3 - 3
src/business/table/index.ts

@@ -1,5 +1,5 @@
 import { shallowRef } from 'vue'
-import { sessionData } from '@/stores'
+import { useTableColumnStore } from '@/stores'
 
 type TableColumnKey = typeof tableColumnKeys[number]
 const tableColumnKeys = ['system_menu', 'system_role', 'warehousing_diamond', 'warehousing_warehouse', 'mine_capital', 'listing_sellorder', 'listing_buyorder', 'listing_saleorder', 'listing_purchaseorder', 'listing_delisting', 'listing_bargain_buy', 'listing_bargain_sell', 'mine_address', 'mine_invoice', 'favorite', 'order', 'bargain_buy', 'bargain_sell'] as const
@@ -287,9 +287,9 @@ export function getTableColumns(tableKey: TableColumnKey) {
 }
 
 export function useTableColumns(tableKey: string, operateColumn = true) {
-    const tableColumns = sessionData.getValue('tableColumns')
+    const { tableColumns } = useTableColumnStore()
 
-    const columns = shallowRef(tableColumns.reduce((res, cur) => {
+    const columns = shallowRef(tableColumns.value.reduce((res, cur) => {
         if (cur.tablekey === tableKey) {
             cur.columns.forEach((e) => {
                 res.push({

+ 16 - 16
src/business/trade/desting.ts

@@ -5,7 +5,7 @@ import { Market } from '@/constants/market'
 import { useDataTable } from '@/hooks/datatable'
 import { queryDiamondList } from '@/services/api/goods'
 import { zsBuyOrderDesting, zsBuyOrderDestingNegPrice, zsSellOrderDestingApply } from '@/services/api/trade'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import moment from 'moment'
 import Long from 'long'
 
@@ -14,7 +14,7 @@ import Long from 'long'
  * @returns 
  */
 export function useBuyOrderDesting(selectedRow: Ermcp.DiamondDetailsRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
 
     const formSubmit = () => {
@@ -22,17 +22,17 @@ export function useBuyOrderDesting(selectedRow: Ermcp.DiamondDetailsRsp) {
         return zsBuyOrderDesting({
             data: {
                 Header: {
-                    AccountID: AccountIDs[0],
+                    AccountID: getFirstAccountId(),
                 },
-                UserID,
-                AccountID: AccountIDs[0],
+                UserID: getUserId(),
+                AccountID: getFirstAccountId(),
                 RelatedWRTradeOrderID: Long.fromString(selectedRow.wrtradeorderid),
                 OrderQty: selectedRow.remainqty,
                 OrderSrc: 1,
                 ClientSerialNo: v4(),
                 ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss'),
                 ClientType: ClientType.Web,
-                OperatorID: UserID,
+                OperatorID: getUserId(),
                 MarketID: Market.GZ
             },
             complete: () => {
@@ -52,20 +52,20 @@ export function useBuyOrderDesting(selectedRow: Ermcp.DiamondDetailsRsp) {
  * @returns 
  */
 export function useBuyOrderBargain(selectedRow: Ermcp.DiamondDetailsRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
 
     const formData = reactive<Proto.ZSBuyOrderDestingNegPriceReq>({
         Header: {
-            AccountID: AccountIDs[0],
+            AccountID: getFirstAccountId(),
         },
-        UserID, // 用户ID,必填
-        AccountID: AccountIDs[0], // 资金账号,必填
+        UserID: getUserId(), // 用户ID,必填
+        AccountID: getFirstAccountId(), // 资金账号,必填
         RelatedOrderID: Long.fromString(selectedRow.wrtradeorderid), // 卖委托单号,必填
         OrderQty: selectedRow.remainqty, // 议价数量,2位小数,必填
         OrderSrc: 1, // 委托来源
         ClientType: ClientType.Web, // 终端类型
-        OperatorID: UserID, // 操作员账号ID
+        OperatorID: getUserId(), // 操作员账号ID
         MarketID: Market.GZ, // 市场ID,必填
         ApplyRemark: '' // 申请备注
     })
@@ -96,16 +96,16 @@ export function useBuyOrderBargain(selectedRow: Ermcp.DiamondDetailsRsp) {
  * @returns 
  */
 export function useSellOrderBargain(selectedRow: Ermcp.BuyOrderRsp) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const { dataList } = useDataTable<Ermcp.MyWRPositionRsp>()
     const loading = shallowRef(false)
 
     const formData = reactive<Proto.ZSSellOrderDestingApplyReq>({
         Header: {
-            AccountID: AccountIDs[0],
+            AccountID: getFirstAccountId(),
         },
-        UserID, // 用户ID,必填
-        AccountID: AccountIDs[0], // 资金账户ID,必填
+        UserID: getUserId(), // 用户ID,必填
+        AccountID: getFirstAccountId(), // 资金账户ID,必填
         BuyWRTradeOrderID: Long.fromString(selectedRow.wrtradeorderid), // 买挂牌委托单ID,必填
         WRStandardID: 0, // 现货商品ID,必填
         ApplyQty: 0, // 申请数量,必填,2位小数
@@ -147,7 +147,7 @@ export function useSellOrderBargain(selectedRow: Ermcp.BuyOrderRsp) {
     const getDiamondList = () => {
         return queryDiamondList({
             data: {
-                wruserid: UserID,
+                wruserid: getUserId(),
                 zscategorys: selectedRow.zscategory.toString(),
             },
             success: (res) => {

+ 10 - 23
src/business/trade/list.ts

@@ -1,9 +1,8 @@
 import { shallowRef, ref } from 'vue'
 import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
-import { queryMyFavorite } from '@/services/api/favorite'
 import { queryBuyOrder, querySellOrder, queryMyBuyOrder, queryMySellOrder, queryMyDeListing } from '@/services/api/trade'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { getBuyOrSellList, BuyOrSell } from '@/constants/order'
 import { Category } from '@/constants/diamond'
 
@@ -88,7 +87,6 @@ export function useSellOrder() {
     const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.SellOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_sellorder'))
-    const favoriteList = shallowRef<Ermcp.MyFavoriteRsp[]>([]) // 我的收藏列表
 
     selectList.value = [
         {
@@ -116,8 +114,7 @@ export function useSellOrder() {
     const getSellOrderList = async () => {
         const param = getQueryParam()
         loading.value = true
-
-        const task1 = querySellOrder({
+        return querySellOrder({
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
@@ -129,29 +126,16 @@ export function useSellOrder() {
             success: (res) => {
                 total.value = res.total
                 dataList.value = res.data
-            }
-        })
-
-        const task2 = queryMyFavorite({
-            data: {
-                userid: sessionData.getLoginInfo('UserID'),
             },
-            success: (res) => {
-                favoriteList.value = res.data
+            complete: () => {
+                loading.value = false
             }
         })
-
-        try {
-            return await Promise.all([task1, task2])
-        } finally {
-            loading.value = false
-        }
     }
 
     return {
         loading,
         dataList,
-        favoriteList,
         total,
         pageIndex,
         pageSize,
@@ -167,6 +151,7 @@ export function useSellOrder() {
  * 我的出售
  */
 export function useSaleOrder() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MySellOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_saleorder'))
@@ -212,7 +197,7 @@ export function useSaleOrder() {
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 zscategorys: param.zscategory ? param.zscategory.toString() : categoryList.map((e) => e.value).join(','),
                 wrtradeorderid: param.wrtradeorderid,
                 zsallproperties: param.goodsno,
@@ -249,6 +234,7 @@ export function useSaleOrder() {
  * 我的求购
  */
 export function usePurchaseOrder() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyBuyOrderRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_purchaseorder'))
@@ -294,7 +280,7 @@ export function usePurchaseOrder() {
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 zscategorys: param.zscategory ? param.zscategory.toString() : categoryList.map((e) => e.value).join(','),
                 wrtradeorderid: param.wrtradeorderid,
                 zsallproperties: param.zstabledisplay,
@@ -331,6 +317,7 @@ export function usePurchaseOrder() {
  * 我的摘牌
  */
 export function useDelistingOrder() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize, inputList, selectList, buttonList, filterMethod, getQueryParam } = useDataTable<Ermcp.MyDeListingRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('listing_delisting'))
@@ -378,7 +365,7 @@ export function useDelistingOrder() {
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
                 buyorsell: param.buyorsell,
                 matchusername: param.matchusername,
                 zscategorys: param.zscategory ? param.zscategory.toString() : categoryList.map((e) => e.value).join(','),

+ 19 - 17
src/business/trade/listing.ts

@@ -5,7 +5,7 @@ import { useDataTable } from '@/hooks/datatable'
 import { Market } from '@/constants/market'
 import { queryDiamondList } from '@/services/api/goods'
 import { zsBuyOrderListing, zsSellOrderListing, wrListingCancelOrder } from '@/services/api/trade'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import {
     Category,
     getCurrencyTypeList,
@@ -28,13 +28,13 @@ import Long from 'long'
  * @returns 
  */
 export function useBuyOrderListing() {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
     const performanceId = shallowRef<number>() // 选中的履约模板ID
     const currencyId = shallowRef<number>() // 选中的货币类型ID
     const formData = reactive<Proto.GZBuyOrderDetailExInfo>({
-        UserID,
-        AccountID: AccountIDs[0],
+        UserID: getUserId(),
+        AccountID: getFirstAccountId(),
         ZSCategory: Category.Diamond,
         ZSCurrencyType: [],
         ZSShapeType: [],
@@ -77,10 +77,10 @@ export function useBuyOrderListing() {
         return zsBuyOrderListing({
             data: {
                 Header: {
-                    AccountID: AccountIDs[0],
+                    AccountID: getFirstAccountId(),
                 },
-                UserID,
-                AccountID: AccountIDs[0],
+                UserID: getUserId(),
+                AccountID: getFirstAccountId(),
                 MarketID: Market.GZ,
                 OrderSrc: 1,
                 ClientType: ClientType.Web,
@@ -109,8 +109,8 @@ export function useBuyOrderListing() {
  * @returns 
  */
 export function useSellOrderListing(selectedRow?: Ermcp.MyWRPositionRsp) {
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const { dataList } = useDataTable<Ermcp.MyWRPositionRsp>()
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
     const { zscategory, wrstandardid = 0, ladingbillid = '0', subnum = 0, ftotalqty = 0, ffreezeqty = 0 } = selectedRow ?? {}
 
     const submitLoading = shallowRef(false)
@@ -124,10 +124,10 @@ export function useSellOrderListing(selectedRow?: Ermcp.MyWRPositionRsp) {
 
     const formData = reactive<Proto.ZSSellOrderListingReq>({
         Header: {
-            AccountID: AccountIDs[0],
+            AccountID: getFirstAccountId(),
         },
-        UserID,
-        AccountID: AccountIDs[0],
+        UserID: getUserId(),
+        AccountID: getFirstAccountId(),
         WRStandardID: wrstandardid,
         OrderQty: ftotalqty - ffreezeqty,
         LadingBillID: Long.fromString(ladingbillid),
@@ -147,7 +147,7 @@ export function useSellOrderListing(selectedRow?: Ermcp.MyWRPositionRsp) {
         tableLoading.value = true
         queryDiamondList({
             data: {
-                wruserid: UserID,
+                wruserid: getUserId(),
                 zscategorys: selectedCategoryId.value.toString(),
             },
             success: (res) => {
@@ -265,22 +265,24 @@ export function useSellOrderListing(selectedRow?: Ermcp.MyWRPositionRsp) {
  * 钻石挂牌撤单
  */
 export function useListingCancel(wrtradeorderid: string, buyorsell: number) {
-    const { UserID, AccountIDs } = sessionData.getValue('loginInfo')
+    const { getUserId, getFirstAccountId } = useLoginStore()
     const loading = shallowRef(false)
+    const userId = getUserId()
+    const accountId = getFirstAccountId()
 
     const formSubmit = () => {
         loading.value = true
         return wrListingCancelOrder({
             data: {
                 Header: {
-                    AccountID: AccountIDs[0],
+                    AccountID: accountId,
                 },
-                UserID, // 用户ID
-                AccountID: AccountIDs[0], // 资金账号
+                UserID: userId, // 用户ID
+                AccountID: accountId, // 资金账号
                 OldWRTradeOrderID: Long.fromString(wrtradeorderid), // 目标仓单贸易委托单ID
                 OrderSrc: 1, // 委托来源
                 ClientType: ClientType.Web, // 终端类型
-                OperatorID: UserID, // 操作员账号ID
+                OperatorID: userId, // 操作员账号ID
                 BuyOrSell: buyorsell, // 买卖方向
                 ClientSerialNo: v4(),
                 ClientOrderTime: moment().format('YYYY-MM-DD HH:mm:ss')

+ 10 - 8
src/business/user/index.ts

@@ -2,10 +2,11 @@ import { shallowRef, reactive } from 'vue'
 import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
 import { queryUserReceiveInfo, queryWrUserReceiptInfo, userReceiveInfo, delUserReceiveInfo, userReceiveIsDefault, userReceiptInfo, delUserReceiptInfo } from '@/services/api/user'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { getCertificateTypeList } from '@/constants/certificate'
 
 export function useAddress() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.UserReceiveInfoRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('mine_address'))
@@ -14,7 +15,7 @@ export function useAddress() {
         loading.value = true
         return queryUserReceiveInfo({
             data: {
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
             },
             success: (res) => {
                 total.value = res.total
@@ -38,13 +39,13 @@ export function useAddress() {
 }
 
 export function useAddressForm(selectedRow?: Ermcp.UserReceiveInfoRsp) {
-    const { UserID } = sessionData.getValue('loginInfo')
+    const { getUserId } = useLoginStore()
     const loading = shallowRef(false)
     const certificateTypeList = getCertificateTypeList()
 
     const formData = reactive<Proto.UserReceiveInfoReq>({
         ReceiveInfoId: 0,
-        UserID,
+        UserID: getUserId(),
         CardTypeID: 0,
         ReceiverName: '',
         CardNum: '',
@@ -96,7 +97,7 @@ export function useAddressForm(selectedRow?: Ermcp.UserReceiveInfoRsp) {
         loading.value = true
         return userReceiveIsDefault({
             data: {
-                UserId: UserID,
+                UserId: getUserId(),
                 AutoId: formData.ReceiveInfoId
             },
             complete: () => {
@@ -116,6 +117,7 @@ export function useAddressForm(selectedRow?: Ermcp.UserReceiveInfoRsp) {
 }
 
 export function useInvoice() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.WrUserReceiptInfoRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('mine_invoice'))
@@ -124,7 +126,7 @@ export function useInvoice() {
         loading.value = true
         return queryWrUserReceiptInfo({
             data: {
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
             },
             success: (res) => {
                 total.value = res.total
@@ -148,12 +150,12 @@ export function useInvoice() {
 }
 
 export function useInvoiceForm(selectedRow?: Ermcp.WrUserReceiptInfoRsp) {
-    const { UserID } = sessionData.getValue('loginInfo')
+    const { getUserId } = useLoginStore()
     const loading = shallowRef(false)
     const certificateTypeList = getCertificateTypeList()
 
     const formData = reactive<Proto.UserReceiptInfoReq>({
-        UserID, // 用户ID
+        UserID: getUserId(), // 用户ID
         UserName: '', // 发票抬头姓名
         ReceiptType: 1, // 发票类型
         TaxpayerID: '', // 纳税人识别号

+ 8 - 5
src/business/warehouse/index.ts

@@ -2,9 +2,10 @@ import { shallowRef, reactive } from 'vue'
 import { useDataTable } from '@/hooks/datatable'
 import { getTableColumns } from '@/business/table'
 import { queryWarehouseInfo, warehouseApply } from '@/services/api/warehouse'
-import { commonStore, sessionData } from '@/stores'
+import { useUserStore, useLoginStore } from '@/stores'
 
 export function useWarehouse() {
+    const { getUserId } = useLoginStore()
     const { dataList, total, pageIndex, pageSize } = useDataTable<Ermcp.WarehouseInfoRsp>()
     const loading = shallowRef(false)
     const columns = shallowRef(getTableColumns('warehousing_warehouse'))
@@ -15,7 +16,7 @@ export function useWarehouse() {
             data: {
                 page: pageIndex.value,
                 pagesize: pageSize.value,
-                userid: sessionData.getLoginInfo('UserID'),
+                userid: getUserId(),
             },
             success: (res) => {
                 total.value = res.total
@@ -39,11 +40,13 @@ export function useWarehouse() {
 }
 
 export function useWarehouseForm(selectedRow?: Ermcp.WarehouseInfoRsp) {
+    const { getUserId } = useLoginStore()
+    const { getAccountName } = useUserStore()
+
     const loading = shallowRef(false)
-    const accountName = commonStore.getAccountName()
     const formData = reactive<Proto.WarehouseApplyReq>({
         type: selectedRow?.warehousecode ? 2 : 1,
-        userid: sessionData.getLoginInfo('UserID'),
+        userid: getUserId(),
         warehousetype: 2,
         warehousecode: '',
         warehousename: '',
@@ -77,7 +80,7 @@ export function useWarehouseForm(selectedRow?: Ermcp.WarehouseInfoRsp) {
 
     return {
         loading,
-        accountName,
+        accountName: getAccountName(),
         formData,
         addOrUpdate,
     }

+ 2 - 1
src/constants/certificate.ts

@@ -1,5 +1,6 @@
-import { getEnumTypes, getEnumTypeList, getEnumTypeName } from './index'
+import { useEnumStore } from '@/stores'
 
+const { getEnumTypes, getEnumTypeList, getEnumTypeName } = useEnumStore()
 const enumKeys = ['certificatetype'] as const
 const enumMap = getEnumTypes(...enumKeys)
 

+ 5 - 4
src/constants/client.ts

@@ -1,4 +1,8 @@
-import { getEnumTypes, getEnumTypeList } from './index'
+import { useEnumStore } from '@/stores'
+
+const { getEnumTypes, getEnumTypeList } = useEnumStore()
+const enumKeys = ['clientType'] as const
+const enumMap = getEnumTypes(...enumKeys)
 
 /**
  * 客户端类型
@@ -17,9 +21,6 @@ export enum ClientType {
     TradeInterface = 10 // 交易接口
 }
 
-const enumKeys = ['clientType'] as const
-const enumMap = getEnumTypes(...enumKeys)
-
 /**
  * 获取客户端类型列表
  * @returns 

+ 5 - 4
src/constants/diamond.ts

@@ -1,4 +1,8 @@
-import { getEnumTypes, getEnumTypeInfo, getEnumTypeList } from './index'
+import { useEnumStore } from '@/stores'
+
+const { getEnumTypes, getEnumTypeList, getEnumTypeInfo } = useEnumStore()
+const enumKeys = ['ZSCategory', 'ZSCurrencyType', 'ZSCurrencyType', 'ZSColorType', 'ZSClarityType', 'ZSCutType', 'ZSShapeType', 'ZSSymmetryType', 'ZSPolishType', 'ZSFluorescenceType', 'ZSCertType', 'ZSCrystalType', 'ZSCZColor1Type', 'ZSCZColor2Type', 'ZSCZColor3Type', 'ZSStyleType'] as const
+const enumMap = getEnumTypes(...enumKeys)
 
 /**
  * 钻石类型
@@ -11,9 +15,6 @@ export enum Category {
     Fancy = 5, // 彩色钻石
 }
 
-const enumKeys = ['ZSCategory', 'ZSCurrencyType', 'ZSCurrencyType', 'ZSColorType', 'ZSClarityType', 'ZSCutType', 'ZSShapeType', 'ZSSymmetryType', 'ZSPolishType', 'ZSFluorescenceType', 'ZSCertType', 'ZSCrystalType', 'ZSCZColor1Type', 'ZSCZColor2Type', 'ZSCZColor3Type', 'ZSStyleType'] as const
-const enumMap = getEnumTypes(...enumKeys)
-
 /**
  * 获取钻石分类列表
  * @returns 

+ 0 - 69
src/constants/index.ts

@@ -1,69 +0,0 @@
-import { sessionData } from '@/stores'
-
-/**
- * 枚举类型
- */
-export interface EnumType {
-    label: string;
-    value: number;
-    disabled?: boolean;
-}
-
-/**
- * 获取枚举类型
- * @param args 
- * @returns 
- */
-export function getEnumTypes<T extends string[]>(...args: T) {
-    const enumMap = new Map<typeof args[number], Ermcp.EnumRsp[]>()
-    sessionData.getValue('allEnums').forEach((e) => {
-        if (args.some((code) => code.toLowerCase() === e.enumdiccode.toLowerCase())) {
-            const enums = enumMap.get(e.enumdiccode)
-            if (enums) {
-                enums.push(e)
-            } else {
-                enumMap.set(e.enumdiccode, [e])
-            }
-        }
-    })
-    return enumMap
-}
-
-/**
- * 获取枚举信息
- * @param enums 
- * @param value 
- * @returns 
- */
-export function getEnumTypeInfo(enums: Ermcp.EnumRsp[], value: number) {
-    return enums.find((e) => e.enumitemstatus === 1 && e.enumitemname === value)
-}
-
-/**
- * 获取枚举列表
- * @param enums 
- * @returns 
- */
-export function getEnumTypeList(enums?: Ermcp.EnumRsp[]): EnumType[] {
-    if (enums) {
-        return enums.map((e) => ({
-            label: e.enumdicname,
-            value: e.enumitemname,
-        }))
-    }
-    return []
-}
-
-/**
- * 根据枚举值获取枚举名称
- * @param enums 
- * @param value 
- * @returns 
- */
-export function getEnumTypeName(enums: EnumType[], value?: number): string {
-    const item = enums.find((e) => e.value === value)
-    if (item) {
-        return item.label
-    }
-    return '--'
-}

+ 3 - 1
src/constants/menu.ts

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

+ 5 - 4
src/constants/order.ts

@@ -1,6 +1,7 @@
-import { getEnumTypes, getEnumTypeName, getEnumTypeList } from './index'
-import { sessionData } from '@/stores'
+import { useEnumStore } from '@/stores'
+import { usePerformanceStore } from '@/stores'
 
+const { getEnumTypes, getEnumTypeList, getEnumTypeName } = useEnumStore()
 const enumKeys = ['wrApplyStatus', 'performanceStatus'] as const
 const enumMap = getEnumTypes(...enumKeys)
 
@@ -89,8 +90,8 @@ export enum StepType {
  * @returns 
  */
 export function getStepTypeList() {
-    const stepTypes = sessionData.getValue('performanceStepTypes')
-    return stepTypes.map((e) => ({
+    const { performanceStepTypes } = usePerformanceStore()
+    return performanceStepTypes.value.map((e) => ({
         label: e.steptypename,
         value: e.steptypeid,
     }))

+ 3 - 1
src/constants/receipt.ts

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

+ 6 - 6
src/hooks/auth/index.ts

@@ -1,12 +1,12 @@
 import { defineAsyncComponent, Component } from 'vue'
 import { useRoute, useRouter } from 'vue-router'
-import { sessionData } from '@/stores'
+import { useMenuStore } from '@/stores'
 import { AuthType } from '@/constants/menu'
 
 export function useAuth(authCode?: string) {
+    const { userMenus } = useMenuStore()
     const route = useRoute()
     const router = useRouter()
-    const userMenus = sessionData.getValue('userMenus')
     const componentMap = new Map<string, Component>()
 
     // 过滤菜单
@@ -55,7 +55,7 @@ export function useAuth(authCode?: string) {
             }
             return data
         }
-        return filterMenu(filterLevel(userMenus, level))
+        return filterMenu(filterLevel(userMenus.value, level))
     }
 
     /**
@@ -64,7 +64,7 @@ export function useAuth(authCode?: string) {
     * @returns 
     */
     const getChildrenMenus = (code?: string) => {
-        const children = findChildren(userMenus, code)
+        const children = findChildren(userMenus.value, code)
         return filterMenu(children)
     }
 
@@ -73,7 +73,7 @@ export function useAuth(authCode?: string) {
      * @returns 
      */
     const getAuth = (authType: AuthType) => {
-        const children = findChildren(userMenus, authCode)
+        const children = findChildren(userMenus.value, authCode)
         return children.reduce((res, cur) => {
             if (cur.authType === authType) {
                 if (!componentMap.get(cur.code) && cur.component) {
@@ -84,7 +84,7 @@ export function useAuth(authCode?: string) {
                     })
                     componentMap.set(cur.code, asyncComponent)
                 }
-                res.push(cur)
+                res.push(JSON.parse(JSON.stringify(cur)))
             }
             return res
         }, [] as Ermcp.UserMenu[])

+ 8 - 3
src/hooks/datatable/index.ts

@@ -1,7 +1,7 @@
 import { reactive, ref, shallowRef, toRefs, computed, UnwrapRef } from 'vue'
-import { FilterValue, FilterOptions } from './interface'
+import { FilterValue, FilterOptions, DataTableOptions } from './interface'
 
-export function useDataTable<T>() {
+export function useDataTable<T>(options?: DataTableOptions) {
     // 数据源
     const dataSource = ref<T[]>([])
     // 总记录条数
@@ -58,7 +58,7 @@ export function useDataTable<T>() {
     // 数据列表
     const dataList = computed<UnwrapRef<T[]>>({
         get() {
-            return dataSource.value.filter((row) => {
+            const result = dataSource.value.filter((row) => {
                 // 过滤所有查询条件
                 return filters.value.every((e) => {
                     return e.keys.some((key) => {
@@ -72,6 +72,11 @@ export function useDataTable<T>() {
                     })
                 })
             })
+            // 本地分页
+            if (options?.pagination) {
+                return result.slice((pageIndex.value - 1) * pageSize.value, pageIndex.value * pageSize.value)
+            }
+            return result
         },
         set(val) {
             dataSource.value = val

+ 7 - 0
src/hooks/datatable/interface.ts

@@ -50,4 +50,11 @@ export interface FilterButton {
     lable: string;
     className?: string;
     onClick: () => void;
+}
+
+/** 
+ * 数据表配置项
+ */
+export interface DataTableOptions {
+    pagination: boolean; // 是否进行本地分页
 }

+ 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 { getQuoteDayInfoByCode } = 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.getQuoteDayInfoByCode(goodscode); // 实时行情
+    const quote = getQuoteDayInfoByCode(goodscode); // 实时行情
 
     // 当前选中的数据项
     const selectedItem = computed(() => {

+ 4 - 4
src/hooks/echarts/candlestick/options.ts

@@ -1,11 +1,11 @@
 import { reactive, watch } from 'vue'
 import { ECOption } from '@/components/base/echarts/core'
 import { timerInterceptor } from '@/utils/timer'
-import { localData } from '@/stores'
+import { useThemeStore } from '@/stores'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 import moment from 'moment'
 
-const theme = localData.getRef('appTheme');
+const { appTheme } = useThemeStore();
 
 function getColors() {
     // 默认主题色配置
@@ -26,7 +26,7 @@ function getColors() {
         }
     }
 
-    return colors[theme.value];
+    return colors[appTheme.value];
 }
 
 export function useOptions(dataset: EchartsDataset) {
@@ -370,7 +370,7 @@ export function useOptions(dataset: EchartsDataset) {
     }, 1000)
 
     // 监听主题变化
-    watch(theme, () => {
+    watch(appTheme, () => {
         options.colors = getColors();
         initOptions();
     })

+ 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 { getQuoteDayInfoByCode } = 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.getQuoteDayInfoByCode(goodscode); // 实时行情
+    const quote = getQuoteDayInfoByCode(goodscode); // 实时行情
 
     // 当前选中的数据项
     const selectedItem = computed(() => {

+ 4 - 5
src/hooks/echarts/timeline/options.ts

@@ -1,11 +1,10 @@
 import { reactive, watch } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
-import { localData } from '@/stores'
+import { useThemeStore } from '@/stores'
 import { echarts } from '@/components/base/echarts/core'
 import { EchartsDataset, EchartsOptions, Colors } from './interface'
 
-
-const theme = localData.getRef('appTheme');
+const { appTheme } = useThemeStore();
 
 function getColors() {
     // 默认主题色配置
@@ -46,7 +45,7 @@ function getColors() {
         }
     }
 
-    return colors[theme.value];
+    return colors[appTheme.value];
 }
 
 export function useOptions(dataset: EchartsDataset) {
@@ -246,7 +245,7 @@ export function useOptions(dataset: EchartsDataset) {
     }, 1000)
 
     // 监听主题变化
-    watch(theme, () => {
+    watch(appTheme, () => {
         options.colors = getColors();
         initOptions();
     })

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

@@ -1,9 +1,11 @@
 import { createWebHashHistory, RouteRecordRaw } from 'vue-router'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import service from '@/services'
 import Page from '@mobile/components/layouts/page/index.vue'
 import animateRouter from './animateRouter'
 
+const { getToken } = useLoginStore()
+
 const routes: Array<RouteRecordRaw> = [
   {
     path: '/:pathMatch(.*)*',
@@ -65,11 +67,9 @@ const router = animateRouter.create({
 
 // 路由跳转拦截
 router.beforeEach((to, from, next) => {
-  const token = sessionData.getLoginInfo('Token');
-
   // 判断服务是否加载完成
   if (service.isReady) {
-    if (to.meta.requireAuth && !token) {
+    if (to.meta.requireAuth && !getToken()) {
       next({
         name: 'login',
         query: { redirect: to.fullPath },

+ 7 - 6
src/packages/mobile/views/home/components/market/index.vue

@@ -34,15 +34,16 @@
 <script lang="ts" setup>
 import { ref, reactive, onActivated, onDeactivated } from 'vue'
 import { Grid, GridItem, Button, ActionSheet, ActionSheetAction } from 'vant'
-import { futuresStore, localData } from '@/stores'
+import { useFuturesStore, useThemeStore } from '@/stores'
 import { handlePriceColor, handleNoneValue } from '@/filters'
 import AppTable from '@mobile/components/base/table/index.vue'
 import { TableColumn } from '@mobile/components/base/table/interface'
 import subscribe from '@/services/subscribe'
 
-const showAction = ref(false);
-const { quoteDayList } = futuresStore;
+const { setTheme } = useThemeStore();
+const { quoteDayList } = useFuturesStore();
 const quoteSubscribe = subscribe.addQuoteSubscribe(['cu2206', 'cu2207', 'cu2208', 'cu2209', 'cu2301', 'cu2303', 'cu2304']);
+const showAction = ref(false);
 
 const columns = reactive<TableColumn[]>([
   { prop: 'goodscode', label: '合约' },
@@ -62,15 +63,15 @@ const actions: ActionSheetAction[] = [
 const themeChange = (action: ActionSheetAction) => {
   switch (action.name) {
     case '默认': {
-      localData.setTheme('Default');
+      setTheme('Default');
       break;
     }
     case '浅色': {
-      localData.setTheme('Light');
+      setTheme('Light');
       break;
     }
     case '深色': {
-      localData.setTheme('Dark')
+      setTheme('Dark')
       break;
     }
   }

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

@@ -16,10 +16,11 @@ import { ref, watch } from 'vue'
 import { useRouter, useRoute } from 'vue-router'
 import { ElMessageBox } from 'element-plus'
 import { logout } from '@/business/common'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import zhCn from 'element-plus/lib/locale/lang/zh-cn'
 import eventBus from '@/services/bus'
 
+const { getToken } = useLoginStore()
 const route = useRoute()
 const router = useRouter()
 const isReady = ref(false)
@@ -35,7 +36,7 @@ eventBus.$on('LogoutNotify', (msg) => {
 })
 
 watch(() => route.name, (routeName) => {
-  const token = sessionData.getLoginInfo('Token')
+  const token = getToken()
   if (routeName !== 'boot' && token) {
     isReady.value = true
   } else {

+ 1 - 1
src/packages/pc/components/base/multiple/index.vue

@@ -21,7 +21,7 @@
 
 <script lang="ts" setup>
 import { shallowRef, watch, PropType } from 'vue'
-import { EnumType } from '@/constants'
+import { EnumType } from '@/stores/modules/enum'
 
 const props = defineProps({
     modelValue: {

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

@@ -25,8 +25,8 @@
             </div>
             <el-dropdown class="user-dropdown" trigger="click">
                 <span class="user-dropdown__link">
-                    <img class="g-image--avatar" :title="accountName" />
-                    <span v-if="!state.isMobile">{{ accountName }}</span>
+                    <img class="g-image--avatar" :title="getAccountName()" />
+                    <span v-if="!state.isMobile">{{ getAccountName() }}</span>
                     <app-icon class="el-icon--right" icon="ArrowDown" />
                 </span>
                 <template #dropdown>
@@ -46,7 +46,7 @@
 import { ref, onMounted, defineAsyncComponent } from 'vue'
 import { useRouter } from 'vue-router'
 import client from '@/utils/client'
-import { commonStore } from '@/stores'
+import { useUserStore } from '@/stores'
 import { useSign } from '@/business/sign'
 import { useComponent } from '@/hooks/component'
 import { useNotice } from '@/business/notice'
@@ -62,7 +62,7 @@ const { componentId, openComponent, closeComponent } = useComponent()
 const { dataList, unreadList, getNoticeList } = useNotice()
 const { state } = client
 const { signOut } = useSign()
-const accountName = commonStore.getAccountName()
+const { getAccountName } = useUserStore()
 const router = useRouter()
 const fullScreen = ref(false)
 

+ 3 - 3
src/packages/pc/components/modules/address/index.vue

@@ -9,7 +9,7 @@
 <script lang="ts" setup>
 import { shallowRef } from 'vue'
 import { queryUserReceiveInfo } from '@/services/api/user'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 
 const props = defineProps({
     modelValue: Number,
@@ -19,8 +19,8 @@ const props = defineProps({
     }
 })
 
+const { getUserId } = useLoginStore()
 const emit = defineEmits(['update:modelValue', 'change'])
-
 const dataList = shallowRef<Ermcp.UserReceiveInfoRsp[]>([])
 const selectedItem = shallowRef<Ermcp.UserReceiveInfoRsp>()
 
@@ -31,7 +31,7 @@ const onChange = (item?: Ermcp.UserReceiveInfoRsp) => {
 
 queryUserReceiveInfo({
     data: {
-        userid: sessionData.getLoginInfo('UserID')
+        userid: getUserId()
     },
     success: (res) => {
         dataList.value = res.data

+ 3 - 3
src/packages/pc/components/modules/invoice/index.vue

@@ -10,7 +10,7 @@
 import { shallowRef } from 'vue'
 import { getReceiptTypeName } from '@/constants/receipt'
 import { queryWrUserReceiptInfo } from '@/services/api/user'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 
 const props = defineProps({
     modelValue: Number,
@@ -20,8 +20,8 @@ const props = defineProps({
     }
 })
 
+const { getUserId } = useLoginStore()
 const emit = defineEmits(['update:modelValue', 'change'])
-
 const dataList = shallowRef<Ermcp.WrUserReceiptInfoRsp[]>([])
 const selectedItem = shallowRef<Ermcp.WrUserReceiptInfoRsp>()
 
@@ -32,7 +32,7 @@ const onChange = (item?: Ermcp.WrUserReceiptInfoRsp) => {
 
 queryWrUserReceiptInfo({
     data: {
-        userid: sessionData.getLoginInfo('UserID')
+        userid: getUserId()
     },
     success: (res) => {
         dataList.value = res.data

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

@@ -5,7 +5,7 @@ import directives from '@/directives' // 自定义指令集
 import '@/services/subscribe' // 全局订阅通知
 import '@/mock' // 模拟数据
 import client from '@/utils/client' // 适配客户端
-import language from '@/services/language' // 国际化语言
+import { useLanguageStore } from '@/stores' // 国际化语言
 import layouts from "./components/layouts" // 布局组件
 import ElementPlus from 'element-plus'
 import * as ElementIcons from '@element-plus/icons-vue'
@@ -13,12 +13,14 @@ import 'element-plus/dist/index.css'
 import './assets/themes/style.less' // 主题样式
 import { timerInterceptor } from '@/utils/timer'
 
+const { i18n } = useLanguageStore()
+
 const app = createApp(App)
 app.use(router)
 app.use(directives)
 app.use(ElementPlus)
 app.use(layouts)
-app.use(language.i18n)
+app.use(i18n)
 app.mount('#app')
 
 // 等待 html 加载完成

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

@@ -1,6 +1,6 @@
 import { RouteRecordRaw } from 'vue-router'
 import { AuthType } from '@/constants/menu'
-import { sessionData } from '@/stores'
+import { useMenuStore } from '@/stores'
 import router from '../router'
 
 export default new (class {
@@ -68,9 +68,9 @@ export default new (class {
      * @returns 
      */
     registerRoutes() {
-        const menus = sessionData.getValue('userMenus');
+        const { userMenus } = useMenuStore();
         this.addNotFound();
-        this.addRoutes(menus);
+        this.addRoutes(userMenus.value);
         this.isReady = true;
     }
 })

+ 5 - 3
src/packages/pc/router/index.ts

@@ -1,12 +1,14 @@
 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import dynamicRouter from './dynamicRouter'
 import service from '@/services'
 
+const { getToken } = useLoginStore()
+
 const routes: Array<RouteRecordRaw> = [
     {
         path: '/',
-        redirect: () => sessionData.getLoginInfo('Token') ? '/home' : '/login', // 重定向到默认页面
+        redirect: () => getToken() ? '/home' : '/login', // 重定向到默认页面
     },
     {
         path: '/login',
@@ -57,7 +59,7 @@ router.beforeEach((to, from, next) => {
 
     // 判断服务是否加载完成
     if (service.isReady) {
-        if (sessionData.getLoginInfo('Token')) {
+        if (getToken()) {
             if (dynamicRouter.isReady) {
                 if (isLoginOrRegister) {
                     next('/');

+ 8 - 10
src/packages/pc/views/boot/index.vue

@@ -10,11 +10,13 @@ import { ref } from 'vue'
 import { ElMessage } from 'element-plus'
 import { useRoute, useRouter } from 'vue-router'
 import { initBaseData, checkToken } from '@/business/common'
-import { sessionData } from '@/stores'
+import { useEnumStore, useErrorInfoStore, useLoginStore } from '@/stores'
 import service from '@/services'
-import eventBus from '@/services/bus'
 import socket from '@/services/socket'
 
+const { getToken } = useLoginStore()
+const { getAllEnumList } = useEnumStore()
+const { getErrorInfoList } = useErrorInfoStore()
 const route = useRoute()
 const router = useRouter()
 const loading = ref(false)
@@ -28,21 +30,17 @@ const initService = async () => {
     loading.value = false
   })
 
-  await sessionData.getAllEnumList()
-  await sessionData.getErrorInfoList()
+  await getAllEnumList()
+  await getErrorInfoList()
 
-  if (sessionData.getLoginInfo('Token')) {
+  if (getToken()) {
     // 等待连接交易服务
     await socket.connectTrade().catch((err) => {
       ElMessage.error(err)
       loading.value = false
     })
-
     // 等待令牌效验
-    await checkToken().catch(() => {
-      eventBus.$emit('LogoutNotify')
-    })
-
+    await checkToken()
     // 等待业务数据初始化
     await initBaseData().catch((err) => {
       ElMessage.error(err)

+ 1 - 5
src/packages/pc/views/favorite/main/index.vue

@@ -10,15 +10,13 @@
                 <app-auth-operation :options="{ selectedRow: row }" @closed="getFavoriteList" />
             </template>
             <template #footer>
-                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex"
-                    @change="getFavoriteList" />
+                <app-pagination :total="total" v-model:page-size="pageSize" v-model:page-index="pageIndex" />
             </template>
         </app-table>
     </app-view>
 </template>
 
 <script lang="ts" setup>
-import { ElMessage } from 'element-plus'
 import { useFavorite } from '@/business/favorite'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppTable from '@pc/components/base/table/index.vue'
@@ -26,6 +24,4 @@ import AppPagination from '@pc/components/base/pagination/index.vue'
 import AppFilter from '@pc/components/base/table-filter/index.vue'
 
 const { loading, dataList, columns, total, pageIndex, pageSize, selectList, buttonList, getFavoriteList } = useFavorite()
-
-getFavoriteList().catch((err) => ElMessage.error(err))
 </script>

+ 5 - 4
src/packages/pc/views/search/diamond/index.vue

@@ -67,7 +67,7 @@
 import { ref } from 'vue'
 import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
-import { sessionData } from '@/stores'
+import { useLoginStore, useFavoriteStore } from '@/stores'
 import { useSearch } from '@/business/search'
 import { Category } from '@/constants/diamond'
 import AppMultiple from '@pc/components/base/multiple/index.vue'
@@ -75,7 +75,9 @@ import AppTable from '@pc/components/base/table/index.vue'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
 
-const { loading, dataList, favoriteList, columns, total, pageIndex, pageSize, formData, enums, getSellOrderList, onSearch, onReset } = useSearch(Category.Diamond)
+const { getUserId } = useLoginStore()
+const { hasFavorite } = useFavoriteStore()
+const { loading, dataList, columns, total, pageIndex, pageSize, formData, enums, getSellOrderList, onSearch, onReset } = useSearch(Category.Diamond)
 const formRef = ref<FormInstance>()
 
 const formRules: FormRules = {
@@ -101,8 +103,7 @@ const formRules: FormRules = {
 
 // 未收藏的卖委托有收藏按钮
 const handleTableButtons = (row: Ermcp.SellOrderRsp) => {
-    const favorites = favoriteList.value.map((e) => e.goodsno)
-    if (favorites.includes(row.goodsno) || row.userid === sessionData.getLoginInfo('UserID')) {
+    if (hasFavorite(row.goodsno) || row.userid === getUserId()) {
         return ['details']
     }
     return ['details', 'favorite']

+ 5 - 4
src/packages/pc/views/search/fancy/index.vue

@@ -63,7 +63,7 @@
 <script lang="ts" setup>
 import { ref } from 'vue'
 import type { FormInstance, FormRules } from 'element-plus'
-import { sessionData } from '@/stores'
+import { useLoginStore, useFavoriteStore } from '@/stores'
 import { useSearch } from '@/business/search'
 import { Category } from '@/constants/diamond'
 import AppMultiple from '@pc/components/base/multiple/index.vue'
@@ -71,7 +71,9 @@ import AppTable from '@pc/components/base/table/index.vue'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
 
-const { loading, dataList, favoriteList, columns, total, pageIndex, pageSize, formData, enums, getSellOrderList, onSearch, onReset } = useSearch(Category.Fancy)
+const { getUserId } = useLoginStore()
+const { hasFavorite } = useFavoriteStore()
+const { loading, dataList, columns, total, pageIndex, pageSize, formData, enums, getSellOrderList, onSearch, onReset } = useSearch(Category.Fancy)
 const formRef = ref<FormInstance>()
 
 const formRules: FormRules = {
@@ -97,8 +99,7 @@ const formRules: FormRules = {
 
 // 未收藏的卖委托有收藏按钮
 const handleTableButtons = (row: Ermcp.SellOrderRsp) => {
-    const favorites = favoriteList.value.map((e) => e.goodsno)
-    if (favorites.includes(row.goodsno) || row.userid === sessionData.getLoginInfo('UserID')) {
+    if (hasFavorite(row.goodsno) || row.userid === getUserId()) {
         return ['details']
     }
     return ['details', 'favorite']

+ 3 - 2
src/packages/pc/views/trade/buy/components/details/index.vue

@@ -30,7 +30,7 @@
 <script lang="ts" setup>
 import { computed, PropType } from 'vue'
 import { useAuth } from '@/hooks/auth'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 
 const props = defineProps({
     code: String,
@@ -40,10 +40,11 @@ const props = defineProps({
     }
 })
 
+const { getUserId } = useLoginStore()
 const { componentMap, getAuthComponent } = useAuth(props.code)
 
 // 不能购买自己发布的求购
 const showComponent = computed(() => {
-    return props.selectedRow.userid !== sessionData.getLoginInfo('UserID')
+    return props.selectedRow.userid !== getUserId()
 })
 </script>

+ 3 - 2
src/packages/pc/views/trade/buy/index.vue

@@ -22,17 +22,18 @@
 <script lang="ts" setup>
 import { ElMessage } from 'element-plus'
 import { useBuyOrder } from '@/business/trade/list'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
 import AppFilter from '@pc/components/base/table-filter/index.vue'
 
+const { getUserId } = useLoginStore()
 const { loading, dataList, columns, total, pageIndex, pageSize, selectList, inputList, buttonList, getBuyOrderList } = useBuyOrder()
 const operateButtons = ['details', 'delisting']
 
 const handleOperateButtons = (row: Ermcp.SellOrderRsp) => {
-    if (row.userid === sessionData.getLoginInfo('UserID')) {
+    if (row.userid === getUserId()) {
         // 自己上架的商品不能摘牌
         return operateButtons.filter((code) => !['delisting'].includes(code))
     }

+ 5 - 4
src/packages/pc/views/trade/sell/index.vue

@@ -21,19 +21,20 @@
 
 <script lang="ts" setup>
 import { ElMessage } from 'element-plus'
-import { sessionData } from '@/stores'
+import { useLoginStore, useFavoriteStore } from '@/stores'
 import { useSellOrder } from '@/business/trade/list'
 import AppAuthOperation from '@pc/components/modules/auth-operation/index.vue'
 import AppTable from '@pc/components/base/table/index.vue'
 import AppPagination from '@pc/components/base/pagination/index.vue'
 import AppFilter from '@pc/components/base/table-filter/index.vue'
 
-const { loading, dataList, favoriteList, columns, total, pageIndex, pageSize, selectList, inputList, buttonList, getSellOrderList } = useSellOrder()
+const { getUserId } = useLoginStore()
+const { hasFavorite } = useFavoriteStore()
+const { loading, dataList, columns, total, pageIndex, pageSize, selectList, inputList, buttonList, getSellOrderList } = useSellOrder()
 
 // 未收藏的卖委托有收藏按钮
 const handleTableButtons = (row: Ermcp.SellOrderRsp) => {
-    const favorites = favoriteList.value.map((e) => e.goodsno)
-    if (favorites.includes(row.goodsno) || row.userid === sessionData.getLoginInfo('UserID')) {
+    if (hasFavorite(row.goodsno) || row.userid === getUserId()) {
         return ['details']
     }
     return ['details', 'favorite']

+ 3 - 2
src/packages/pc/views/warehousing/goods/components/details/index.vue

@@ -118,7 +118,7 @@
 
 <script lang="ts" setup>
 import { computed, PropType, defineAsyncComponent } from 'vue'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { useComponent } from '@/hooks/component'
 import { useDiamondDetails } from '@/business/goods'
 
@@ -139,13 +139,14 @@ const props = defineProps({
     },
 })
 
+const { getUserId } = useLoginStore()
 const { details, showFavorite, getDiamondDetails } = useDiamondDetails(props.selectedRow.goodsno)
 const { componentId, openComponent, closeComponent } = useComponent()
 
 // 不能购买自己上架的商品
 const showButton = computed(() => {
     if (details.value) {
-        return details.value.userid !== sessionData.getLoginInfo('UserID')
+        return details.value.userid !== getUserId()
     }
     return false
 })

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

@@ -2,7 +2,7 @@ import axios, { AxiosRequestConfig, Method } from 'axios'
 //import qs from 'qs'
 //import cryptojs from 'crypto-js'
 import { addPending, removePending } from './pending'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import { HttpRequest, HttpResponse, ResultCode } from './interface'
 import service from '@/services'
 
@@ -15,12 +15,13 @@ const http = axios.create({
  */
 http.interceptors.request.use(
     (config) => {
+        const { getToken } = useLoginStore();
         removePending(config); //在请求开始前,对之前的请求做检查取消操作
         addPending(config); //将当前请求添加到列表中
 
         //请求头签名
         const sign = {
-            token: sessionData.getLoginInfo('Token'),
+            token: getToken(),
             signsecret: 'qz7qWOMXKTMT5JlDs5w4NTPwWeR3xhF1v6wqbZ9cExmP6cc3spvNAp1wJJ1SqRI5',
             timestamp: new Date().getTime(),
         };

+ 0 - 30
src/services/language/index.ts

@@ -1,30 +0,0 @@
-import axios from 'axios'
-import { createI18n } from 'vue-i18n'
-import { Language } from '@/constants/language'
-import { localData } from '@/stores'
-
-export default new (class {
-    i18n = createI18n({})
-
-    constructor() {
-        const lang = localData.getValue('lang')
-        this.setLanguage(lang)
-    }
-
-    /**
-     * 设置语言
-     * @param lang 
-     */
-    async setLanguage(lang: Language) {
-        const locale = this.i18n.global.getLocaleMessage(lang)
-
-        if (!Object.keys(locale).length) {
-            await axios(`./language/${lang}.json`).then((res) => {
-                this.i18n.global.setLocaleMessage(lang, res.data)
-            })
-        }
-
-        this.i18n.global.locale = lang
-        localData.setValue('lang', lang);
-    }
-})

+ 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 { sessionData } from '@/stores'
+import { useErrorInfoStore } from '@/stores/modules/errorInfo'
 import service from '@/services'
 import eventBus from '@/services/bus'
 
@@ -35,6 +35,7 @@ export default new (class {
         }
 
         this.tradeServer.onPush = (p) => {
+            const { getErrorInfoByCode } = useErrorInfoStore();
             const { funCode, content } = p;
             const delay = 1000; // 延迟推送消息,防止短时间内重复请求
 
@@ -49,7 +50,7 @@ export default new (class {
                 case FunCode.LogoutRsp: {
                     // 通知上层 用户登出
                     protobuf.responseDecode<Proto.LogoutRsp>(FunCode[funCode], content).then(({ RetCode, RetDesc }) => {
-                        const msg = sessionData.getErrorInfoByCode(RetCode)
+                        const msg = getErrorInfoByCode(RetCode)
                         const error = (RetDesc || RetCode).toString();
                         eventBus.$emit('LogoutNotify', msg ?? error);
                     })

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

@@ -4,7 +4,7 @@ import { FunCode } from '@/constants/funcode'
 import { QuoteRequest } from './interface'
 import { subscribeListToByteArrary } from './build/encode'
 import { parseSubscribeRsp } from './build/decode'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import socket from '../index'
 
 /**
@@ -12,8 +12,8 @@ import socket from '../index'
  * @param params 
  */
 function quoteServerMiddleware(params: QuoteRequest): Promise<Proto.QuoteRsp[]> {
-    const { LoginID, Token } = sessionData.getValue('loginInfo');
-    const content = subscribeListToByteArrary(params.data, Token, Long.fromNumber(LoginID));
+    const { getLoginId, getToken } = useLoginStore();
+    const content = subscribeListToByteArrary(params.data, getToken(), Long.fromNumber(getLoginId()));
 
     return new Promise((resolve, reject) => {
         socket.sendQuoteServer({

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

@@ -1,7 +1,8 @@
 import { v4 } from 'uuid'
 import { Package50 } from '@/utils/websocket/package'
 import { FunCode } from '@/constants/funcode'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores/modules/login'
+import { useErrorInfoStore } from '@/stores/modules/errorInfo'
 import { IMessageHead } from './protobuf/proto'
 import { TradeRequest, TradeResponse } from './interface'
 import Protobuf from './protobuf'
@@ -11,11 +12,12 @@ import socket from '../index'
  * 构建消息头部
  */
 function getProtoHeader(funCode: keyof typeof FunCode, header?: IMessageHead, marketId?: number) {
+    const { getUserId } = useLoginStore();
     // 组合请求头
     const protoHeader: IMessageHead = {
         FunCode: FunCode[funCode],
         UUID: v4(),
-        UserID: sessionData.getLoginInfo('UserID'),
+        UserID: getUserId(),
         ...(header ?? {})
     }
     if (marketId) {
@@ -72,6 +74,7 @@ function tradeServerMiddleware<Req, Rsp>(reqKey: keyof typeof FunCode, rspKey: k
  * @param marketId 
  */
 export async function tradeServerRequest<Req, Rsp>(reqKey: keyof typeof FunCode, rspKey: keyof typeof FunCode, params: TradeRequest<Req, Rsp & TradeResponse>, marketId?: number) {
+    const { getErrorInfoByCode } = useErrorInfoStore();
     const { success, fail, complete } = params;
 
     await tradeServerMiddleware(reqKey, rspKey, params, marketId).then((res) => {
@@ -94,7 +97,7 @@ export async function tradeServerRequest<Req, Rsp>(reqKey: keyof typeof FunCode,
                 return Promise.reject(res.RetDesc);
             }
             default: {
-                const msg = sessionData.getErrorInfoByCode(RetCode)
+                const msg = getErrorInfoByCode(RetCode)
                 const error = (RetDesc || RetCode).toString();
                 return Promise.reject(msg ?? error);
             }

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

@@ -1,6 +1,6 @@
 import { v4 } from 'uuid'
 import { quoteServerRequest } from '@/services/socket/quote'
-import { sessionData } from '@/stores'
+import { useLoginStore } from '@/stores'
 import eventBus from '@/services/bus'
 import socket from '@/services/socket'
 
@@ -61,6 +61,7 @@ export default new (class {
      * @returns 
      */
     addQuoteSubscribe = (goodsCodes: string[], key?: string) => {
+        const { getToken } = useLoginStore()
         const uuid = key ?? v4()
         const value = this.quoteSubscribeMap.get(uuid) ?? []
 
@@ -78,7 +79,7 @@ export default new (class {
                 if (flag) {
                     console.log('删除订阅', uuid)
                 }
-                if (sessionData.getLoginInfo('Token')) {
+                if (getToken()) {
                     this.quoteSubscribe()
                 }
                 return flag

+ 49 - 0
src/stores/base.ts

@@ -0,0 +1,49 @@
+import { reactive, toRefs, ComputedRef, UnwrapNestedRefs, ToRefs } from 'vue'
+
+/**
+ * 状态存储
+ */
+export interface Store<T> {
+    state: UnwrapNestedRefs<T>;
+    getters?: { [propName: string]: ComputedRef };
+    actions?: { [propName: string]: (...args: never[]) => unknown };
+    methods?: {
+        $setData: (callback: (state: UnwrapNestedRefs<T>) => void) => void;
+        $storeToRefs: () => ToRefs<UnwrapNestedRefs<T>>;
+    }
+}
+
+/**
+ * 状态存储控制类
+ */
+export abstract class VueStore<T extends object> implements Store<T>{
+    constructor(state: T) {
+        this.state = reactive<T>(state)
+    }
+
+    state
+    getters = {}
+    actions = {}
+    methods = {
+        $setData: (callback: (state: UnwrapNestedRefs<T>) => void) => {
+            callback(this.state)
+        },
+        $storeToRefs: () => {
+            return toRefs(this.state)
+        },
+    }
+}
+
+/**
+ * 创建状态管理
+ * @param store
+ * @returns
+ */
+// export function createStore<T extends object>(store: VueStore<T>) {
+//     return shallowReadonly({
+//         ...toRefs(store.state),
+//         ...store.getters,
+//         ...store.actions,
+//         ...store.methods,
+//     })
+// }

+ 41 - 9
src/stores/index.ts

@@ -1,12 +1,44 @@
-import { localData, sessionData } from './modules/storage'
-import commonStore from './modules/common'
-import accountStore from './modules/account'
-import futuresStore from './modules/futures'
+import { useLoginStore } from './modules/login'
+import { useUserStore } from './modules/user'
+import { useThemeStore } from './modules/theme'
+import { useMenuStore } from './modules/menu'
+import { useAccountStore } from './modules/account'
+import { useFuturesStore } from './modules/futures'
+import { useLanguageStore } from './modules/language'
+import { useEnumStore } from './modules/enum'
+import { useErrorInfoStore } from './modules/errorInfo'
+import { useFavoriteStore } from './modules/favorite'
+import { useTableColumnStore } from './modules/tableColumn'
+import { usePerformanceStore } from './modules/performance'
 
 export {
-    localData,
-    sessionData,
-    commonStore,
-    accountStore,
-    futuresStore,
+    useLoginStore,
+    useUserStore,
+    useThemeStore,
+    useMenuStore,
+    useAccountStore,
+    useFuturesStore,
+    useLanguageStore,
+    useEnumStore,
+    useErrorInfoStore,
+    useFavoriteStore,
+    useTableColumnStore,
+    usePerformanceStore,
+}
+
+export function useStore() {
+    return {
+        loginStore: useLoginStore(),
+        userStore: useUserStore(),
+        themeStore: useThemeStore(),
+        menuStore: useMenuStore(),
+        accountStore: useAccountStore(),
+        futuresStore: useFuturesStore(),
+        languageStore: useLanguageStore(),
+        enumStore: useEnumStore(),
+        errorInfoStore: useErrorInfoStore(),
+        favoriteStore: useFavoriteStore(),
+        tableColumnStore: useTableColumnStore(),
+        performanceStore: usePerformanceStore(),
+    }
 }

+ 67 - 49
src/stores/modules/account.ts

@@ -1,69 +1,87 @@
-import { ref, computed } from 'vue'
+import { computed, toRefs, shallowReadonly } from 'vue'
 import { queryTaAccounts } from '@/services/api/account'
-import { sessionData } from './storage'
+import { useLoginStore } from './login'
+import { VueStore } from '../base'
 import eventBus from '@/services/bus'
 
+interface StoreState {
+    loading: boolean;
+    accountList: Ermcp.TaAccountsRsp[]; // 资金账户列表
+    currentAccountId: number; // 当前资金账户ID
+}
+
 /**
  * 账号存储类
  */
-export default new (class {
-    loading = ref(false)
-    accountId = ref(0) // 当前资金账户ID
-    accountList = ref<Ermcp.TaAccountsRsp[]>([]) // 资金账户列表
-
+const store = new (class extends VueStore<StoreState> {
     constructor() {
+        const state: StoreState = {
+            loading: false,
+            accountList: [],
+            currentAccountId: 0,
+        }
+        super(state)
+
         // 接收资金变动通知
         eventBus.$on('MoneyChangedNotify', () => {
-            this.getAccountList()
+            this.actions.getAccountList()
         })
     }
 
-    /**
-     * 当前资金账户信息
-     */
-    accountInfo = computed(() => {
-        return this.accountList.value.find((e) => e.accountid === this.accountId.value)
+    /** 当前资金账户信息 */
+    private currentAccountInfo = computed(() => {
+        return this.state.accountList.find((e) => e.accountid === this.state.currentAccountId)
     })
 
-    /**
-     * 获取资金账户列表
-     * @returns 
-     */
-    getAccountList = async () => {
-        this.loading.value = true
+    getters = {
+        currentAccountInfo: this.currentAccountInfo
+    }
+
+    actions = {
+        /** 获取资金账户列表 */
+        getAccountList: () => {
+            const { getLoginId } = useLoginStore()
+            this.state.loading = true
 
-        return queryTaAccounts({
-            data: {
-                loginID: sessionData.getLoginInfo('LoginID')
-            },
-            success: (res) => {
-                const dataList = res.data
-                if (dataList.length) {
-                    this.accountList.value = dataList
-                    // 查找当前选中的资金账户
-                    const account = dataList.find((e) => e.accountid === this.accountId.value)
-                    if (account) {
-                        this.loading.value = false
+            return queryTaAccounts({
+                data: {
+                    loginID: getLoginId()
+                },
+                success: (res) => {
+                    const dataList = res.data
+                    if (dataList.length) {
+                        this.state.accountList = dataList
+                        // 查找当前选中的资金账户
+                        const account = dataList.find((e) => e.accountid === this.state.currentAccountId)
+                        if (account) {
+                            this.state.loading = false
+                        } else {
+                            // 如果不存在,默认选中第一个账户
+                            this.state.currentAccountId = dataList[0].accountid
+                        }
                     } else {
-                        // 如果不存在,默认选中第一个账户
-                        this.accountId.value = dataList[0].accountid
+                        this.state.loading = false
+                        this.actions.reset()
                     }
-                } else {
-                    this.loading.value = false
-                    this.reset()
+                },
+                fail: () => {
+                    this.state.loading = false
                 }
-            },
-            fail: () => {
-                this.loading.value = false
-            }
-        })
+            })
+        },
+        /** 重置数据 */
+        reset: () => {
+            this.state.accountList = []
+            this.state.currentAccountId = 0
+        }
     }
+})
 
-    /**
-     * 重置数据
-     */
-    reset = () => {
-        this.accountId.value = 0
-        this.accountList.value = []
-    }
-})
+export function useAccountStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.getters,
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 0 - 54
src/stores/modules/common.ts

@@ -1,54 +0,0 @@
-import { ref } from 'vue'
-import { queryLoginData } from '@/services/api/account'
-import { sessionData } from './storage'
-
-/**
- * 公共存储类
- */
-export default new (class {
-    loading = ref(false)
-    loginData = ref<Ermcp.LoginQueryRsp>({
-        arearole: [],
-        externalExchanges: [],
-        goodsgroups: [],
-        markets: [],
-        systemParams: []
-    })
-
-    /**
-     * 获取登录数据
-     * @returns 
-     */
-    getLoginData = () => {
-        this.loading.value = true
-        return queryLoginData({
-            data: {
-                loginID: sessionData.getLoginInfo('LoginID')
-            },
-            success: (res) => {
-                this.loginData.value = res.data
-            },
-            complete: () => {
-                this.loading.value = false
-            }
-        })
-    }
-
-    /**
-     * 获取登录数据
-     * @param key 
-     * @returns 
-     */
-    getLoginDataInfo = <K extends keyof Ermcp.LoginQueryRsp>(key: K) => {
-        return this.loginData.value[key]!
-    }
-
-    /**
-     * 获取登录机构名称
-     * @returns 
-     */
-    getAccountName = () => {
-        const { userAccount } = this.loginData.value
-        return userAccount?.accountname
-    }
-})

+ 95 - 0
src/stores/modules/enum.ts

@@ -0,0 +1,95 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { queryAllEnums } from '@/services/api/common'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+/**
+ * 枚举类型
+ */
+export interface EnumType {
+    label: string;
+    value: number;
+    disabled?: boolean;
+}
+
+interface StoreState {
+    loading: boolean;
+    allEnums: ShallowRef<Ermcp.EnumRsp[]>;
+}
+
+/**
+ * 枚举存储类
+ */
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Ermcp.EnumRsp[]>(sessionStorage, 'allEnums', [])
+        const state: StoreState = {
+            loading: false,
+            allEnums: storage.getRef(),
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取所有枚举列表 */
+        getAllEnumList: () => {
+            if (this.state.allEnums.length) {
+                return Promise.resolve()
+            }
+            this.state.loading = true
+            return queryAllEnums({
+                success: (res) => {
+                    this.state.allEnums = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        },
+        /** 获取枚举类型 */
+        getEnumTypes: <T extends string[]>(...args: T) => {
+            const enumMap = new Map<typeof args[number], Ermcp.EnumRsp[]>()
+            this.state.allEnums.forEach((e) => {
+                if (args.some((code) => code.toLowerCase() === e.enumdiccode.toLowerCase())) {
+                    const enums = enumMap.get(e.enumdiccode)
+                    if (enums) {
+                        enums.push(e)
+                    } else {
+                        enumMap.set(e.enumdiccode, [e])
+                    }
+                }
+            })
+            return enumMap
+        },
+        /** 获取枚举信息 */
+        getEnumTypeInfo: (enums: Ermcp.EnumRsp[], value: number) => {
+            return enums.find((e) => e.enumitemstatus === 1 && e.enumitemname === value)
+        },
+        /** 获取枚举列表 */
+        getEnumTypeList: (enums?: Ermcp.EnumRsp[]) => {
+            if (enums) {
+                return enums.map((e) => ({
+                    label: e.enumdicname,
+                    value: e.enumitemname,
+                }))
+            }
+            return []
+        },
+        /** 根据枚举值获取枚举名称 */
+        getEnumTypeName: (enums: EnumType[], value?: number) => {
+            const item = enums.find((e) => e.value === value)
+            if (item) {
+                return item.label
+            }
+            return '--'
+        }
+    }
+})
+
+export function useEnumStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 55 - 0
src/stores/modules/errorInfo.ts

@@ -0,0 +1,55 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { queryErrorInfos } from '@/services/api/common'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    loading: boolean;
+    errorInfos: ShallowRef<Ermcp.ErrorInfosRsp[]>;
+}
+
+/**
+ * 错误信息存储类
+ */
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Ermcp.ErrorInfosRsp[]>(sessionStorage, 'errorInfos', [])
+        const state: StoreState = {
+            loading: false,
+            errorInfos: storage.getRef(),
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取系统错误信息 */
+        getErrorInfoList: () => {
+            if (this.state.errorInfos.length) {
+                return Promise.resolve()
+            }
+            this.state.loading = true
+            return queryErrorInfos({
+                success: (res) => {
+                    this.state.errorInfos = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        },
+        /** 根据 code 获取错误信息 */
+        getErrorInfoByCode: (code: number) => {
+            const errorInfos = this.state.errorInfos
+            const error = errorInfos.find((e) => e.errorid === code)
+            return error?.description
+        }
+    }
+})
+
+export function useErrorInfoStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 54 - 0
src/stores/modules/favorite.ts

@@ -0,0 +1,54 @@
+import { toRefs, shallowReadonly } from 'vue'
+import { queryMyFavorite } from '@/services/api/favorite'
+import { useLoginStore } from './login'
+import { VueStore } from '../base'
+
+interface StoreState {
+    loading: boolean;
+    favoriteList: Ermcp.MyFavoriteRsp[]; // 收藏列表
+}
+
+/**
+ * 商品收藏存储类
+ */
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const state: StoreState = {
+            loading: false,
+            favoriteList: [],
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取收藏列表 */
+        getFavoriteList: () => {
+            const { getUserId } = useLoginStore()
+            this.state.loading = true
+
+            return queryMyFavorite({
+                data: {
+                    userid: getUserId(),
+                },
+                success: (res) => {
+                    this.state.favoriteList = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        },
+        /** 是否已收藏 */
+        hasFavorite: (goodsno: string) => {
+            return this.state.favoriteList.some((e) => e.goodsno === goodsno)
+        }
+    }
+})
+
+export function useFavoriteStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 58 - 50
src/stores/modules/futures.ts

@@ -1,21 +1,29 @@
-import { ref, computed } from 'vue'
+import { computed, toRefs, shallowReadonly } from 'vue'
 import { timerInterceptor } from '@/utils/timer'
 import { queryGoodsList } from '@/services/api/goods'
-import { sessionData } from './storage'
-import moment from 'moment'
+import { useLoginStore } from './login'
+import { VueStore } from '../base'
 import eventBus from '@/services/bus'
+import moment from 'moment'
+
+interface StoreState {
+    loading: boolean;
+    goodsList: Ermcp.GoodsRsp[]; // 商品列表
+    quoteDayList: Ermcp.QuoteDay[]; // 盘面列表
+}
 
 /**
  * 期货存储类
  */
-export default new (class {
-    private quotes: Proto.Quote[] = [] // 行情数据
-
-    loading = ref(false)
-    goodsList = ref<Ermcp.GoodsRsp[]>([]) // 商品列表
-    quoteDayList = ref<Ermcp.QuoteDay[]>([]) // 盘面列表
-
+const store = new (class extends VueStore<StoreState> {
     constructor() {
+        const state: StoreState = {
+            loading: false,
+            goodsList: [],
+            quoteDayList: [],
+        }
+        super(state)
+
         // 接收行情推送通知
         eventBus.$on('QuotePushNotify', (res) => {
             const data = res as Proto.Quote[]
@@ -31,11 +39,11 @@ export default new (class {
         })
     }
 
-    /**
-     * 处理行情数据
-     */
+    private quotes: Proto.Quote[] = [] // 行情数据
+
+    /** 处理行情数据 */
     private handleQuote = timerInterceptor.setThrottle(() => {
-        const quoteList = this.quoteDayList.value
+        const quoteList = this.state.quoteDayList
         this.quotes.forEach((item) => {
             const quote = quoteList.find((e) => e.goodscode.toUpperCase() === item.goodscode?.toUpperCase())
             const last = item.last ?? 0
@@ -193,42 +201,42 @@ export default new (class {
         })
     }, 200)
 
-    /**
-     * 获取商品列表
-     */
-    getGoodsList = () => {
-        this.loading.value = true
-        return queryGoodsList({
-            data: {
-                userid: sessionData.getLoginInfo('UserID')
-            },
-            success: (res) => {
-                this.goodsList.value = res.data
-            },
-            complete: () => {
-                this.loading.value = false
-            }
-        })
-    }
+    actions = {
+        // 获取商品列表
+        getGoodsList: () => {
+            const { getUserId } = useLoginStore()
+            this.state.loading = true
 
-    /**
-     * 通过 goodscode 获取盘面实时行情
-     * @param goodscode 
-     * @returns 
-     */
-    getQuoteDayInfoByCode = (goodscode: string) => {
-        return computed(() => this.quoteDayList.value.find((e) => e.goodscode.toUpperCase() === goodscode.toUpperCase()))
+            return queryGoodsList({
+                data: {
+                    userid: getUserId()
+                },
+                success: (res) => {
+                    this.state.goodsList = res.data
+                },
+                complete: () => {
+                    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
+            })
+        }
     }
+})
 
-    /**
-     * 通过 goodscode 获取商品实时报价
-     * @param goodscode 
-     * @returns 
-     */
-    getGoodsPriceByCode = (goodscode: string) => {
-        return computed(() => {
-            const quote = this.getQuoteDayInfoByCode(goodscode)
-            return quote.value?.last ?? 0
-        })
-    }
-})
+export function useFuturesStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 52 - 0
src/stores/modules/language.ts

@@ -0,0 +1,52 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import axios from 'axios'
+import { createI18n } from 'vue-i18n'
+import { Language } from '@/constants/language'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    lang: ShallowRef<Language>;
+}
+
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Language>(localStorage, 'language', Language.ZhCN)
+        const state: StoreState = {
+            lang: storage.getRef()
+        }
+
+        super(state)
+        const lang = this.state.lang
+        this.actions.setLanguage(lang)
+    }
+
+    i18n = createI18n({})
+
+    actions = {
+        /** 设置语言 */
+        setLanguage: async (lang: Language) => {
+            const locale = this.i18n.global.getLocaleMessage(lang)
+
+            if (!Object.keys(locale).length) {
+                await axios(`./language/${lang}.json`).then((res) => {
+                    this.i18n.global.setLocaleMessage(lang, res.data)
+                }).catch(() => {
+                    // 默认语言
+                })
+            }
+
+            this.i18n.global.locale = lang
+            this.state.lang = lang
+        }
+    }
+})
+
+export function useLanguageStore() {
+    return shallowReadonly({
+        i18n: store.i18n,
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 108 - 0
src/stores/modules/login.ts

@@ -0,0 +1,108 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { login, queryLoginId } from '@/services/api/account'
+import { VueStore } from '../base'
+import cryptojs from 'crypto-js'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    loading: boolean;
+    loginInfo: ShallowRef<Proto.LoginRsp>;
+}
+
+function getInitData(): Proto.LoginRsp {
+    return {
+        AccountIDs: [],
+        LoginCode: '',
+        LoginID: 0,
+        LoginUserType: 0,
+        AccountStatus: 0,
+        UserID: 0,
+        ClientID: 0,
+        MemberUserID: 0,
+        Token: '',
+    }
+}
+
+/**
+ * 登录存储类
+ */
+const store = new (class extends VueStore<StoreState> {
+    constructor() {
+        const storage = new WebStorage(sessionStorage, 'loginInfo', getInitData())
+        const state: StoreState = {
+            loading: false,
+            loginInfo: storage.getRef(),
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 用户登录 */
+        userLogin: (param: Proto.LoginReq) => {
+            this.state.loading = true
+            return new Promise<Proto.LoginRsp>((resolve, reject) => {
+                queryLoginId({
+                    data: {
+                        username: param.LoginID
+                    },
+                    success: (res) => {
+                        login({
+                            data: {
+                                ...param,
+                                LoginID: res.data,
+                                LoginPWD: cryptojs.SHA256(res.data + param.LoginPWD).toString(),
+                            },
+                            success: (res) => {
+                                this.state.loginInfo = res
+                                resolve(res)
+                            },
+                            fail: (err) => {
+                                reject(err)
+                            },
+                            complete: () => {
+                                this.state.loading = false
+                            }
+                        })
+                    },
+                    fail: (err) => {
+                        this.state.loading = false
+                        reject(err)
+                    }
+                })
+            })
+        },
+        /** 获取用户登录信息 */
+        getLoginInfo: <K extends keyof Proto.LoginRsp>(key: K) => {
+            return this.state.loginInfo[key]
+        },
+        /** 获取登录令牌 */
+        getToken: () => {
+            return this.state.loginInfo.Token
+        },
+        /** 获取用户ID */
+        getUserId: () => {
+            return this.state.loginInfo.UserID
+        },
+        /** 获取登录ID */
+        getLoginId: () => {
+            return this.state.loginInfo.LoginID
+        },
+        /** 获取首个账户ID */
+        getFirstAccountId: () => {
+            const accounts = this.state.loginInfo.AccountIDs
+            return accounts[0] ?? 0
+        },
+        /** 重置数据 */
+        reset: () => {
+            this.state.loginInfo = getInitData()
+        }
+    }
+})
+
+export function useLoginStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 88 - 0
src/stores/modules/menu.ts

@@ -0,0 +1,88 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { queryNewFuncmenu } from '@/services/api/common'
+import { queryAccountMenu } from '@/services/api/account'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    loading: boolean;
+    userMenus: ShallowRef<Ermcp.UserMenu[]>;
+}
+
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Ermcp.UserMenu[]>(sessionStorage, 'userMenus', [])
+        const state: StoreState = {
+            loading: false,
+            userMenus: storage.getRef()
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取用户菜单列表 */
+        getUserMenuList: () => {
+            this.state.loading = true
+            return queryAccountMenu({
+                success: (res) => {
+                    this.state.userMenus = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+            return queryNewFuncmenu({
+                data: {
+                    menutype: '5',
+                },
+                success: (res) => {
+                    // 扁平列表树形化
+                    const arrayToTree = (list: Ermcp.NewFuncmenuRsp[], code: null | string = null) => {
+                        const getChildren = (parent: null | string) => {
+                            const result: Ermcp.UserMenu[] = []
+                            list.forEach((e) => {
+                                if (e.parentcode === parent) {
+                                    const item = {
+                                        id: 0,
+                                        authType: e.authtype,
+                                        title: e.resourcename,
+                                        code: e.resourcecode,
+                                        urlType: e.urltype,
+                                        url: e.url || '',
+                                        component: e.component,
+                                        icon: e.iconame,
+                                        buttonName: e.buttonname,
+                                        buttonType: e.buttontype,
+                                        sort: e.sort,
+                                        hidden: Boolean(e.hidden),
+                                        remark: e.remark,
+                                        children: getChildren(e.resourcecode),
+                                    }
+                                    result.push(item)
+                                }
+                            })
+                            return result
+                        }
+                        return getChildren(code)
+                    }
+                    this.state.userMenus = arrayToTree(res.data)
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        },
+        /** 重置数据 */
+        reset: () => {
+            this.state.userMenus = []
+        }
+    }
+})
+
+export function useMenuStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 46 - 0
src/stores/modules/performance.ts

@@ -0,0 +1,46 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { queryWrPerformanceStepType } from '@/services/api/performance'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    loading: boolean;
+    performanceStepTypes: ShallowRef<Ermcp.WrPerformanceStepTypeRsp[]>;
+}
+
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Ermcp.WrPerformanceStepTypeRsp[]>(sessionStorage, 'performanceStepTypes', [])
+        const state: StoreState = {
+            loading: false,
+            performanceStepTypes: storage.getRef()
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取履约步骤列表 */
+        getPerformanceStepList: () => {
+            if (this.state.performanceStepTypes.length) {
+                return Promise.resolve()
+            }
+            this.state.loading = true
+            return queryWrPerformanceStepType({
+                success: (res) => {
+                    this.state.performanceStepTypes = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        }
+    }
+})
+
+export function usePerformanceStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 0 - 232
src/stores/modules/storage.ts

@@ -1,232 +0,0 @@
-import { queryAllEnums, queryNewFuncmenu, queryTableDefine, queryErrorInfos } from '@/services/api/common'
-import { queryAccountMenu } from '@/services/api/account'
-import { queryWrPerformanceStepType } from '@/services/api/performance'
-import { AppTheme } from '@/constants/theme'
-import { Language } from '@/constants/language'
-import WebStorage from '@/utils/storage'
-import plus from '@/utils/h5plus'
-
-/**
- * 初始数据
- */
-const initData: Store.GlobalStorage = {
-    appTheme: AppTheme.Default,
-    lang: Language.ZhCN,
-    loginInfo: {
-        AccountIDs: [],
-        LoginCode: '',
-        LoginID: 0,
-        LoginUserType: 0,
-        AccountStatus: 0,
-        UserID: 0,
-        ClientID: 0,
-        MemberUserID: 0,
-        Token: '',
-    },
-    userMenus: [],
-    allEnums: [],
-    tableColumns: [],
-    errorInfos: [],
-    performanceStepTypes: [],
-}
-
-/**
- * 本地存储实例
- */
-export const localData = new (class extends WebStorage<Store.GlobalStorage>{
-    constructor() {
-        super(localStorage, initData)
-        document.addEventListener('DOMContentLoaded', this.loadTheme, false)
-    }
-
-    /**
-     * 加载主题
-     */
-    private loadTheme = () => {
-        const theme = this.getValue('appTheme')
-        this.setStatusBarTheme(theme)
-        document.documentElement.setAttribute('theme', theme)
-        document.removeEventListener('DOMContentLoaded', this.loadTheme)
-    }
-
-    /**
-     * 设置状态栏主题色
-     * @param theme 
-     */
-    private setStatusBarTheme = (theme: AppTheme) => {
-        switch (theme) {
-            case AppTheme.Default:
-            case AppTheme.Dark: {
-                plus.setStatusBarStyle('light')
-                break
-            }
-            default: {
-                plus.setStatusBarStyle('dark')
-            }
-        }
-    }
-
-    /**
-     * 设置主题
-     * @param key 
-     */
-    setTheme = (key: keyof typeof AppTheme) => {
-        const theme = AppTheme[key]
-        this.setStatusBarTheme(theme)
-        document.documentElement.setAttribute('theme', theme)
-        this.setValue('appTheme', theme)
-    }
-
-    /**
-     * 重置数据
-     */
-    reset = () => {
-        this.clear('loginInfo', 'userMenus')
-    }
-})
-
-/**
- * 会话存储实例
- */
-export const sessionData = new (class extends WebStorage<Store.GlobalStorage>{
-    constructor() {
-        super(sessionStorage, initData)
-    }
-
-    /**
-     * 获取登录信息
-     * @param key 
-     * @returns 
-     */
-    getLoginInfo = <K extends keyof Proto.LoginRsp>(key: K) => {
-        return this.getValue('loginInfo')[key]
-    }
-
-    /**
-     * 获取所有枚举列表
-     * @returns 
-     */
-    getAllEnumList = () => {
-        if (this.getValue('allEnums').length) {
-            return Promise.resolve()
-        }
-        return queryAllEnums({
-            success: (res) => {
-                this.setValue('allEnums', res.data)
-            }
-        })
-    }
-
-    /**
-     * 获取履约步骤列表
-     */
-    getPerformanceStepList = () => {
-        if (this.getValue('performanceStepTypes').length) {
-            return Promise.resolve()
-        }
-        return queryWrPerformanceStepType({
-            success: (res) => {
-                this.setValue('performanceStepTypes', res.data)
-            }
-        })
-    }
-
-    /**
-     * 获取系统错误信息
-     * @returns 
-     */
-    getErrorInfoList = () => {
-        if (this.getValue('errorInfos').length) {
-            return Promise.resolve()
-        }
-        return queryErrorInfos({
-            success: (res) => {
-                this.setValue('errorInfos', res.data)
-            }
-        })
-    }
-
-    /**
-     * 根据 code 获取错误信息
-     * @param code 
-     * @returns 
-     */
-    getErrorInfoByCode = (code: number) => {
-        const errorInfos = this.getValue('errorInfos')
-        const error = errorInfos.find((e) => e.errorid === code)
-        return error?.description
-    }
-
-    /**
-     * 获取用户菜单列表
-     */
-    getUserMenuList = () => {
-        return queryAccountMenu({
-            success: (res) => {
-                this.setValue('userMenus', res.data)
-            }
-        })
-        return queryNewFuncmenu({
-            data: {
-                menutype: '5',
-            },
-            success: (res) => {
-                // 扁平列表树形化
-                const arrayToTree = (list: Ermcp.NewFuncmenuRsp[], code: null | string = null) => {
-                    const getChildren = (parent: null | string) => {
-                        const result: Ermcp.UserMenu[] = []
-                        list.forEach((e) => {
-                            if (e.parentcode === parent) {
-                                const item = {
-                                    id: 0,
-                                    authType: e.authtype,
-                                    title: e.resourcename,
-                                    code: e.resourcecode,
-                                    urlType: e.urltype,
-                                    url: e.url || '',
-                                    component: e.component,
-                                    icon: e.iconame,
-                                    buttonName: e.buttonname,
-                                    buttonType: e.buttontype,
-                                    sort: e.sort,
-                                    hidden: Boolean(e.hidden),
-                                    remark: e.remark,
-                                    children: getChildren(e.resourcecode),
-                                }
-                                result.push(item)
-                            }
-                        })
-                        return result
-                    }
-                    return getChildren(code)
-                }
-                this.setValue('userMenus', arrayToTree(res.data))
-            }
-        })
-    }
-
-    /**
-     * 获取表格列列表
-     * @returns 
-     */
-    getTableColumnList = () => {
-        if (this.getValue('tableColumns').length) {
-            return Promise.resolve()
-        }
-        return queryTableDefine({
-            data: {
-                tableType: 2
-            },
-            success: (res) => {
-                this.setValue('tableColumns', res.data)
-            }
-        })
-    }
-
-    /**
-     * 重置数据
-     */
-    reset = () => {
-        this.clear('loginInfo', 'userMenus')
-    }
-})

+ 46 - 0
src/stores/modules/tableColumn.ts

@@ -0,0 +1,46 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { queryTableDefine } from '@/services/api/common'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+
+interface StoreState {
+    loading: boolean;
+    tableColumns: ShallowRef<Ermcp.TableDefineRsp[]>;
+}
+
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<Ermcp.TableDefineRsp[]>(sessionStorage, 'tableColumns', [])
+        const state: StoreState = {
+            loading: false,
+            tableColumns: storage.getRef()
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取表格列列表 */
+        getTableColumnList: () => {
+            this.state.loading = true
+            return queryTableDefine({
+                data: {
+                    tableType: 2
+                },
+                success: (res) => {
+                    this.state.tableColumns = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        }
+    }
+})
+
+export function useTableColumnStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 65 - 0
src/stores/modules/theme.ts

@@ -0,0 +1,65 @@
+import { toRefs, shallowReadonly, ShallowRef } from 'vue'
+import { AppTheme } from '@/constants/theme'
+import { VueStore } from '../base'
+import WebStorage from '@/utils/storage/base'
+import plus from '@/utils/h5plus'
+
+interface StoreState {
+    appTheme: ShallowRef<AppTheme>;
+}
+
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const storage = new WebStorage<AppTheme>(localStorage, 'appTheme', AppTheme.Default)
+        const state: StoreState = {
+            appTheme: storage.getRef()
+        }
+        super(state)
+        document.addEventListener('DOMContentLoaded', this.loadTheme, false)
+    }
+
+    /**
+     * 加载主题
+     */
+    private loadTheme = () => {
+        const theme = this.state.appTheme
+        this.setStatusBarTheme(theme)
+        document.documentElement.setAttribute('theme', theme)
+        document.removeEventListener('DOMContentLoaded', this.loadTheme)
+    }
+
+    /**
+     * 设置状态栏主题色
+     * @param theme 
+     */
+    private setStatusBarTheme = (theme: AppTheme) => {
+        switch (theme) {
+            case AppTheme.Default:
+            case AppTheme.Dark: {
+                plus.setStatusBarStyle('light')
+                break
+            }
+            default: {
+                plus.setStatusBarStyle('dark')
+            }
+        }
+    }
+
+    actions = {
+        /** 设置主题 */
+        setTheme: (key: keyof typeof AppTheme) => {
+            const theme = AppTheme[key]
+            this.setStatusBarTheme(theme)
+            document.documentElement.setAttribute('theme', theme)
+            this.state.appTheme = theme
+        }
+    }
+})
+
+export function useThemeStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 65 - 0
src/stores/modules/user.ts

@@ -0,0 +1,65 @@
+import { toRefs, shallowReadonly } from 'vue'
+import { queryLoginData } from '@/services/api/account'
+import { useLoginStore } from './login'
+import { VueStore } from '../base'
+
+interface StoreState {
+    loading: boolean;
+    userData: Ermcp.LoginQueryRsp;
+}
+
+/**
+ * 用户存储类
+ */
+const store = new (class extends VueStore<StoreState>{
+    constructor() {
+        const state: StoreState = {
+            loading: false,
+            userData: {
+                arearole: [],
+                externalExchanges: [],
+                goodsgroups: [],
+                markets: [],
+                systemParams: []
+            },
+        }
+        super(state)
+    }
+
+    actions = {
+        /** 获取用户数据 */
+        getUserData: () => {
+            const { getLoginId } = useLoginStore()
+            this.state.loading = true
+
+            return queryLoginData({
+                data: {
+                    loginID: getLoginId()
+                },
+                success: (res) => {
+                    this.state.userData = res.data
+                },
+                complete: () => {
+                    this.state.loading = false
+                }
+            })
+        },
+        /** 获取用户数据 */
+        getUserDataInfo: <K extends keyof Ermcp.LoginQueryRsp>(key: K) => {
+            return this.state.userData[key]!
+        },
+        /** 获取登录机构名称 */
+        getAccountName: () => {
+            const { userAccount } = this.state.userData
+            return userAccount?.accountname
+        }
+    }
+})
+
+export function useUserStore() {
+    return shallowReadonly({
+        ...toRefs(store.state),
+        ...store.actions,
+        ...store.methods,
+    })
+}

+ 0 - 18
src/types/store/globalStorage.d.ts

@@ -1,18 +0,0 @@
-import { AppTheme } from '@/constants/theme'
-import { Language } from '@/constants/language'
-
-declare global {
-    namespace Store {
-        /** 本地缓存数据 */
-        interface GlobalStorage {
-            appTheme: AppTheme; // 应用主题色
-            lang: Language;
-            loginInfo: Proto.LoginRsp; // 账号登录返回信息 token等
-            userMenus: Ermcp.UserMenu[];
-            allEnums: Ermcp.EnumRsp[]; // 所有枚举
-            tableColumns: Ermcp.TableDefineRsp[];
-            errorInfos: Ermcp.ErrorInfosRsp[];
-            performanceStepTypes: Ermcp.WrPerformanceStepTypeRsp[];
-        }
-    }
-}

+ 69 - 0
src/utils/storage/base.ts

@@ -0,0 +1,69 @@
+import { shallowRef, watch } from 'vue'
+
+/**
+ * 本地存储类(基础版)
+ */
+export default class <T> {
+    constructor(storage: Storage, key: string, value: T) {
+        this.storage = storage
+        this.storageKey = key
+        this.source = value
+        this.state = shallowRef(this.getValue())
+        this.observe()
+    }
+
+    private readonly source // 原始数据
+    private readonly storage
+    readonly storageKey
+    private state
+
+    /**
+     * 监听数据变化
+     */
+    private observe() {
+        watch(this.state, (value) => {
+            if (value === undefined || value === null) {
+                this.storage.removeItem(this.storageKey)
+            } else {
+                const storageValue = JSON.stringify(value) // 注意数值长度过长会被自动转换为 String 类型
+                this.storage.setItem(this.storageKey, storageValue)
+            }
+        })
+    }
+
+    /**
+     * 获取数据
+     * @returns 
+     */
+    getValue() {
+        const storageValue = this.storage.getItem(this.storageKey)
+        if (storageValue !== 'undefined' && storageValue !== null) {
+            return JSON.parse(storageValue) as T
+        } else {
+            return this.source
+        }
+    }
+
+    /**
+     * 更新数据
+     * @param value 
+     */
+    setValue(value: T) {
+        this.state.value = value
+    }
+
+    /**
+     * 获取响应数据
+     * @returns 
+     */
+    getRef() {
+        return this.state
+    }
+
+    /**
+     * 重置数据
+     */
+    reset() {
+        this.state.value = this.source
+    }
+}

+ 52 - 51
src/utils/storage/index.ts

@@ -1,100 +1,101 @@
-import { reactive, toRef, readonly, computed, WritableComputedRef, UnwrapNestedRefs } from 'vue'
+import { shallowRef, ShallowRef, watch } from 'vue'
 
 /**
  * 本地存储类
  */
 export default class <T extends object> {
-    private readonly storage: Storage
-    private readonly source // 初始数据
-    private state
-
     constructor(storage: Storage, source: T) {
         this.storage = storage
         this.source = source
-        this.state = reactive({ ...source })
 
         // 读取本地数据
-        for (const key in this.state) {
-            const strValue = this.storage.getItem(key)
-            if (strValue !== 'undefined' && strValue !== null) {
-                this.state[key] = JSON.parse(strValue)
+        for (const key in source) {
+            const storageValue = this.getValue(key)
+            const state = this.stateMap.get(key)
+
+            if (state) {
+                state.value = storageValue
+            } else {
+                this.stateMap.set(key, shallowRef(storageValue))
             }
+
+            this.observe(key)
         }
     }
 
+    private readonly storage: Storage
+    private readonly source // 初始数据
+    private stateMap = new Map<keyof T, ShallowRef<T[keyof T]>>()
+
     /**
-     * 获取状态数据 (不建议使用,可能存在对象内部值变更无法同步 Storage 的问题)
-     * @returns 
+     * 监听数据变化
+     * @param key 
      */
-    getState = () => {
-        const state = {} as { [key in keyof UnwrapNestedRefs<T>]: WritableComputedRef<UnwrapNestedRefs<T>[key]> }
-        for (const key in this.state) {
-            state[key] = computed({
-                get: () => this.getValue(key),
-                set: (value) => this.setValue(key, value)
-            })
-        }
-        return state
+    private observe<K extends keyof T>(key: K) {
+        watch(this.getRef(key), (value) => {
+            if (value === undefined || value === null) {
+                this.reset(key)
+            } else {
+                const strValue = JSON.stringify(value) // 注意数值长度过长会被自动转换为 String 类型
+                this.storage.setItem(key.toString(), strValue)
+            }
+        })
     }
 
     /**
-     * 获取属性响应值 (不建议使用,可能存在对象内部值变更无法同步 Storage 的问题)
+     * 获取数据
      * @param key 
      * @returns 
      */
-    getComputedRef<K extends keyof UnwrapNestedRefs<T>>(key: K) {
-        const state = this.getState()
-        return state[key]
+    getValue<K extends keyof T>(key: K) {
+        const storageValue = this.storage.getItem(key.toString())
+        if (storageValue !== 'undefined' && storageValue !== null) {
+            return JSON.parse(storageValue) as T[K]
+        } else {
+            return this.source[key]
+        }
     }
 
     /**
-     * 获取属性响应值 (只读)
+     * 更新数据
      * @param key 
-     * @returns 
+     * @param value 
      */
-    getRef<K extends keyof UnwrapNestedRefs<T>>(key: K) {
-        return readonly(toRef(this.state, key))
+    setValue<K extends keyof T>(key: K, value: T[K]) {
+        const state = this.getRef(key)
+        state.value = value
     }
 
     /**
-     * 获取属性值
-     * @param key 
+     * 获取响应对象
      * @returns 
      */
-    getValue<K extends keyof UnwrapNestedRefs<T>>(key: K) {
-        return this.state[key]
+    getRefs() {
+        return [...this.stateMap.entries()].reduce((obj, [key, value]) => (obj[key] = value, obj), {} as { [key in keyof T]: ShallowRef<T[key]> })
     }
 
     /**
-     * 设置属性值
+     * 获取响应数据
      * @param key 
-     * @param value 
+     * @returns 
      */
-    setValue<K extends keyof UnwrapNestedRefs<T>>(key: K, value: UnwrapNestedRefs<T>[K]) {
-        if (value === undefined || value === null) {
-            this.clear(key)
-        } else {
-            const strValue = JSON.stringify(value) // 注意数值长度过长会被自动转换为 String 类型
-            this.storage.setItem(key.toString(), strValue)
-            this.state[key] = value
-        }
+    getRef<K extends keyof T>(key: K) {
+        return this.stateMap.get(key)!
     }
 
     /**
-     * 清除属性值
+     * 重置数据
      * @param keys 
      */
-    clear<K extends keyof UnwrapNestedRefs<T>>(...keys: K[]) {
-        const source = reactive({ ...this.source })
+    reset<K extends keyof T>(...keys: K[]) {
         if (keys.length) {
             keys.forEach((key) => {
-                this.storage.removeItem(key.toString())
-                this.state[key] = source[key]
+                const state = this.getRef(key)
+                state.value = this.source[key]
             })
         } else {
-            for (const key in this.state) {
-                this.storage.removeItem(key)
-                this.state[key] = source[key]
+            for (const [key, state] of this.stateMap) {
+                state.value = this.source[key]
             }
         }
     }