Преглед изворни кода

feat: 删除非必要的界面

zhanghaijun пре 1 година
родитељ
комит
7acc54b45c
43 измењених фајлова са 12 додато и 3876 уклоњено
  1. 0 75
      src/router/routes/modules/examples.ts
  2. 0 9
      src/router/routesAlias.ts
  3. 0 249
      src/views/article/comment/index.vue
  4. 0 116
      src/views/article/detail/index.vue
  5. 0 365
      src/views/article/list/index.vue
  6. 0 342
      src/views/article/publish/index.vue
  7. 0 240
      src/views/change/log/index.vue
  8. 0 53
      src/views/dashboard/analysis/index.vue
  9. 0 61
      src/views/dashboard/analysis/style.scss
  10. 0 59
      src/views/dashboard/analysis/widget/CustomerSatisfaction.vue
  11. 0 29
      src/views/dashboard/analysis/widget/SalesMappingByCountry.vue
  12. 0 144
      src/views/dashboard/analysis/widget/TargetVsReality.vue
  13. 0 184
      src/views/dashboard/analysis/widget/TodaySales.vue
  14. 0 98
      src/views/dashboard/analysis/widget/TopProducts.vue
  15. 0 42
      src/views/dashboard/analysis/widget/TotalRevenue.vue
  16. 0 41
      src/views/dashboard/analysis/widget/VisitorInsights.vue
  17. 0 41
      src/views/dashboard/analysis/widget/VolumeServiceLevel.vue
  18. 0 44
      src/views/dashboard/console/index2.vue
  19. 0 43
      src/views/dashboard/console/style.scss
  20. 0 103
      src/views/dashboard/console/widget/ActiveUser.vue
  21. 0 148
      src/views/dashboard/console/widget/CardList.vue
  22. 0 100
      src/views/dashboard/console/widget/Dynamic.vue
  23. 0 168
      src/views/dashboard/console/widget/NewUser.vue
  24. 0 41
      src/views/dashboard/console/widget/SalesOverview.vue
  25. 0 102
      src/views/dashboard/console/widget/TodoList.vue
  26. 0 80
      src/views/dashboard/ecommerce/index.vue
  27. 0 72
      src/views/dashboard/ecommerce/style.scss
  28. 0 46
      src/views/dashboard/ecommerce/widget/AnnualSales.vue
  29. 0 89
      src/views/dashboard/ecommerce/widget/Banner.vue
  30. 0 3
      src/views/dashboard/ecommerce/widget/CartConversionRate.vue
  31. 0 100
      src/views/dashboard/ecommerce/widget/HotCommodity.vue
  32. 0 219
      src/views/dashboard/ecommerce/widget/HotProductsList.vue
  33. 0 10
      src/views/dashboard/ecommerce/widget/ProductSales.vue
  34. 0 41
      src/views/dashboard/ecommerce/widget/RecentTransaction.vue
  35. 0 41
      src/views/dashboard/ecommerce/widget/SalesClassification.vue
  36. 0 10
      src/views/dashboard/ecommerce/widget/SalesGrowth.vue
  37. 0 9
      src/views/dashboard/ecommerce/widget/SalesTrend.vue
  38. 0 20
      src/views/dashboard/ecommerce/widget/TotalOrderVolume.vue
  39. 0 9
      src/views/dashboard/ecommerce/widget/TotalProducts.vue
  40. 0 45
      src/views/dashboard/ecommerce/widget/TransactionList.vue
  41. 0 124
      src/views/examples/tabs/index.vue
  42. 10 53
      src/views/widgets/context-menu/index.vue
  43. 2 8
      src/views/widgets/icon-list/index.vue

+ 0 - 75
src/router/routes/modules/examples.ts

@@ -88,14 +88,6 @@ export const routes: AppRouteRecord[] = [
       showBadge: true
     },
     children: [
-      {
-        path: 'tabs',
-        name: 'Tabs',
-        component: RoutesAlias.ExamplesTabs,
-        meta: {
-          title: 'menus.examples.tabs'
-        }
-      },
       {
         path: 'tables/basic',
         name: 'TablesBasic',
@@ -194,73 +186,6 @@ export const routes: AppRouteRecord[] = [
         }
       }
     ]
-  },
-  {
-    path: '/article',
-    name: 'Article',
-    component: RoutesAlias.Layout,
-    meta: {
-      title: 'menus.article.title',
-      icon: '',
-      roles: ['R_SUPER', 'R_ADMIN']
-    },
-    children: [
-      {
-        path: 'article-list',
-        name: 'ArticleList',
-        component: RoutesAlias.ArticleList,
-        meta: {
-          title: 'menus.article.articleList',
-          keepAlive: true,
-          authList: [
-            {
-              title: '新增',
-              authMark: 'add'
-            },
-            {
-              title: '编辑',
-              authMark: 'edit'
-            }
-          ]
-        }
-      },
-
-      {
-        path: 'detail',
-        name: 'ArticleDetail',
-        component: RoutesAlias.ArticleDetail,
-        meta: {
-          title: 'menus.article.articleDetail',
-          isHide: true,
-          keepAlive: true,
-          activePath: '/article/article-list' // 激活菜单路径
-        }
-      },
-      {
-        path: 'comment',
-        name: 'ArticleComment',
-        component: RoutesAlias.Comment,
-        meta: {
-          title: 'menus.article.comment',
-          keepAlive: true
-        }
-      },
-      {
-        path: 'publish',
-        name: 'ArticlePublish',
-        component: RoutesAlias.ArticlePublish,
-        meta: {
-          title: 'menus.article.articlePublish',
-          keepAlive: true,
-          authList: [
-            {
-              title: '发布',
-              authMark: 'article/article-publish/add'
-            }
-          ]
-        }
-      }
-    ]
   }
 ]
 export default routes

+ 0 - 9
src/router/routesAlias.ts

@@ -14,8 +14,6 @@ export enum RoutesAlias {
   Success = '/result/success', // 成功
   Fail = '/result/fail', // 失败
   Dashboard = '/dashboard/console', // 工作台
-  Analysis = '/dashboard/analysis', // 分析页
-  Ecommerce = '/dashboard/ecommerce', // 电子商务
   IconList = '/widgets/icon-list', // 图标列表
   IconSelector = '/widgets/icon-selector', // 图标选择器
   ImageCrop = '/widgets/image-crop', // 图片裁剪
@@ -31,18 +29,11 @@ export enum RoutesAlias {
   Cards = '/template/cards', // 卡片
   Banners = '/template/banners', // 横幅
   Charts = '/template/charts', // 图表
-  Map = '/template/map', // 地图
   Calendar = '/template/calendar', // 日历
-  Pricing = '/template/pricing', // 定价
-  ArticleList = '/article/list', // 文章列表
-  ArticleDetail = '/article/detail', // 文章详情
-  Comment = '/article/comment', // 评论
-  ArticlePublish = '/article/publish', // 文章发布
   User = '/system/user', // 账户
   Role = '/system/role', // 角色
   UserCenter = '/system/user-center', // 用户中心
   Menu = '/system/menu', // 菜单
-  ExamplesTabs = '/examples/tabs', // 标签页
   ExamplesTablesBasic = '/examples/tables/basic', // 基础表格示例
   ExamplesTables = '/examples/tables', // 高级表格示例
   ExamplesTablesTree = '/examples/tables/tree', // 左右布局表格示例

+ 0 - 249
src/views/article/comment/index.vue

@@ -1,249 +0,0 @@
-<template>
-  <div class="page-comment">
-    <h1 class="title">留言墙</h1>
-    <p class="desc">每一份留言都记录了您的想法,也为我们提供了珍贵的回忆</p>
-
-    <div class="list">
-      <ul class="offset">
-        <li class="comment-box" v-for="item in commentList" :key="item.id" :style="{ background: randomColor() }" @click="openDrawer(item)">
-          <p class="date">{{ item.date }}</p>
-          <p class="content">{{ item.content }}</p>
-          <div class="bottom">
-            <div class="left">
-              <span><i class="iconfont-sys">&#xe6eb;</i>{{ item.collection }}</span>
-              <span><i class="iconfont-sys">&#xe6e9;</i>{{ item.comment }}</span>
-            </div>
-            <div class="right">
-              <span>{{ item.userName }}</span>
-            </div>
-          </div>
-        </li>
-      </ul>
-    </div>
-
-    <ElDrawer lDrawer v-model="showDrawer" :lock-scroll="false" :size="360" modal-class="comment-modal">
-      <template #header>
-        <h4>详情</h4>
-      </template>
-      <template #default>
-        <div class="drawer-default">
-          <div class="comment-box" :style="{ background: randomColor() }">
-            <p class="date">{{ clickItem.date }}</p>
-            <p class="content">{{ clickItem.content }}</p>
-            <div class="bottom">
-              <div class="left">
-                <span><i class="iconfont-sys">&#xe6eb;</i>{{ clickItem.collection }}</span>
-                <span><i class="iconfont-sys">&#xe6e9;</i>{{ clickItem.comment }}</span>
-              </div>
-              <div class="right">
-                <span>{{ clickItem.userName }}</span>
-              </div>
-            </div>
-          </div>
-
-          <!-- 评论组件 -->
-          <CommentWidget />
-        </div>
-      </template>
-      <template #footer>
-        <div>
-          <!-- <ElButton @click="cancelClick">cancel</ElButton> -->
-          <!-- <ElButton type="primary" @click="confirmClick">confirm</ElButton> -->
-        </div>
-      </template>
-    </ElDrawer>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { commentList } from '@/mock/temp/commentList'
-  const showDrawer = ref(false)
-
-  defineOptions({ name: 'ArticleComment' })
-
-  // const colorList = reactive([
-  //   'rgba(216, 248, 255, 0.8)',
-  //   'rgba(253, 223, 217, 0.8)',
-  //   'rgba(252, 230, 240, 0.8)',
-  //   'rgba(211, 248, 240, 0.8)',
-  //   'rgba(255, 234, 188, 0.8)',
-  //   'rgba(245, 225, 255, 0.8)',
-  //   'rgba(225, 230, 254, 0.8)'
-  // ])
-
-  const colorList = reactive(['#D8F8FF', '#FDDFD9', '#FCE6F0', '#D3F8F0', '#FFEABC', '#F5E1FF', '#E1E6FE'])
-
-  let lastColor: string | null = null
-
-  const randomColor = () => {
-    let newColor: string
-
-    do {
-      const index = Math.floor(Math.random() * colorList.length)
-      newColor = colorList[index]
-    } while (newColor === lastColor)
-
-    lastColor = newColor
-    return newColor
-  }
-
-  const clickItem = ref({
-    id: 1,
-    date: '2024-9-3',
-    content: '加油!学好Node 自己写个小Demo',
-    collection: 5,
-    comment: 8,
-    userName: '匿名'
-  })
-
-  const openDrawer = (item: any) => {
-    showDrawer.value = true
-    clickItem.value = item
-  }
-</script>
-
-<style lang="scss" scoped>
-  .page-comment {
-    background-color: transparent !important;
-    box-shadow: none !important;
-
-    :deep(.comment-modal) {
-      background-color: transparent;
-    }
-
-    .title {
-      margin-top: 20px;
-      font-size: 36px;
-      font-weight: 500;
-    }
-
-    .desc {
-      margin-top: 15px;
-      font-size: 14px;
-      color: var(--art-text-gray-600);
-    }
-
-    .list {
-      margin-top: 40px;
-
-      .offset {
-        display: flex;
-        flex-wrap: wrap;
-        width: calc(100% + 16px);
-      }
-    }
-
-    .comment-box {
-      position: relative;
-      box-sizing: border-box;
-      width: calc(20% - 16px);
-      aspect-ratio: 16 / 12;
-      padding: 16px;
-      margin: 0 16px 16px 0;
-      cursor: pointer;
-      background-color: #eae2cb;
-      transition: all 0.3s;
-
-      &:hover {
-        transform: translateY(-5px);
-      }
-
-      .date {
-        font-size: 12px;
-        color: #949494;
-      }
-
-      .content {
-        margin-top: 16px;
-        font-size: 14px;
-        color: #333;
-      }
-
-      .bottom {
-        position: absolute;
-        bottom: 16px;
-        left: 0;
-        box-sizing: border-box;
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        width: 100%;
-        padding: 0 16px;
-
-        .left {
-          display: flex;
-          align-items: center;
-
-          span {
-            display: flex;
-            align-items: center;
-            margin-right: 20px;
-            font-size: 12px;
-            color: #949494;
-
-            i {
-              margin-right: 5px;
-            }
-          }
-        }
-
-        .right {
-          span {
-            font-size: 14px;
-            color: #333;
-          }
-        }
-      }
-    }
-
-    .drawer-default {
-      .comment-box {
-        width: 100%;
-
-        &:hover {
-          transform: translateY(0);
-        }
-      }
-    }
-  }
-
-  @media screen and (max-width: $device-notebook) {
-    .page-comment {
-      .comment-box {
-        width: calc(25% - 16px);
-      }
-    }
-  }
-
-  @media screen and (max-width: $device-ipad-pro) {
-    .page-comment {
-      .comment-box {
-        width: calc(33.333% - 16px);
-      }
-    }
-  }
-
-  @media screen and (max-width: $device-ipad) {
-    .page-comment {
-      .comment-box {
-        width: calc(50% - 16px);
-      }
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .page-comment {
-      .comment-box {
-        width: calc(100% - 16px);
-      }
-    }
-  }
-
-  .dark {
-    .page-comment {
-      .comment-box {
-        color: #333 !important;
-      }
-    }
-  }
-</style>

+ 0 - 116
src/views/article/detail/index.vue

@@ -1,116 +0,0 @@
-<template>
-  <div class="article-detail page-content">
-    <div class="content">
-      <h1>{{ articleTitle }}</h1>
-      <div class="markdown-body" v-highlight v-html="articleHtml"></div>
-    </div>
-    <ArtBackToTop />
-  </div>
-</template>
-
-<script setup lang="ts">
-  import '@/assets/styles/markdown.scss'
-  import '@/assets/styles/one-dark-pro.scss'
-  import { useCommon } from '@/composables/useCommon'
-  import axios from 'axios'
-  // import 'highlight.js/styles/atom-one-dark.css';
-  // import 'highlight.js/styles/vs2015.css';
-
-  defineOptions({ name: 'ArticleDetail' })
-
-  const articleId = ref(0)
-  const router = useRoute()
-  const articleTitle = ref('')
-  const articleHtml = ref('')
-
-  onMounted(() => {
-    useCommon().scrollToTop()
-    articleId.value = Number(router.params.id)
-    getArticleDetail()
-  })
-
-  const getArticleDetail = async () => {
-    if (articleId.value) {
-      const res = await axios.get('https://www.qiniu.lingchen.kim/blog_detail.json')
-      if (res.data.code === 200) {
-        articleTitle.value = res.data.data.title
-        articleHtml.value = res.data.data.html_content
-      }
-    }
-  }
-</script>
-
-<style lang="scss">
-  .article-detail {
-    .content {
-      max-width: 800px;
-      margin: auto;
-      margin-top: 60px;
-
-      .markdown-body {
-        margin-top: 60px;
-
-        img {
-          width: 100%;
-          border: 1px solid var(--art-gray-200);
-        }
-
-        pre {
-          position: relative;
-
-          &:hover {
-            .copy-button {
-              opacity: 1;
-            }
-          }
-
-          &::before {
-            position: absolute;
-            top: 0;
-            left: 50px;
-            width: 1px;
-            height: 100%;
-            content: '';
-            background: #0a0a0e;
-          }
-        }
-
-        .code-wrapper {
-          overflow-x: auto;
-        }
-
-        .line-number {
-          position: sticky;
-          left: 0;
-          z-index: 2;
-          box-sizing: border-box;
-          display: inline-block;
-          width: 50px;
-          margin-right: 10px;
-          font-size: 14px;
-          color: #9e9e9e;
-          text-align: center;
-        }
-
-        .copy-button {
-          position: absolute;
-          top: 6px;
-          right: 6px;
-          z-index: 1;
-          width: 40px;
-          height: 40px;
-          font-size: 20px;
-          line-height: 40px;
-          color: #999;
-          text-align: center;
-          cursor: pointer;
-          background-color: #000;
-          border: none;
-          border-radius: 8px;
-          opacity: 0;
-          transition: all 0.2s;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 365
src/views/article/list/index.vue

@@ -1,365 +0,0 @@
-<template>
-  <div class="page-content article-list">
-    <ElRow justify="space-between" :gutter="10">
-      <ElCol :lg="6" :md="6" :sm="14" :xs="16">
-        <ElInput v-model="searchVal" :prefix-icon="Search" clearable placeholder="输入文章标题查询" @keyup.enter="searchArticle" />
-      </ElCol>
-      <ElCol :lg="12" :md="12" :sm="0" :xs="0">
-        <div class="custom-segmented">
-          <ElSegmented v-model="yearVal" :options="options" @change="searchArticleByYear" />
-        </div>
-      </ElCol>
-      <ElCol :lg="6" :md="6" :sm="10" :xs="6" style="display: flex; justify-content: end">
-        <ElButton @click="toAddArticle" v-auth="'add'">新增文章</ElButton>
-      </ElCol>
-    </ElRow>
-
-    <div class="list">
-      <div class="offset">
-        <div class="item" v-for="item in articleList" :key="item.id" @click="toDetail(item)">
-          <!-- 骨架屏 -->
-          <ElSkeleton animated :loading="isLoading" style="width: 100%; height: 100%">
-            <template #template>
-              <div class="top">
-                <ElSkeletonItem variant="image" style="width: 100%; height: 100%; border-radius: 10px" />
-                <div style="padding: 16px 0">
-                  <ElSkeletonItem variant="p" style="width: 80%" />
-                  <ElSkeletonItem variant="p" style="width: 40%; margin-top: 10px" />
-                </div>
-              </div>
-            </template>
-
-            <template #default>
-              <div class="top">
-                <ElImage class="cover" :src="item.home_img" lazy fit="cover">
-                  <template #error>
-                    <div class="image-slot">
-                      <ElIcon><icon-picture /></ElIcon>
-                    </div>
-                  </template>
-                </ElImage>
-
-                <span class="type">{{ item.type_name }}</span>
-              </div>
-              <div class="bottom">
-                <h2>{{ item.title }}</h2>
-                <div class="info">
-                  <div class="text">
-                    <i class="iconfont-sys">&#xe6f7;</i>
-                    <span>{{ useDateFormat(item.create_time, 'YYYY-MM-DD') }}</span>
-                    <div class="line"></div>
-                    <i class="iconfont-sys">&#xe689;</i>
-                    <span>{{ item.count }}</span>
-                  </div>
-                  <ElButton v-auth="'edit'" size="small" @click.stop="toEdit(item)">编辑</ElButton>
-                </div>
-              </div>
-            </template>
-          </ElSkeleton>
-        </div>
-      </div>
-    </div>
-
-    <div style="margin-top: 16vh" v-if="showEmpty">
-      <ElEmpty :description="`未找到相关数据 ${EmojiText[0]}`" />
-    </div>
-
-    <div style="display: flex; justify-content: center; margin-top: 20px">
-      <ElPagination
-        size="default"
-        background
-        v-model:current-page="currentPage"
-        :page-size="pageSize"
-        :pager-count="9"
-        layout="prev, pager, next, total,jumper"
-        :total="total"
-        :hide-on-single-page="true"
-        @current-change="handleCurrentChange"
-      />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { Picture as IconPicture } from '@element-plus/icons-vue'
-
-  import { ref, onMounted, computed } from 'vue'
-  import { router } from '@/router'
-  import { useDateFormat } from '@vueuse/core'
-  import { Search } from '@element-plus/icons-vue'
-  import EmojiText from '@/utils/ui/emojo'
-  import { ArticleList } from '@/mock/temp/articleList'
-  import { useCommon } from '@/composables/useCommon'
-  import { RoutesAlias } from '@/router/routesAlias'
-
-  defineOptions({ name: 'ArticleList' })
-
-  const yearVal = ref('All')
-
-  const options = ['All', '2024', '2023', '2022', '2021', '2020', '2019']
-
-  const searchVal = ref('')
-  const articleList = ref<any[]>([])
-  const currentPage = ref(1)
-  const pageSize = ref(40)
-  // const lastPage = ref(0)
-  const total = ref(0)
-  const isLoading = ref(true)
-
-  const showEmpty = computed(() => {
-    return articleList.value.length === 0 && !isLoading.value
-  })
-
-  onMounted(() => {
-    getArticleList({ backTop: false })
-  })
-
-  // 搜索文章
-  const searchArticle = () => {
-    getArticleList({ backTop: true })
-  }
-
-  // 根据年份查询文章
-  const searchArticleByYear = () => {
-    getArticleList({ backTop: true })
-  }
-
-  const getArticleList = async ({ backTop = false }) => {
-    isLoading.value = true
-    // let year = yearVal.value
-
-    if (searchVal.value) {
-      yearVal.value = 'All'
-    }
-
-    if (yearVal.value === 'All') {
-      // year = ''
-    }
-
-    // const params = {
-    //   page: currentPage.value,
-    //   size: pageSize.value,
-    //   searchVal: searchVal.value,
-    //   year
-    // }
-
-    articleList.value = ArticleList
-    isLoading.value = false
-
-    if (backTop) {
-      useCommon().scrollToTop()
-    }
-
-    // const res = await ArticleService.getArticleList(params)
-    // if (res.code === ApiStatus.success) {
-    //   currentPage.value = res.currentPage
-    //   pageSize.value = res.pageSize
-    //   lastPage.value = res.lastPage
-    //   total.value = res.total
-    //   articleList.value = res.data
-
-    //   // setTimeout(() => {
-    //   isLoading.value = false
-    //   // }, 3000)
-
-    //   if (searchVal.value) {
-    //     searchVal.value = ''
-    //   }
-    // }
-  }
-
-  const handleCurrentChange = (val: number) => {
-    currentPage.value = val
-    getArticleList({ backTop: true })
-  }
-
-  const toDetail = (item: any) => {
-    router.push({ name: 'ArticleDetail', params: { id: item.id } })
-  }
-
-  const toEdit = (item: any) => {
-    router.push({
-      path: RoutesAlias.ArticlePublish,
-      query: {
-        id: item.id
-      }
-    })
-  }
-
-  const toAddArticle = () => {
-    router.push({
-      path: RoutesAlias.ArticlePublish
-    })
-  }
-</script>
-
-<style lang="scss" scoped>
-  .article-list {
-    .custom-segmented .el-segmented {
-      height: 40px;
-      padding: 6px;
-
-      --el-border-radius-base: 8px;
-    }
-
-    .list {
-      margin-top: 20px;
-
-      .offset {
-        display: flex;
-        flex-wrap: wrap;
-        width: calc(100% + 20px);
-
-        .item {
-          box-sizing: border-box;
-          width: calc(20% - 20px);
-          margin: 0 20px 20px 0;
-          cursor: pointer;
-          border: 1px solid var(--art-border-color);
-          border-radius: calc(var(--custom-radius) / 2 + 2px) !important;
-
-          &:hover {
-            .el-button {
-              opacity: 1 !important;
-            }
-          }
-
-          .top {
-            position: relative;
-            aspect-ratio: 16/9.5;
-
-            .cover {
-              display: flex;
-              align-items: center;
-              justify-content: center;
-              width: 100%;
-              height: 100%;
-              object-fit: cover;
-              background: var(--art-gray-200);
-              border-radius: calc(var(--custom-radius) / 2 + 2px) calc(var(--custom-radius) / 2 + 2px) 0 0;
-
-              .image-slot {
-                font-size: 26px;
-                color: var(--art-gray-400);
-              }
-            }
-
-            .type {
-              position: absolute;
-              top: 5px;
-              right: 5px;
-              padding: 5px 4px;
-              font-size: 12px;
-              color: rgba(#fff, 0.8);
-              background: rgba($color: #000, $alpha: 60%);
-              border-radius: 4px;
-            }
-          }
-
-          .bottom {
-            padding: 5px 10px;
-
-            h2 {
-              font-size: 16px;
-              font-weight: 500;
-              color: #333;
-
-              @include ellipsis();
-            }
-
-            .info {
-              display: flex;
-              justify-content: space-between;
-              width: 100%;
-              height: 25px;
-              margin-top: 6px;
-              line-height: 25px;
-
-              .text {
-                display: flex;
-                align-items: center;
-                color: var(--art-text-gray-600);
-
-                i {
-                  margin-right: 5px;
-                  font-size: 14px;
-                }
-
-                span {
-                  font-size: 13px;
-                  color: var(--art-gray-600);
-                }
-
-                .line {
-                  width: 1px;
-                  height: 12px;
-                  margin: 0 15px;
-                  background-color: var(--art-border-dashed-color);
-                }
-              }
-
-              .el-button {
-                opacity: 0;
-                transition: all 0.3s;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  @media only screen and (max-width: $device-notebook) {
-    .article-list {
-      .list {
-        .offset {
-          .item {
-            width: calc(25% - 20px);
-          }
-        }
-      }
-    }
-  }
-
-  @media only screen and (max-width: $device-ipad-pro) {
-    .article-list {
-      .list {
-        .offset {
-          .item {
-            width: calc(33.333% - 20px);
-
-            .bottom {
-              h2 {
-                font-size: 16px;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  @media only screen and (max-width: $device-ipad) {
-    .article-list {
-      .list {
-        .offset {
-          .item {
-            width: calc(50% - 20px);
-          }
-        }
-      }
-    }
-  }
-
-  @media only screen and (max-width: $device-phone) {
-    .article-list {
-      .list {
-        .offset {
-          .item {
-            width: calc(100% - 20px);
-          }
-        }
-      }
-    }
-  }
-</style>

+ 0 - 342
src/views/article/publish/index.vue

@@ -1,342 +0,0 @@
-<template>
-  <div class="article-edit">
-    <div>
-      <div class="editor-wrap">
-        <!-- 文章标题、类型 -->
-        <ElRow :gutter="10">
-          <ElCol :span="18">
-            <ElInput v-model.trim="articleName" placeholder="请输入文章标题(最多100个字符)" maxlength="100" />
-          </ElCol>
-          <ElCol :span="6">
-            <ElSelect v-model="articleType" placeholder="请选择文章类型" filterable>
-              <ElOption v-for="item in articleTypes" :key="item.id" :label="item.name" :value="item.id" />
-            </ElSelect>
-          </ElCol>
-        </ElRow>
-
-        <!-- 富文本编辑器 -->
-        <ArtWangEditor class="el-top" v-model="editorHtml" />
-
-        <div class="form-wrap">
-          <h2>发布设置</h2>
-          <!-- 图片上传 -->
-          <ElForm>
-            <ElFormItem label="封面">
-              <div class="el-top upload-container">
-                <ElUpload class="cover-uploader" :action="uploadImageUrl" :headers="uploadHeaders" :show-file-list="false" :on-success="onSuccess" :on-error="onError" :before-upload="beforeUpload">
-                  <div v-if="!cover" class="upload-placeholder">
-                    <ElIcon class="upload-icon"><Plus /></ElIcon>
-                    <div class="upload-text">点击上传封面</div>
-                  </div>
-                  <img v-else :src="cover" class="cover-image" />
-                </ElUpload>
-                <div class="el-upload__tip">建议尺寸 16:9,jpg/png 格式</div>
-              </div>
-            </ElFormItem>
-            <ElFormItem label="可见">
-              <ElSwitch v-model="visible" />
-            </ElFormItem>
-          </ElForm>
-
-          <div style="display: flex; justify-content: flex-end">
-            <ElButton type="primary" @click="submit" style="width: 100px">
-              {{ pageMode === PageModeEnum.Edit ? '保存' : '发布' }}
-            </ElButton>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- <div class="outline-wrap">
-        <div class="item" v-for="(item, index) in outlineList" :key="index">
-          <p :class="`level${item.level}`">{{ item.text }}</p>
-        </div>
-      </div> -->
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { Plus } from '@element-plus/icons-vue'
-  import { ElMessage } from 'element-plus'
-  import { useUserStore } from '@/store/modules/user'
-  import EmojiText from '@/utils/ui/emojo'
-  import { PageModeEnum } from '@/enums/formEnum'
-  import axios from 'axios'
-  import { useCommon } from '@/composables/useCommon'
-  import { ApiStatus } from '@/utils/http/server.type'
-
-  defineOptions({ name: 'ArticlePublish' })
-
-  const route = useRoute()
-
-  const userStore = useUserStore()
-  let { accessToken } = userStore
-
-  // 上传路径
-  const uploadImageUrl = `${import.meta.env.VITE_API_URL}/api/common/upload`
-  // 传递 token
-  const uploadHeaders = { Authorization: accessToken }
-
-  let pageMode: PageModeEnum = PageModeEnum.Add // 页面类型 新增 | 编辑
-  const articleName = ref('') // 文章标题
-  const articleType = ref() // 文章类型
-  const articleTypes = ref() // 类型列表
-  const editorHtml = ref('') // 编辑器内容
-  const createDate = ref('') // 创建时间
-  const cover = ref('') // 图片
-  const visible = ref(true) // 可见
-  // const outlineList = ref()
-
-  onMounted(() => {
-    useCommon().scrollToTop()
-    getArticleTypes()
-    initPageMode()
-  })
-
-  // 初始化页面类型 新增 | 编辑
-  const initPageMode = () => {
-    const { id } = route.query
-    pageMode = id ? PageModeEnum.Edit : PageModeEnum.Add
-    if (pageMode === PageModeEnum.Edit && id) {
-      initEditArticle()
-    } else {
-      initAddArticle()
-    }
-  }
-
-  // 初始化编辑文章的逻辑
-  const initEditArticle = () => {
-    getArticleDetail()
-  }
-
-  // 初始化新增文章逻辑
-  const initAddArticle = () => {
-    createDate.value = formDate(useNow().value)
-  }
-
-  // 获取文章类型
-  const getArticleTypes = async () => {
-    try {
-      const response = await axios.get('https://www.qiniu.lingchen.kim/classify.json')
-      if (response.data.code === 200) {
-        articleTypes.value = response.data.data
-      }
-    } catch (error) {
-      console.error('Error fetching JSON data:', error)
-    }
-    // try {
-    //   const res = await ArticleService.getArticleTypes({})
-    //   if (res.code === ApiStatus.success) {
-    //     articleTypes.value = res.data
-    //   }
-    // } catch (err) { }
-  }
-
-  const getArticleDetail = async () => {
-    const res = await axios.get('https://www.qiniu.lingchen.kim/blog_list.json')
-
-    if (res.data.code === ApiStatus.success) {
-      let { title, blog_class, html_content } = res.data.data
-      articleName.value = title
-      articleType.value = Number(blog_class)
-      editorHtml.value = html_content
-    }
-  }
-
-  // const getOutline = (content: string) => {
-  //   const regex = /<h([1-3])>(.*?)<\/h\1>/g
-  //   const headings = []
-  //   let match
-
-  //   while ((match = regex.exec(content)) !== null) {
-  //     headings.push({ level: match[1], text: match[2] })
-  //   }
-  //   outlineList.value = headings
-  // }
-
-  // 提交
-  const submit = () => {
-    if (pageMode === PageModeEnum.Edit) {
-      editArticle()
-    } else {
-      addArticle()
-    }
-  }
-
-  // 格式化日期
-  const formDate = (date: string | Date): string => {
-    return useDateFormat(date, 'YYYY-MM-DD').value
-  }
-
-  // 验证输入
-  const validateArticle = () => {
-    if (!articleName.value) {
-      ElMessage.error(`请输入文章标题`)
-      return false
-    }
-
-    if (!articleType.value) {
-      ElMessage.error(`请选择文章类型`)
-      return false
-    }
-
-    if (editorHtml.value === '<p><br></p>') {
-      ElMessage.error(`请输入文章内容`)
-      return false
-    }
-
-    if (!cover.value) {
-      ElMessage.error(`请上传图片`)
-      return false
-    }
-
-    return true
-  }
-
-  // 添加文章
-  const addArticle = async () => {
-    try {
-      if (!validateArticle()) return
-      editorHtml.value = delCodeTrim(editorHtml.value)
-    } catch (err) {
-      console.error(err)
-    }
-  }
-
-  // 编辑文章
-  const editArticle = async () => {
-    try {
-      if (!validateArticle()) return
-
-      editorHtml.value = delCodeTrim(editorHtml.value)
-    } catch (err) {
-      console.error(err)
-    }
-  }
-
-  const delCodeTrim = (content: string): string => {
-    return content.replace(/(\s*)<\/code>/g, '</code>')
-  }
-
-  const onSuccess = (response: any) => {
-    cover.value = response.data.url
-    ElMessage.success(`图片上传成功 ${EmojiText[200]}`)
-  }
-
-  const onError = () => {
-    ElMessage.error(`图片上传失败 ${EmojiText[500]}`)
-  }
-
-  // 添加上传前的校验
-  const beforeUpload = (file: File) => {
-    const isImage = file.type.startsWith('image/')
-    const isLt2M = file.size / 1024 / 1024 < 2
-
-    if (!isImage) {
-      ElMessage.error('只能上传图片文件!')
-      return false
-    }
-    if (!isLt2M) {
-      ElMessage.error('图片大小不能超过 2MB!')
-      return false
-    }
-    return true
-  }
-</script>
-
-<style lang="scss" scoped>
-  .article-edit {
-    .editor-wrap {
-      max-width: 1000px;
-      margin: 20px auto;
-
-      .el-top {
-        margin-top: 10px;
-      }
-
-      .form-wrap {
-        padding: 20px;
-        margin-top: 20px;
-        background-color: var(--art-main-bg-color);
-        border: 1px solid var(--art-border-color);
-        border-radius: calc(var(--custom-radius) / 2 + 2px) !important;
-
-        h2 {
-          margin-bottom: 20px;
-          font-size: 20px;
-          font-weight: 500;
-        }
-      }
-    }
-
-    .outline-wrap {
-      box-sizing: border-box;
-      width: 280px;
-      padding: 20px;
-      border: 1px solid #e3e3e3;
-      border-radius: 8px;
-
-      .item {
-        p {
-          height: 30px;
-          font-size: 13px;
-          line-height: 30px;
-          cursor: pointer;
-        }
-
-        .level3 {
-          padding-left: 10px;
-        }
-      }
-    }
-
-    .upload-container {
-      .cover-uploader {
-        position: relative;
-        overflow: hidden;
-        cursor: pointer;
-        border-radius: 6px;
-        transition: var(--el-transition-duration);
-
-        &:hover {
-          border-color: var(--el-color-primary);
-        }
-
-        .upload-placeholder {
-          display: flex;
-          flex-direction: column;
-          align-items: center;
-          justify-content: center;
-          width: 260px;
-          height: 160px;
-          border: 1px dashed #d9d9d9;
-          border-radius: 6px;
-
-          .upload-icon {
-            font-size: 28px;
-            color: #8c939d;
-          }
-
-          .upload-text {
-            margin-top: 8px;
-            font-size: 14px;
-            color: #8c939d;
-          }
-        }
-
-        .cover-image {
-          display: block;
-          width: 260px;
-          height: 160px;
-          object-fit: cover;
-        }
-      }
-
-      .el-upload__tip {
-        margin-top: 8px;
-        font-size: 12px;
-        color: #666;
-      }
-    }
-  }
-</style>

+ 0 - 240
src/views/change/log/index.vue

@@ -1,240 +0,0 @@
-<template>
-  <div class="page-content">
-    <h3 class="table-title"><i class="iconfont-sys">&#xe74d;</i>更新日志</h3>
-
-    <!-- 桌面端表格显示 -->
-    <div class="desktop-view">
-      <ArtTable :data="upgradeLogList">
-        <ElTableColumn label="版本号" prop="version" width="100" />
-        <ElTableColumn label="内容">
-          <template #default="scope">
-            <div class="title">{{ scope.row.title }}</div>
-            <div v-if="scope.row.detail" style="margin-top: 10px">
-              <div class="detail-item" v-for="(item, index) in scope.row.detail" :key="index"> {{ index + 1 }}. {{ item }} </div>
-            </div>
-          </template>
-        </ElTableColumn>
-        <ElTableColumn label="发布日期" prop="date" width="150" />
-        <ElTableColumn label="备注" prop="remark" width="260" />
-      </ArtTable>
-    </div>
-
-    <!-- 移动端卡片显示 -->
-    <div class="mobile-view">
-      <div class="changelog-cards">
-        <div v-for="item in upgradeLogList" :key="item.version" class="changelog-card">
-          <div class="card-header">
-            <div class="version-tag">{{ item.version }}</div>
-            <div class="date">{{ item.date }}</div>
-          </div>
-
-          <div class="card-content">
-            <h4 class="title">{{ item.title }}</h4>
-
-            <div v-if="item.detail && item.detail.length > 0" class="details">
-              <div class="detail-list">
-                <div v-for="(detail, index) in item.detail" :key="index" class="detail-item">
-                  <span class="detail-number">{{ index + 1 }}.</span>
-                  <span class="detail-text">{{ detail }}</span>
-                </div>
-              </div>
-            </div>
-
-            <div v-if="item.remark" class="remark">
-              {{ item.remark }}
-            </div>
-
-            <div v-if="item.requireReLogin" class="require-relogin">
-              <ElTag type="warning" size="small"> 需要重新登录 </ElTag>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { upgradeLogList } from '@/mock/upgrade/changeLog'
-
-  defineOptions({ name: 'ChangeLog' })
-</script>
-
-<style lang="scss" scoped>
-  .page-content {
-    .table-title {
-      display: flex;
-      align-items: center;
-      padding: 10px 0 0;
-      font-size: 18px;
-      font-weight: 500;
-
-      i {
-        margin-right: 10px;
-        font-size: 24px;
-      }
-    }
-
-    .title {
-      color: var(--art-gray-800);
-    }
-
-    .detail-item {
-      color: var(--art-gray-600);
-    }
-
-    // 桌面端显示
-    .desktop-view {
-      display: block;
-    }
-
-    // 移动端样式
-    .mobile-view {
-      display: none;
-
-      .changelog-cards {
-        display: flex;
-        flex-direction: column;
-        gap: 16px;
-        margin-top: 20px;
-      }
-
-      .changelog-card {
-        padding: 16px;
-        background: var(--el-bg-color);
-        border: 1px solid var(--el-border-color-light);
-        border-radius: 8px;
-        transition: all 0.3s ease;
-      }
-
-      .card-header {
-        display: flex;
-        flex-wrap: wrap;
-        gap: 8px;
-        align-items: center;
-        justify-content: space-between;
-        margin-bottom: 12px;
-
-        .version-tag {
-          min-width: fit-content;
-          padding: 4px 12px;
-          font-size: 12px;
-          font-weight: 600;
-          color: white;
-          background: linear-gradient(135deg, var(--el-color-primary), var(--el-color-primary-light-3));
-          border-radius: 20px;
-        }
-
-        .date {
-          min-width: fit-content;
-          font-size: 13px;
-          color: var(--art-gray-600);
-        }
-      }
-
-      .card-content {
-        .title {
-          margin-bottom: 12px;
-          font-size: 15px;
-          font-weight: 500;
-          line-height: 1.4;
-          color: var(--art-gray-800);
-        }
-
-        .details {
-          margin-bottom: 12px;
-
-          .detail-list {
-            padding: 12px;
-            background: rgba(var(--art-gray-200-rgb), 0.6);
-            border-radius: 6px;
-          }
-
-          .detail-item {
-            display: flex;
-            margin-bottom: 8px;
-            font-size: 13px;
-            line-height: 1.6;
-            color: var(--art-gray-600);
-
-            &:last-child {
-              margin-bottom: 0;
-            }
-
-            .detail-number {
-              min-width: 20px;
-            }
-
-            .detail-text {
-              flex: 1;
-              word-break: break-word;
-            }
-          }
-        }
-
-        .remark {
-          padding: 8px;
-          margin-bottom: 12px;
-          font-size: 12px;
-          color: var(--art-gray-600);
-          background: rgba(var(--art-gray-200-rgb), 0.6);
-          border-radius: 4px;
-        }
-
-        .remark,
-        .require-relogin {
-          margin-top: 12px;
-
-          :deep(.el-tag) {
-            font-size: 12px;
-            border-radius: 6px;
-
-            i {
-              margin-right: 4px;
-            }
-          }
-        }
-      }
-    }
-
-    // 移动端媒体查询
-    @media (width <= 768px) {
-      .desktop-view {
-        display: none;
-      }
-
-      .mobile-view {
-        display: block;
-      }
-
-      .table-title {
-        padding: 8px 0 0;
-        font-size: 16px;
-
-        i {
-          font-size: 20px;
-        }
-      }
-    }
-
-    // 平板端优化
-    @media (width <= 1024px) and (width >= 769px) {
-      .changelog-card {
-        .card-header {
-          .version-tag {
-            padding: 6px 14px;
-            font-size: 13px;
-          }
-
-          .date {
-            font-size: 14px;
-          }
-        }
-
-        .card-content .title {
-          font-size: 16px;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 53
src/views/dashboard/analysis/index.vue

@@ -1,53 +0,0 @@
-<template>
-  <div class="analysis-dashboard">
-    <el-row :gutter="20">
-      <el-col :xl="14" :lg="15" :xs="24">
-        <TodaySales />
-      </el-col>
-      <el-col :xl="10" :lg="9" :xs="24">
-        <VisitorInsights />
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20" class="mt-20">
-      <el-col :xl="10" :lg="10" :xs="24">
-        <TotalRevenue />
-      </el-col>
-      <el-col :xl="7" :lg="7" :xs="24">
-        <CustomerSatisfaction />
-      </el-col>
-      <el-col :xl="7" :lg="7" :xs="24">
-        <TargetVsReality />
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20" class="mt-20">
-      <el-col :xl="10" :lg="10" :xs="24">
-        <TopProducts />
-      </el-col>
-      <el-col :xl="7" :lg="7" :xs="24">
-        <SalesMappingByCountry />
-      </el-col>
-      <el-col :xl="7" :lg="7" :xs="24">
-        <VolumeServiceLevel />
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import TodaySales from './widget/TodaySales.vue'
-  import VisitorInsights from './widget/VisitorInsights.vue'
-  import TotalRevenue from './widget/TotalRevenue.vue'
-  import CustomerSatisfaction from './widget/CustomerSatisfaction.vue'
-  import TargetVsReality from './widget/TargetVsReality.vue'
-  import TopProducts from './widget/TopProducts.vue'
-  import SalesMappingByCountry from './widget/SalesMappingByCountry.vue'
-  import VolumeServiceLevel from './widget/VolumeServiceLevel.vue'
-
-  defineOptions({ name: 'Analysis' })
-</script>
-
-<style lang="scss" scoped>
-  @use './style';
-</style>

+ 0 - 61
src/views/dashboard/analysis/style.scss

@@ -1,61 +0,0 @@
-.analysis-dashboard {
-  padding-bottom: 20px;
-
-  :deep(.custom-card) {
-    background: var(--art-main-bg-color);
-    border-radius: calc(var(--custom-radius) + 4px) !important;
-  }
-
-  // 卡片头部
-  :deep(.custom-card-header) {
-    position: relative;
-    box-sizing: border-box;
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    padding: 18px 20px;
-
-    .title {
-      font-size: 20px;
-      font-weight: 400;
-      color: var(--art-text-gray-900);
-    }
-
-    .subtitle {
-      position: absolute;
-      bottom: 2px;
-      left: 21px;
-      font-size: 13px;
-      color: var(--art-gray-600);
-    }
-  }
-
-  .el-card {
-    border: 1px solid #e8ebf1;
-    box-shadow: none;
-  }
-
-  .mt-20 {
-    margin-top: 20px;
-  }
-}
-
-.dark {
-  .analysis-dashboard {
-    :deep(.custom-card) {
-      box-shadow: 0 4px 20px rgb(0 0 0 / 50%);
-    }
-  }
-}
-
-@media (width <= 1200px) {
-  .analysis-dashboard {
-    .mt-20 {
-      margin-top: 0;
-    }
-
-    :deep(.custom-card) {
-      margin-bottom: 20px;
-    }
-  }
-}

+ 0 - 59
src/views/dashboard/analysis/widget/CustomerSatisfaction.vue

@@ -1,59 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card customer-satisfaction">
-    <div class="custom-card-header">
-      <span class="title">客户满意度</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtLineChart height="100%" :data="chartData" :xAxisData="xAxisData" :showLegend="true" :showAxisLabel="true" :showAxisLine="false" :showSplitLine="true" />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import type { LineDataItem } from '@/types/component/chart'
-
-  // 图表数据配置
-  const chartData = computed<LineDataItem[]>(() => [
-    {
-      name: '上个月',
-      data: [65, 72, 68, 75, 82, 78, 85],
-      areaStyle: {
-        startOpacity: 0.08,
-        endOpacity: 0
-      }
-    },
-    {
-      name: '本月',
-      data: [78, 85, 82, 88, 92, 89, 95],
-      areaStyle: {
-        startOpacity: 0.08,
-        endOpacity: 0
-      }
-    }
-  ])
-
-  // X轴数据
-  const xAxisData = ['1', '2', '3', '4', '5', '6', '7']
-</script>
-
-<style lang="scss" scoped>
-  .customer-satisfaction {
-    height: 400px;
-
-    .custom-card-body {
-      height: calc(100% - 145px);
-      padding: 60px 20px 10px;
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .customer-satisfaction {
-      height: 300px;
-
-      .custom-card-body {
-        height: calc(100% - 100px);
-        padding-top: 20px;
-      }
-    }
-  }
-</style>

+ 0 - 29
src/views/dashboard/analysis/widget/SalesMappingByCountry.vue

@@ -1,29 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card sales-mapping-country">
-    <div class="custom-card-header">
-      <span class="title">全国销售分布</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtRingChart
-        :data="[
-          { value: 30, name: '北京' },
-          { value: 25, name: '上海' },
-          { value: 45, name: '广州' }
-        ]"
-        :color="['#4C87F3', '#93F1B4', '#8BD8FC']"
-        :radius="['46%', '60%']"
-      />
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-  .sales-mapping-country {
-    height: 330px;
-
-    .sales-mapping-chart {
-      width: 100%;
-      height: 260px;
-    }
-  }
-</style>

+ 0 - 144
src/views/dashboard/analysis/widget/TargetVsReality.vue

@@ -1,144 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card target-vs-reality">
-    <div class="custom-card-header">
-      <span class="title">目标与实际</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtBarChart height="10rem" :data="revenueData" :xAxisData="weekDays" :showAxisLine="false" barWidth="28%" />
-    </div>
-    <div class="custom-card-footer">
-      <div class="total-item">
-        <div class="label">
-          <i class="iconfont-sys">&#xe77f;</i>
-          <div class="label-text">
-            <span>实际销售额</span>
-            <span>全球</span>
-          </div>
-        </div>
-        <div class="value text-color-green">8,823</div>
-      </div>
-      <div class="total-item">
-        <div class="label">
-          <i class="iconfont-sys">&#xe77c;</i>
-          <div class="label-text">
-            <span>目标销售额</span>
-            <span>商业</span>
-          </div>
-        </div>
-        <div class="value text-color-orange">12,122</div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  const weekDays = ref(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
-
-  const revenueData = ref([
-    {
-      name: '线上销售',
-      data: [12, 13, 5, 15, 10, 15, 18]
-      // color: '#6E93FF'
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .custom-card {
-    height: 400px;
-
-    &-body {
-      padding: 20px;
-    }
-
-    &-footer {
-      box-sizing: border-box;
-      padding: 0 20px;
-      margin-top: 15px;
-
-      .total-item {
-        display: flex;
-        margin-bottom: 20px;
-        text-align: center;
-
-        &:first-of-type .label .iconfont-sys {
-          color: #2b8dfa !important;
-          background-color: #e6f7ff !important;
-        }
-
-        &:last-of-type .label .iconfont-sys {
-          color: #1cb8fc !important;
-          background-color: #e6f7ff !important;
-        }
-
-        .label {
-          display: flex;
-          align-items: center;
-          justify-content: flex-start;
-          width: 60%;
-          font-size: 14px;
-          color: #606266;
-
-          .iconfont-sys {
-            width: 40px;
-            height: 40px;
-            margin-right: 12px;
-            font-size: 18px;
-            line-height: 40px;
-            text-align: center;
-            background-color: #f2f2f2;
-            border-radius: 6px;
-          }
-
-          .label-text {
-            display: flex;
-            flex-direction: column;
-            align-items: flex-start;
-
-            span {
-              &:first-of-type {
-                font-size: 16px;
-                color: var(--art-text-gray-800);
-              }
-
-              &:last-of-type {
-                margin-top: 4px;
-                font-size: 12px;
-                color: #737791;
-              }
-            }
-          }
-        }
-
-        .value {
-          font-size: 18px;
-          font-weight: 400;
-
-          &.text-color-green {
-            color: #2b8dfa !important;
-          }
-
-          &.text-color-orange {
-            color: #1cb8fc !important;
-          }
-        }
-      }
-    }
-  }
-
-  .dark {
-    .custom-card {
-      &-footer {
-        .total-item {
-          &:first-of-type .label .iconfont-sys {
-            background-color: #222 !important;
-          }
-
-          &:last-of-type .label .iconfont-sys {
-            background-color: #222 !important;
-          }
-        }
-      }
-    }
-  }
-</style>

+ 0 - 184
src/views/dashboard/analysis/widget/TodaySales.vue

@@ -1,184 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card today-sales">
-    <div class="custom-card-header">
-      <span class="title">今日销售</span>
-      <span class="subtitle">销售总结</span>
-      <div class="export-btn">
-        <i class="iconfont-sys">&#xe6d1;</i>
-        <span>导出</span>
-      </div>
-    </div>
-    <div class="sales-summary">
-      <el-row :gutter="20">
-        <el-col :span="6" :xs="24" v-for="(item, index) in salesData" :key="index">
-          <div :class="['sales-card']">
-            <i class="iconfont-sys" v-html="item.iconfont"></i>
-            <h2>
-              <ArtCountTo class="number box-title" :target="item.value" :duration="1500" />
-            </h2>
-            <p>{{ item.label }}</p>
-            <small>
-              较昨天
-              <span :class="[item.change.indexOf('+') === -1 ? 'text-danger' : 'text-success']">{{ item.change }}</span>
-            </small>
-          </div>
-        </el-col>
-      </el-row>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  const salesData = ref([
-    {
-      label: '总销售额',
-      value: 999,
-      change: '+10%',
-      iconfont: '&#xe7d9',
-      class: 'bg-primary'
-    },
-    {
-      label: '总订单量',
-      value: 300,
-      change: '+15%',
-      iconfont: '&#xe70f',
-      class: 'bg-warning'
-    },
-    {
-      label: '产品销售量',
-      value: 56,
-      change: '-5%',
-      iconfont: '&#xe712',
-      class: 'bg-error'
-    },
-    {
-      label: '新客户数',
-      value: 68,
-      change: '+8%',
-      iconfont: '&#xe77f',
-      class: 'bg-success'
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .today-sales {
-    height: 330px;
-
-    .export-btn {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      min-width: 66px;
-      padding: 6px 0;
-      color: var(--art-gray-600);
-      cursor: pointer;
-      border: 1px solid var(--art-border-dashed-color);
-      border-radius: 6px;
-      transition: all 0.3s;
-
-      &:hover {
-        color: var(--main-color);
-        border-color: var(--main-color);
-      }
-
-      .iconfont-sys {
-        margin-right: 5px;
-        font-size: 10px;
-      }
-
-      span {
-        font-size: 12px;
-      }
-    }
-
-    .sales-summary {
-      padding: 20px;
-
-      .sales-card {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        height: 220px;
-        padding: 0 20px;
-        overflow: hidden;
-        border: 1px solid var(--art-border-color) !important;
-        border-radius: calc(var(--custom-radius) / 2 + 4px) !important;
-
-        .iconfont-sys {
-          width: 48px;
-          height: 48px;
-          font-size: 20px;
-          line-height: 48px;
-          color: var(--el-color-primary);
-          text-align: center;
-          background-color: var(--el-color-primary-light-9);
-          border-radius: 10px;
-        }
-
-        h2 {
-          margin-top: 26px;
-          font-size: 26px;
-          font-weight: 400;
-          color: var(--art-text-gray-900) !important;
-        }
-
-        p {
-          margin-top: 6px;
-          font-size: 16px;
-          color: var(--art-text-gray-700) !important;
-
-          @include ellipsis;
-        }
-
-        small {
-          display: block;
-          margin-top: 5px;
-          font-size: 12px;
-          color: var(--art-text-gray-600) !important;
-
-          @include ellipsis;
-        }
-      }
-    }
-  }
-
-  // 暗黑模式降低颜色强度
-  .dark {
-    .today-sales {
-      .sales-summary {
-        .sales-card {
-          .iconfont-sys {
-            &.red,
-            &.yellow,
-            &.green,
-            &.purple {
-              background-color: #222 !important;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  @media (width <= 768px) {
-    .today-sales {
-      height: auto;
-
-      .sales-summary {
-        padding-bottom: 0;
-
-        .sales-card {
-          height: auto;
-          padding: 16px;
-          margin-bottom: 20px;
-
-          h2 {
-            margin-top: 10px;
-            font-size: 24px;
-          }
-        }
-      }
-    }
-  }
-</style>

+ 0 - 98
src/views/dashboard/analysis/widget/TopProducts.vue

@@ -1,98 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card top-products">
-    <div class="custom-card-header">
-      <span class="title">热门产品</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtTable :data="products" style="width: 100%" size="large" :border="false" :stripe="false" :header-cell-style="{ background: 'transparent' }">
-        <el-table-column prop="name" label="产品名称" width="200" />
-        <el-table-column prop="popularity" label="销量">
-          <template #default="scope">
-            <el-progress :percentage="scope.row.popularity" :color="getColor(scope.row.popularity)" :stroke-width="5" :show-text="false" />
-          </template>
-        </el-table-column>
-        <el-table-column prop="sales" label="销量" width="80">
-          <template #default="scope">
-            <span
-              :style="{
-                color: getColor(scope.row.popularity),
-                backgroundColor: `rgba(${hexToRgb(getColor(scope.row.popularity))}, 0.08)`,
-                border: '1px solid',
-                padding: '3px 6px',
-                borderRadius: '4px',
-                fontSize: '12px'
-              }"
-              >{{ scope.row.sales }}</span
-            >
-          </template>
-        </el-table-column>
-      </ArtTable>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { hexToRgb } from '@/utils/ui'
-
-  const products = computed(() => [
-    {
-      name: '智能手机',
-      popularity: 10,
-      sales: '100'
-    },
-    {
-      name: '笔记本电脑',
-      popularity: 29,
-      sales: '100'
-    },
-    {
-      name: '平板电脑',
-      popularity: 65,
-      sales: '100'
-    },
-    {
-      name: '智能手表',
-      popularity: 32,
-      sales: '100'
-    },
-    {
-      name: '无线耳机',
-      popularity: 78,
-      sales: '100'
-    },
-    {
-      name: '智能音箱',
-      popularity: 41,
-      sales: '100'
-    }
-  ])
-
-  const getColor = (percentage: number) => {
-    if (percentage < 25) return '#00E096'
-    if (percentage < 50) return '#0095FF'
-    if (percentage < 75) return '#884CFF'
-    return '#FE8F0E'
-  }
-</script>
-
-<style lang="scss" scoped>
-  .custom-card {
-    height: 330px;
-    overflow-y: scroll;
-
-    // 隐藏滚动条
-    &::-webkit-scrollbar {
-      display: none;
-    }
-
-    &-body {
-      padding: 0 6px;
-    }
-  }
-
-  @media (width <= 1200px) {
-    .custom-card {
-      height: auto;
-    }
-  }
-</style>

+ 0 - 42
src/views/dashboard/analysis/widget/TotalRevenue.vue

@@ -1,42 +0,0 @@
-<template>
-  <div class="custom-card total-revenue-card art-custom-card">
-    <div class="custom-card-header">
-      <span class="title">总收入</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtBarChart height="100%" :data="revenueData" :xAxisData="weekDays" :showLegend="true" :showAxisLine="false" barWidth="18%" />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  const weekDays = ref(['周一', '周二', '周三', '周四', '周五', '周六', '周日'])
-
-  const revenueData = ref([
-    {
-      name: '线上销售',
-      data: [12, 13, 5, 15, 10, 15, 18]
-    },
-    {
-      name: '线下销售',
-      data: [10, 11, 20, 5, 11, 13, 10]
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .total-revenue-card {
-    height: 400px;
-
-    .custom-card-body {
-      height: calc(100% - 108px);
-      padding: 20px;
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .total-revenue-card {
-      height: 300px;
-    }
-  }
-</style>

+ 0 - 41
src/views/dashboard/analysis/widget/VisitorInsights.vue

@@ -1,41 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card visitor-insights">
-    <div class="custom-card-header">
-      <span class="title">访客洞察</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtLineChart height="15rem" :data="chartData" :xAxisData="xAxisData" :showLegend="true" :showAxisLabel="true" :showAxisLine="false" :showSplitLine="true" />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import type { LineDataItem } from '@/types/component/chart'
-
-  // 图表数据配置
-  const chartData = computed<LineDataItem[]>(() => [
-    {
-      name: '老客户',
-      data: [280, 350, 300, 250, 230, 210, 240, 280, 320, 350, 300, 200]
-      // color: '#4ABEFF'
-    },
-    {
-      name: '新客户',
-      data: [260, 200, 150, 130, 180, 270, 340, 380, 300, 220, 170, 130]
-      // color: '#6E93FF'
-    }
-  ])
-
-  // X轴数据
-  const xAxisData = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
-</script>
-
-<style lang="scss" scoped>
-  .visitor-insights {
-    height: 330px;
-
-    .custom-card-body {
-      padding: 10px 20px;
-    }
-  }
-</style>

+ 0 - 41
src/views/dashboard/analysis/widget/VolumeServiceLevel.vue

@@ -1,41 +0,0 @@
-<template>
-  <div class="custom-card art-custom-card volume-service-level">
-    <div class="custom-card-header">
-      <span class="title">业务量与服务水平</span>
-    </div>
-    <div class="custom-card-body">
-      <ArtBarChart height="14.3rem" :data="volumeServiceData" :xAxisData="serviceCategories" :showLegend="true" :showAxisLine="false" :stack="true" barWidth="22%" />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  // 服务类别数据
-  const serviceCategories = ref(['产品A', '产品B', '产品C', '产品D', '产品E'])
-
-  // 服务量数据
-  const volumeServiceData = ref([
-    {
-      name: '业务量',
-      data: [20, 25, 30, 35, 40],
-      stack: 'total'
-      // color: '#0095FF'
-    },
-    {
-      name: '服务量',
-      data: [30, 35, 40, 45, 50],
-      stack: 'total'
-      // color: '#95E0FB'
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .volume-service-level {
-    height: 330px;
-
-    .custom-card-body {
-      padding: 20px;
-    }
-  }
-</style>

+ 0 - 44
src/views/dashboard/console/index2.vue

@@ -1,44 +0,0 @@
-<template>
-  <div class="console">
-    <CardList></CardList>
-
-    <el-row :gutter="20">
-      <el-col :sm="24" :md="12" :lg="10">
-        <ActiveUser />
-      </el-col>
-      <el-col :sm="24" :md="12" :lg="14">
-        <SalesOverview />
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20">
-      <el-col :sm="24" :md="24" :lg="12">
-        <NewUser />
-      </el-col>
-      <el-col :sm="24" :md="12" :lg="6">
-        <Dynamic />
-      </el-col>
-      <el-col :sm="24" :md="12" :lg="6">
-        <TodoList />
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import CardList from './widget/CardList.vue'
-  import ActiveUser from './widget/ActiveUser.vue'
-  import SalesOverview from './widget/SalesOverview.vue'
-  import NewUser from './widget/NewUser.vue'
-  import Dynamic from './widget/Dynamic.vue'
-  import TodoList from './widget/TodoList.vue'
-  import { useCommon } from '@/composables/useCommon'
-
-  defineOptions({ name: 'Console' })
-
-  useCommon().scrollToTop()
-</script>
-
-<style lang="scss" scoped>
-  @use './style';
-</style>

+ 0 - 43
src/views/dashboard/console/style.scss

@@ -1,43 +0,0 @@
-@use '@styles/variables.scss' as *;
-
-.console {
-  --card-spacing: 20px;
-
-  // 卡片头部
-  :deep(.card-header) {
-    display: flex;
-    justify-content: space-between;
-    padding: 20px 25px 5px 0;
-
-    .title {
-      h4 {
-        font-size: 18px;
-        font-weight: 500;
-        color: var(--art-gray-900) !important;
-      }
-
-      p {
-        margin-top: 3px;
-        font-size: 13px;
-        color: var(--art-gray-600) !important;
-
-        span {
-          margin-left: 10px;
-          color: #52c41a;
-        }
-      }
-    }
-  }
-
-  // 设置卡片背景色、圆角、间隙
-  :deep(.card-list .card),
-  .card {
-    margin-bottom: var(--card-spacing);
-    background: var(--art-main-bg-color);
-    border-radius: calc(var(--custom-radius) + 4px) !important;
-  }
-
-  @media screen and (max-width: $device-phone) {
-    --card-spacing: 15px;
-  }
-}

+ 0 - 103
src/views/dashboard/console/widget/ActiveUser.vue

@@ -1,103 +0,0 @@
-<template>
-  <div class="card art-custom-card">
-    <ArtBarChart class="chart" barWidth="50%" height="13.7rem" :showAxisLine="false" :data="[160, 100, 150, 80, 190, 100, 175, 120, 160]" :xAxisData="['1', '2', '3', '4', '5', '6', '7', '8', '9']" />
-    <div class="text">
-      <h3 class="box-title">用户概述</h3>
-      <p class="subtitle">比上周 <span class="text-success">+23%</span></p>
-      <p class="subtitle">我们为您创建了多个选项,可将它们组合在一起并定制为像素完美的页面</p>
-    </div>
-    <div class="list">
-      <div v-for="(item, index) in list" :key="index">
-        <p>{{ item.num }}</p>
-        <p class="subtitle">{{ item.name }}</p>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  const list = [
-    { name: '总用户量', num: '32k' },
-    { name: '总访问量', num: '128k' },
-    { name: '日访问量', num: '1.2k' },
-    { name: '周同比', num: '+5%' }
-  ]
-</script>
-
-<style lang="scss" scoped>
-  .card {
-    box-sizing: border-box;
-    width: 100%;
-    height: 420px;
-    padding: 16px;
-
-    .chart {
-      box-sizing: border-box;
-      width: 100%;
-      height: 220px;
-      padding: 10px;
-      border-radius: calc(var(--custom-radius) / 2 + 4px) !important;
-    }
-
-    .text {
-      margin-left: 3px;
-
-      h3 {
-        margin-top: 20px;
-        font-size: 18px;
-        font-weight: 500;
-      }
-
-      p {
-        margin-top: 5px;
-        font-size: 14px;
-
-        &:last-of-type {
-          height: 42px;
-          margin-top: 5px;
-        }
-      }
-    }
-
-    .list {
-      display: flex;
-      justify-content: space-between;
-      margin-left: 3px;
-
-      > div {
-        flex: 1;
-
-        p {
-          font-weight: 400;
-
-          &:first-of-type {
-            font-size: 24px;
-            color: var(--art-gray-900);
-          }
-
-          &:last-of-type {
-            font-size: 13px;
-          }
-        }
-      }
-    }
-  }
-
-  .dark {
-    .card {
-      .chart {
-        background: none;
-      }
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .dark {
-      .card {
-        .chart {
-          padding: 15px 0 0 !important;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 148
src/views/dashboard/console/widget/CardList.vue

@@ -1,148 +0,0 @@
-<template>
-  <el-row :gutter="20" class="card-list">
-    <el-col v-for="(item, index) in dataList" :key="index" :sm="12" :md="6" :lg="6">
-      <div class="card art-custom-card">
-        <span class="des subtitle">{{ item.des }}</span>
-        <ArtCountTo class="number box-title" :target="item.num" :duration="1300" />
-        <div class="change-box">
-          <span class="change-text">较上周</span>
-          <span class="change" :class="[item.change.indexOf('+') === -1 ? 'text-danger' : 'text-success']">
-            {{ item.change }}
-          </span>
-        </div>
-        <i class="iconfont-sys" v-html="item.icon"></i>
-      </div>
-    </el-col>
-  </el-row>
-</template>
-
-<script setup lang="ts">
-  import { reactive } from 'vue'
-
-  const dataList = reactive([
-    {
-      des: '总访问次数',
-      icon: '&#xe721;',
-      startVal: 0,
-      duration: 1000,
-      num: 9120,
-      change: '+20%'
-    },
-    {
-      des: '在线访客数',
-      icon: '&#xe724;',
-      startVal: 0,
-      duration: 1000,
-      num: 182,
-      change: '+10%'
-    },
-    {
-      des: '点击量',
-      icon: '&#xe7aa;',
-      startVal: 0,
-      duration: 1000,
-      num: 9520,
-      change: '-12%'
-    },
-    {
-      des: '新用户',
-      icon: '&#xe82a;',
-      startVal: 0,
-      duration: 1000,
-      num: 156,
-      change: '+30%'
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .card-list {
-    box-sizing: border-box;
-    display: flex;
-    flex-wrap: wrap;
-    background-color: transparent !important;
-
-    .art-custom-card {
-      position: relative;
-      box-sizing: border-box;
-      display: flex;
-      flex-direction: column;
-      justify-content: center;
-      width: 100%;
-      height: 140px;
-      padding: 0 18px;
-      list-style: none;
-      transition: all 0.3s ease;
-
-      $icon-size: 52px;
-
-      .iconfont-sys {
-        position: absolute;
-        top: 0;
-        right: 20px;
-        bottom: 0;
-        width: $icon-size;
-        height: $icon-size;
-        margin: auto;
-        overflow: hidden;
-        font-size: 22px;
-        line-height: $icon-size;
-        color: var(--el-color-primary) !important;
-        text-align: center;
-        background-color: var(--el-color-primary-light-9);
-        border-radius: 12px;
-      }
-
-      .des {
-        display: block;
-        height: 14px;
-        font-size: 14px;
-        line-height: 14px;
-      }
-
-      .number {
-        display: block;
-        margin-top: 10px;
-        font-size: 28px;
-        font-weight: 400;
-      }
-
-      .change-box {
-        display: flex;
-        align-items: center;
-        margin-top: 10px;
-
-        .change-text {
-          display: block;
-          font-size: 13px;
-          color: var(--art-text-gray-600);
-        }
-
-        .change {
-          display: block;
-          margin-left: 5px;
-          font-size: 13px;
-          font-weight: bold;
-
-          &.text-success {
-            color: var(--el-color-success);
-          }
-
-          &.text-danger {
-            color: var(--el-color-danger);
-          }
-        }
-      }
-    }
-  }
-
-  .dark {
-    .card-list {
-      .art-custom-card {
-        .iconfont-sys {
-          background-color: #232323 !important;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 100
src/views/dashboard/console/widget/Dynamic.vue

@@ -1,100 +0,0 @@
-<template>
-  <div class="card art-custom-card">
-    <div class="card-header">
-      <div class="title">
-        <h4 class="box-title">动态</h4>
-        <p class="subtitle">新增<span class="text-success">+6</span></p>
-      </div>
-    </div>
-
-    <div class="list">
-      <div v-for="(item, index) in list" :key="index">
-        <span class="user">{{ item.username }}</span>
-        <span class="type">{{ item.type }}</span>
-        <span class="target">{{ item.target }}</span>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { reactive } from 'vue-demi'
-
-  const list = reactive([
-    {
-      username: '中小鱼',
-      type: '关注了',
-      target: '誶誶淰'
-    },
-    {
-      username: '何小荷',
-      type: '发表文章',
-      target: 'Vue3 + Typescript + Vite 项目实战笔记'
-    },
-    {
-      username: '誶誶淰',
-      type: '提出问题',
-      target: '主题可以配置吗'
-    },
-    {
-      username: '发呆草',
-      type: '兑换了物品',
-      target: '《奇特的一生》'
-    },
-    {
-      username: '甜筒',
-      type: '关闭了问题',
-      target: '发呆草'
-    },
-    {
-      username: '冷月呆呆',
-      type: '兑换了物品',
-      target: '《高效人士的七个习惯》'
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .card {
-    box-sizing: border-box;
-    width: 100%;
-    height: 510px;
-    padding: 0 25px;
-
-    .header {
-      display: flex;
-      justify-content: space-between;
-      padding: 20px 0 0;
-    }
-
-    .list {
-      height: calc(100% - 100px);
-      margin-top: 10px;
-      overflow: hidden;
-
-      > div {
-        height: 70px;
-        overflow: hidden;
-        line-height: 70px;
-        border-bottom: 1px solid var(--art-border-color);
-
-        span {
-          font-size: 13px;
-        }
-
-        .user {
-          font-weight: 500;
-          color: var(--art-text-gray-800);
-        }
-
-        .type {
-          margin: 0 8px;
-        }
-
-        .target {
-          color: var(--main-color);
-        }
-      }
-    }
-  }
-</style>

+ 0 - 168
src/views/dashboard/console/widget/NewUser.vue

@@ -1,168 +0,0 @@
-<template>
-  <div class="card art-custom-card">
-    <div class="card-header">
-      <div class="title">
-        <h4 class="box-title">新用户</h4>
-        <p class="subtitle">这个月增长<span class="text-success">+20%</span></p>
-      </div>
-      <el-radio-group v-model="radio2">
-        <el-radio-button value="本月" label="本月"></el-radio-button>
-        <el-radio-button value="上月" label="上月"></el-radio-button>
-        <el-radio-button value="今年" label="今年"></el-radio-button>
-      </el-radio-group>
-    </div>
-    <ArtTable class="table" :data="tableData" style="width: 100%" size="large" :border="false" :stripe="false" :header-cell-style="{ background: 'transparent' }">
-      <template #default>
-        <el-table-column label="头像" prop="avatar" width="150px">
-          <template #default="scope">
-            <div style="display: flex; align-items: center">
-              <img class="avatar" :src="scope.row.avatar" alt="avatar" />
-              <span class="user-name">{{ scope.row.username }}</span>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="地区" prop="province" />
-        <el-table-column label="性别" prop="avatar">
-          <template #default="scope">
-            <div style="display: flex; align-items: center">
-              <span style="margin-left: 10px">{{ scope.row.sex === 1 ? '男' : '女' }}</span>
-            </div>
-          </template>
-        </el-table-column>
-        <el-table-column label="进度" width="240">
-          <template #default="scope">
-            <el-progress :percentage="scope.row.pro" :color="scope.row.color" :stroke-width="4" :aria-label="`${scope.row.username}的完成进度: ${scope.row.pro}%`" />
-          </template>
-        </el-table-column>
-      </template>
-    </ArtTable>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { onMounted, ref, reactive } from 'vue-demi'
-  import avatar1 from '@/assets/img/avatar/avatar1.webp'
-  import avatar2 from '@/assets/img/avatar/avatar2.webp'
-  import avatar3 from '@/assets/img/avatar/avatar3.webp'
-  import avatar4 from '@/assets/img/avatar/avatar4.webp'
-  import avatar5 from '@/assets/img/avatar/avatar5.webp'
-  import avatar6 from '@/assets/img/avatar/avatar6.webp'
-
-  const radio2 = ref('本月')
-
-  const tableData = reactive([
-    {
-      username: '中小鱼',
-      province: '北京',
-      sex: 0,
-      age: 22,
-      percentage: 60,
-      pro: 0,
-      color: 'rgb(var(--art-primary)) !important',
-      avatar: avatar1
-    },
-    {
-      username: '何小荷',
-      province: '深圳',
-      sex: 1,
-      age: 21,
-      percentage: 20,
-      pro: 0,
-      color: 'rgb(var(--art-secondary)) !important',
-      avatar: avatar2
-    },
-    {
-      username: '誶誶淰',
-      province: '上海',
-      sex: 1,
-      age: 23,
-      percentage: 60,
-      pro: 0,
-      color: 'rgb(var(--art-warning)) !important',
-      avatar: avatar3
-    },
-    {
-      username: '发呆草',
-      province: '长沙',
-      sex: 0,
-      age: 28,
-      percentage: 50,
-      pro: 0,
-      color: 'rgb(var(--art-info)) !important',
-      avatar: avatar4
-    },
-    {
-      username: '甜筒',
-      province: '浙江',
-      sex: 1,
-      age: 26,
-      percentage: 70,
-      pro: 0,
-      color: 'rgb(var(--art-error)) !important',
-      avatar: avatar5
-    },
-    {
-      username: '冷月呆呆',
-      province: '湖北',
-      sex: 1,
-      age: 25,
-      percentage: 90,
-      pro: 0,
-      color: 'rgb(var(--art-success)) !important',
-      avatar: avatar6
-    }
-  ])
-
-  onMounted(() => {
-    addAnimation()
-  })
-
-  const addAnimation = () => {
-    setTimeout(() => {
-      for (let i = 0; i < tableData.length; i++) {
-        let item = tableData[i]
-        tableData[i].pro = item.percentage
-      }
-    }, 100)
-  }
-</script>
-
-<style lang="scss">
-  .card {
-    // 进度动画
-    .el-progress-bar__inner {
-      transition: all 1s !important;
-    }
-
-    .el-radio-button__original-radio:checked + .el-radio-button__inner {
-      color: var(--el-color-primary) !important;
-      background: transparent !important;
-    }
-  }
-</style>
-
-<style lang="scss" scoped>
-  .card {
-    width: 100%;
-    height: 510px;
-    overflow: hidden;
-
-    .card-header {
-      padding-left: 25px !important;
-    }
-
-    :deep(.el-table__body tr:last-child td) {
-      border-bottom: none !important;
-    }
-
-    .avatar {
-      width: 36px;
-      height: 36px;
-      border-radius: 6px;
-    }
-
-    .user-name {
-      margin-left: 10px;
-    }
-  }
-</style>

+ 0 - 41
src/views/dashboard/console/widget/SalesOverview.vue

@@ -1,41 +0,0 @@
-<template>
-  <div class="card art-custom-card">
-    <div class="card-header">
-      <div class="title">
-        <h4 class="box-title">访问量</h4>
-        <p class="subtitle">今年增长<span class="text-success">+15%</span></p>
-      </div>
-    </div>
-    <ArtLineChart class="chart" height="calc(100% - 40px)" :data="data" :xAxisData="xAxisData" :showAreaColor="true" :showAxisLine="false" />
-  </div>
-</template>
-
-<script setup lang="ts">
-  const data = [50, 25, 40, 20, 70, 35, 65, 30, 35, 20, 40, 44]
-  const xAxisData = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
-</script>
-
-<style lang="scss" scoped>
-  .card {
-    box-sizing: border-box;
-    width: 100%;
-    height: 420px;
-    padding: 20px 0 30px;
-
-    .card-header {
-      padding: 0 18px !important;
-    }
-
-    .chart {
-      box-sizing: border-box;
-      width: 100%;
-      padding: 20px 20px 0;
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .card {
-      height: 280px;
-    }
-  }
-</style>

+ 0 - 102
src/views/dashboard/console/widget/TodoList.vue

@@ -1,102 +0,0 @@
-<template>
-  <div class="card art-custom-card">
-    <div class="card-header">
-      <div class="title">
-        <h4 class="box-title">代办事项</h4>
-        <p class="subtitle">待处理<span class="text-danger">3</span></p>
-      </div>
-    </div>
-
-    <div class="list">
-      <div v-for="(item, index) in list" :key="index">
-        <p class="title">{{ item.username }}</p>
-        <p class="date subtitle">{{ item.date }}</p>
-        <el-checkbox v-model="item.complate" />
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { reactive } from 'vue-demi'
-
-  const list = reactive([
-    {
-      username: '查看今天工作内容',
-      date: '上午 09:30',
-      complate: true
-    },
-    {
-      username: '回复邮件',
-      date: '上午 10:30',
-      complate: true
-    },
-    {
-      username: '工作汇报整理',
-      date: '上午 11:00',
-      complate: true
-    },
-    {
-      username: '产品需求会议',
-      date: '下午 02:00',
-      complate: false
-    },
-    {
-      username: '整理会议内容',
-      date: '下午 03:30',
-      complate: false
-    },
-    {
-      username: '明天工作计划',
-      date: '下午 06:30',
-      complate: false
-    }
-  ])
-</script>
-
-<style lang="scss" scoped>
-  .card {
-    box-sizing: border-box;
-    width: 100%;
-    height: 510px;
-    padding: 0 25px;
-
-    .list {
-      height: calc(100% - 90px);
-      margin-top: 10px;
-      overflow: hidden;
-
-      > div {
-        position: relative;
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        height: 70px;
-        overflow: hidden;
-        border-bottom: 1px solid var(--art-border-color);
-
-        p {
-          font-size: 13px;
-        }
-
-        .title {
-          font-size: 14px;
-        }
-
-        .date {
-          margin-top: 6px;
-          font-size: 12px;
-          font-weight: 400;
-        }
-
-        .el-checkbox {
-          position: absolute;
-          top: 0;
-          right: 10px;
-          bottom: 0;
-          margin: auto;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 80
src/views/dashboard/ecommerce/index.vue

@@ -1,80 +0,0 @@
-<template>
-  <div class="ecommerce">
-    <el-row :gutter="20">
-      <el-col :sm="24" :md="24" :lg="16">
-        <Banner />
-      </el-col>
-      <el-col :sm="12" :md="12" :lg="4">
-        <TotalOrderVolume />
-      </el-col>
-      <el-col :sm="12" :md="12" :lg="4">
-        <TotalProducts />
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20">
-      <el-col :sm="12" :md="12" :lg="8">
-        <SalesTrend />
-      </el-col>
-      <el-col :sm="12" :md="12" :lg="8">
-        <SalesClassification />
-      </el-col>
-      <el-col :sm="24" :md="24" :lg="8">
-        <el-row :gutter="20">
-          <el-col :sm="24" :md="12" :lg="12">
-            <ProductSales />
-          </el-col>
-          <el-col :sm="24" :md="12" :lg="12">
-            <SalesGrowth />
-          </el-col>
-          <el-col :span="24" class="no-margin-bottom">
-            <CartConversionRate />
-          </el-col>
-        </el-row>
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20">
-      <el-col :sm="24" :md="12" :lg="8">
-        <HotCommodity />
-      </el-col>
-      <el-col :sm="24" :md="12" :lg="8">
-        <AnnualSales />
-      </el-col>
-      <el-col :sm="24" :md="24" :lg="8">
-        <TransactionList />
-      </el-col>
-    </el-row>
-
-    <el-row :gutter="20">
-      <el-col :md="24" :lg="8">
-        <RecentTransaction />
-      </el-col>
-      <el-col :md="24" :lg="16" class="no-margin-bottom">
-        <HotProductsList />
-      </el-col>
-    </el-row>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import Banner from './widget/Banner.vue'
-  import TotalOrderVolume from './widget/TotalOrderVolume.vue'
-  import TotalProducts from './widget/TotalProducts.vue'
-  import SalesTrend from './widget/SalesTrend.vue'
-  import SalesClassification from './widget/SalesClassification.vue'
-  import TransactionList from './widget/TransactionList.vue'
-  import HotCommodity from './widget/HotCommodity.vue'
-  import RecentTransaction from './widget/RecentTransaction.vue'
-  import AnnualSales from './widget/AnnualSales.vue'
-  import ProductSales from './widget/ProductSales.vue'
-  import SalesGrowth from './widget/SalesGrowth.vue'
-  import CartConversionRate from './widget/CartConversionRate.vue'
-  import HotProductsList from './widget/HotProductsList.vue'
-
-  defineOptions({ name: 'Ecommerce' })
-</script>
-
-<style lang="scss" scoped>
-  @use './style';
-</style>

+ 0 - 72
src/views/dashboard/ecommerce/style.scss

@@ -1,72 +0,0 @@
-.ecommerce {
-  :deep(.card) {
-    box-sizing: border-box;
-    padding: 20px;
-    background-color: var(--art-main-bg-color);
-    border-radius: var(--custom-radius);
-
-    .card-header {
-      padding-bottom: 15px;
-
-      .title {
-        font-size: 18px;
-        font-weight: 500;
-        color: var(--art-gray-900);
-
-        i {
-          margin-left: 10px;
-        }
-      }
-
-      .subtitle {
-        font-size: 14px;
-        color: var(--art-gray-500);
-      }
-    }
-  }
-
-  :deep(.icon-text-widget) {
-    display: flex;
-    justify-content: space-around;
-
-    .item {
-      display: flex;
-      align-items: center;
-
-      .icon {
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        width: 42px;
-        height: 42px;
-        margin-right: 10px;
-        line-height: 42px;
-        color: var(--main-color);
-        background-color: var(--el-color-primary-light-9);
-        border-radius: 8px;
-
-        i {
-          font-size: 20px;
-        }
-      }
-
-      .content {
-        p {
-          font-size: 18px;
-        }
-
-        span {
-          font-size: 14px;
-        }
-      }
-    }
-  }
-
-  .no-margin-bottom {
-    margin-bottom: 0 !important;
-  }
-
-  .el-col {
-    margin-bottom: 20px;
-  }
-}

+ 0 - 46
src/views/dashboard/ecommerce/widget/AnnualSales.vue

@@ -1,46 +0,0 @@
-<template>
-  <div class="card art-custom-card yearly-card">
-    <div class="card-header">
-      <p class="title">年度销售额</p>
-      <p class="subtitle">按季度统计</p>
-    </div>
-
-    <ArtBarChart :showAxisLabel="false" :showAxisLine="false" :showSplitLine="false" :data="[50, 80, 50, 90, 60, 70, 50]" barWidth="26px" height="calc(100% - 155px)" />
-    <div class="icon-text-widget">
-      <div class="item">
-        <div class="icon">
-          <i class="iconfont-sys">&#xe718;</i>
-        </div>
-        <div class="content">
-          <p>¥200,858</p>
-          <span>线上销售</span>
-        </div>
-      </div>
-      <div class="item">
-        <div class="icon">
-          <i class="iconfont-sys">&#xe70c;</i>
-        </div>
-        <div class="content">
-          <p>¥102,927</p>
-          <span>线下销售</span>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<style lang="scss" scoped>
-  .card {
-    height: 28.2rem;
-
-    .icon-text-widget {
-      margin-top: 2.5rem;
-    }
-  }
-
-  @media screen and (max-width: $device-phone) {
-    .card {
-      height: 20rem;
-    }
-  }
-</style>

+ 0 - 89
src/views/dashboard/ecommerce/widget/Banner.vue

@@ -1,89 +0,0 @@
-<template>
-  <ArtBasicBanner
-    class="banner"
-    height="13.3rem"
-    :title="`欢迎回来 ${userInfo.username}`"
-    backgroundColor="var(--el-color-primary-light-9)"
-    titleColor="var(--art-gray-900)"
-    :decoration="false"
-    :meteorConfig="{
-      enabled: true,
-      count: 10
-    }"
-    :buttonConfig="{
-      show: false,
-      text: ''
-    }"
-    :imageConfig="{
-      src: bannerCover,
-      width: '18rem',
-      bottom: '-7.5rem'
-    }"
-    @click="handleBannerClick"
-  >
-    <div class="banner-slot">
-      <div class="item">
-        <p class="title">
-          <ArtCountTo class="number box-title" :target="2340" :duration="1500" prefix="¥" separator="," />
-          <i class="iconfont-sys text-success">&#xe8d5;</i>
-        </p>
-        <p class="subtitle">今日销售额</p>
-      </div>
-      <div class="item">
-        <p class="title">
-          <ArtCountTo class="number box-title" :target="35" :duration="1500" suffix="%" />
-          <i class="iconfont-sys text-success">&#xe8d5;</i>
-        </p>
-        <p class="subtitle">较昨日</p>
-      </div>
-    </div>
-  </ArtBasicBanner>
-</template>
-
-<script setup lang="ts">
-  import bannerCover from '@imgs/login/lf_icon2.webp'
-  import { useUserStore } from '@/store/modules/user'
-  const userStore = useUserStore()
-
-  const userInfo = computed(() => userStore.getUserInfo)
-
-  const handleBannerClick = () => {}
-</script>
-
-<style lang="scss" scoped>
-  .banner {
-    justify-content: center;
-
-    .banner-slot {
-      display: flex;
-      margin-top: 24px;
-
-      .item {
-        margin-right: 30px;
-
-        &:first-of-type {
-          padding-right: 30px;
-          border-right: 1px solid var(--art-gray-300);
-        }
-
-        .title {
-          font-size: 30px;
-          color: var(--art-gray-900) !important;
-
-          i {
-            position: relative;
-            top: -10px;
-            margin-left: 10px;
-            font-size: 16px;
-          }
-        }
-
-        .subtitle {
-          margin-top: 4px;
-          font-size: 14px;
-          color: var(--art-gray-700) !important;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 3
src/views/dashboard/ecommerce/widget/CartConversionRate.vue

@@ -1,3 +0,0 @@
-<template>
-  <ArtLineChartCard class="margin-bottom-0" :value="2545" label="购物车转化率" :percentage="1.2" :height="13.5" :chartData="[120, 132, 101, 134, 90, 230, 210]" :showAreaColor="true" />
-</template>

+ 0 - 100
src/views/dashboard/ecommerce/widget/HotCommodity.vue

@@ -1,100 +0,0 @@
-<template>
-  <div class="card art-custom-card weekly-card" style="height: 28.2rem">
-    <div class="card-header">
-      <p class="title">热销商品</p>
-      <p class="subtitle">本周销售排行</p>
-    </div>
-    <ArtLineChart :showAxisLabel="false" :showAxisLine="false" :showSplitLine="false" :showAreaColor="true" :data="[8, 40, 82, 35, 90, 52, 35]" height="9rem" />
-    <div class="content">
-      <div class="item" v-for="item in weeklyList" :key="item.title">
-        <div class="icon" :class="item.color">
-          <i class="iconfont-sys">&#xe718;</i>
-        </div>
-        <div class="text">
-          <p class="title">{{ item.title }}</p>
-          <span class="subtitle">{{ item.subtitle }}</span>
-        </div>
-        <div class="value" :class="item.color">
-          <span>+{{ item.value }}</span>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  const weeklyList = [
-    {
-      icon: '&#xe718;',
-      title: '智能手表Pro',
-      subtitle: '电子产品',
-      value: '1,286件',
-      color: 'bg-primary'
-    },
-    {
-      icon: '&#xe70c;',
-      title: '时尚连衣裙',
-      subtitle: '女装服饰',
-      value: '892件',
-      color: 'bg-success'
-    },
-    {
-      icon: '&#xe813;',
-      title: '厨房小家电',
-      subtitle: '家居用品',
-      value: '756件',
-      color: 'bg-error'
-    }
-  ]
-</script>
-
-<style lang="scss" scoped>
-  .weekly-card {
-    .content {
-      margin-top: 40px;
-
-      .item {
-        display: flex;
-        align-items: center;
-        margin-top: 20px;
-
-        .icon {
-          width: 42px;
-          height: 42px;
-          line-height: 42px;
-          text-align: center;
-          background-color: var(--el-color-primary-light-9);
-          border-radius: 8px;
-
-          i {
-            font-size: 20px;
-          }
-        }
-
-        .text {
-          margin-left: 10px;
-
-          .title {
-            font-size: 14px;
-            font-weight: 500;
-            color: var(--art-gray-800);
-          }
-
-          .subtitle {
-            font-size: 14px;
-            color: var(--art-gray-600);
-          }
-        }
-
-        .value {
-          padding: 6px 12px;
-          margin-left: auto;
-          font-size: 14px;
-          text-align: center;
-          background-color: var(--el-color-primary-light-9);
-          border-radius: 4px;
-        }
-      }
-    }
-  }
-</style>

+ 0 - 219
src/views/dashboard/ecommerce/widget/HotProductsList.vue

@@ -1,219 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 27.8rem">
-    <div class="card-header">
-      <p class="title">热销产品</p>
-      <p class="subtitle">本月销售情况</p>
-    </div>
-    <div class="table">
-      <el-scrollbar style="height: 21.55rem">
-        <ArtTable :data="tableData" style="margin-top: 0 !important" :border="false" :stripe="false" :header-cell-style="{ background: 'transparent' }">
-          <template #default>
-            <el-table-column label="产品" prop="product" width="220px">
-              <template #default="scope">
-                <div style="display: flex; align-items: center">
-                  <img class="product-image" :src="scope.row.image" />
-                  <div class="product-info">
-                    <div class="product-name">{{ scope.row.name }}</div>
-                    <div class="product-category">{{ scope.row.category }}</div>
-                  </div>
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="价格" prop="price">
-              <template #default="scope">
-                <span class="price">¥{{ scope.row.price.toLocaleString() }}</span>
-              </template>
-            </el-table-column>
-            <el-table-column label="库存" prop="stock">
-              <template #default="scope">
-                <div class="stock-badge" :class="getStockClass(scope.row.stock)">
-                  {{ getStockStatus(scope.row.stock) }}
-                </div>
-              </template>
-            </el-table-column>
-            <el-table-column label="销量" prop="sales" />
-            <el-table-column label="销售趋势" width="240">
-              <template #default="scope">
-                <el-progress :percentage="scope.row.pro" :color="scope.row.color" :stroke-width="4" />
-              </template>
-            </el-table-column>
-          </template>
-        </ArtTable>
-      </el-scrollbar>
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { reactive, onMounted } from 'vue'
-
-  // 导入产品图片
-  import product1 from '@/assets/img/3d/icon1.webp'
-  import product2 from '@/assets/img/3d/icon2.webp'
-  import product3 from '@/assets/img/3d/icon3.webp'
-  import product4 from '@/assets/img/3d/icon4.webp'
-  import product5 from '@/assets/img/3d/icon5.webp'
-  import product6 from '@/assets/img/3d/icon6.webp'
-
-  const tableData = reactive([
-    {
-      name: '智能手表 Pro',
-      category: '电子设备',
-      price: 1299,
-      stock: 156,
-      sales: 423,
-      percentage: 75,
-      pro: 0,
-      color: 'rgb(var(--art-primary)) !important',
-      image: product1
-    },
-    {
-      name: '无线蓝牙耳机',
-      category: '音频设备',
-      price: 499,
-      stock: 89,
-      sales: 652,
-      percentage: 85,
-      pro: 0,
-      color: 'rgb(var(--art-success)) !important',
-      image: product2
-    },
-    {
-      name: '机械键盘',
-      category: '电脑配件',
-      price: 399,
-      stock: 12,
-      sales: 238,
-      percentage: 45,
-      pro: 0,
-      color: 'rgb(var(--art-warning)) !important',
-      image: product3
-    },
-    {
-      name: '超薄笔记本电脑',
-      category: '电子设备',
-      price: 5999,
-      stock: 0,
-      sales: 126,
-      percentage: 30,
-      pro: 0,
-      color: 'rgb(var(--art-error)) !important',
-      image: product4
-    },
-    {
-      name: '智能音箱',
-      category: '智能家居',
-      price: 799,
-      stock: 45,
-      sales: 321,
-      percentage: 60,
-      pro: 0,
-      color: 'rgb(var(--art-info)) !important',
-      image: product5
-    },
-    {
-      name: '游戏手柄',
-      category: '游戏配件',
-      price: 299,
-      stock: 78,
-      sales: 489,
-      percentage: 70,
-      pro: 0,
-      color: 'rgb(var(--art-secondary)) !important',
-      image: product6
-    }
-  ])
-
-  // 根据库存获取状态文本
-  const getStockStatus = (stock: number) => {
-    if (stock === 0) return '缺货'
-    if (stock < 20) return '低库存'
-    if (stock < 50) return '适中'
-    return '充足'
-  }
-
-  // 根据库存获取状态类名
-  const getStockClass = (stock: number) => {
-    if (stock === 0) return 'out-of-stock'
-    if (stock < 20) return 'low-stock'
-    if (stock < 50) return 'medium-stock'
-    return 'in-stock'
-  }
-
-  onMounted(() => {
-    addAnimation()
-  })
-
-  const addAnimation = () => {
-    setTimeout(() => {
-      for (let i = 0; i < tableData.length; i++) {
-        let item = tableData[i]
-        tableData[i].pro = item.percentage
-      }
-    }, 100)
-  }
-</script>
-
-<style lang="scss" scoped>
-  .table {
-    width: 100%;
-
-    .card-header {
-      padding-left: 25px !important;
-    }
-
-    .product-image {
-      width: 50px;
-      height: 50px;
-      object-fit: cover;
-      border-radius: 6px;
-    }
-
-    .product-info {
-      display: flex;
-      flex-direction: column;
-      margin-left: 12px;
-    }
-
-    .product-name {
-      font-weight: 500;
-    }
-
-    .product-category {
-      font-size: 12px;
-      color: #64748b;
-    }
-
-    .price {
-      font-weight: 600;
-    }
-
-    .stock-badge {
-      display: inline-block;
-      padding: 4px 8px;
-      font-size: 12px;
-      font-weight: 500;
-      border-radius: 4px;
-    }
-
-    .in-stock {
-      color: rgb(var(--art-success));
-      background-color: rgba(var(--art-success-rgb), 0.1);
-    }
-
-    .medium-stock {
-      color: rgb(var(--art-info));
-      background-color: rgba(var(--art-info-rgb), 0.1);
-    }
-
-    .low-stock {
-      color: rgb(var(--art-warning));
-      background-color: rgba(var(--art-warning-rgb), 0.1);
-    }
-
-    .out-of-stock {
-      color: rgb(var(--art-error));
-      background-color: rgba(var(--art-error-rgb), 0.1);
-    }
-  }
-</style>

+ 0 - 10
src/views/dashboard/ecommerce/widget/ProductSales.vue

@@ -1,10 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 11rem">
-    <div class="card-header">
-      <p class="title" style="font-size: 24px">14.5k<i class="iconfont-sys text-success">&#xe8d5;</i></p>
-      <p class="subtitle">销售量</p>
-    </div>
-
-    <ArtBarChart :showAxisLabel="false" :showAxisLine="false" :showSplitLine="false" :data="[50, 80, 50, 90, 60, 70, 50]" barWidth="16px" height="4rem" />
-  </div>
-</template>

+ 0 - 41
src/views/dashboard/ecommerce/widget/RecentTransaction.vue

@@ -1,41 +0,0 @@
-<template>
-  <ArtTimelineListCard :list="timelineData" title="最近交易" subtitle="今日订单动态" />
-</template>
-
-<script setup lang="ts">
-  const timelineData = [
-    {
-      time: '上午 09:30',
-      status: 'rgb(73, 190, 255)',
-      content: '收到订单 #38291 支付 ¥385.90'
-    },
-    {
-      time: '上午 10:00',
-      status: 'rgb(54, 158, 255)',
-      content: '新商品上架',
-      code: 'SKU-3467'
-    },
-    {
-      time: '上午 12:00',
-      status: 'rgb(103, 232, 207)',
-      content: '向供应商支付了 ¥6495.00'
-    },
-    {
-      time: '下午 14:30',
-      status: 'rgb(255, 193, 7)',
-      content: '促销活动开始',
-      code: 'PROMO-2023'
-    },
-    {
-      time: '下午 15:45',
-      status: 'rgb(255, 105, 105)',
-      content: '订单取消提醒',
-      code: 'ORD-9876'
-    },
-    {
-      time: '下午 17:00',
-      status: 'rgb(103, 232, 207)',
-      content: '完成日销售报表'
-    }
-  ]
-</script>

+ 0 - 41
src/views/dashboard/ecommerce/widget/SalesClassification.vue

@@ -1,41 +0,0 @@
-<template>
-  <div class="card art-custom-card sales-card" style="height: 26rem">
-    <div class="card-header">
-      <p class="title">销售分类</p>
-      <p class="subtitle">按产品类别</p>
-    </div>
-    <ArtRingChart
-      :data="[
-        { value: 30, name: '电子产品' },
-        { value: 55, name: '服装鞋包' },
-        { value: 36, name: '家居用品' }
-      ]"
-      :color="['#4C87F3', '#EDF2FF', '#8BD8FC']"
-      :radius="['70%', '80%']"
-      height="16.5rem"
-      :showLabel="false"
-      :borderRadius="0"
-      centerText="¥300,458"
-    />
-    <div class="icon-text-widget">
-      <div class="item">
-        <div class="icon">
-          <i class="iconfont-sys">&#xe718;</i>
-        </div>
-        <div class="content">
-          <p>¥500,458</p>
-          <span>总收入</span>
-        </div>
-      </div>
-      <div class="item">
-        <div class="icon">
-          <i class="iconfont-sys">&#xe70c;</i>
-        </div>
-        <div class="content">
-          <p>¥130,580</p>
-          <span>净利润</span>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>

+ 0 - 10
src/views/dashboard/ecommerce/widget/SalesGrowth.vue

@@ -1,10 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 11rem">
-    <div class="card-header">
-      <p class="title" style="font-size: 24px">12%<i class="iconfont-sys text-success">&#xe8d5;</i></p>
-      <p class="subtitle">增长</p>
-    </div>
-
-    <ArtLineChart :showAreaColor="true" :showAxisLabel="false" :showAxisLine="false" :showSplitLine="false" :data="[50, 85, 65, 95, 75, 130, 180]" barWidth="16px" height="4rem" />
-  </div>
-</template>

+ 0 - 9
src/views/dashboard/ecommerce/widget/SalesTrend.vue

@@ -1,9 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 26rem">
-    <div class="card-header">
-      <p class="title">销售趋势</p>
-      <p class="subtitle">月度销售对比</p>
-    </div>
-    <ArtDualBarCompareChart :positiveData="[50, 80, 120, 90, 60]" :negativeData="[30, 60, 90, 70, 40]" :xAxisData="['一月', '二月', '三月', '四月', '五月']" height="19rem" />
-  </div>
-</template>

+ 0 - 20
src/views/dashboard/ecommerce/widget/TotalOrderVolume.vue

@@ -1,20 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 13.3rem">
-    <div class="card-header">
-      <p class="title" style="font-size: 24px">205,216</p>
-      <p class="subtitle">总订单量</p>
-    </div>
-    <ArtRingChart
-      :data="[
-        { value: 30, name: '已完成' },
-        { value: 25, name: '处理中' },
-        { value: 45, name: '待发货' }
-      ]"
-      :color="['#4C87F3', '#93F1B4', '#8BD8FC']"
-      :radius="['56%', '76%']"
-      height="7rem"
-      :showLabel="false"
-      :borderRadius="0"
-    />
-  </div>
-</template>

+ 0 - 9
src/views/dashboard/ecommerce/widget/TotalProducts.vue

@@ -1,9 +0,0 @@
-<template>
-  <div class="card art-custom-card" style="height: 13.3rem">
-    <div class="card-header">
-      <p class="title" style="font-size: 24px">55,231</p>
-      <p class="subtitle">商品总数</p>
-    </div>
-    <ArtBarChart :showAxisLabel="false" :showAxisLine="false" :showSplitLine="false" :data="[50, 80, 40, 90, 60, 70]" height="7rem" barWidth="18px" />
-  </div>
-</template>

+ 0 - 45
src/views/dashboard/ecommerce/widget/TransactionList.vue

@@ -1,45 +0,0 @@
-<template>
-  <ArtDataListCard :maxCount="4" :list="dataList" title="最近活动" subtitle="订单处理状态" :showMoreButton="true" @more="handleMore" />
-</template>
-
-<script setup lang="ts">
-  const dataList = [
-    {
-      title: '新订单 #38291',
-      status: '待处理',
-      time: '5分钟',
-      class: 'bg-primary',
-      icon: '&#xe6f2;'
-    },
-    {
-      title: '退款申请 #12845',
-      status: '处理中',
-      time: '10分钟',
-      class: 'bg-secondary',
-      icon: '&#xe806;'
-    },
-    {
-      title: '客户投诉处理',
-      status: '待处理',
-      time: '15分钟',
-      class: 'bg-warning',
-      icon: '&#xe6fb;'
-    },
-    {
-      title: '库存不足提醒',
-      status: '紧急',
-      time: '20分钟',
-      class: 'bg-danger',
-      icon: '&#xe813;'
-    },
-    {
-      title: '订单 #29384 已发货',
-      status: '已完成',
-      time: '20分钟',
-      class: 'bg-success',
-      icon: '&#xe70c;'
-    }
-  ]
-
-  const handleMore = () => {}
-</script>

+ 0 - 124
src/views/examples/tabs/index.vue

@@ -1,124 +0,0 @@
-<template>
-  <div class="page-content">
-    <h3 class="page-title">标签页操作</h3>
-
-    <!-- 修改标签标题模块 -->
-    <ElCard class="module-card" header="修改标签标题" shadow="never">
-      <div style="display: flex; gap: 10px">
-        <ElInput v-model="newTabTitle" placeholder="请输入新的标签页标题" clearable style="width: 300px" />
-
-        <ElButton type="primary" @click="handleUpdateTabTitle" :disabled="!newTabTitle.trim()"> 修改 </ElButton>
-        <ElButton @click="handleResetTabTitle"> 重置 </ElButton>
-      </div>
-    </ElCard>
-
-    <!-- 获取标签页模块 -->
-    <ElCard class="module-card" header="获取标签页信息" shadow="never">
-      <div class="mb-4">
-        <p class="tab-info">当前标签页信息:{{ currentTab }}</p>
-      </div>
-      <ElRow :gutter="20">
-        <ElCol :span="24">
-          <ElButton type="success" plain @click="handleGetCurrentTabTitle(routePath)"> 获取当前标签页信息 </ElButton>
-        </ElCol>
-      </ElRow>
-    </ElCard>
-
-    <!-- 关闭标签页模块 -->
-    <ElCard class="module-card" header="关闭标签页" shadow="never">
-      <ElRow :gutter="20">
-        <ElCol :span="24">
-          <ElButton type="danger" plain @click="handleCloseTab(routePath)"> 关闭当前标签 </ElButton>
-          <ElButton type="warning" plain @click="handleCloseOthersTab(routePath)"> 关闭其他标签 </ElButton>
-          <ElButton type="danger" plain @click="handleCloseAllTab"> 关闭所有标签 </ElButton>
-        </ElCol>
-      </ElRow>
-    </ElCard>
-  </div>
-</template>
-
-<script setup lang="ts">
-  import { useWorktabStore } from '@/store/modules/worktab'
-  import { WorkTab } from '@/types'
-  import { ElMessage } from 'element-plus'
-  const worktabStore = useWorktabStore()
-  const currentTab = ref<WorkTab | null>(null)
-  const newTabTitle = ref('')
-  const routePath = '/examples/tabs'
-
-  /**
-   * 处理更新标签页标题
-   * 验证输入内容后调用store方法更新标题
-   */
-  const handleUpdateTabTitle = () => {
-    if (newTabTitle.value.trim()) {
-      worktabStore.updateTabTitle(routePath, newTabTitle.value.trim())
-    }
-  }
-
-  /**
-   * 处理重置标签页标题
-   * 将标题重置为默认值并清空输入框
-   */
-  const handleResetTabTitle = () => {
-    worktabStore.resetTabTitle(routePath)
-    newTabTitle.value = ''
-  }
-
-  /**
-   * 获取指定路径的标签页信息
-   * @param path - 标签页路径
-   */
-  const handleGetCurrentTabTitle = (path: string) => {
-    const tab = worktabStore.getTabTitle(path)
-    if (tab) {
-      currentTab.value = tab
-    } else {
-      ElMessage.warning('未找到标签信息')
-    }
-  }
-
-  /**
-   * 关闭指定路径的标签页
-   * @param path - 要关闭的标签页路径
-   */
-  const handleCloseTab = (path: string) => {
-    worktabStore.removeTab(path)
-  }
-
-  /**
-   * 关闭除指定路径外的其他所有标签页
-   * @param path - 要保留的标签页路径
-   */
-  const handleCloseOthersTab = (path: string) => {
-    worktabStore.removeOthers(path)
-  }
-
-  /**
-   * 关闭所有标签页
-   */
-  const handleCloseAllTab = () => {
-    worktabStore.removeAll()
-  }
-</script>
-
-<style lang="scss" scoped>
-  .page-content {
-    .page-title {
-      margin-bottom: 20px;
-      font-size: 20px;
-      font-weight: 400;
-      color: var(--el-text-color-primary);
-    }
-
-    .module-card {
-      margin-bottom: 30px;
-    }
-
-    .tab-info {
-      margin: 0 0 10px;
-      font-size: 14px;
-      color: var(--art-gray-600);
-    }
-  }
-</style>

+ 10 - 53
src/views/widgets/context-menu/index.vue

@@ -18,37 +18,16 @@
 
   // 右键菜单选项
   const menuItems = computed((): MenuItemType[] => [
-    {
-      key: 'copy',
-      label: '复制',
-      icon: '&#xe7b2;'
-    },
-    {
-      key: 'paste',
-      label: '粘贴',
-      icon: '&#xe70b;'
-    },
-    {
-      key: 'cut',
-      label: '剪切',
-      icon: '&#xe7b8;',
-      showLine: true
-    },
+    { key: 'copy', label: '复制', icon: '&#xe7b2;' },
+    { key: 'paste', label: '粘贴', icon: '&#xe70b;' },
+    { key: 'cut', label: '剪切', icon: '&#xe7b8;', showLine: true },
     {
       key: 'export',
       label: '导出选项',
       icon: '&#xe78b;',
       children: [
-        {
-          key: 'exportExcel',
-          label: '导出 Excel',
-          icon: '&#xe604;'
-        },
-        {
-          key: 'exportPdf',
-          label: '导出 PDF',
-          icon: '&#xe89e;'
-        }
+        { key: 'exportExcel', label: '导出 Excel', icon: '&#xe604;' },
+        { key: 'exportPdf', label: '导出 PDF', icon: '&#xe89e;' }
       ]
     },
     {
@@ -56,35 +35,13 @@
       label: '编辑选项',
       icon: '&#xe706;',
       children: [
-        {
-          key: 'rename',
-          label: '重命名',
-          icon: '&#xe607;'
-        },
-        {
-          key: 'duplicate',
-          label: '复制副本',
-          icon: '&#xe608;'
-        }
+        { key: 'rename', label: '重命名', icon: '&#xe607;' },
+        { key: 'duplicate', label: '复制副本', icon: '&#xe608;' }
       ]
     },
-    {
-      key: 'share',
-      label: '分享',
-      icon: '&#xe73b;',
-      showLine: true
-    },
-    {
-      key: 'delete',
-      label: '删除',
-      icon: '&#xe850;'
-    },
-    {
-      key: 'disabled',
-      label: '禁用选项',
-      icon: '&#xe619;',
-      disabled: true
-    }
+    { key: 'share', label: '分享', icon: '&#xe73b;', showLine: true },
+    { key: 'delete', label: '删除', icon: '&#xe850;' },
+    { key: 'disabled', label: '禁用选项', icon: '&#xe619;', disabled: true }
   ])
 
   const handleSelect = (item: MenuItemType) => {

+ 2 - 8
src/views/widgets/icon-list/index.vue

@@ -26,14 +26,8 @@
 
   const iconType = ref('unicode')
   const options = [
-    {
-      value: 'unicode',
-      label: 'Unicode'
-    },
-    {
-      value: 'fontClass',
-      label: 'Font class'
-    }
+    { value: 'unicode', label: 'Unicode' },
+    { value: 'fontClass', label: 'Font class' }
   ]
   const systemIconClasses = ref<IconfontType[]>([])