DESKTOP-USV654P\pc 1 рік тому
батько
коміт
b0504dc837

BIN
apps/web-baicai/public/favicon.ico


+ 1 - 0
apps/web-baicai/src/api/system/index.ts

@@ -9,6 +9,7 @@ export * from './menu';
 export * from './post';
 export * from './query';
 export * from './role';
+export * from './server';
 export * from './table';
 export * from './tenant';
 export * from './user';

+ 18 - 0
apps/web-baicai/src/api/system/server.ts

@@ -0,0 +1,18 @@
+import { requestClient } from '#/api/request';
+
+export namespace ServerApi {
+  export interface DiskInfo {
+    diskName: string;
+    typeName: string;
+    totalFree: number;
+    totalSize: number;
+    used: number;
+    availableFreeSpace: number;
+    availablePercent: number;
+  }
+  export const getInfo = () => requestClient.get('/server/info');
+
+  export const getUsed = () => requestClient.get('/server/used');
+
+  export const getDisk = () => requestClient.get<DiskInfo[]>('/server/disk');
+}

+ 53 - 12
apps/web-baicai/src/components/table-action/src/table-action.vue

@@ -134,12 +134,16 @@ const handleMenuClick = (e: any) => {
             <Icon :icon="action.popConfirm.icon" />
           </template>
           <Button v-bind="getButtonProps(action)">
-            <Icon v-if="action.icon" :icon="action.icon" />
+            <template v-if="action.icon" #icon>
+              <Icon :icon="action.icon" />
+            </template>
             {{ action.label }}
           </Button>
         </Popconfirm>
         <Button v-else v-bind="getButtonProps(action)" @click="action.onClick">
-          <Icon v-if="action.icon" :icon="action.icon" />
+          <template v-if="action.icon" #icon>
+            <Icon :icon="action.icon" />
+          </template>
           {{ action.label }}
         </Button>
       </template>
@@ -147,31 +151,43 @@ const handleMenuClick = (e: any) => {
 
     <Dropdown v-if="getDropdownList.length > 0" :trigger="['hover']">
       <slot name="more">
-        <Button size="small" type="text">
-          <Icon class="icon-more size-5" icon="ic:twotone-more-horiz" />
+        <Button size="small" type="link">
+          <template #icon>
+            <Icon class="icon-more size-5" icon="ic:twotone-more-horiz" />
+          </template>
         </Button>
       </slot>
       <template #overlay>
         <Menu @click="handleMenuClick">
-          <MenuItem
-            v-for="(action, index) in getDropdownList"
-            :key="index"
-            :disabled="action.disabled"
-          >
+          <MenuItem v-for="(action, index) in getDropdownList" :key="index">
             <template v-if="action.popConfirm">
               <Popconfirm v-bind="getPopConfirmProps(action.popConfirm)">
                 <template v-if="action.popConfirm.icon" #icon>
                   <Icon :icon="action.popConfirm.icon" />
                 </template>
-                <div>
+                <div
+                  :class="
+                    action.disabled === true
+                      ? 'cursor-not-allowed text-gray-300'
+                      : ''
+                  "
+                >
                   <Icon v-if="action.icon" :icon="action.icon" />
                   <span class="ml-1">{{ action.text }}</span>
                 </div>
               </Popconfirm>
             </template>
             <template v-else>
-              <Icon v-if="action.icon" :icon="action.icon" />
-              {{ action.label }}
+              <div
+                :class="
+                  action.disabled === true
+                    ? 'cursor-not-allowed text-gray-300'
+                    : ''
+                "
+              >
+                <Icon v-if="action.icon" :icon="action.icon" />
+                {{ action.label }}
+              </div>
             </template>
           </MenuItem>
         </Menu>
@@ -179,3 +195,28 @@ const handleMenuClick = (e: any) => {
     </Dropdown>
   </div>
 </template>
+<style lang="less">
+/** 修复 iconify 位置问题 **/
+.m-table-action {
+  .ant-btn > .iconify + span,
+  .ant-btn > span + .iconify {
+    margin-inline-start: 8px;
+  }
+
+  .ant-btn > .iconify {
+    display: inline-flex;
+    align-items: center;
+    width: 1em;
+    height: 1em;
+    font-style: normal;
+    line-height: 0;
+    color: inherit;
+    text-align: center;
+    text-transform: none;
+    vertical-align: -0.125em;
+    text-rendering: optimizelegibility;
+    -webkit-font-smoothing: antialiased;
+    -moz-osx-font-smoothing: grayscale;
+  }
+}
+</style>

+ 1 - 0
apps/web-baicai/src/components/table-action/src/types.d.ts

@@ -8,6 +8,7 @@ export interface PopConfirm {
   confirm: Fn;
   cancel?: Fn;
   icon?: string;
+  disabled?: boolean;
 }
 export interface ActionItem extends ButtonProps {
   onClick?: Fn;

+ 8 - 8
apps/web-baicai/src/router/routes/modules/dashboard.ts

@@ -15,22 +15,22 @@ const routes: RouteRecordRaw[] = [
     path: '/',
     children: [
       {
-        name: 'Analytics',
-        path: '/analytics',
-        component: () => import('#/views/dashboard/analytics/index.vue'),
+        name: 'home',
+        path: '/home',
+        component: () => import('#/views/dashboard/home/index.vue'),
         meta: {
           affixTab: true,
           icon: 'lucide:area-chart',
-          title: $t('page.dashboard.analytics'),
+          title: $t('工作台'),
         },
       },
       {
-        name: 'Workspace',
-        path: '/workspace',
-        component: () => import('#/views/dashboard/workspace/index.vue'),
+        name: 'notice',
+        path: '/notice',
+        component: () => import('#/views/dashboard/notice/index.vue'),
         meta: {
           icon: 'carbon:workspace',
-          title: $t('page.dashboard.workspace'),
+          title: $t('站内信'),
         },
       },
     ],

+ 0 - 0
apps/web-baicai/src/views/dashboard/analytics/analytics-trends.vue → apps/web-baicai/src/views/dashboard/home/analytics-trends.vue


+ 0 - 0
apps/web-baicai/src/views/dashboard/analytics/analytics-visits-data.vue → apps/web-baicai/src/views/dashboard/home/analytics-visits-data.vue


+ 0 - 0
apps/web-baicai/src/views/dashboard/analytics/analytics-visits-sales.vue → apps/web-baicai/src/views/dashboard/home/analytics-visits-sales.vue


+ 0 - 0
apps/web-baicai/src/views/dashboard/analytics/analytics-visits-source.vue → apps/web-baicai/src/views/dashboard/home/analytics-visits-source.vue


+ 0 - 0
apps/web-baicai/src/views/dashboard/analytics/analytics-visits.vue → apps/web-baicai/src/views/dashboard/home/analytics-visits.vue


+ 33 - 37
apps/web-baicai/src/views/dashboard/analytics/index.vue → apps/web-baicai/src/views/dashboard/home/index.vue

@@ -2,17 +2,18 @@
 import type { AnalysisOverviewItem } from '@vben/common-ui';
 import type { TabOption } from '@vben/types';
 
+import { onMounted, reactive } from 'vue';
+
 import {
   AnalysisChartCard,
   AnalysisChartsTabs,
   AnalysisOverview,
+  WorkbenchHeader,
 } from '@vben/common-ui';
-import {
-  SvgBellIcon,
-  SvgCakeIcon,
-  SvgCardIcon,
-  SvgDownloadIcon,
-} from '@vben/icons';
+import { preferences } from '@vben/preferences';
+import { useUserStore } from '@vben/stores';
+
+import { ServerApi } from '#/api';
 
 import AnalyticsTrends from './analytics-trends.vue';
 import AnalyticsVisits from './analytics-visits.vue';
@@ -20,36 +21,9 @@ import AnalyticsVisitsData from './analytics-visits-data.vue';
 import AnalyticsVisitsSales from './analytics-visits-sales.vue';
 import AnalyticsVisitsSource from './analytics-visits-source.vue';
 
-const overviewItems: AnalysisOverviewItem[] = [
-  {
-    icon: SvgCardIcon,
-    title: '用户量',
-    totalTitle: '总用户量',
-    totalValue: 120_000,
-    value: 2000,
-  },
-  {
-    icon: SvgCakeIcon,
-    title: '访问量',
-    totalTitle: '总访问量',
-    totalValue: 500_000,
-    value: 20_000,
-  },
-  {
-    icon: SvgDownloadIcon,
-    title: '下载量',
-    totalTitle: '总下载量',
-    totalValue: 120_000,
-    value: 8000,
-  },
-  {
-    icon: SvgBellIcon,
-    title: '使用量',
-    totalTitle: '总使用量',
-    totalValue: 50_000,
-    value: 5000,
-  },
-];
+const userStore = useUserStore();
+
+const overviewItems = reactive<AnalysisOverviewItem[]>([]);
 
 const chartTabs: TabOption[] = [
   {
@@ -61,11 +35,33 @@ const chartTabs: TabOption[] = [
     value: 'visits',
   },
 ];
+
+onMounted(async () => {
+  const disks = await ServerApi.getDisk();
+  disks &&
+    disks.forEach((disk) => {
+      overviewItems.push({
+        icon: 'clarity:hard-disk-solid',
+        title: `${disk.diskName.split(':')[0]} 盘`,
+        totalTitle: '已使用(GB)',
+        totalValue: disk.used,
+        value: disk.totalSize,
+      });
+    });
+});
 </script>
 
 <template>
   <div class="p-5">
-    <AnalysisOverview :items="overviewItems" />
+    <WorkbenchHeader
+      :avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar"
+    >
+      <template #title>
+        早安, {{ userStore.userInfo?.realName }}, 开始您一天的工作吧!
+      </template>
+      <template #description> 今日晴,20℃ - 32℃! </template>
+    </WorkbenchHeader>
+    <AnalysisOverview :items="overviewItems" class="mt-5" />
     <AnalysisChartsTabs :tabs="chartTabs" class="mt-5">
       <template #trends>
         <AnalyticsTrends />

+ 1 - 15
apps/web-baicai/src/views/dashboard/workspace/index.vue → apps/web-baicai/src/views/dashboard/notice/index.vue

@@ -10,18 +10,13 @@ import { ref } from 'vue';
 
 import {
   AnalysisChartCard,
-  WorkbenchHeader,
   WorkbenchProject,
   WorkbenchQuickNav,
   WorkbenchTodo,
   WorkbenchTrends,
 } from '@vben/common-ui';
-import { preferences } from '@vben/preferences';
-import { useUserStore } from '@vben/stores';
 
-import AnalyticsVisitsSource from '../analytics/analytics-visits-source.vue';
-
-const userStore = useUserStore();
+import AnalyticsVisitsSource from '../home/analytics-visits-source.vue';
 
 const projectItems: WorkbenchProjectItem[] = [
   {
@@ -199,15 +194,6 @@ const trendItems: WorkbenchTrendItem[] = [
 
 <template>
   <div class="p-5">
-    <WorkbenchHeader
-      :avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar"
-    >
-      <template #title>
-        早安, {{ userStore.userInfo?.realName }}, 开始您一天的工作吧!
-      </template>
-      <template #description> 今日晴,20℃ - 32℃! </template>
-    </WorkbenchHeader>
-
     <div class="mt-5 flex flex-col lg:flex-row">
       <div class="mr-4 w-full lg:w-3/5">
         <WorkbenchProject :items="projectItems" title="项目" />