index.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <script setup>
  2. import {onMounted, ref} from 'vue'
  3. import * as echarts from 'echarts'
  4. import {
  5. Award,
  6. Bell,
  7. FileText,
  8. Home,
  9. Lightbulb,
  10. LucideTimer,
  11. Newspaper,
  12. Package,
  13. Plus,
  14. Trophy,
  15. Users
  16. } from 'lucide-vue-next'
  17. import useUserStore from "@/store/modules/user.js";
  18. import request from "@/utils/request.js";
  19. import {ElMessage} from "element-plus";
  20. import {useRouter} from "vue-router";
  21. // 响应式数据
  22. const currentDate = ref('')
  23. const productChart = ref(null)
  24. const trendChart = ref(null)
  25. const store = useUserStore();
  26. const router = useRouter();
  27. // 统计数据
  28. const stats = ref({
  29. productCount: 156,
  30. newsCount: 89,
  31. jobCount: 12,
  32. honerCount: 25
  33. })
  34. // 快速入口配置
  35. const quickEntries = ref([
  36. {
  37. name: '产品发布',
  38. description: '发布新产品信息',
  39. icon: Package,
  40. route: '/gwnrgl/cpzx',
  41. bgColor: 'bg-blue-100',
  42. iconColor: 'text-blue-600'
  43. },
  44. {
  45. name: '发展历程',
  46. description: '管理公司历程',
  47. icon: LucideTimer,
  48. route: '/gwnrgl/fzlc',
  49. bgColor: 'bg-green-100',
  50. iconColor: 'text-green-600'
  51. },
  52. {
  53. name: '招聘管理',
  54. description: '发布招聘信息',
  55. icon: Users,
  56. route: '/gwnrgl/zpgl',
  57. bgColor: 'bg-purple-100',
  58. iconColor: 'text-purple-600'
  59. },
  60. {
  61. name: '新闻动态',
  62. description: '发布新闻资讯',
  63. icon: Newspaper,
  64. route: '/gwnrgl/xwgl',
  65. bgColor: 'bg-orange-100',
  66. iconColor: 'text-orange-600'
  67. },
  68. {
  69. name: '荣誉资质',
  70. description: '管理荣誉证书',
  71. icon: Trophy,
  72. route: '/gwnrgl/ryzz',
  73. bgColor: 'bg-red-100',
  74. iconColor: 'text-red-600'
  75. },
  76. {
  77. name: '解决方案',
  78. description: '管理解决方案',
  79. icon: Lightbulb,
  80. route: '/gwnrgl/jjfa',
  81. bgColor: 'bg-yellow-100',
  82. iconColor: 'text-yellow-600'
  83. },
  84. {
  85. name: '首页信息',
  86. description: '首页内容管理',
  87. icon: Home,
  88. route: '/gwnrgl/syxxgl',
  89. bgColor: 'bg-indigo-100',
  90. iconColor: 'text-indigo-600'
  91. }
  92. ])
  93. // 最新动态
  94. const recentActivities = ref([
  95. {
  96. id: 1,
  97. title: '新产品"智能解决方案V2.0"已发布',
  98. time: '2小时前',
  99. icon: Plus,
  100. bgColor: 'bg-blue-100',
  101. iconColor: 'text-blue-600'
  102. },
  103. {
  104. id: 2,
  105. title: '招聘信息已更新,新增3个职位',
  106. time: '4小时前',
  107. icon: Users,
  108. bgColor: 'bg-green-100',
  109. iconColor: 'text-green-600'
  110. },
  111. {
  112. id: 3,
  113. title: '公司荣获"年度创新企业"奖项',
  114. time: '1天前',
  115. icon: Award,
  116. bgColor: 'bg-yellow-100',
  117. iconColor: 'text-yellow-600'
  118. },
  119. {
  120. id: 4,
  121. title: '新闻"行业发展趋势分析"已发布',
  122. time: '2天前',
  123. icon: Bell,
  124. bgColor: 'bg-purple-100',
  125. iconColor: 'text-purple-600'
  126. }
  127. ])
  128. // 初始化图表
  129. const initCharts = () => {
  130. // 产品分类饼图
  131. const productChartInstance = echarts.init(productChart.value)
  132. const productOption = {
  133. tooltip: {
  134. trigger: 'item',
  135. formatter: '{a} <br/>{b}: {c} ({d}%)'
  136. },
  137. legend: {
  138. orient: 'vertical',
  139. left: 'left'
  140. },
  141. series: [
  142. {
  143. name: '产品分类',
  144. type: 'pie',
  145. radius: ['40%', '70%'],
  146. avoidLabelOverlap: false,
  147. itemStyle: {
  148. borderRadius: 10,
  149. borderColor: '#fff',
  150. borderWidth: 2
  151. },
  152. label: {
  153. show: false,
  154. position: 'center'
  155. },
  156. emphasis: {
  157. label: {
  158. show: true,
  159. fontSize: 20,
  160. fontWeight: 'bold'
  161. }
  162. },
  163. labelLine: {
  164. show: false
  165. },
  166. data: [
  167. { value: 45, name: '软件产品' },
  168. { value: 35, name: '硬件设备' },
  169. { value: 28, name: '解决方案' },
  170. { value: 25, name: '技术服务' },
  171. { value: 23, name: '其他产品' }
  172. ]
  173. }
  174. ]
  175. }
  176. productChartInstance.setOption(productOption)
  177. // 月度趋势图
  178. const trendChartInstance = echarts.init(trendChart.value)
  179. const trendOption = {
  180. tooltip: {
  181. trigger: 'axis'
  182. },
  183. legend: {
  184. data: ['产品发布', '新闻发布', '招聘发布']
  185. },
  186. grid: {
  187. left: '3%',
  188. right: '4%',
  189. bottom: '3%',
  190. containLabel: true
  191. },
  192. xAxis: {
  193. type: 'category',
  194. boundaryGap: false,
  195. data: ['1月', '2月', '3月', '4月', '5月', '6月']
  196. },
  197. yAxis: {
  198. type: 'value'
  199. },
  200. series: [
  201. {
  202. name: '产品发布',
  203. type: 'line',
  204. stack: 'Total',
  205. smooth: true,
  206. data: [12, 15, 18, 22, 25, 28]
  207. },
  208. {
  209. name: '新闻发布',
  210. type: 'line',
  211. stack: 'Total',
  212. smooth: true,
  213. data: [8, 12, 14, 16, 18, 20]
  214. },
  215. {
  216. name: '招聘发布',
  217. type: 'line',
  218. stack: 'Total',
  219. smooth: true,
  220. data: [2, 3, 4, 3, 5, 4]
  221. }
  222. ]
  223. }
  224. trendChartInstance.setOption(trendOption)
  225. }
  226. // 快速入口点击处理
  227. const handleQuickEntry = (route) => {
  228. // 这里可以添加路由跳转逻辑
  229. router.push(route)
  230. }
  231. // 获取当前日期
  232. const getCurrentDate = () => {
  233. const now = new Date()
  234. const year = now.getFullYear()
  235. const month = String(now.getMonth() + 1).padStart(2, '0')
  236. const day = String(now.getDate()).padStart(2, '0')
  237. const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
  238. const weekday = weekdays[now.getDay()]
  239. currentDate.value = `${year}年${month}月${day}日 ${weekday}`
  240. }
  241. const getData = async () => {
  242. const res = await request.get("/home/getHomeInfo")
  243. if (res.code !== 200) {
  244. ElMessage.error(res.msg)
  245. return
  246. }
  247. stats.value = res.data
  248. console.log(stats.value);
  249. }
  250. onMounted(() => {
  251. getCurrentDate()
  252. getData()
  253. // setTimeout(() => {
  254. // initCharts()
  255. // }, 100)
  256. })
  257. </script>
  258. <template>
  259. <div class="min-h-screen bg-gray-50 p-6">
  260. <!-- 顶部欢迎区域 -->
  261. <div class="mb-8">
  262. <div class="bg-white rounded-lg shadow-sm p-6">
  263. <p class="text-gray-600">{{ currentDate }} | 欢迎回来,{{store.nickName}}</p>
  264. </div>
  265. </div>
  266. <!-- 核心数据统计 -->
  267. <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
  268. <el-card class="stat-card">
  269. <div class="flex items-center">
  270. <div class="p-3 bg-blue-100 rounded-lg mr-4">
  271. <Package class="w-6 h-6 text-blue-600" />
  272. </div>
  273. <div>
  274. <p class="text-sm text-gray-600">产品总数</p>
  275. <p class="text-2xl font-bold text-gray-800">{{ stats.productCount }}</p>
  276. </div>
  277. </div>
  278. </el-card>
  279. <el-card class="stat-card">
  280. <div class="flex items-center">
  281. <div class="p-3 bg-green-100 rounded-lg mr-4">
  282. <FileText class="w-6 h-6 text-green-600" />
  283. </div>
  284. <div>
  285. <p class="text-sm text-gray-600">新闻文章</p>
  286. <p class="text-2xl font-bold text-gray-800">{{ stats.newsCount }}</p>
  287. </div>
  288. </div>
  289. </el-card>
  290. <el-card class="stat-card">
  291. <div class="flex items-center">
  292. <div class="p-3 bg-purple-100 rounded-lg mr-4">
  293. <Users class="w-6 h-6 text-purple-600" />
  294. </div>
  295. <div>
  296. <p class="text-sm text-gray-600">招聘职位</p>
  297. <p class="text-2xl font-bold text-gray-800">{{ stats.jobCount }}</p>
  298. </div>
  299. </div>
  300. </el-card>
  301. <el-card class="stat-card">
  302. <div class="flex items-center">
  303. <div class="p-3 bg-orange-100 rounded-lg mr-4">
  304. <Award class="w-6 h-6 text-orange-600" />
  305. </div>
  306. <div>
  307. <p class="text-sm text-gray-600">荣誉资质</p>
  308. <p class="text-2xl font-bold text-gray-800">{{ stats.honerCount }}</p>
  309. </div>
  310. </div>
  311. </el-card>
  312. </div>
  313. <!-- 快速入口区域 -->
  314. <div class="mb-8">
  315. <h2 class="text-xl font-semibold text-gray-800 mb-6">快速入口</h2>
  316. <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
  317. <el-card
  318. v-for="item in quickEntries"
  319. :key="item.name"
  320. class="quick-entry-card cursor-pointer hover:shadow-lg transition-all duration-300"
  321. @click="handleQuickEntry(item.route)"
  322. >
  323. <div class="text-center p-4">
  324. <div class="mb-4 flex justify-center">
  325. <div :class="`p-4 rounded-full ${item.bgColor}`">
  326. <component :is="item.icon" :class="`w-8 h-8 ${item.iconColor}`" />
  327. </div>
  328. </div>
  329. <h3 class="font-semibold text-gray-800 mb-2">{{ item.name }}</h3>
  330. <p class="text-sm text-gray-600">{{ item.description }}</p>
  331. </div>
  332. </el-card>
  333. </div>
  334. </div>
  335. <!-- 数据展示区域 -->
  336. <!-- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">-->
  337. <!-- &lt;!&ndash; 产品分类统计 &ndash;&gt;-->
  338. <!-- <el-card>-->
  339. <!-- <template #header>-->
  340. <!-- <h3 class="text-lg font-semibold text-gray-800">产品分类分布</h3>-->
  341. <!-- </template>-->
  342. <!-- <div ref="productChart" class="h-80"></div>-->
  343. <!-- </el-card>-->
  344. <!-- &lt;!&ndash; 月度数据趋势 &ndash;&gt;-->
  345. <!-- <el-card>-->
  346. <!-- <template #header>-->
  347. <!-- <h3 class="text-lg font-semibold text-gray-800">月度数据趋势</h3>-->
  348. <!-- </template>-->
  349. <!-- <div ref="trendChart" class="h-80"></div>-->
  350. <!-- </el-card>-->
  351. <!-- </div>-->
  352. </div>
  353. </template>
  354. <style scoped>
  355. .stat-card {
  356. transition: all 0.3s ease;
  357. }
  358. .stat-card:hover {
  359. transform: translateY(-2px);
  360. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  361. }
  362. .quick-entry-card {
  363. transition: all 0.3s ease;
  364. border: 1px solid #e5e7eb;
  365. }
  366. .quick-entry-card:hover {
  367. transform: translateY(-4px);
  368. border-color: #3b82f6;
  369. }
  370. </style>