Index.vue 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. <!-- <div>
  2. <el-card shadow="never">
  3. <el-skeleton :loading="loading" animated>
  4. <el-row :gutter="16" justify="space-between">
  5. <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  6. <div class="flex items-center">
  7. <el-avatar :src="avatar" :size="70" class="mr-16px">
  8. <img src="@/assets/imgs/avatar.gif" alt="" />
  9. </el-avatar>
  10. <div>
  11. <div class="text-20px">
  12. {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
  13. </div>
  14. <div class="mt-10px text-14px text-gray-500">
  15. {{ t('workplace.toady') }},20℃ - 32℃!
  16. </div>
  17. </div>
  18. </div>
  19. </el-col>
  20. <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  21. <div class="h-70px flex items-center justify-end lt-sm:mt-10px">
  22. <div class="px-8px text-right">
  23. <div class="mb-16px text-14px text-gray-400">{{ t('workplace.project') }}</div>
  24. <CountTo class="text-20px" :start-val="0" :end-val="totalSate.project" :duration="2600" />
  25. </div>
  26. <el-divider direction="vertical" />
  27. <div class="px-8px text-right">
  28. <div class="mb-16px text-14px text-gray-400">{{ t('workplace.toDo') }}</div>
  29. <CountTo class="text-20px" :start-val="0" :end-val="totalSate.todo" :duration="2600" />
  30. </div>
  31. <el-divider direction="vertical" border-style="dashed" />
  32. <div class="px-8px text-right">
  33. <div class="mb-16px text-14px text-gray-400">{{ t('workplace.access') }}</div>
  34. <CountTo class="text-20px" :start-val="0" :end-val="totalSate.access" :duration="2600" />
  35. </div>
  36. </div>
  37. </el-col>
  38. </el-row>
  39. </el-skeleton>
  40. </el-card>
  41. </div> -->
  42. <!-- 日期
  43. <div class="mt-16px text-12px text-gray-400">
  44. {{ formatTime(item.date, 'yyyy-MM-dd') }}
  45. </div> -->
  46. <!-- 更多<el-link type="primary" :underline="false" href="https://github.com/yudaocode" target="_blank"> {{
  47. t('action.more') }}
  48. </el-link> -->
  49. <template>
  50. <el-skeleton :loading="loading" animated>
  51. <el-row :gutter="8">
  52. <!-- 第一部分 -->
  53. <el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10">
  54. <el-card style="height: 99%;">
  55. <el-card shadow="never" class="h-100% ">
  56. <template #header>
  57. <div class="h-7 flex justify-between fw-800 text-20px">
  58. <span>基本信息</span>
  59. </div>
  60. </template>
  61. <el-row style="flex-wrap: wrap; ">
  62. <el-col v-for="(item, index) in projects" :key="`card-${index}`" :xs="24" :sm="24" :md="24" :lg="8" :xl="8">
  63. <el-card shadow="hover" class="mr-5px mt-5px " style="background-color:#2585a6 ">
  64. <div class="flex items-center h-90px ">
  65. <!-- <Icon :icon="item.icon" :size="25" class="mr-8px" /> -->
  66. <Icon :icon="item.icon" :size="38" class="mr-8px " />
  67. <span class="text-17px c-white">{{ item.name }}</span>
  68. </div>
  69. <div class="mb-18px text-32px c-white ml-20px text-center">{{ t(item.message) }}</div>
  70. <!-- <div class="mt-12px flex justify-between text-12px text-gray-400">
  71. <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
  72. </div> -->
  73. </el-card>
  74. </el-col>
  75. </el-row>
  76. </el-card>
  77. <el-card shadow="never" class=" h-100% mt-20px ">
  78. <template #header>
  79. <div class="h-5 flex justify-between fw-800 text-20px">
  80. <span>出勤统计</span>
  81. </div>
  82. </template>
  83. <el-card shadow="never" class="ml-2px pr-10px mt-10px" style="background-color:#33a3dc ;opacity: 0.8; ">
  84. <div class="h-70px flex items-center justify-center flex-wrap mt-10px c-white">
  85. <div class="px-8px text-right">
  86. <div class="mb-10px text-20px text-white ">当日出勤情况</div>
  87. </div>
  88. <el-divider direction="vertical" style="border-left-black" />
  89. <div class="px-25px text-center">
  90. <div class="mb-16px text-18px text-white ">正常人数</div>
  91. <CountTo class="text-20px" :start-val="0" :end-val="totalSate.normal" :duration="2600" />
  92. </div>
  93. <el-divider direction="vertical" border-style="dashed" />
  94. <div class="px-8px text-center">
  95. <div class="mb-16px text-18px text-white ">异常人数</div>
  96. <CountTo class="text-20px" :start-val="0" :end-val="totalSate.unusual" :duration="2600" />
  97. </div>
  98. </div>
  99. </el-card>
  100. </el-card>
  101. <el-card shadow="hover" class="mb-8px mt-30px">
  102. <template #header>
  103. <div class="h-5 flex justify-between fw-800 text-20px">
  104. <span>实时人数统计</span>
  105. </div>
  106. </template>
  107. <el-skeleton :loading="loading" animated>
  108. <Echart :options="pieOptionsData" :height="250" />
  109. </el-skeleton>
  110. </el-card>
  111. </el-card>
  112. </el-col>
  113. <!-- 第二部分 -->
  114. <el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="10">
  115. <!-- 第一个el-row -->
  116. <el-row :gutter="15">
  117. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
  118. <el-card shadow="never" class="ml-10px h-480px ">
  119. <template #header>
  120. <div class="h-5 flex justify-between fw-800 text-20px">
  121. <span>周出勤情况</span>
  122. </div>
  123. </template>
  124. <el-card shadow="hover" class="mt-1px h-380px ">
  125. <el-skeleton :loading="loading" animated>
  126. <Echart :options="barOptionsData" :height="350" />
  127. </el-skeleton>
  128. </el-card>
  129. </el-card>
  130. </el-col>
  131. <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="10">
  132. <el-card shadow="never">
  133. <template #header>
  134. <div class="h-5 flex justify-between fw-800 text-20px">
  135. <span>实时打卡状态</span>
  136. </div>
  137. </template>
  138. <div class="demo">
  139. <vue3ScrollSeamless class="scroll-wrap text-color" :classOptions="classOptions" :dataList="list">
  140. <div v-if="list.length > 0">
  141. <el-row v-for="(item, i) of list" :key="i" class="shouye"
  142. style="margin-bottom: 10px; display: flex; justify-content: center;">
  143. <el-col :span="7" class="center"
  144. style="display: flex; justify-content: center; align-items: center; padding: 6px;">
  145. <div>{{ item.trainNumber }}</div>
  146. </el-col>
  147. <el-col :span="6" class="center"
  148. style="display: flex; justify-content: center; align-items: center; padding: 6px;">
  149. <div>{{ item.destination }}</div>
  150. </el-col>
  151. <el-col :span="6" class="center"
  152. style="display: flex; justify-content: center; align-items: center; padding: 6px;">
  153. <div>{{ item.departureTime }}</div>
  154. </el-col>
  155. <el-col :span="5" class="center"
  156. style="display: flex; justify-content: center; align-items: center; padding: 6px;">
  157. <div>{{ item.status }}</div>
  158. </el-col>
  159. </el-row>
  160. </div>
  161. <div v-if="list.length == 0"
  162. style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
  163. 暂无预测记录
  164. </div>
  165. </vue3ScrollSeamless>
  166. </div>
  167. </el-card>
  168. </el-col>
  169. </el-row>
  170. <!-- 第二个el-row -->
  171. <el-row class="mt-12px" :gutter="15" align="center">
  172. <el-col :xs="24" :sm="24" :md="24" :lg="13" :xl="7">
  173. <el-card shadow="never" class="mt-1px h-480px ml-10px" style="border: none;"> <!-- 移除 el-card 的边框 -->
  174. <template #header>
  175. <div class="h-7 flex justify-between fw-800 text-20px">
  176. <span>缺勤预警</span>
  177. </div>
  178. </template>
  179. <div class="demos">
  180. <!-- <div class="table-header">
  181. <div class="header">
  182. <el-row class="shouye" style="border: none;">
  183. <el-col :span="8" class="center text-18px" style="border: none;">
  184. <div>学生学号</div>
  185. </el-col>
  186. <el-col :span="10" class="center text-18px" style="border: none;">
  187. <div>工作间</div>
  188. </el-col>
  189. <el-col :span="6" class="center text-18px" style="border: none;">
  190. <div>导师</div>
  191. </el-col>
  192. <el-col :span="10" class="center text-18px" style="border: none;">
  193. <div>缺勤时间段</div>
  194. </el-col>
  195. </el-row>
  196. </div>
  197. </div> -->
  198. <vue3ScrollSeamless class="scroll-wraps text-color" :classOptions="class2Options" :dataList="list2">
  199. <div v-if="list2.length > 0">
  200. <el-row v-for="(item, i) of list2" :key="i" class="shouye">
  201. <el-col :span="6" class="center" style="padding: 10px; border: none;">
  202. <div>{{ item.ID }}</div>
  203. </el-col>
  204. <el-col :span="6" class="center" style="padding: 10px; border: none;">
  205. <div>{{ item.destination }}</div>
  206. </el-col>
  207. <el-col :span="6" class="center" style="padding: 10px; border: none;">
  208. <div>{{ item.trainNumber }}</div>
  209. </el-col>
  210. <el-col :span="6" class="center" style="padding: 10px; border: none;">
  211. <div>{{ item.departureTime }}</div>
  212. </el-col>
  213. </el-row>
  214. </div>
  215. <div v-if="list2.length == 0"
  216. style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
  217. 暂无预测记录
  218. </div>
  219. </vue3ScrollSeamless>
  220. </div>
  221. </el-card>
  222. </el-col>
  223. <el-col :xs="24" :sm="24" :md="24" :lg="11" :xl="7">
  224. <el-card shadow="never" class="mr-8px mt-1px h-480px ">
  225. <template #header>
  226. <div class="h-7 flex justify-between fw-800 text-20px">
  227. <span>学生毕业条件达成率</span>
  228. </div>
  229. </template>
  230. <div class="demoss">
  231. <!-- <div class="table-header">
  232. <div class="header">
  233. <el-row class="shouye">
  234. <el-col :span="12" class="center text-18px">
  235. <div>工作间</div>
  236. </el-col>
  237. <el-col :span="15" class="center text-18px ">
  238. <div>学生毕业条件达成率</div>
  239. </el-col>
  240. </el-row>
  241. </div>
  242. </div> -->
  243. <vue3ScrollSeamless class="scroll-wrapss text-color" :classOptions="list1Options" :dataList="list1">
  244. <div v-if="list1.length > 0">
  245. <el-row v-for="(item, i) of list1" :key="i" class="shouye" :style="{ marginBottom: '10px' }">
  246. <!-- 增加行与行之间的间距 -->
  247. <el-col :span="12" class="center" style="padding: 8px;"> <!-- 增加内边距 -->
  248. <div>{{ item.destination }}</div>
  249. </el-col>
  250. <el-col :span="12" class="center" style="padding: 8px;">
  251. <div>{{ item.departureNumber }}</div>
  252. </el-col>
  253. </el-row>
  254. </div>
  255. <div v-if="list1.length == 0"
  256. style="width: 100%; height: 100px; display: flex; justify-content: center; align-items: center; color: white; font-size: 18px;">
  257. 暂无预测记录
  258. </div>
  259. </vue3ScrollSeamless>
  260. </div>
  261. </el-card>
  262. </el-col>
  263. </el-row>
  264. </el-col>
  265. </el-row>
  266. </el-skeleton>
  267. </template>
  268. <script lang="ts" setup>
  269. import { set } from 'lodash-es'
  270. import { EChartsOption, List } from 'echarts'
  271. import { formatTime } from '@/utils'
  272. import { useUserStore } from '@/store/modules/user'
  273. import { useWatermark } from '@/hooks/web/useWatermark'
  274. import type { WorkplaceTotal, Project, Notice, Shortcut } from './types'
  275. import { pieOptions, barOptions } from './echarts-data'
  276. import { center } from "diagram-js/lib/util/PositionUtil";
  277. import { reactive, onMounted, watchEffect } from "vue";
  278. import { vue3ScrollSeamless } from "vue3-scroll-seamless";
  279. import * as UserApi from '@/api/system/user'
  280. import { on } from 'events'
  281. defineOptions({ name: 'Home' })
  282. const { t } = useI18n()
  283. const userStore = useUserStore()
  284. const { setWatermark } = useWatermark()
  285. const loading = ref(true)
  286. const avatar = userStore.getUser.avatar
  287. const username = userStore.getUser.nickname
  288. let pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
  289. // 获取统计数
  290. let totalSate = reactive<WorkplaceTotal>({
  291. project: 0,
  292. access: 0,
  293. todo: 0
  294. })
  295. const detail = reactive({
  296. "deptNum": undefined,
  297. "teacherNum": undefined,
  298. "studentNum": undefined
  299. })
  300. const getCount = async () => {
  301. const data = {
  302. project: 40,
  303. access: 2340,
  304. todo: 10,
  305. college: 80,
  306. normal: 125,
  307. unusual: 5
  308. }
  309. totalSate = Object.assign(totalSate, data)
  310. }
  311. // 获取项目数
  312. let projects = reactive<Project[]>([])
  313. const getProject = async () => {
  314. // console.log("getProject",detail.deptNum);
  315. const data = [
  316. {
  317. name: '学院工作间数量',
  318. icon: 'svg-icon:gzs',
  319. message: String(detail.deptNum) + '个',
  320. time: new Date()
  321. },
  322. {
  323. name: '导师数量',
  324. icon: 'svg-icon:ds',
  325. message: String(detail.teacherNum) + '人',
  326. time: new Date()
  327. },
  328. {
  329. name: '在校生数量',
  330. icon: 'svg-icon:zxs',
  331. message: String(detail.studentNum) + '人',
  332. time: new Date()
  333. }
  334. ]
  335. projects = Object.assign(projects, data)
  336. }
  337. // 获取通知公告
  338. let notice = reactive<Notice[]>([])
  339. const getNotice = async () => {
  340. const data = [
  341. {
  342. title: '系统支持 JDK 8/17/21,Vue 2/3',
  343. type: '通知',
  344. keys: ['通知', '8', '17', '21', '2', '3'],
  345. date: new Date()
  346. },
  347. {
  348. title: '后端提供 Spring Boot 2.7/3.2 + Cloud 双架构',
  349. type: '公告',
  350. keys: ['公告', 'Boot', 'Cloud'],
  351. date: new Date()
  352. },
  353. {
  354. title: '全部开源,个人与企业可 100% 直接使用,无需授权',
  355. type: '通知',
  356. keys: ['通知', '无需授权'],
  357. date: new Date()
  358. },
  359. {
  360. title: '国内使用最广泛的快速开发平台,超 300+ 人贡献',
  361. type: '公告',
  362. keys: ['公告', '最广泛'],
  363. date: new Date()
  364. }
  365. ]
  366. notice = Object.assign(notice, data)
  367. }
  368. // 获取基本信息
  369. let basic = reactive<Basic[]>([])
  370. const getBasic = async () => {
  371. const data = [
  372. {
  373. title: '学院工作间数量',
  374. type: '通知',
  375. keys: ['通知', '8', '17', '21', '2', '3'],
  376. date: new Date()
  377. },
  378. {
  379. title: '硕士研究生数量',
  380. type: '公告',
  381. keys: ['公告', 'Boot', 'Cloud'],
  382. date: new Date()
  383. },
  384. {
  385. title: '博士研究生数量',
  386. type: '通知',
  387. keys: ['通知', '无需授权'],
  388. date: new Date()
  389. },
  390. {
  391. title: '硕士研究生导师数量',
  392. type: '公告',
  393. keys: ['公告', '最广泛'],
  394. date: new Date()
  395. },
  396. {
  397. title: '博士生导师数量',
  398. type: '公告',
  399. keys: ['公告', '最广泛'],
  400. date: new Date()
  401. }
  402. ]
  403. basic = Object.assign(basic, data)
  404. }
  405. // 获取快捷入口
  406. let shortcut = reactive<Shortcut[]>([])
  407. const getShortcut = async () => {
  408. const data = [
  409. {
  410. name: 'Github',
  411. icon: 'akar-icons:github-fill',
  412. url: 'github.io'
  413. },
  414. {
  415. name: 'Vue',
  416. icon: 'logos:vue',
  417. url: 'vuejs.org'
  418. },
  419. {
  420. name: 'Vite',
  421. icon: 'vscode-icons:file-type-vite',
  422. url: 'https://vitejs.dev/'
  423. },
  424. {
  425. name: 'Angular',
  426. icon: 'logos:angular-icon',
  427. url: 'github.io'
  428. },
  429. {
  430. name: 'React',
  431. icon: 'logos:react',
  432. url: 'github.io'
  433. },
  434. {
  435. name: 'Webpack',
  436. icon: 'logos:webpack',
  437. url: 'github.io'
  438. }
  439. ]
  440. shortcut = Object.assign(shortcut, data)
  441. }
  442. // 用户来源
  443. const getUserAccessSource = async () => {
  444. const data = [
  445. { value: 1048, name: '在线人数' },
  446. { value: 735, name: '离线人数' },
  447. ];
  448. const options = {
  449. title: {
  450. text: null,
  451. left: 'center',
  452. top: '20px'
  453. },
  454. tooltip: {
  455. trigger: 'item',
  456. },
  457. legend: {
  458. top: '10%', // 顶部位置
  459. left: 'left', // 左侧位置
  460. },
  461. series: [
  462. {
  463. type: 'pie',
  464. radius: ['120px', '70px'], // 设定内圈和外圈半径
  465. center: ['50%', '85%'], // 中心位置
  466. startAngle: 180,
  467. endAngle: 360,
  468. data: data.map(v => ({
  469. value: v.value,
  470. name: t(v.name),
  471. label: {
  472. show: true,
  473. position: 'outside', // 拉出标注
  474. formatter: '{b}: {c}', // 显示名称和数值
  475. // 可以自定义引线的样式
  476. emphasis: {
  477. show: true,
  478. },
  479. },
  480. // 自定义引线样式
  481. labelLine: {
  482. show: true,
  483. length: 75, // 引线长度
  484. length2: 10, // 后半段引线的长度
  485. smooth: true, // 引线是否平滑
  486. lineDash: [5, 5], // 引线虚线样式
  487. },
  488. })),
  489. itemStyle: {
  490. // 设置饼图的颜色
  491. color: function (params) {
  492. const colorList = ['#94d6da', '#00a6ac']; // 定义颜色数组
  493. return colorList[params.dataIndex]; // 根据数据索引返回对应的颜色
  494. }
  495. }
  496. },
  497. ],
  498. };
  499. set(
  500. pieOptionsData,
  501. 'legend.data',
  502. data.map((v) => t(v.name))
  503. );
  504. pieOptionsData = Object.assign(pieOptionsData, options);
  505. };
  506. let barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
  507. // 周活跃量
  508. const getWeeklyUserActivity = async () => {
  509. const data = [
  510. { value: 13253, name: '异常人数' },
  511. { value: 34235, name: '正常人数' },
  512. ];
  513. const options = {
  514. title: {
  515. text: null,
  516. },
  517. tooltip: {
  518. trigger: 'item',
  519. },
  520. grid: {
  521. left: '80px',
  522. top: '10px', // 上方偏移
  523. },
  524. series: [
  525. {
  526. name: '人数',
  527. type: 'bar',
  528. barWidth: '40%', // 设置柱子的宽度为40%
  529. data: data.map((v) => v.value), // 设置Y轴数据
  530. itemStyle: {
  531. // 设置每个柱状的颜色
  532. color: function (params) {
  533. const colorList = ['#145b7d', '#33a3dc']; // 定义颜色数组
  534. return colorList[params.dataIndex]; // 根据数据索引返回对应的颜色
  535. }
  536. }
  537. }
  538. ]
  539. };
  540. set(
  541. barOptionsData,
  542. 'xAxis.data',
  543. data.map((v) => t(v.name))
  544. );
  545. barOptionsData = Object.assign(barOptionsData, options);
  546. };
  547. //打卡滚动列表
  548. const list = reactive([
  549. { trainNumber: '张一', destination: '101', departureTime: '09:00', status: '准点' },
  550. { trainNumber: '张二', destination: '102', departureTime: '09:15', status: '准点' },
  551. { trainNumber: '张三', destination: '103', departureTime: '09:30', status: '晚点' },
  552. { trainNumber: '张四', destination: '104', departureTime: '09:45', status: '准点' },
  553. { trainNumber: '张五', destination: '105', departureTime: '10:00', status: '准点' },
  554. { trainNumber: '李一', destination: '201', departureTime: '10:15', status: '准点' },
  555. { trainNumber: '李二', destination: '202', departureTime: '10:30', status: '晚点' },
  556. { trainNumber: '李三', destination: '203', departureTime: '10:45', status: '准点' },
  557. { trainNumber: '李四', destination: '204', departureTime: '11:00', status: '晚点' },
  558. { trainNumber: '李五', destination: '205', departureTime: '11:15', status: '准点' },
  559. { trainNumber: '王一', destination: '301', departureTime: '11:30', status: '准点' },
  560. { trainNumber: '王二', destination: '302', departureTime: '11:45', status: '准点' },
  561. { trainNumber: '王三', destination: '303', departureTime: '12:00', status: '晚点' },
  562. { trainNumber: '王四', destination: '304', departureTime: '12:15', status: '准点' },
  563. { trainNumber: '王五', destination: '305', departureTime: '12:30', status: '准点' },
  564. { trainNumber: '王六', destination: '306', departureTime: '12:45', status: '准点' },
  565. { trainNumber: '王七', destination: '307', departureTime: '13:00', status: '晚点' }
  566. ]);
  567. const classOptions = reactive({
  568. step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
  569. limitMoveNum: list.length,//无缝滚动列表元素的长度,一般设置为列表的长度
  570. direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
  571. });
  572. //在线情况滚动列表
  573. const list1 = reactive([
  574. { destination: '101', departureNumber: '98%' },
  575. { destination: '102', departureNumber: '94%' },
  576. { destination: '103', departureNumber: '96%' },
  577. { destination: '104', departureNumber: '98%' },
  578. { destination: '105', departureNumber: '93%' },
  579. { destination: '201', departureNumber: '97%' },
  580. { destination: '202', departureNumber: '95%' },
  581. { destination: '203', departureNumber: '98%' },
  582. { destination: '204', departureNumber: '96%' },
  583. { destination: '205', departureNumber: '94%' },
  584. { destination: '301', departureNumber: '97%' },
  585. { destination: '302', departureNumber: '96%' },
  586. { destination: '303', departureNumber: '95%' },
  587. { destination: '304', departureNumber: '97%' },
  588. { destination: '305', departureNumber: '98%' },
  589. { destination: '306', departureNumber: '99%' },
  590. { destination: '307', departureNumber: '96%' }
  591. ]);
  592. const list1Options = reactive({
  593. step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
  594. limitMoveNum: list1.length,//无缝滚动列表元素的长度,一般设置为列表的长度
  595. direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
  596. });
  597. const list2 = reactive([
  598. { trainNumber: '张一', destination: '101', departureTime: '09:00', ID: '10' },
  599. { trainNumber: '张二', destination: '102', departureTime: '09:15', ID: '15' },
  600. { trainNumber: '张三', destination: '103', departureTime: '09:30', ID: '13' },
  601. { trainNumber: '张四', destination: '104', departureTime: '09:45', ID: '18' },
  602. { trainNumber: '张五', destination: '105', departureTime: '10:00', ID: '19' },
  603. { trainNumber: '李一', destination: '201', departureTime: '10:15', ID: '12' },
  604. { trainNumber: '李二', destination: '202', departureTime: '10:30', ID: '02' },
  605. { trainNumber: '李三', destination: '203', departureTime: '10:45', ID: '09' },
  606. { trainNumber: '李四', destination: '204', departureTime: '11:00', ID: '16' },
  607. { trainNumber: '李五', destination: '205', departureTime: '11:15', ID: '20' },
  608. { trainNumber: '王一', destination: '301', departureTime: '11:30', ID: '28' },
  609. { trainNumber: '王二', destination: '302', departureTime: '11:45', ID: '36' },
  610. { trainNumber: '王三', destination: '303', departureTime: '12:00', ID: '07' },
  611. { trainNumber: '王四', destination: '304', departureTime: '12:15', ID: '41' },
  612. { trainNumber: '王五', destination: '305', departureTime: '12:30', ID: '15' },
  613. { trainNumber: '王六', destination: '306', departureTime: '12:45', ID: '22' },
  614. { trainNumber: '王七', destination: '307', departureTime: '13:00', ID: '27' }
  615. ]);
  616. const class2Options = reactive({
  617. step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
  618. limitMoveNum: list2.length,//无缝滚动列表元素的长度,一般设置为列表的长度
  619. direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
  620. });
  621. const getDetail = async () => {
  622. loading.value = true
  623. try {
  624. // const D = await UserApi.getDetail();
  625. // detail.deptNum = D.deptNum
  626. // detail.studentNum = D.studentNum
  627. // detail.teacherNum = D.teacherNum
  628. } finally {
  629. loading.value = false
  630. }
  631. }
  632. const getAllApi = async () => {
  633. await Promise.all([
  634. await getDetail(),
  635. getCount(),
  636. getProject(),
  637. getNotice(),
  638. getBasic(),
  639. getShortcut(),
  640. getUserAccessSource(),
  641. getWeeklyUserActivity()
  642. ])
  643. loading.value = false
  644. }
  645. // watchEffect(detail => {
  646. // console.log('detail', detail)
  647. // getBasic()
  648. // })
  649. // onMounted(() => {
  650. // })
  651. getAllApi()
  652. </script>
  653. <style scoped>
  654. .center {
  655. text-align: center;
  656. }
  657. /* 滚动列表 */
  658. .title-container {
  659. display: flex;
  660. align-items: center;
  661. justify-content: center;
  662. height: 20px;
  663. margin-bottom: 30px;
  664. }
  665. .title {
  666. font-size: 19px;
  667. }
  668. .demo {
  669. width: 99%;
  670. height: 362px;
  671. }
  672. .demos {
  673. width: 95%;
  674. height: 100%;
  675. }
  676. .demoss {
  677. width: 95%;
  678. height: 100%;
  679. }
  680. .scroll-wrap {
  681. width: 95%;
  682. height: 330px;
  683. margin: 0 auto;
  684. overflow: hidden;
  685. /* background-color: #feeeed; */
  686. opacity: 0.6;
  687. font-size: 15px;
  688. margin-top: 20px;
  689. margin-left: 18px;
  690. }
  691. .scroll-wraps {
  692. width: 101%;
  693. height: 350px;
  694. margin: 0 auto;
  695. overflow: hidden;
  696. opacity: 0.6;
  697. font-size: 15px;
  698. border: none;
  699. margin-top: 20px;
  700. }
  701. .scroll-wrapss {
  702. width: 90%;
  703. height: 350px;
  704. margin: 0 auto;
  705. overflow: hidden;
  706. /* background-color: rgba(198, 204, 238, 0.3); */
  707. /* background-color: #feeeed; */
  708. opacity: 0.6;
  709. font-size: 15px;
  710. margin-top: 10px;
  711. }
  712. /* 轮播图的导航条
  713. .table-header {
  714. font-family: Arial, sans-serif;
  715. height: 30px;
  716. display: flex;
  717. align-items: center;
  718. border: 1px solid;
  719. width: 280px;
  720. flex-wrap: nowrap;
  721. padding-right: 10px;
  722. }
  723. .header {
  724. width: 660px;
  725. font-size: 16px;
  726. } */
  727. .border {
  728. border: 1px solid;
  729. }
  730. .center {
  731. display: flex;
  732. align-items: center;
  733. justify-content: center;
  734. }
  735. /* .text-color {
  736. color: rgb(15, 131, 233);
  737. } */
  738. .shouye {
  739. flex-wrap: nowrap;
  740. border-bottom: 1px solid;
  741. }
  742. ::v-deep .el-divider.el-divider--vertical {
  743. border-left: 1px solid white;
  744. }
  745. </style>