mirror of
				https://github.com/continew-org/continew-admin-ui.git
				synced 2025-11-04 10:57:08 +08:00 
			
		
		
		
	refactor: 重构工作台
This commit is contained in:
		@@ -1,5 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <a-layout class="layout layout-default">
 | 
					  <a-layout class="layout layout-default" :class="{ mobile: isMobile }">
 | 
				
			||||||
    <Asider></Asider>
 | 
					    <Asider></Asider>
 | 
				
			||||||
    <a-layout class="layout-default-right">
 | 
					    <a-layout class="layout-default-right">
 | 
				
			||||||
      <Header></Header>
 | 
					      <Header></Header>
 | 
				
			||||||
@@ -17,9 +17,11 @@ import Main from './components/Main.vue'
 | 
				
			|||||||
import Tabs from './components/Tabs/index.vue'
 | 
					import Tabs from './components/Tabs/index.vue'
 | 
				
			||||||
import GiFooter from '@/components/GiFooter/index.vue'
 | 
					import GiFooter from '@/components/GiFooter/index.vue'
 | 
				
			||||||
import { useAppStore } from '@/stores'
 | 
					import { useAppStore } from '@/stores'
 | 
				
			||||||
 | 
					import { useDevice } from '@/hooks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'LayoutDefault' })
 | 
					defineOptions({ name: 'LayoutDefault' })
 | 
				
			||||||
const appStore = useAppStore()
 | 
					const appStore = useAppStore()
 | 
				
			||||||
 | 
					const { isMobile } = useDevice()
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,219 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-spin :loading="loading" style="width: 100%">
 | 
					 | 
				
			||||||
    <a-card title="访问趋势" :bordered="false" class="gi_card_title">
 | 
					 | 
				
			||||||
      <template #extra>
 | 
					 | 
				
			||||||
        <a-radio-group v-model:model-value="dateRange" type="button" size="small" @change="onChange">
 | 
					 | 
				
			||||||
          <a-radio :value="7">近7天</a-radio>
 | 
					 | 
				
			||||||
          <a-radio :value="30">近30天</a-radio>
 | 
					 | 
				
			||||||
        </a-radio-group>
 | 
					 | 
				
			||||||
      </template>
 | 
					 | 
				
			||||||
      <VCharts :option="chartOption" autoresize :style="{ height: '326px' }"></VCharts>
 | 
					 | 
				
			||||||
    </a-card>
 | 
					 | 
				
			||||||
  </a-spin>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script lang="ts" setup>
 | 
					 | 
				
			||||||
import VCharts from 'vue-echarts'
 | 
					 | 
				
			||||||
import { graphic } from 'echarts'
 | 
					 | 
				
			||||||
import { type DashboardAccessTrendResp, getDashboardAccessTrend as getData } from '@/apis'
 | 
					 | 
				
			||||||
import { useChart } from '@/hooks'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 提示框
 | 
					 | 
				
			||||||
const tooltipItemsHtmlString = (items) => {
 | 
					 | 
				
			||||||
  return items
 | 
					 | 
				
			||||||
    .map(
 | 
					 | 
				
			||||||
      (el) => `<div class="content-panel">
 | 
					 | 
				
			||||||
        <p>
 | 
					 | 
				
			||||||
          <span style="background-color: ${el.color}" class="tooltip-item-icon"></span>
 | 
					 | 
				
			||||||
          <span>${el.seriesName}</span>
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
        <span class="tooltip-value">
 | 
					 | 
				
			||||||
        ${el.value}
 | 
					 | 
				
			||||||
        </span>
 | 
					 | 
				
			||||||
      </div>`
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    .join('')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const xData = ref<string[]>([])
 | 
					 | 
				
			||||||
const pvStatisticsData = ref<number[]>([])
 | 
					 | 
				
			||||||
const ipStatisticsData = ref<number[]>([])
 | 
					 | 
				
			||||||
const { chartOption } = useChart((isDark) => {
 | 
					 | 
				
			||||||
  return {
 | 
					 | 
				
			||||||
    grid: {
 | 
					 | 
				
			||||||
      left: '38',
 | 
					 | 
				
			||||||
      right: '0',
 | 
					 | 
				
			||||||
      top: '10',
 | 
					 | 
				
			||||||
      bottom: '50'
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    legend: {
 | 
					 | 
				
			||||||
      bottom: -3,
 | 
					 | 
				
			||||||
      icon: 'circle',
 | 
					 | 
				
			||||||
      textStyle: {
 | 
					 | 
				
			||||||
        color: '#4E5969'
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    xAxis: {
 | 
					 | 
				
			||||||
      type: 'category',
 | 
					 | 
				
			||||||
      offset: 2,
 | 
					 | 
				
			||||||
      data: xData.value,
 | 
					 | 
				
			||||||
      boundaryGap: false,
 | 
					 | 
				
			||||||
      axisLabel: {
 | 
					 | 
				
			||||||
        color: '#4E5969',
 | 
					 | 
				
			||||||
        formatter(value: number, idx: number) {
 | 
					 | 
				
			||||||
          if (idx === 0) return ''
 | 
					 | 
				
			||||||
          if (idx === xData.value.length - 1) return ''
 | 
					 | 
				
			||||||
          return `${value}`
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      axisLine: {
 | 
					 | 
				
			||||||
        show: false
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      axisTick: {
 | 
					 | 
				
			||||||
        show: false
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      splitLine: {
 | 
					 | 
				
			||||||
        show: true,
 | 
					 | 
				
			||||||
        interval: (idx: number) => {
 | 
					 | 
				
			||||||
          if (idx === 0) return false
 | 
					 | 
				
			||||||
          return idx !== xData.value.length - 1
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        lineStyle: {
 | 
					 | 
				
			||||||
          color: isDark ? '#3F3F3F' : '#E5E8EF'
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      axisPointer: {
 | 
					 | 
				
			||||||
        show: true,
 | 
					 | 
				
			||||||
        lineStyle: {
 | 
					 | 
				
			||||||
          color: '#23ADFF',
 | 
					 | 
				
			||||||
          width: 2
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    yAxis: {
 | 
					 | 
				
			||||||
      type: 'value',
 | 
					 | 
				
			||||||
      axisLabel: {
 | 
					 | 
				
			||||||
        formatter(value: any, idx: number) {
 | 
					 | 
				
			||||||
          if (idx === 0) return value
 | 
					 | 
				
			||||||
          if (value >= 1000) {
 | 
					 | 
				
			||||||
            return `${value / 1000}k`
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
          return `${value}`
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      axisLine: {
 | 
					 | 
				
			||||||
        show: false
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      splitLine: {
 | 
					 | 
				
			||||||
        lineStyle: {
 | 
					 | 
				
			||||||
          type: 'dashed',
 | 
					 | 
				
			||||||
          color: isDark ? '#3F3F3F' : '#E5E8EF'
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    tooltip: {
 | 
					 | 
				
			||||||
      show: true,
 | 
					 | 
				
			||||||
      trigger: 'axis',
 | 
					 | 
				
			||||||
      formatter(params) {
 | 
					 | 
				
			||||||
        const [firstElement] = params
 | 
					 | 
				
			||||||
        return `<div>
 | 
					 | 
				
			||||||
            <p class="tooltip-title">${firstElement.axisValueLabel}</p>
 | 
					 | 
				
			||||||
            ${tooltipItemsHtmlString(params)}
 | 
					 | 
				
			||||||
          </div>`
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      className: 'echarts-tooltip-diy'
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    series: [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        name: '浏览量(PV)',
 | 
					 | 
				
			||||||
        data: pvStatisticsData.value,
 | 
					 | 
				
			||||||
        type: 'line',
 | 
					 | 
				
			||||||
        smooth: true,
 | 
					 | 
				
			||||||
        showSymbol: false,
 | 
					 | 
				
			||||||
        color: '#246EFF',
 | 
					 | 
				
			||||||
        symbol: 'circle',
 | 
					 | 
				
			||||||
        symbolSize: 10,
 | 
					 | 
				
			||||||
        emphasis: {
 | 
					 | 
				
			||||||
          focus: 'series',
 | 
					 | 
				
			||||||
          itemStyle: {
 | 
					 | 
				
			||||||
            borderWidth: 2,
 | 
					 | 
				
			||||||
            borderColor: '#E0E3FF'
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        areaStyle: {
 | 
					 | 
				
			||||||
          opacity: 0.8,
 | 
					 | 
				
			||||||
          color: new graphic.LinearGradient(0, 0, 0, 1, [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              offset: 0,
 | 
					 | 
				
			||||||
              color: 'rgba(17, 126, 255, 0.16)'
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              offset: 1,
 | 
					 | 
				
			||||||
              color: 'rgba(17, 128, 255, 0)'
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        name: 'IP数',
 | 
					 | 
				
			||||||
        data: ipStatisticsData.value,
 | 
					 | 
				
			||||||
        type: 'line',
 | 
					 | 
				
			||||||
        smooth: true,
 | 
					 | 
				
			||||||
        showSymbol: false,
 | 
					 | 
				
			||||||
        color: '#00B2FF',
 | 
					 | 
				
			||||||
        symbol: 'circle',
 | 
					 | 
				
			||||||
        symbolSize: 10,
 | 
					 | 
				
			||||||
        emphasis: {
 | 
					 | 
				
			||||||
          focus: 'series',
 | 
					 | 
				
			||||||
          itemStyle: {
 | 
					 | 
				
			||||||
            borderWidth: 2,
 | 
					 | 
				
			||||||
            borderColor: '#E2F2FF'
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        areaStyle: {
 | 
					 | 
				
			||||||
          opacity: 0.8,
 | 
					 | 
				
			||||||
          color: new graphic.LinearGradient(0, 0, 0, 1, [
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              offset: 0,
 | 
					 | 
				
			||||||
              color: 'rgba(17, 126, 255, 0.16)'
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
              offset: 1,
 | 
					 | 
				
			||||||
              color: 'rgba(17, 128, 255, 0)'
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          ])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const loading = ref(false)
 | 
					 | 
				
			||||||
const dateRange = ref(30)
 | 
					 | 
				
			||||||
// 查询图表数据
 | 
					 | 
				
			||||||
const getChartData = async (days: number) => {
 | 
					 | 
				
			||||||
  try {
 | 
					 | 
				
			||||||
    loading.value = true
 | 
					 | 
				
			||||||
    xData.value = []
 | 
					 | 
				
			||||||
    pvStatisticsData.value = []
 | 
					 | 
				
			||||||
    ipStatisticsData.value = []
 | 
					 | 
				
			||||||
    const { data } = await getData(days)
 | 
					 | 
				
			||||||
    data.forEach((el: DashboardAccessTrendResp) => {
 | 
					 | 
				
			||||||
      xData.value.push(el.date)
 | 
					 | 
				
			||||||
      pvStatisticsData.value.push(el.pvCount)
 | 
					 | 
				
			||||||
      ipStatisticsData.value.push(el.ipCount)
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  } finally {
 | 
					 | 
				
			||||||
    loading.value = false
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 切换
 | 
					 | 
				
			||||||
const onChange = (days: number) => {
 | 
					 | 
				
			||||||
  getChartData(days)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
onMounted(() => {
 | 
					 | 
				
			||||||
  getChartData(30)
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
							
								
								
									
										33
									
								
								src/views/dashboard/workplace/components/Carousel.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/views/dashboard/workplace/components/Carousel.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-carousel
 | 
				
			||||||
 | 
					    indicator-type="slider"
 | 
				
			||||||
 | 
					    show-arrow="hover"
 | 
				
			||||||
 | 
					    auto-play
 | 
				
			||||||
 | 
					    style="width: 100%; height: 150px; border-radius: 4px; overflow: hidden"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <a-carousel-item v-for="(image, idx) in images" :key="idx">
 | 
				
			||||||
 | 
					      <div>
 | 
				
			||||||
 | 
					        <a-link
 | 
				
			||||||
 | 
					          :href="image.url"
 | 
				
			||||||
 | 
					          target="_blank"
 | 
				
			||||||
 | 
					          rel="noopener"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <img :src="`${image.src}?${new Date().getTime()}`" style="width: 100%" alt="" />
 | 
				
			||||||
 | 
					        </a-link>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </a-carousel-item>
 | 
				
			||||||
 | 
					  </a-carousel>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					const images = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    src: 'https://continew.top/qrcode-text.png',
 | 
				
			||||||
 | 
					    url: 'https://continew.top/about/intro.html'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    src: 'https://continew.top/sponsor.png',
 | 
				
			||||||
 | 
					    url: 'https://continew.top/sponsor.html'
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/views/dashboard/workplace/components/Docs.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/views/dashboard/workplace/components/Docs.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-card
 | 
				
			||||||
 | 
					    class="general-card"
 | 
				
			||||||
 | 
					    title="帮助文档"
 | 
				
			||||||
 | 
					    :header-style="{ paddingBottom: 0 }"
 | 
				
			||||||
 | 
					    :body-style="{ paddingTop: '5px' }"
 | 
				
			||||||
 | 
					    style="height: 166px"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <template #extra>
 | 
				
			||||||
 | 
					      <a-link href="https://continew.top" target="_blank" rel="noopener">更多</a-link>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <a-row>
 | 
				
			||||||
 | 
					      <a-col v-for="link in links" :key="link.text" :span="12">
 | 
				
			||||||
 | 
					        <a-link
 | 
				
			||||||
 | 
					          :href="link.url"
 | 
				
			||||||
 | 
					          target="_blank"
 | 
				
			||||||
 | 
					          rel="noopener"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          {{ link.text }}
 | 
				
			||||||
 | 
					        </a-link>
 | 
				
			||||||
 | 
					      </a-col>
 | 
				
			||||||
 | 
					    </a-row>
 | 
				
			||||||
 | 
					  </a-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					const links = [
 | 
				
			||||||
 | 
					  { text: '项目简介', url: 'https://continew.top/admin/intro/what-is.html' },
 | 
				
			||||||
 | 
					  { text: '快速开始', url: 'https://continew.top/admin/intro/quick-start.html' },
 | 
				
			||||||
 | 
					  { text: '常见问题', url: 'https://continew.top/faq.html' },
 | 
				
			||||||
 | 
					  { text: '更新日志', url: 'https://continew.top/admin/other/changelog.html' },
 | 
				
			||||||
 | 
					  { text: '贡献指南', url: 'https://continew.top/admin/other/contributing.html' },
 | 
				
			||||||
 | 
					  { text: '赞助支持 💖', url: 'https://continew.top/sponsor.html' }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="less" scoped>
 | 
				
			||||||
 | 
					.arco-card-body .arco-link {
 | 
				
			||||||
 | 
					  margin: 5px 0;
 | 
				
			||||||
 | 
					  color: rgb(var(--gray-8));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -1,77 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="快捷操作" :bordered="false" size="medium" class="card gi_card_title">
 | 
					 | 
				
			||||||
    <a-card-grid v-for="(item, index) in list" :key="item.name" class="card-grid-item" :style="{ width: '33.33%' }">
 | 
					 | 
				
			||||||
      <a-card :bordered="false" hoverable>
 | 
					 | 
				
			||||||
        <a-row justify="center" align="center" :class="`animated-fade-up-${index + 1}`">
 | 
					 | 
				
			||||||
          <a-space direction="vertical" align="center" class="wrapper" @click="router.replace({ path: item.path })">
 | 
					 | 
				
			||||||
            <component :is="item.icon" :size="30" class="icon"></component>
 | 
					 | 
				
			||||||
            <a-typography-text class="text">{{ item.name }}</a-typography-text>
 | 
					 | 
				
			||||||
          </a-space>
 | 
					 | 
				
			||||||
        </a-row>
 | 
					 | 
				
			||||||
      </a-card>
 | 
					 | 
				
			||||||
    </a-card-grid>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
const router = useRouter()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const list = [
 | 
					 | 
				
			||||||
  { name: '用户管理', icon: 'icon-user', path: '/system/user' },
 | 
					 | 
				
			||||||
  { name: '角色管理', icon: 'icon-user-group', path: '/system/role' },
 | 
					 | 
				
			||||||
  { name: '菜单管理', icon: 'icon-menu', path: '/system/menu' },
 | 
					 | 
				
			||||||
  { name: '文件管理', icon: 'icon-file', path: '/system/file' },
 | 
					 | 
				
			||||||
  { name: '系统配置', icon: 'icon-desktop', path: '/system/config' },
 | 
					 | 
				
			||||||
  { name: '系统日志', icon: 'icon-history', path: '/monitor/log' }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
.card {
 | 
					 | 
				
			||||||
  overflow: hidden;
 | 
					 | 
				
			||||||
  :deep(.arco-card-header) {
 | 
					 | 
				
			||||||
    border: none;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  .card-grid-item {
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  :deep(.text) {
 | 
					 | 
				
			||||||
    font-size: 12px;
 | 
					 | 
				
			||||||
    text-align: center;
 | 
					 | 
				
			||||||
    color: rgb(var(--gray-8));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  :deep(.wrapper) {
 | 
					 | 
				
			||||||
    margin-bottom: 8px;
 | 
					 | 
				
			||||||
    text-align: center;
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    &:last-child {
 | 
					 | 
				
			||||||
      .text {
 | 
					 | 
				
			||||||
        margin-bottom: 0;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    &:hover {
 | 
					 | 
				
			||||||
      .icon {
 | 
					 | 
				
			||||||
        color: rgb(var(--arcoblue-6));
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      .text {
 | 
					 | 
				
			||||||
        color: rgb(var(--arcoblue-6));
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  :deep(.icon) {
 | 
					 | 
				
			||||||
    display: inline-block;
 | 
					 | 
				
			||||||
    width: 32px;
 | 
					 | 
				
			||||||
    height: 32px;
 | 
					 | 
				
			||||||
    margin-bottom: 4px;
 | 
					 | 
				
			||||||
    color: rgb(var(--gray-8));
 | 
					 | 
				
			||||||
    line-height: 32px;
 | 
					 | 
				
			||||||
    font-size: 16px;
 | 
					 | 
				
			||||||
    text-align: center;
 | 
					 | 
				
			||||||
    border-radius: 4px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,54 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="公告" :bordered="false" size="medium" class="gi_card_title">
 | 
					 | 
				
			||||||
    <template #extra>
 | 
					 | 
				
			||||||
      <a-link>更多</a-link>
 | 
					 | 
				
			||||||
    </template>
 | 
					 | 
				
			||||||
    <a-comment
 | 
					 | 
				
			||||||
      v-for="(item, index) in list"
 | 
					 | 
				
			||||||
      :key="index"
 | 
					 | 
				
			||||||
      align="right"
 | 
					 | 
				
			||||||
      :class="`animated-fade-up-${index}`"
 | 
					 | 
				
			||||||
      style="overflow: hidden"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <template #content>
 | 
					 | 
				
			||||||
        <div class="content">
 | 
					 | 
				
			||||||
          <a-tag v-if="item.type === 1" color="blue" size="small">通知</a-tag>
 | 
					 | 
				
			||||||
          <a-tag v-if="item.type === 2" color="orangered" size="small">活动</a-tag>
 | 
					 | 
				
			||||||
          <a-tag v-if="item.type === 3" color="cyan" size="small">消息</a-tag>
 | 
					 | 
				
			||||||
          <p>{{ item.content }}</p>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      </template>
 | 
					 | 
				
			||||||
    </a-comment>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
const list = [
 | 
					 | 
				
			||||||
  { type: 1, content: 'v2.4.0 版本发布公告🎉' },
 | 
					 | 
				
			||||||
  { type: 1, content: 'v2.3.0 版本发布公告🎉' },
 | 
					 | 
				
			||||||
  { type: 1, content: 'v2.2.0 版本发布公告🎉' },
 | 
					 | 
				
			||||||
  { type: 2, content: '作者喊你来贡献代码了~' },
 | 
					 | 
				
			||||||
  { type: 2, content: '作者喊你来提需求了~' }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
:deep(.arco-comment:not(:first-of-type), .arco-comment-inner-comment) {
 | 
					 | 
				
			||||||
  margin-top: 10px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
:deep(.arco-comment-content) {
 | 
					 | 
				
			||||||
  font-size: 14px;
 | 
					 | 
				
			||||||
  color: var(--color-text-1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
:deep(.arco-comment-datetime) {
 | 
					 | 
				
			||||||
  color: var(--color-text-4);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.content {
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  align-items: center;
 | 
					 | 
				
			||||||
  > p {
 | 
					 | 
				
			||||||
    margin-left: 6px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
							
								
								
									
										89
									
								
								src/views/dashboard/workplace/components/Notice.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/views/dashboard/workplace/components/Notice.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-card
 | 
				
			||||||
 | 
					    class="general-card"
 | 
				
			||||||
 | 
					    title="公告"
 | 
				
			||||||
 | 
					    :header-style="{ paddingBottom: '0' }"
 | 
				
			||||||
 | 
					    :body-style="{ padding: '15px 20px 13px 20px' }"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <template #extra>
 | 
				
			||||||
 | 
					      <a-link @click="router.replace({ path: '/system/notice' })">更多</a-link>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <a-skeleton v-if="loading" :loading="loading" :animation="true">
 | 
				
			||||||
 | 
					      <a-skeleton-line :rows="5" />
 | 
				
			||||||
 | 
					    </a-skeleton>
 | 
				
			||||||
 | 
					    <div v-else>
 | 
				
			||||||
 | 
					      <a-empty v-if="dataList.length === 0">暂无公告</a-empty>
 | 
				
			||||||
 | 
					      <div v-else>
 | 
				
			||||||
 | 
					        <div v-for="(item, idx) in dataList" :key="idx" class="item">
 | 
				
			||||||
 | 
					          <GiCellTag :value="item.type" :dict="notice_type" />
 | 
				
			||||||
 | 
					          <a-link class="item-content" @click="onDetail(item.id)">
 | 
				
			||||||
 | 
					            <a-typography-paragraph
 | 
				
			||||||
 | 
					              :ellipsis="{
 | 
				
			||||||
 | 
					                rows: 1,
 | 
				
			||||||
 | 
					                showTooltip: true,
 | 
				
			||||||
 | 
					                css: true,
 | 
				
			||||||
 | 
					              }"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					            {{ item.title }}
 | 
				
			||||||
 | 
					            </a-typography-paragraph>
 | 
				
			||||||
 | 
					          </a-link>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </a-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <NoticeDetailModal ref="NoticeDetailModalRef" />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import { type DashboardNoticeResp, listDashboardNotice } from '@/apis'
 | 
				
			||||||
 | 
					import { useDict } from '@/hooks/app'
 | 
				
			||||||
 | 
					import NoticeDetailModal from '@/views/system/notice/NoticeDetailModal.vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = useRouter()
 | 
				
			||||||
 | 
					const { notice_type } = useDict('notice_type')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const dataList = ref<DashboardNoticeResp[]>([])
 | 
				
			||||||
 | 
					const loading = ref(false)
 | 
				
			||||||
 | 
					// 查询列表数据
 | 
				
			||||||
 | 
					const getDataList = async () => {
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    loading.value = true
 | 
				
			||||||
 | 
					    const res = await listDashboardNotice()
 | 
				
			||||||
 | 
					    dataList.value = res.data
 | 
				
			||||||
 | 
					  } finally {
 | 
				
			||||||
 | 
					    loading.value = false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const NoticeDetailModalRef = ref<InstanceType<typeof NoticeDetailModal>>()
 | 
				
			||||||
 | 
					// 详情
 | 
				
			||||||
 | 
					const onDetail = (id: string) => {
 | 
				
			||||||
 | 
					  NoticeDetailModalRef.value?.onDetail(id)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  getDataList()
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped lang="less">
 | 
				
			||||||
 | 
					.item {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  height: 24px;
 | 
				
			||||||
 | 
					  margin-bottom: 4px;
 | 
				
			||||||
 | 
					  .item-content {
 | 
				
			||||||
 | 
					    flex: 1;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    text-overflow: ellipsis;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					    margin-left: 4px;
 | 
				
			||||||
 | 
					    color: var(--color-text-2);
 | 
				
			||||||
 | 
					    text-decoration: none;
 | 
				
			||||||
 | 
					    font-size: 13px;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -1,84 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="公告" :bordered="false" class="gi_card_title">
 | 
					 | 
				
			||||||
    <template #extra>
 | 
					 | 
				
			||||||
      <a-link href="/system/notice">更多</a-link>
 | 
					 | 
				
			||||||
    </template>
 | 
					 | 
				
			||||||
    <a-empty v-if="dataList.length === 0">暂无公告</a-empty>
 | 
					 | 
				
			||||||
    <a-comment
 | 
					 | 
				
			||||||
      v-for="(item, index) in dataList"
 | 
					 | 
				
			||||||
      :key="index"
 | 
					 | 
				
			||||||
      align="right"
 | 
					 | 
				
			||||||
      :class="`animated-fade-up-${index}`"
 | 
					 | 
				
			||||||
      style="overflow: hidden"
 | 
					 | 
				
			||||||
    >
 | 
					 | 
				
			||||||
      <template #content>
 | 
					 | 
				
			||||||
        <a-space>
 | 
					 | 
				
			||||||
          <GiCellTag :value="item.type" :dict="notice_type" />
 | 
					 | 
				
			||||||
          <a-link @click="onDetail(item.id)">
 | 
					 | 
				
			||||||
            <a-typography-paragraph
 | 
					 | 
				
			||||||
              :ellipsis="{
 | 
					 | 
				
			||||||
                rows: 1,
 | 
					 | 
				
			||||||
                showTooltip: true,
 | 
					 | 
				
			||||||
                css: true,
 | 
					 | 
				
			||||||
              }"
 | 
					 | 
				
			||||||
            >
 | 
					 | 
				
			||||||
              {{ item.title }}
 | 
					 | 
				
			||||||
            </a-typography-paragraph>
 | 
					 | 
				
			||||||
          </a-link>
 | 
					 | 
				
			||||||
        </a-space>
 | 
					 | 
				
			||||||
      </template>
 | 
					 | 
				
			||||||
    </a-comment>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <NoticeDetailModal ref="NoticeDetailModalRef" />
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
import { type DashboardNoticeResp, listDashboardNotice } from '@/apis'
 | 
					 | 
				
			||||||
import { useDict } from '@/hooks/app'
 | 
					 | 
				
			||||||
import NoticeDetailModal from '@/views/system/notice/NoticeDetailModal.vue'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { notice_type } = useDict('notice_type')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const dataList = ref<DashboardNoticeResp[]>([])
 | 
					 | 
				
			||||||
// 查询列表数据
 | 
					 | 
				
			||||||
const getDataList = async () => {
 | 
					 | 
				
			||||||
  const res = await listDashboardNotice()
 | 
					 | 
				
			||||||
  dataList.value = res.data
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const NoticeDetailModalRef = ref<InstanceType<typeof NoticeDetailModal>>()
 | 
					 | 
				
			||||||
// 详情
 | 
					 | 
				
			||||||
const onDetail = (id: string) => {
 | 
					 | 
				
			||||||
  NoticeDetailModalRef.value?.onDetail(id)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
onMounted(() => {
 | 
					 | 
				
			||||||
  getDataList()
 | 
					 | 
				
			||||||
})
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
:deep(.arco-comment:not(:first-of-type), .arco-comment-inner-comment) {
 | 
					 | 
				
			||||||
  margin-top: 10px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
:deep(.arco-comment-content) {
 | 
					 | 
				
			||||||
  font-size: 14px;
 | 
					 | 
				
			||||||
  color: var(--color-text-1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
:deep(.arco-comment-datetime) {
 | 
					 | 
				
			||||||
  color: var(--color-text-4);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.arco-link {
 | 
					 | 
				
			||||||
  color: rgb(var(--gray-8));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.icon {
 | 
					 | 
				
			||||||
  margin-right: 3px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.update-time-row {
 | 
					 | 
				
			||||||
  text-align: right;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,42 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <div v-if="time" class="now-time">
 | 
					 | 
				
			||||||
    <p class="now-time__time gi_line_1">{{ time }}</p>
 | 
					 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
import Dayjs from 'dayjs'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
defineOptions({ name: 'NowTime' })
 | 
					 | 
				
			||||||
const time = ref('')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 获取现在时间
 | 
					 | 
				
			||||||
const getFormatNowTime = () => {
 | 
					 | 
				
			||||||
  const weekList = ['日', '一', '二', '三', '四', '五', '六']
 | 
					 | 
				
			||||||
  return `${Dayjs(new Date()).format('YYYY年MM月DD日 HH:mm:ss')} 星期${weekList[Dayjs(new Date()).day()]}`
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 初始化时间
 | 
					 | 
				
			||||||
const initTime = () => {
 | 
					 | 
				
			||||||
  time.value = getFormatNowTime()
 | 
					 | 
				
			||||||
  setInterval(() => {
 | 
					 | 
				
			||||||
    time.value = getFormatNowTime()
 | 
					 | 
				
			||||||
  }, 1000)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
initTime()
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
@import url('@/assets/fonts/font.css');
 | 
					 | 
				
			||||||
.now-time {
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  align-items: center;
 | 
					 | 
				
			||||||
  font-size: 14px;
 | 
					 | 
				
			||||||
  font-family: DINPro-Medium;
 | 
					 | 
				
			||||||
  color: var(--color-text-1);
 | 
					 | 
				
			||||||
  &__time {
 | 
					 | 
				
			||||||
    margin-left: 6px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
							
								
								
									
										157
									
								
								src/views/dashboard/workplace/components/Project.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/views/dashboard/workplace/components/Project.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,157 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-card class="general-card" title="我的项目">
 | 
				
			||||||
 | 
					    <template #extra>
 | 
				
			||||||
 | 
					      <a-link href="https://github.com/charles7c" target="_blank" rel="noopener">更多</a-link>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					    <a-row :gutter="16">
 | 
				
			||||||
 | 
					      <a-col
 | 
				
			||||||
 | 
					        v-for="(item, index) in list"
 | 
				
			||||||
 | 
					        :key="index"
 | 
				
			||||||
 | 
					        :xs="12"
 | 
				
			||||||
 | 
					        :sm="12"
 | 
				
			||||||
 | 
					        :md="12"
 | 
				
			||||||
 | 
					        :lg="12"
 | 
				
			||||||
 | 
					        :xl="8"
 | 
				
			||||||
 | 
					        :xxl="8"
 | 
				
			||||||
 | 
					        class="my-project-item"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <a-card style="min-height: 204px" :bordered="true" hoverable>
 | 
				
			||||||
 | 
					          <div class="badge badge-right" :style="`background-color: ${item.statusColor}`">{{ item.status }}</div>
 | 
				
			||||||
 | 
					          <a :href="item.url" target="_blank">
 | 
				
			||||||
 | 
					            <a-space direction="vertical">
 | 
				
			||||||
 | 
					              <a-space>
 | 
				
			||||||
 | 
					                <img :src="item.logo" width="30px" alt="logo" />
 | 
				
			||||||
 | 
					                <a-typography-text bold>{{ item.name }}</a-typography-text>
 | 
				
			||||||
 | 
					              </a-space>
 | 
				
			||||||
 | 
					              <a-typography-paragraph
 | 
				
			||||||
 | 
					                :ellipsis="{
 | 
				
			||||||
 | 
					                  rows: 6,
 | 
				
			||||||
 | 
					                  showTooltip: true,
 | 
				
			||||||
 | 
					                  css: true,
 | 
				
			||||||
 | 
					                }"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <a-typography-text type="secondary">
 | 
				
			||||||
 | 
					                  {{ item.desc }}
 | 
				
			||||||
 | 
					                </a-typography-text>
 | 
				
			||||||
 | 
					              </a-typography-paragraph>
 | 
				
			||||||
 | 
					            </a-space>
 | 
				
			||||||
 | 
					          </a>
 | 
				
			||||||
 | 
					        </a-card>
 | 
				
			||||||
 | 
					      </a-col>
 | 
				
			||||||
 | 
					    </a-row>
 | 
				
			||||||
 | 
					  </a-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					const list = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'ContiNew Admin',
 | 
				
			||||||
 | 
					    desc: '🔥Almost最佳后端规范🔥持续迭代优化的前后端分离中后台管理系统框架,开箱即用,持续提供舒适的开发体验。当前采用技术栈:Spring Boot3(Java17)、Vue3 & Arco Design、TS、Vite5 、Sa-Token、MyBatisPlus、Redisson、JetCache、Jackson、SpringDoc、Crane4j、Liquibase、Hutool 等。',
 | 
				
			||||||
 | 
					    logo: 'https://continew.top/logo.svg',
 | 
				
			||||||
 | 
					    url: 'https://gitee.com/continew/continew-admin',
 | 
				
			||||||
 | 
					    status: '迭代',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--primary-6))'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'ContiNew Starter',
 | 
				
			||||||
 | 
					    desc: '🔥高质量Starter🔥包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken),可轻松集成到应用中,为开发人员减少手动引入依赖及配置的麻烦,为 Spring Boot Web 项目的灵活快速构建提供支持。',
 | 
				
			||||||
 | 
					    logo: 'https://continew.top/logo.svg',
 | 
				
			||||||
 | 
					    url: 'https://gitee.com/continew/continew-starter',
 | 
				
			||||||
 | 
					    status: '迭代',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--primary-6))'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'ContiNew Admin UI',
 | 
				
			||||||
 | 
					    desc: '全新 3.x 版本,基于 Gi Demo 前端模板开发的 ContiNew Admin 前端适配项目。',
 | 
				
			||||||
 | 
					    logo: 'https://continew.top/logo.svg',
 | 
				
			||||||
 | 
					    url: 'https://gitee.com/continew/continew-admin-ui',
 | 
				
			||||||
 | 
					    status: '迭代',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--primary-6))'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'ContiNew Admin UI Arco',
 | 
				
			||||||
 | 
					    desc: '2.5 版本,基于 Arco Design Pro 前端模板开发的 ContiNew Admin 前端适配项目。',
 | 
				
			||||||
 | 
					    logo: 'https://continew.top/logo.svg',
 | 
				
			||||||
 | 
					    url: 'https://gitee.com/continew/continew-admin-ui-arco',
 | 
				
			||||||
 | 
					    status: '归档',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--warning-6))'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'ContiNew Cloud',
 | 
				
			||||||
 | 
					    desc: 'ContiNew Admin 微服务版本。',
 | 
				
			||||||
 | 
					    logo: 'https://continew.top/logo.svg',
 | 
				
			||||||
 | 
					    url: '#',
 | 
				
			||||||
 | 
					    status: '孵化',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--danger-6))'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    name: 'charles7c.github.io',
 | 
				
			||||||
 | 
					    desc: '基于 VitePress 构建的个人知识库/博客。扩展 VitePress 默认主题:增加ICP备案号、公安备案号显示,增加文章元数据信息(原创标识、作者、发布时间、分类、标签)显示,增加文末版权声明,增加 Gitalk 评论功能,主页美化、自动生成侧边栏、文章内支持 Mermaid 流程图、MD公式、MD脚注、增加我的标签、我的归档等独立页面,以及浏览器滚条等细节优化。查尔斯的个人技术知识库,记录 & 分享个人碎片化、结构化、体系化的技术知识内容。',
 | 
				
			||||||
 | 
					    logo: 'https://blog.charles7c.top/logo.png',
 | 
				
			||||||
 | 
					    url: 'https://github.com/Charles7c/charles7c.github.io',
 | 
				
			||||||
 | 
					    status: '归档',
 | 
				
			||||||
 | 
					    statusColor: 'rgb(var(--warning-6))'
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped lang="less">
 | 
				
			||||||
 | 
					:deep(.arco-card-body) {
 | 
				
			||||||
 | 
					  min-height: 128px;
 | 
				
			||||||
 | 
					  overflow: hidden;
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  .badge {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    font-size: 12px;
 | 
				
			||||||
 | 
					    height: 18px;
 | 
				
			||||||
 | 
					    line-height: 18px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    width: 74px;
 | 
				
			||||||
 | 
					    color: #fff;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .badge-left {
 | 
				
			||||||
 | 
					    -moz-transform: rotate(-45deg);
 | 
				
			||||||
 | 
					    -ms-transform: rotate(-45deg);
 | 
				
			||||||
 | 
					    -o-transform: rotate(-45deg);
 | 
				
			||||||
 | 
					    -webkit-transform: rotate(-45deg);
 | 
				
			||||||
 | 
					    transform: rotate(-45deg);
 | 
				
			||||||
 | 
					    left: -18px;
 | 
				
			||||||
 | 
					    top: 9px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .badge-right {
 | 
				
			||||||
 | 
					    -moz-transform: rotate(45deg);
 | 
				
			||||||
 | 
					    -ms-transform: rotate(45deg);
 | 
				
			||||||
 | 
					    -o-transform: rotate(45deg);
 | 
				
			||||||
 | 
					    -webkit-transform: rotate(45deg);
 | 
				
			||||||
 | 
					    transform: rotate(45deg);
 | 
				
			||||||
 | 
					    right: -18px;
 | 
				
			||||||
 | 
					    top: 9px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.my-project {
 | 
				
			||||||
 | 
					  &-header {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    align-items: flex-start;
 | 
				
			||||||
 | 
					    justify-content: space-between;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &-title {
 | 
				
			||||||
 | 
					    margin-top: 0 !important;
 | 
				
			||||||
 | 
					    margin-bottom: 18px !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &-list {
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: space-between;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &-item {
 | 
				
			||||||
 | 
					    // padding-right: 16px;
 | 
				
			||||||
 | 
					    margin-bottom: 16px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:last-child {
 | 
				
			||||||
 | 
					      padding-right: 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -1,111 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="项目" :bordered="false" size="medium" class="gi_card_title" style="overflow: hidden">
 | 
					 | 
				
			||||||
    <a-row align="stretch">
 | 
					 | 
				
			||||||
      <a-col v-for="(item, index) in list" :key="item.name" :xs="12" :sm="8" :md="8">
 | 
					 | 
				
			||||||
        <a-card-grid class="w-full h-full">
 | 
					 | 
				
			||||||
          <a-card :bordered="false" hoverable :class="`animated-fade-up-${index}`">
 | 
					 | 
				
			||||||
            <a :href="item.url" target="_blank">
 | 
					 | 
				
			||||||
              <section class="item">
 | 
					 | 
				
			||||||
                <div class="item__header">
 | 
					 | 
				
			||||||
                  <img :src="item.logo" width="30px" alt="logo" />
 | 
					 | 
				
			||||||
                  <span class="item__name gi_line_1">{{ item.name }}</span>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
                <div class="item__middle">
 | 
					 | 
				
			||||||
                  <p class="item__desc gi_line_2">{{ item.desc }}</p>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
              </section>
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
          </a-card>
 | 
					 | 
				
			||||||
        </a-card-grid>
 | 
					 | 
				
			||||||
      </a-col>
 | 
					 | 
				
			||||||
    </a-row>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
const list = [
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'ContiNew Admin',
 | 
					 | 
				
			||||||
    desc: '持续优化的前后端分离中后台管理框架,开箱即用,持续提供舒适的开发体验。',
 | 
					 | 
				
			||||||
    logo: 'https://continew.top/logo.svg',
 | 
					 | 
				
			||||||
    url: 'https://gitee.com/continew/continew-admin'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'ContiNew Starter',
 | 
					 | 
				
			||||||
    desc: '包含了一系列经过企业实践优化的依赖包(如 MyBatis-Plus、SaToken)。',
 | 
					 | 
				
			||||||
    logo: 'https://continew.top/logo.svg',
 | 
					 | 
				
			||||||
    url: 'https://gitee.com/continew/continew-starter'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'ContiNew Admin UI',
 | 
					 | 
				
			||||||
    desc: '全新 3.0 版本,基于 Gi Demo 前端模板开发的 ContiNew Admin 前端适配项目。',
 | 
					 | 
				
			||||||
    logo: 'https://continew.top/logo.svg',
 | 
					 | 
				
			||||||
    url: 'https://gitee.com/continew/continew-admin-ui'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'ContiNew Admin UI Arco',
 | 
					 | 
				
			||||||
    desc: '2.5 版本,基于 Arco Design Pro 前端模板开发的 ContiNew Admin 前端适配项目。',
 | 
					 | 
				
			||||||
    logo: 'https://continew.top/logo.svg',
 | 
					 | 
				
			||||||
    url: 'https://gitee.com/continew/continew-admin-ui-arco'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'ContiNew Cloud(孵化中)',
 | 
					 | 
				
			||||||
    desc: 'ContiNew Admin 微服务版本',
 | 
					 | 
				
			||||||
    logo: 'https://continew.top/logo.svg',
 | 
					 | 
				
			||||||
    url: '#'
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    name: 'charles7c.github.io',
 | 
					 | 
				
			||||||
    desc: '基于 VitePress 构建的个人知识库/博客,扩展 VitePress 默认主题。',
 | 
					 | 
				
			||||||
    logo: 'https://blog.charles7c.top/logo.png',
 | 
					 | 
				
			||||||
    url: 'https://github.com/Charles7c/charles7c.github.io'
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
:deep(.arco-card) {
 | 
					 | 
				
			||||||
  height: 100%;
 | 
					 | 
				
			||||||
  .arco-card-body {
 | 
					 | 
				
			||||||
    height: 100%;
 | 
					 | 
				
			||||||
    box-sizing: border-box;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
:deep(.arco-card-header) {
 | 
					 | 
				
			||||||
  border: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.item {
 | 
					 | 
				
			||||||
  height: 100%;
 | 
					 | 
				
			||||||
  display: flex;
 | 
					 | 
				
			||||||
  flex-direction: column;
 | 
					 | 
				
			||||||
  &__header {
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    align-items: center;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &__name {
 | 
					 | 
				
			||||||
    margin-left: 10px;
 | 
					 | 
				
			||||||
    font-size: 1.125rem;
 | 
					 | 
				
			||||||
    line-height: 1.75rem;
 | 
					 | 
				
			||||||
    color: var(--color-text-1);
 | 
					 | 
				
			||||||
    &:hover {
 | 
					 | 
				
			||||||
      color: rgb(var(--arcoblue-6));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &__middle {
 | 
					 | 
				
			||||||
    flex: 1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &__desc {
 | 
					 | 
				
			||||||
    flex: 1;
 | 
					 | 
				
			||||||
    margin-top: 10px;
 | 
					 | 
				
			||||||
    line-height: 1.5;
 | 
					 | 
				
			||||||
    color: var(--color-text-2);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  &__footer {
 | 
					 | 
				
			||||||
    font-size: 12px;
 | 
					 | 
				
			||||||
    color: var(--color-text-3);
 | 
					 | 
				
			||||||
    margin-top: 8px;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
							
								
								
									
										40
									
								
								src/views/dashboard/workplace/components/QuickOperation.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/views/dashboard/workplace/components/QuickOperation.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-card
 | 
				
			||||||
 | 
					    class="general-card"
 | 
				
			||||||
 | 
					    title="快捷操作"
 | 
				
			||||||
 | 
					    :header-style="{ paddingBottom: '0' }"
 | 
				
			||||||
 | 
					    :body-style="{ padding: '24px 20px 16px 20px' }"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <a-row :gutter="8">
 | 
				
			||||||
 | 
					      <a-col
 | 
				
			||||||
 | 
					        v-for="link in links"
 | 
				
			||||||
 | 
					        :key="link.text"
 | 
				
			||||||
 | 
					        :span="8"
 | 
				
			||||||
 | 
					        class="wrapper"
 | 
				
			||||||
 | 
					        @click="router.replace({ path: link.path })"
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					        <div class="icon">
 | 
				
			||||||
 | 
					          <GiSvgIcon :name="link.icon" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <a-typography-paragraph class="text">
 | 
				
			||||||
 | 
					          {{ link.text }}
 | 
				
			||||||
 | 
					        </a-typography-paragraph>
 | 
				
			||||||
 | 
					      </a-col>
 | 
				
			||||||
 | 
					    </a-row>
 | 
				
			||||||
 | 
					  </a-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					const router = useRouter()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const links = [
 | 
				
			||||||
 | 
					  { text: '用户管理', icon: 'user', path: '/system/user' },
 | 
				
			||||||
 | 
					  { text: '角色管理', icon: 'user-group', path: '/system/role' },
 | 
				
			||||||
 | 
					  { text: '菜单管理', icon: 'menu', path: '/system/menu' },
 | 
				
			||||||
 | 
					  { text: '文件管理', icon: 'file', path: '/system/file' },
 | 
				
			||||||
 | 
					  { text: '代码生成', icon: 'code', path: '/tool/generator' },
 | 
				
			||||||
 | 
					  { text: '系统日志', icon: 'history', path: '/monitor/log' }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped lang="less"></style>
 | 
				
			||||||
@@ -1,34 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="特别赞助" :bordered="false" size="medium" class="card gi_card_title">
 | 
					 | 
				
			||||||
    <template #extra>
 | 
					 | 
				
			||||||
      <a-link href="https://continew.top/other/sponsor.html" target="_blank" rel="noopener">>></a-link>
 | 
					 | 
				
			||||||
    </template>
 | 
					 | 
				
			||||||
    <a-row :gutter="8">
 | 
					 | 
				
			||||||
      <a-carousel
 | 
					 | 
				
			||||||
        v-if="imageList.length"
 | 
					 | 
				
			||||||
        indicator-type="slider"
 | 
					 | 
				
			||||||
        show-arrow="always"
 | 
					 | 
				
			||||||
        auto-play
 | 
					 | 
				
			||||||
        style="width: 100%; height: 110px; border-radius: 4px; overflow: hidden"
 | 
					 | 
				
			||||||
      >
 | 
					 | 
				
			||||||
        <a-carousel-item v-for="(image, idx) in imageList" :key="idx">
 | 
					 | 
				
			||||||
          <a :href="image.link" target="_blank" :title="image.title">
 | 
					 | 
				
			||||||
            <img :src="image.src" style="width: 100%; height: 100%" :alt="image.title" />
 | 
					 | 
				
			||||||
          </a>
 | 
					 | 
				
			||||||
        </a-carousel-item>
 | 
					 | 
				
			||||||
      </a-carousel>
 | 
					 | 
				
			||||||
      <a-empty v-else />
 | 
					 | 
				
			||||||
    </a-row>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script lang="ts" setup>
 | 
					 | 
				
			||||||
interface ImageType {
 | 
					 | 
				
			||||||
  src: string
 | 
					 | 
				
			||||||
  title: string
 | 
					 | 
				
			||||||
  link: string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const imageList: ImageType[] = [
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
@@ -1,19 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-carousel
 | 
					 | 
				
			||||||
    indicator-type="slider"
 | 
					 | 
				
			||||||
    show-arrow="hover"
 | 
					 | 
				
			||||||
    auto-play
 | 
					 | 
				
			||||||
    style="width: 120px; height: 100px; border-radius: 4px; overflow: hidden"
 | 
					 | 
				
			||||||
  >
 | 
					 | 
				
			||||||
    <a-carousel-item v-for="(src, idx) in imageSrc" :key="idx">
 | 
					 | 
				
			||||||
      <div style="padding-bottom: 10px; text-align: center">
 | 
					 | 
				
			||||||
        <img :src="src" style="width: 80px" alt="QrCode" />
 | 
					 | 
				
			||||||
        <div style="text-align: center">备注cnadmin进群</div>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </a-carousel-item>
 | 
					 | 
				
			||||||
  </a-carousel>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script lang="ts" setup>
 | 
					 | 
				
			||||||
const imageSrc = [`https://continew.top/qrcode.jpg?${new Date().getTime()}`]
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
							
								
								
									
										43
									
								
								src/views/dashboard/workplace/components/Welcome.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/views/dashboard/workplace/components/Welcome.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <a-card class="card" :bordered="false">
 | 
				
			||||||
 | 
					    <a-row align="center" wrap :gutter="[{ xs: 0, sm: 14, md: 14, lg: 14, xl: 14, xxl: 14 }, 16]" class="content">
 | 
				
			||||||
 | 
					      <a-space size="medium">
 | 
				
			||||||
 | 
					        <a-avatar :size="68">
 | 
				
			||||||
 | 
					          <img :src="userStore.avatar" alt="avatar" />
 | 
				
			||||||
 | 
					        </a-avatar>
 | 
				
			||||||
 | 
					        <div class="welcome">
 | 
				
			||||||
 | 
					          <p class="hello">{{ goodTimeText() }}!{{ userStore.name }}</p>
 | 
				
			||||||
 | 
					          <p>北海虽赊,扶摇可接;东隅已逝,桑榆非晚。</p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </a-space>
 | 
				
			||||||
 | 
					    </a-row>
 | 
				
			||||||
 | 
					  </a-card>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useUserStore } from '@/stores'
 | 
				
			||||||
 | 
					import { goodTimeText } from '@/utils'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const userStore = useUserStore()
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					:deep(.arco-statistic-title) {
 | 
				
			||||||
 | 
					  margin-bottom: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.card {
 | 
				
			||||||
 | 
					  .content {
 | 
				
			||||||
 | 
					    padding: 8px 20px;
 | 
				
			||||||
 | 
					    .welcome {
 | 
				
			||||||
 | 
					      margin: 8px 0;
 | 
				
			||||||
 | 
					      color: $color-text-3;
 | 
				
			||||||
 | 
					      .hello {
 | 
				
			||||||
 | 
					        font-size: 1.25rem;
 | 
				
			||||||
 | 
					        color: $color-text-1;
 | 
				
			||||||
 | 
					        margin-bottom: 10px;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -1,57 +0,0 @@
 | 
				
			|||||||
<template>
 | 
					 | 
				
			||||||
  <a-card title="工作台" :bordered="false" class="card">
 | 
					 | 
				
			||||||
    <template #extra>
 | 
					 | 
				
			||||||
      <NowTime />
 | 
					 | 
				
			||||||
    </template>
 | 
					 | 
				
			||||||
    <a-row align="center" wrap :gutter="[{ xs: 0, sm: 14, md: 14, lg: 14, xl: 14, xxl: 14 }, 16]" class="content">
 | 
					 | 
				
			||||||
      <a-col :xs="24" :sm="24" :md="14" :lg="16" :xl="16" :xxl="18">
 | 
					 | 
				
			||||||
        <a-space size="medium">
 | 
					 | 
				
			||||||
          <a-avatar :size="68">
 | 
					 | 
				
			||||||
            <img :src="userStore.avatar" alt="avatar" />
 | 
					 | 
				
			||||||
          </a-avatar>
 | 
					 | 
				
			||||||
          <div class="welcome">
 | 
					 | 
				
			||||||
            <p class="hello">{{ goodTimeText() }}!{{ userStore.name }}</p>
 | 
					 | 
				
			||||||
            <p>北海虽赊,扶摇可接;东隅已逝,桑榆非晚。</p>
 | 
					 | 
				
			||||||
          </div>
 | 
					 | 
				
			||||||
        </a-space>
 | 
					 | 
				
			||||||
      </a-col>
 | 
					 | 
				
			||||||
      <a-col :xs="24" :sm="24" :md="10" :lg="8" :xl="8" :xxl="6" style="margin: -8px -7px">
 | 
					 | 
				
			||||||
        <a-row justify="end">
 | 
					 | 
				
			||||||
          <SupportCard v-if="isDesktop" />
 | 
					 | 
				
			||||||
        </a-row>
 | 
					 | 
				
			||||||
      </a-col>
 | 
					 | 
				
			||||||
    </a-row>
 | 
					 | 
				
			||||||
  </a-card>
 | 
					 | 
				
			||||||
</template>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<script setup lang="ts">
 | 
					 | 
				
			||||||
import NowTime from './NowTime/index.vue'
 | 
					 | 
				
			||||||
import SupportCard from './SupportCard.vue'
 | 
					 | 
				
			||||||
import { useDevice } from '@/hooks'
 | 
					 | 
				
			||||||
import { useUserStore } from '@/stores'
 | 
					 | 
				
			||||||
import { goodTimeText } from '@/utils'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const { isDesktop } = useDevice()
 | 
					 | 
				
			||||||
const userStore = useUserStore()
 | 
					 | 
				
			||||||
</script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<style lang="scss" scoped>
 | 
					 | 
				
			||||||
:deep(.arco-statistic-title) {
 | 
					 | 
				
			||||||
  margin-bottom: 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.card {
 | 
					 | 
				
			||||||
  .content {
 | 
					 | 
				
			||||||
    padding: 8px 20px;
 | 
					 | 
				
			||||||
    .welcome {
 | 
					 | 
				
			||||||
      margin: 8px 0;
 | 
					 | 
				
			||||||
      color: $color-text-3;
 | 
					 | 
				
			||||||
      .hello {
 | 
					 | 
				
			||||||
        font-size: 1.25rem;
 | 
					 | 
				
			||||||
        color: $color-text-1;
 | 
					 | 
				
			||||||
        margin-bottom: 10px;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</style>
 | 
					 | 
				
			||||||
@@ -1,63 +1,128 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div id="home" class="gi_page home">
 | 
					  <div class="gi_page container">
 | 
				
			||||||
    <WorkCard />
 | 
					    <div class="left-side">
 | 
				
			||||||
 | 
					      <div class="panel">
 | 
				
			||||||
    <a-alert>
 | 
					        <Welcome />
 | 
				
			||||||
      全新版本 v3.3.0 已发布,重构全局响应处理,点击查看
 | 
					      </div>
 | 
				
			||||||
      <span class="link" @click="open('https://continew.top/admin/other/changelog.html')">更新日志</span>。
 | 
					      <div style="margin-top: 14px">
 | 
				
			||||||
    </a-alert>
 | 
					        <a-grid :cols="24" :col-gap="14" :row-gap="14">
 | 
				
			||||||
 | 
					          <a-grid-item :span="24">
 | 
				
			||||||
    <a-row class="home__content">
 | 
					            <Project />
 | 
				
			||||||
      <a-col :xs="24" :sm="24" :md="24" :lg="12" :xl="18" :xxl="18">
 | 
					          </a-grid-item>
 | 
				
			||||||
        <div class="home__item"><ProjectCard /></div>
 | 
					        </a-grid>
 | 
				
			||||||
        <div class="home__item"><AccessTrendCard /></div>
 | 
					      </div>
 | 
				
			||||||
      </a-col>
 | 
					    </div>
 | 
				
			||||||
      <a-col :xs="24" :sm="24" :md="24" :lg="12" :xl="6" :xxl="6">
 | 
					    <div class="right-side">
 | 
				
			||||||
        <div class="home__item"><FastCard /></div>
 | 
					      <a-grid :cols="24" :row-gap="14">
 | 
				
			||||||
        <div class="home__item"><SponsorCard /></div>
 | 
					        <a-grid-item :span="24">
 | 
				
			||||||
        <div class="home__item"><NoticeCard /></div>
 | 
					          <div class="panel moduler-wrap">
 | 
				
			||||||
      </a-col>
 | 
					            <QuickOperation />
 | 
				
			||||||
    </a-row>
 | 
					          </div>
 | 
				
			||||||
 | 
					        </a-grid-item>
 | 
				
			||||||
    <a-back-top :visible-height="100" target-container="#home" />
 | 
					        <a-grid-item class="panel" :span="24">
 | 
				
			||||||
 | 
					          <Carousel />
 | 
				
			||||||
 | 
					        </a-grid-item>
 | 
				
			||||||
 | 
					        <a-grid-item class="panel" :span="24">
 | 
				
			||||||
 | 
					          <Notice />
 | 
				
			||||||
 | 
					        </a-grid-item>
 | 
				
			||||||
 | 
					        <a-grid-item class="panel" :span="24">
 | 
				
			||||||
 | 
					          <Docs />
 | 
				
			||||||
 | 
					        </a-grid-item>
 | 
				
			||||||
 | 
					      </a-grid>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import WorkCard from './components/WorkCard.vue'
 | 
					import Welcome from './components/Welcome.vue'
 | 
				
			||||||
import ProjectCard from './components/ProjectCard.vue'
 | 
					import Project from './components/Project.vue'
 | 
				
			||||||
import AccessTrendCard from './components/AccessTrendCard.vue'
 | 
					import QuickOperation from './components/QuickOperation.vue'
 | 
				
			||||||
import FastCard from './components/FastCard.vue'
 | 
					import Carousel from './components/Carousel.vue'
 | 
				
			||||||
import NoticeCard from './components/NoticeCard.vue'
 | 
					import Notice from './components/Notice.vue'
 | 
				
			||||||
import SponsorCard from './components/SponsorCard.vue'
 | 
					import Docs from './components/Docs.vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({ name: 'Workplace' })
 | 
					defineOptions({ name: 'Workplace' })
 | 
				
			||||||
 | 
					 | 
				
			||||||
const open = (url: string) => {
 | 
					 | 
				
			||||||
  window.open(url, '_blank')
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="scss" scoped>
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
.home {
 | 
					.container {
 | 
				
			||||||
  padding: 0;
 | 
					  display: flex;
 | 
				
			||||||
  span.link {
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.left-side {
 | 
				
			||||||
 | 
					  flex: 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.right-side {
 | 
				
			||||||
 | 
					  width: 280px;
 | 
				
			||||||
 | 
					  margin-left: 14px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.panel {
 | 
				
			||||||
 | 
					  background-color: var(--color-bg-2);
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  overflow: auto;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					:deep(.panel-border) {
 | 
				
			||||||
 | 
					  margin-bottom: 0;
 | 
				
			||||||
 | 
					  border-bottom: 1px solid rgb(var(--gray-2));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					.moduler-wrap {
 | 
				
			||||||
 | 
					  border-radius: 4px;
 | 
				
			||||||
 | 
					  background-color: var(--color-bg-2);
 | 
				
			||||||
 | 
					  :deep(.text) {
 | 
				
			||||||
 | 
					    font-size: 12px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    color: rgb(var(--gray-8));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  :deep(.wrapper) {
 | 
				
			||||||
 | 
					    margin-bottom: 8px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    color: rgb(var(--arcoblue-6));
 | 
					
 | 
				
			||||||
    font-weight: bold;
 | 
					    &:last-child {
 | 
				
			||||||
 | 
					      .text {
 | 
				
			||||||
 | 
					        margin-bottom: 0;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    &:hover {
 | 
					    &:hover {
 | 
				
			||||||
      opacity: 0.7;
 | 
					      .icon {
 | 
				
			||||||
 | 
					        color: rgb(var(--arcoblue-6));
 | 
				
			||||||
 | 
					        background-color: #e8f3ff;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      .text {
 | 
				
			||||||
 | 
					        color: rgb(var(--arcoblue-6));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  &__content {
 | 
					
 | 
				
			||||||
    padding: 6px;
 | 
					  :deep(.icon) {
 | 
				
			||||||
  }
 | 
					    display: inline-block;
 | 
				
			||||||
  &__item {
 | 
					    width: 32px;
 | 
				
			||||||
    padding: 6px;
 | 
					    height: 32px;
 | 
				
			||||||
    box-sizing: border-box;
 | 
					    margin-bottom: 4px;
 | 
				
			||||||
  }
 | 
					    color: rgb(var(--dark-gray-1));
 | 
				
			||||||
  .backtop-icon {
 | 
					    line-height: 32px;
 | 
				
			||||||
    cursor: pointer;
 | 
					    font-size: 16px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    background-color: rgb(var(--gray-1));
 | 
				
			||||||
 | 
					    border-radius: 4px;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="less" scoped>
 | 
				
			||||||
 | 
					// responsive
 | 
				
			||||||
 | 
					.mobile {
 | 
				
			||||||
 | 
					  .container {
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  .right-side {
 | 
				
			||||||
 | 
					    // display: none;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    margin-left: 0;
 | 
				
			||||||
 | 
					    margin-top: 16px;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user