dashboard.vue 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. <template>
  2. <div class="default-main">
  3. <!-- <div class="banner">
  4. <el-row :gutter="10">
  5. <el-col :md="24" :lg="18">
  6. <div class="welcome suspension">
  7. <img class="welcome-img" :src="headerSvg" alt="" />
  8. <div class="welcome-text">
  9. <div class="welcome-title">{{ adminInfo.nickname + t('utils.comma') + getGreet() }}</div>
  10. <div class="welcome-note">{{ state.remark }}</div>
  11. </div>
  12. </div>
  13. </el-col>
  14. <el-col :lg="6" class="hidden-md-and-down">
  15. <div class="working">
  16. <img class="working-coffee" :src="coffeeSvg" alt="" />
  17. <div class="working-text">
  18. {{ t('dashboard.You have worked today') }}<span class="time">{{ state.workingTimeFormat }}</span>
  19. </div>
  20. <div @click="onChangeWorkState()" class="working-opt working-rest">
  21. {{ state.pauseWork ? t('dashboard.Continue to work') : t('dashboard.have a bit of rest') }}
  22. </div>
  23. </div>
  24. </el-col>
  25. </el-row>
  26. </div> -->
  27. <el-row :gutter="20">
  28. <el-col :sm="12" :lg="12">
  29. <el-card style="height: calc(50% - 10px);">
  30. <div class="small-panel-box">
  31. <div class="panel-title-box">
  32. <div class="title">互认情况</div>
  33. <div>
  34. <el-radio-group v-model="radio2" size="small" @change="eventHandler($event)">
  35. <el-radio-button label="周" value="1" />
  36. <el-radio-button label="月" value="2" />
  37. </el-radio-group>
  38. </div>
  39. </div>
  40. <el-row :gutter="20">
  41. <el-col :sm="12" :lg="8">
  42. <div class="small-panel user-reg suspension" style="border-left: 2px solid #D9001B;border-top-left-radius: 0;border-bottom-left-radius: 0;">
  43. <div class="small-panel-title">互认的患者</div>
  44. <div class="small-panel-content">
  45. <div class="content-left">
  46. <!-- <Icon color="#8595F4" size="20" name="fa fa-line-chart" /> -->
  47. <!-- <Icon color="#74A8B5" size="20" name="fa fa-users" /> -->
  48. <span id="user_reg_number">{{state.dashboardData?.hr?.patient}}</span>
  49. <span class="text">人次</span>
  50. </div>
  51. <!-- <div class="content-right">+14%</div> -->
  52. </div>
  53. </div>
  54. </el-col>
  55. <el-col :sm="12" :lg="8">
  56. <div class="small-panel file suspension" style="border-left: 2px solid #95f204;border-top-left-radius: 0;border-bottom-left-radius: 0;">
  57. <div class="small-panel-title">互认的医学影像项目</div>
  58. <div class="small-panel-content">
  59. <div class="content-left">
  60. <!-- <Icon color="#AD85F4" size="20" name="fa fa-file-text" /> -->
  61. <span id="file_number">{{state.dashboardData?.hr?.jc}}</span>
  62. <span class="text">项</span>
  63. </div>
  64. <!-- <div class="content-right">+50%</div> -->
  65. </div>
  66. </div>
  67. </el-col>
  68. <el-col :sm="12" :lg="8">
  69. <div class="small-panel users suspension" style="border-left: 2px solid #02A7F0;border-top-left-radius: 0;border-bottom-left-radius: 0;">
  70. <div class="small-panel-title">互认的检验项目</div>
  71. <div class="small-panel-content">
  72. <div class="content-left">
  73. <!-- <Icon color="#74A8B5" size="20" name="fa fa-users" /> -->
  74. <!-- <Icon color="#AD85F4" size="20" name="fa fa-file-text" /> -->
  75. <span id="users_number">{{state.dashboardData?.hr?.jy}}</span>
  76. <span class="text">项</span>
  77. </div>
  78. <!-- <div class="content-right">+28%</div> -->
  79. </div>
  80. </div>
  81. </el-col>
  82. </el-row>
  83. </div>
  84. </el-card>
  85. <el-card style="height: calc(50% - 10px);">
  86. <div class="small-panel-box is-active">
  87. <div class="title">互认项目字典</div>
  88. <el-row :gutter="20">
  89. <el-col :sm="12" :lg="12" @click="goDict('1')">
  90. <div class="small-panel user-reg suspension" style="border-left: 2px solid #EC808D;border-top-left-radius: 0;border-bottom-left-radius: 0;">
  91. <div class="small-panel-title" style="text-align: center;">医学影像项目</div>
  92. <div class="small-panel-content">
  93. <div class="content-left">
  94. <!-- <Icon color="#8595F4" size="20" name="fa fa-line-chart" /> -->
  95. <!-- <Icon color="#AD85F4" size="20" name="fa fa-file-text" /> -->
  96. <span id="user_reg_number">{{state.dashboardData?.dict?.jc}}</span>
  97. <span class="text">人次</span>
  98. </div>
  99. <!-- <div class="content-right">+14%</div> -->
  100. </div>
  101. </div>
  102. </el-col>
  103. <el-col :sm="12" :lg="12" @click="goDict('2')">
  104. <div class="small-panel file suspension" style="border-left: 2px solid #C280FF;border-top-left-radius: 0;border-bottom-left-radius: 0;">
  105. <div class="small-panel-title" style="text-align: center;">临床检验项目</div>
  106. <div class="small-panel-content">
  107. <div class="content-left">
  108. <!-- <Icon color="#AD85F4" size="20" name="fa fa-file-text" /> -->
  109. <span id="file_number">{{state.dashboardData?.dict?.jy}}</span>
  110. <span class="text">项</span>
  111. </div>
  112. <!-- <div class="content-right">+50%</div> -->
  113. </div>
  114. </div>
  115. </el-col>
  116. </el-row>
  117. </div>
  118. </el-card>
  119. </el-col>
  120. <el-col :sm="12" :lg="12" style="padding-left: 0;">
  121. <el-card>
  122. <div class="small-panel-box">
  123. <div class="title" style="display: flex;justify-content: space-between;align-items: center;">
  124. <span>今日互认动态</span>
  125. <span class="more" @click="goHRResult">更多>></span>
  126. </div>
  127. <div class="table-container" v-loading="!state.tableData">
  128. <el-table :data="state.tableData" border class="top-table" header-cell-class-name="table-header-cell" showOverflowTooltip style="width: 100%;">
  129. <!-- 列定义 -->
  130. <el-table-column type="index" align="center" />
  131. <!-- <el-table-column prop="create_time" label="互认的时间" width="100" align="center"></el-table-column> -->
  132. <el-table-column prop="create_time" label="互认时间" width="81" align="center">
  133. <template #default="scope">
  134. <span>{{timeFormat(scope.row.create_time, 'hh:MM')}}</span>
  135. </template>
  136. </el-table-column>
  137. <el-table-column prop="ORGNAME" label="所属机构" align="center"></el-table-column>
  138. <el-table-column prop="NAME" label="姓名" width="60" align="center"></el-table-column>
  139. <el-table-column prop="LAB_ITEMNAME" label="检验项目" align="center"></el-table-column>
  140. <el-table-column prop="EXAM_ITEMNAME" label="检查项目" align="center"></el-table-column>
  141. <el-table-column prop="HRORGNAME" label="互认机构" align="center"></el-table-column>
  142. </el-table>
  143. <Vue3SeamlessScroll class="seamless" :list="state.tableData" :loop="false" :hover="true" :step="0.4" :wheel="true" :isWatch="true">
  144. <el-table
  145. ref="tableRef" :fit="true" :data="state.tableData" class="bottom-table" header-cell-class-name="table-header-cell" stripe showOverflowTooltip
  146. style="width: 100%">
  147. <!-- 表格列定义 -->
  148. <el-table-column type="index" align="center" />
  149. <!-- <el-table-column prop="create_time" label="互认的时间" width="100" align="center"></el-table-column> -->
  150. <el-table-column prop="create_time" label="互认的时间" width="81" align="center">
  151. <template #default="scope">
  152. <span>{{timeFormat(scope.row.create_time, 'hh:MM')}}</span>
  153. </template>
  154. </el-table-column>
  155. <el-table-column prop="ORGNAME" label="所属机构" align="center"></el-table-column>
  156. <el-table-column prop="NAME" label="姓名" width="60" align="center"></el-table-column>
  157. <el-table-column prop="LAB_ITEMNAME" label="检验项目" align="center"></el-table-column>
  158. <el-table-column prop="EXAM_ITEMNAME" label="检查项目" align="center"></el-table-column>
  159. <el-table-column prop="HRORGNAME" label="互认机构" align="center"></el-table-column>
  160. <!-- 其他列 -->
  161. </el-table>
  162. </Vue3SeamlessScroll>
  163. </div>
  164. </div>
  165. </el-card>
  166. </el-col>
  167. </el-row>
  168. <el-card>
  169. <div class="small-panel-box">
  170. <div class="title">参与互认的机构统计</div>
  171. <el-row :gutter="20">
  172. <el-col :sm="12" :lg="3" v-for="([key, value]) in state.dashboardData?.hr_ins && Object.entries(state.dashboardData?.hr_ins)" :key="key">
  173. <div class="small-panel user-reg suspension">
  174. <div class="small-panel-title">{{key}}</div>
  175. <div class="small-panel-content">
  176. <div class="content-left">
  177. <!-- <Icon color="#8595F4" size="20" name="fa fa-line-chart" /> -->
  178. <span id="user_reg_number">{{value}}</span>
  179. <span class="text">家</span>
  180. </div>
  181. <!-- <div class="content-right">+14%</div> -->
  182. </div>
  183. </div>
  184. </el-col>
  185. </el-row>
  186. </div>
  187. </el-card>
  188. <el-card>
  189. <div class="small-panel-box is-active">
  190. <div class="title" style="display: flex;justify-content: space-between;align-items: center;">
  191. <span>参与互认的机构</span>
  192. <div class="mt-4">
  193. <el-input
  194. v-model="state.insNameValue"
  195. style="max-width: 600px"
  196. placeholder="请输入机构名称过滤"
  197. class="input-with-select"
  198. clearable
  199. >
  200. <template #prepend>
  201. <el-select v-model="state.insTypeValue" @change="handelTypeChange" placeholder="机构类型" clearable style="width: 115px">
  202. <el-option v-for="(item, index) in state.insTypeOption" :key="index" :label="item.label" :value="item.label" />
  203. <!-- <el-option label="Order No." value="2" /> -->
  204. <!-- <el-option label="Tel" value="3" /> -->
  205. </el-select>
  206. </template>
  207. <template #append>
  208. <el-button :icon="Search" @click="handelSearch"/>
  209. </template>
  210. </el-input>
  211. </div>
  212. </div>
  213. <el-row :gutter="20">
  214. <el-col :sm="12" :lg="6" v-for="(item, i) in state.all_ins" :key="i" @click="goInstitution(item)">
  215. <div class="small-panel user-reg suspension ins-panel">
  216. <div class="small-panel-title">{{item.name}}</div>
  217. <div class="small-panel-type">机构类型: {{item.institution_type}}</div>
  218. <div class="small-panel-type">创建时间: {{item.create_time}}</div>
  219. <!-- <div class="small-panel-content">
  220. <div class="content-left">
  221. <Icon color="#8595F4" size="20" name="fa fa-line-chart" />
  222. <span id="user_reg_number">{{value}}</span>
  223. <span class="text">家</span>
  224. </div>
  225. </div> -->
  226. </div>
  227. </el-col>
  228. </el-row>
  229. </div>
  230. </el-card>
  231. <!-- <div class="growth-chart">
  232. <el-row :gutter="20">
  233. <el-col class="lg-mb-20" :xs="24" :sm="24" :md="12" :lg="9">
  234. <el-card shadow="hover" :header="t('dashboard.Membership growth')">
  235. <div class="user-growth-chart" :ref="chartRefs.set"></div>
  236. </el-card>
  237. </el-col>
  238. <el-col class="lg-mb-20" :xs="24" :sm="24" :md="12" :lg="9">
  239. <el-card shadow="hover" :header="t('dashboard.Annex growth')">
  240. <div class="file-growth-chart" :ref="chartRefs.set"></div>
  241. </el-card>
  242. </el-col>
  243. <el-col :xs="24" :sm="24" :md="24" :lg="6">
  244. <el-card class="new-user-card" shadow="hover" :header="t('dashboard.New member')">
  245. <div class="new-user-growth">
  246. <el-scrollbar>
  247. <div class="new-user-item">
  248. <img class="new-user-avatar" src="~assets/login-header.png" alt="" />
  249. <div class="new-user-base">
  250. <div class="new-user-name">妙码生花</div>
  251. <div class="new-user-time">12分钟前{{ t('dashboard.Joined us') }}</div>
  252. </div>
  253. <Icon class="new-user-arrow" color="#8595F4" name="fa fa-angle-right" />
  254. </div>
  255. <div class="new-user-item">
  256. <img class="new-user-avatar" src="~assets/login-header.png" alt="" />
  257. <div class="new-user-base">
  258. <div class="new-user-name">码上生花</div>
  259. <div class="new-user-time">12分钟前{{ t('dashboard.Joined us') }}</div>
  260. </div>
  261. <Icon class="new-user-arrow" color="#8595F4" name="fa fa-angle-right" />
  262. </div>
  263. <div class="new-user-item">
  264. <img class="new-user-avatar" src="~assets/login-header.png" alt="" />
  265. <div class="new-user-base">
  266. <div class="new-user-name">Admin</div>
  267. <div class="new-user-time">12分钟前{{ t('dashboard.Joined us') }}</div>
  268. </div>
  269. <Icon class="new-user-arrow" color="#8595F4" name="fa fa-angle-right" />
  270. </div>
  271. <div class="new-user-item">
  272. <img class="new-user-avatar" :src="fullUrl('/static/images/avatar.png')" alt="" />
  273. <div class="new-user-base">
  274. <div class="new-user-name">纯属虚构</div>
  275. <div class="new-user-time">12分钟前{{ t('dashboard.Joined us') }}</div>
  276. </div>
  277. <Icon class="new-user-arrow" color="#8595F4" name="fa fa-angle-right" />
  278. </div>
  279. </el-scrollbar>
  280. </div>
  281. </el-card>
  282. </el-col>
  283. </el-row>
  284. </div> -->
  285. <!-- <div class="growth-chart">
  286. <el-row :gutter="20">
  287. <el-col class="lg-mb-20" :xs="24" :sm="24" :md="24" :lg="12">
  288. <el-card shadow="hover" :header="t('dashboard.Member source')">
  289. <div class="user-source-chart" :ref="chartRefs.set"></div>
  290. </el-card>
  291. </el-col>
  292. <el-col class="lg-mb-20" :xs="24" :sm="24" :md="24" :lg="12">
  293. <el-card shadow="hover" :header="t('dashboard.Member last name')">
  294. <div class="user-surname-chart" :ref="chartRefs.set"></div>
  295. </el-card>
  296. </el-col>
  297. </el-row>
  298. </div> -->
  299. </div>
  300. </template>
  301. <script setup lang="ts">
  302. import { onMounted, onUnmounted, reactive, ref, nextTick, onActivated, watch, onBeforeMount, onBeforeUnmount } from 'vue'
  303. import headerSvg from '/@/assets/dashboard/header-1.svg'
  304. import coffeeSvg from '/@/assets/dashboard/coffee.svg'
  305. import { CountUp } from 'countup.js'
  306. import * as echarts from 'echarts'
  307. import { useNavTabs } from '/@/stores/navTabs'
  308. import { useTemplateRefsList } from '@vueuse/core'
  309. import { index, getDashboard, getHrpatientList, getInsType, getAllIns } from '/@/api/backend/dashboard'
  310. import { useI18n } from 'vue-i18n'
  311. import { Local } from '/@/utils/storage'
  312. import { useAdminInfo } from '/@/stores/adminInfo'
  313. import { WORKING_TIME } from '/@/stores/constant/cacheKey'
  314. import { fullUrl, getGreet } from '/@/utils/common'
  315. import { useEventListener } from '@vueuse/core'
  316. import { setTimeout } from 'timers/promises'
  317. import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
  318. import { routePush } from '/@/utils/router'
  319. import { timeFormat } from '/@/utils/common'
  320. import { Search, Delete } from '@element-plus/icons-vue'
  321. let workTimer: number
  322. defineOptions({
  323. name: 'dashboard',
  324. })
  325. const classOptions = reactive({
  326. step: 0.5,//滚动速度值越大越快,但是值太小会卡顿
  327. limitMoveNum: 10,//无缝滚动列表元素的长度,一般设置为列表的长度
  328. direction: 1,//方向: 0 往下 1 往上 2 向左 3 向右。
  329. });
  330. const d = new Date()
  331. const { t } = useI18n()
  332. const navTabs = useNavTabs()
  333. const adminInfo = useAdminInfo()
  334. const chartRefs = useTemplateRefsList<HTMLDivElement>()
  335. const state: {
  336. charts: any[]
  337. remark: string
  338. workingTimeFormat: string
  339. pauseWork: boolean
  340. dashboardData: any
  341. tableData: any[]
  342. lastId: string
  343. insNameValue: string
  344. insTypeValue: string
  345. insTypeOption: any[]
  346. stempDashboardData: any[]
  347. all_ins: any[]
  348. } = reactive({
  349. charts: [],
  350. remark: 'dashboard.Loading',
  351. workingTimeFormat: '',
  352. pauseWork: false,
  353. dashboardData: {},
  354. tableData: [],
  355. lastId: '',
  356. insNameValue: '',
  357. insTypeValue: '',
  358. insTypeOption: [],
  359. stempDashboardData: [],
  360. all_ins: []
  361. })
  362. const radio2 = ref('1')
  363. index().then((res) => {
  364. state.remark = res.data.remark
  365. })
  366. const fetchDashboard = () => {
  367. // 1 按周统计 2 按月统计
  368. getDashboard({type: radio2.value}).then((res) => {
  369. // state.stempDashboardData = res.data.all_ins
  370. state.dashboardData = res.data
  371. // state.dashboardData.all_ins = state.stempDashboardData.filter((item: any) => state.insNameValue ? item.name === state.insNameValue && item.institution_type === e : item.institution_type === e);
  372. })
  373. }
  374. const fetchAllIns = () => {
  375. getAllIns({type: state.insTypeValue, name: state.insNameValue}).then((res) => {
  376. state.all_ins = res.data.all_ins
  377. })
  378. }
  379. const fetchGetInsType = () => {
  380. getInsType().then((res) => {
  381. console.log(res)
  382. state.insTypeOption = res.data.map((item:any, index:any) => {
  383. return {
  384. label: item,
  385. value: index
  386. }
  387. })
  388. console.log(state.insTypeOption, '00909090')
  389. })
  390. }
  391. const handelTypeChange = (e: any) => {
  392. fetchAllIns()
  393. // state.dashboardData.all_ins = state.stempDashboardData.filter((item: any) => state.insNameValue ? item.name === state.insNameValue && item.institution_type === e : item.institution_type === e);
  394. }
  395. const handelSearch = () => {
  396. fetchAllIns()
  397. // if(state.insNameValue == '') {
  398. // state.dashboardData.all_ins = state.stempDashboardData.filter((item: any) => state.insTypeValue ? item.institution_type === state.insTypeValue : item);
  399. // return
  400. // }
  401. // state.dashboardData.all_ins = state.stempDashboardData.filter((item: any) => state.insTypeValue ? item.institution_type === state.insTypeValue && item.name === state.insNameValue : item.name === state.insNameValue);
  402. }
  403. const eventHandler = (e: string) => {
  404. radio2.value = e
  405. fetchDashboard()
  406. }
  407. const fetchHrpatientList = () => {
  408. getHrpatientList({ID: state.lastId || 0 }).then((res) => {
  409. // state.tableData = res.data.list
  410. if (res.data.list.length > 0 && res.data.list.some((item: any) => !state.tableData.includes(item))) {
  411. state.tableData.push(...res.data.list.filter((item: any) => !state.tableData.includes(item)));
  412. }
  413. console.log(state.tableData.length)
  414. state.lastId = res.data.lastId
  415. })
  416. }
  417. const tableRef = ref<any>(null);
  418. const goDict = (type: string) => {
  419. // type 1 影像互认字典 2 检验互认字典
  420. type === '1'?routePush('/admin/dict/examproject'):routePush('/admin/dict/labitem')
  421. // routePush('/admin/dict/labitem')
  422. }
  423. const goHRResult = () => {
  424. routePush('/admin/hospital/hrpatient')
  425. }
  426. const goInstitution = (item: any) => {
  427. routePush('/admin/hospital/hrpatient?name=' + item.name + '&code=' + item.institution_code)
  428. }
  429. const countUpFun = (id: string) => {
  430. nextTick(() => {
  431. let value = document.getElementById(id)?.innerText
  432. if (value) {
  433. new CountUp(id, parseInt(value), {
  434. startVal: 0,
  435. duration: 3,
  436. }).start()
  437. }
  438. })
  439. }
  440. const initCountUp = () => {
  441. countUpFun('user_reg_number')
  442. countUpFun('file_number')
  443. countUpFun('users_number')
  444. countUpFun('addons_number')
  445. }
  446. const initUserGrowthChart = () => {
  447. const userGrowthChart = echarts.init(chartRefs.value[0] as HTMLElement)
  448. const option = {
  449. grid: {
  450. top: 0,
  451. right: 0,
  452. bottom: 20,
  453. left: 0,
  454. },
  455. xAxis: {
  456. data: [
  457. t('dashboard.Monday'),
  458. t('dashboard.Tuesday'),
  459. t('dashboard.Wednesday'),
  460. t('dashboard.Thursday'),
  461. t('dashboard.Friday'),
  462. t('dashboard.Saturday'),
  463. t('dashboard.Sunday'),
  464. ],
  465. },
  466. yAxis: {},
  467. legend: {
  468. data: [t('dashboard.Visits'), t('dashboard.Registration volume')],
  469. textStyle: {
  470. color: '#73767a',
  471. },
  472. },
  473. series: [
  474. {
  475. name: t('dashboard.Visits'),
  476. data: [100, 160, 280, 230, 190, 200, 480],
  477. type: 'line',
  478. smooth: true,
  479. areaStyle: {
  480. color: '#8595F4',
  481. },
  482. },
  483. {
  484. name: t('dashboard.Registration volume'),
  485. data: [45, 180, 146, 99, 210, 127, 288],
  486. type: 'line',
  487. smooth: true,
  488. areaStyle: {
  489. color: '#F48595',
  490. opacity: 0.5,
  491. },
  492. },
  493. ],
  494. }
  495. userGrowthChart.setOption(option)
  496. state.charts.push(userGrowthChart)
  497. }
  498. const initFileGrowthChart = () => {
  499. const fileGrowthChart = echarts.init(chartRefs.value[1] as HTMLElement)
  500. const option = {
  501. grid: {
  502. top: 30,
  503. right: 0,
  504. bottom: 20,
  505. left: 0,
  506. },
  507. tooltip: {
  508. trigger: 'item',
  509. },
  510. legend: {
  511. type: 'scroll',
  512. bottom: 15,
  513. data: (function () {
  514. var list = []
  515. for (var i = 1; i <= 12; i++) {
  516. list.push(i + t('dashboard.month'))
  517. }
  518. return list
  519. })(),
  520. textStyle: {
  521. color: '#73767a',
  522. },
  523. },
  524. visualMap: {
  525. top: 'middle',
  526. right: 10,
  527. color: ['red', 'yellow'],
  528. calculable: true,
  529. },
  530. radar: {
  531. indicator: [
  532. { name: t('dashboard.picture') },
  533. { name: t('dashboard.file') },
  534. { name: t('dashboard.table') },
  535. { name: t('dashboard.Compressed package') },
  536. ],
  537. },
  538. series: (function () {
  539. var series = []
  540. for (var i = 1; i <= 12; i++) {
  541. series.push({
  542. type: 'radar',
  543. symbol: 'none',
  544. lineStyle: {
  545. width: 1,
  546. },
  547. emphasis: {
  548. areaStyle: {
  549. color: 'rgba(0,250,0,0.3)',
  550. },
  551. },
  552. data: [
  553. {
  554. value: [(40 - i) * 10, (38 - i) * 4 + 60, i * 5 + 10, i * 20],
  555. name: i + t('dashboard.month'),
  556. },
  557. ],
  558. })
  559. }
  560. return series
  561. })(),
  562. }
  563. fileGrowthChart.setOption(option)
  564. state.charts.push(fileGrowthChart)
  565. }
  566. const initUserSourceChart = () => {
  567. const UserSourceChart = echarts.init(chartRefs.value[2] as HTMLElement)
  568. const pathSymbols = {
  569. reindeer:
  570. 'path://M-22.788,24.521c2.08-0.986,3.611-3.905,4.984-5.892 c-2.686,2.782-5.047,5.884-9.102,7.312c-0.992,0.005-0.25-2.016,0.34-2.362l1.852-0.41c0.564-0.218,0.785-0.842,0.902-1.347 c2.133-0.727,4.91-4.129,6.031-6.194c1.748-0.7,4.443-0.679,5.734-2.293c1.176-1.468,0.393-3.992,1.215-6.557 c0.24-0.754,0.574-1.581,1.008-2.293c-0.611,0.011-1.348-0.061-1.959-0.608c-1.391-1.245-0.785-2.086-1.297-3.313 c1.684,0.744,2.5,2.584,4.426,2.586C-8.46,3.012-8.255,2.901-8.04,2.824c6.031-1.952,15.182-0.165,19.498-3.937 c1.15-3.933-1.24-9.846-1.229-9.938c0.008-0.062-1.314-0.004-1.803-0.258c-1.119-0.771-6.531-3.75-0.17-3.33 c0.314-0.045,0.943,0.259,1.439,0.435c-0.289-1.694-0.92-0.144-3.311-1.946c0,0-1.1-0.855-1.764-1.98 c-0.836-1.09-2.01-2.825-2.992-4.031c-1.523-2.476,1.367,0.709,1.816,1.108c1.768,1.704,1.844,3.281,3.232,3.983 c0.195,0.203,1.453,0.164,0.926-0.468c-0.525-0.632-1.367-1.278-1.775-2.341c-0.293-0.703-1.311-2.326-1.566-2.711 c-0.256-0.384-0.959-1.718-1.67-2.351c-1.047-1.187-0.268-0.902,0.521-0.07c0.789,0.834,1.537,1.821,1.672,2.023 c0.135,0.203,1.584,2.521,1.725,2.387c0.102-0.259-0.035-0.428-0.158-0.852c-0.125-0.423-0.912-2.032-0.961-2.083 c-0.357-0.852-0.566-1.908-0.598-3.333c0.4-2.375,0.648-2.486,0.549-0.705c0.014,1.143,0.031,2.215,0.602,3.247 c0.807,1.496,1.764,4.064,1.836,4.474c0.561,3.176,2.904,1.749,2.281-0.126c-0.068-0.446-0.109-2.014-0.287-2.862 c-0.18-0.849-0.219-1.688-0.113-3.056c0.066-1.389,0.232-2.055,0.277-2.299c0.285-1.023,0.4-1.088,0.408,0.135 c-0.059,0.399-0.131,1.687-0.125,2.655c0.064,0.642-0.043,1.768,0.172,2.486c0.654,1.928-0.027,3.496,1,3.514 c1.805-0.424,2.428-1.218,2.428-2.346c-0.086-0.704-0.121-0.843-0.031-1.193c0.221-0.568,0.359-0.67,0.312-0.076 c-0.055,0.287,0.031,0.533,0.082,0.794c0.264,1.197,0.912,0.114,1.283-0.782c0.15-0.238,0.539-2.154,0.545-2.522 c-0.023-0.617,0.285-0.645,0.309,0.01c0.064,0.422-0.248,2.646-0.205,2.334c-0.338,1.24-1.105,3.402-3.379,4.712 c-0.389,0.12-1.186,1.286-3.328,2.178c0,0,1.729,0.321,3.156,0.246c1.102-0.19,3.707-0.027,4.654,0.269 c1.752,0.494,1.531-0.053,4.084,0.164c2.26-0.4,2.154,2.391-1.496,3.68c-2.549,1.405-3.107,1.475-2.293,2.984 c3.484,7.906,2.865,13.183,2.193,16.466c2.41,0.271,5.732-0.62,7.301,0.725c0.506,0.333,0.648,1.866-0.457,2.86 c-4.105,2.745-9.283,7.022-13.904,7.662c-0.977-0.194,0.156-2.025,0.803-2.247l1.898-0.03c0.596-0.101,0.936-0.669,1.152-1.139 c3.16-0.404,5.045-3.775,8.246-4.818c-4.035-0.718-9.588,3.981-12.162,1.051c-5.043,1.423-11.449,1.84-15.895,1.111 c-3.105,2.687-7.934,4.021-12.115,5.866c-3.271,3.511-5.188,8.086-9.967,10.414c-0.986,0.119-0.48-1.974,0.066-2.385l1.795-0.618 C-22.995,25.682-22.849,25.035-22.788,24.521z',
  571. plane: 'path://M1.112,32.559l2.998,1.205l-2.882,2.268l-2.215-0.012L1.112,32.559z M37.803,23.96 c0.158-0.838,0.5-1.509,0.961-1.904c-0.096-0.037-0.205-0.071-0.344-0.071c-0.777-0.005-2.068-0.009-3.047-0.009 c-0.633,0-1.217,0.066-1.754,0.18l2.199,1.804H37.803z M39.738,23.036c-0.111,0-0.377,0.325-0.537,0.924h1.076 C40.115,23.361,39.854,23.036,39.738,23.036z M39.934,39.867c-0.166,0-0.674,0.705-0.674,1.986s0.506,1.986,0.674,1.986 s0.672-0.705,0.672-1.986S40.102,39.867,39.934,39.867z M38.963,38.889c-0.098-0.038-0.209-0.07-0.348-0.073 c-0.082,0-0.174,0-0.268-0.001l-7.127,4.671c0.879,0.821,2.42,1.417,4.348,1.417c0.979,0,2.27-0.006,3.047-0.01 c0.139,0,0.25-0.034,0.348-0.072c-0.646-0.555-1.07-1.643-1.07-2.967C37.891,40.529,38.316,39.441,38.963,38.889z M32.713,23.96 l-12.37-10.116l-4.693-0.004c0,0,4,8.222,4.827,10.121H32.713z M59.311,32.374c-0.248,2.104-5.305,3.172-8.018,3.172H39.629 l-25.325,16.61L9.607,52.16c0,0,6.687-8.479,7.95-10.207c1.17-1.6,3.019-3.699,3.027-6.407h-2.138 c-5.839,0-13.816-3.789-18.472-5.583c-2.818-1.085-2.396-4.04-0.031-4.04h0.039l-3.299-11.371h3.617c0,0,4.352,5.696,5.846,7.5 c2,2.416,4.503,3.678,8.228,3.87h30.727c2.17,0,4.311,0.417,6.252,1.046c3.49,1.175,5.863,2.7,7.199,4.027 C59.145,31.584,59.352,32.025,59.311,32.374z M22.069,30.408c0-0.815-0.661-1.475-1.469-1.475c-0.812,0-1.471,0.66-1.471,1.475 s0.658,1.475,1.471,1.475C21.408,31.883,22.069,31.224,22.069,30.408z M27.06,30.408c0-0.815-0.656-1.478-1.466-1.478 c-0.812,0-1.471,0.662-1.471,1.478s0.658,1.477,1.471,1.477C26.404,31.885,27.06,31.224,27.06,30.408z M32.055,30.408 c0-0.815-0.66-1.475-1.469-1.475c-0.808,0-1.466,0.66-1.466,1.475s0.658,1.475,1.466,1.475 C31.398,31.883,32.055,31.224,32.055,30.408z M37.049,30.408c0-0.815-0.658-1.478-1.467-1.478c-0.812,0-1.469,0.662-1.469,1.478 s0.656,1.477,1.469,1.477C36.389,31.885,37.049,31.224,37.049,30.408z M42.039,30.408c0-0.815-0.656-1.478-1.465-1.478 c-0.811,0-1.469,0.662-1.469,1.478s0.658,1.477,1.469,1.477C41.383,31.885,42.039,31.224,42.039,30.408z M55.479,30.565 c-0.701-0.436-1.568-0.896-2.627-1.347c-0.613,0.289-1.551,0.476-2.73,0.476c-1.527,0-1.639,2.263,0.164,2.316 C52.389,32.074,54.627,31.373,55.479,30.565z',
  572. rocket: 'path://M-244.396,44.399c0,0,0.47-2.931-2.427-6.512c2.819-8.221,3.21-15.709,3.21-15.709s5.795,1.383,5.795,7.325C-237.818,39.679-244.396,44.399-244.396,44.399z M-260.371,40.827c0,0-3.881-12.946-3.881-18.319c0-2.416,0.262-4.566,0.669-6.517h17.684c0.411,1.952,0.675,4.104,0.675,6.519c0,5.291-3.87,18.317-3.87,18.317H-260.371z M-254.745,18.951c-1.99,0-3.603,1.676-3.603,3.744c0,2.068,1.612,3.744,3.603,3.744c1.988,0,3.602-1.676,3.602-3.744S-252.757,18.951-254.745,18.951z M-255.521,2.228v-5.098h1.402v4.969c1.603,1.213,5.941,5.069,7.901,12.5h-17.05C-261.373,7.373-257.245,3.558-255.521,2.228zM-265.07,44.399c0,0-6.577-4.721-6.577-14.896c0-5.942,5.794-7.325,5.794-7.325s0.393,7.488,3.211,15.708C-265.539,41.469-265.07,44.399-265.07,44.399z M-252.36,45.15l-1.176-1.22L-254.789,48l-1.487-4.069l-1.019,2.116l-1.488-3.826h8.067L-252.36,45.15z',
  573. train: 'path://M67.335,33.596L67.335,33.596c-0.002-1.39-1.153-3.183-3.328-4.218h-9.096v-2.07h5.371 c-4.939-2.07-11.199-4.141-14.89-4.141H19.72v12.421v5.176h38.373c4.033,0,8.457-1.035,9.142-5.176h-0.027 c0.076-0.367,0.129-0.751,0.129-1.165L67.335,33.596L67.335,33.596z M27.999,30.413h-3.105v-4.141h3.105V30.413z M35.245,30.413 h-3.104v-4.141h3.104V30.413z M42.491,30.413h-3.104v-4.141h3.104V30.413z M49.736,30.413h-3.104v-4.141h3.104V30.413z M14.544,40.764c1.143,0,2.07-0.927,2.07-2.07V35.59V25.237c0-1.145-0.928-2.07-2.07-2.07H-9.265c-1.143,0-2.068,0.926-2.068,2.07 v10.351v3.105c0,1.144,0.926,2.07,2.068,2.07H14.544L14.544,40.764z M8.333,26.272h3.105v4.141H8.333V26.272z M1.087,26.272h3.105 v4.141H1.087V26.272z M-6.159,26.272h3.105v4.141h-3.105V26.272z M-9.265,41.798h69.352v1.035H-9.265V41.798z',
  574. }
  575. const option = {
  576. tooltip: {
  577. trigger: 'axis',
  578. axisPointer: {
  579. type: 'none',
  580. },
  581. formatter: function (params: any) {
  582. return params[0].name + ': ' + params[0].value
  583. },
  584. },
  585. xAxis: {
  586. data: [t('dashboard.Baidu'), t('dashboard.Direct access'), t('dashboard.take a plane'), t('dashboard.Take the high-speed railway')],
  587. axisTick: { show: false },
  588. axisLine: { show: false },
  589. axisLabel: {
  590. color: '#e54035',
  591. },
  592. },
  593. yAxis: {
  594. splitLine: { show: false },
  595. axisTick: { show: false },
  596. axisLine: { show: false },
  597. axisLabel: { show: false },
  598. },
  599. color: ['#e54035'],
  600. series: [
  601. {
  602. name: 'hill',
  603. type: 'pictorialBar',
  604. barCategoryGap: '-130%',
  605. symbol: 'path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z',
  606. itemStyle: {
  607. opacity: 0.5,
  608. },
  609. emphasis: {
  610. itemStyle: {
  611. opacity: 1,
  612. },
  613. },
  614. data: [123, 60, 25, 80],
  615. z: 10,
  616. },
  617. {
  618. name: 'glyph',
  619. type: 'pictorialBar',
  620. barGap: '-100%',
  621. symbolPosition: 'end',
  622. symbolSize: 50,
  623. symbolOffset: [0, '-120%'],
  624. data: [
  625. {
  626. value: 123,
  627. symbol: pathSymbols.reindeer,
  628. symbolSize: [60, 60],
  629. },
  630. {
  631. value: 60,
  632. symbol: pathSymbols.rocket,
  633. symbolSize: [50, 60],
  634. },
  635. {
  636. value: 25,
  637. symbol: pathSymbols.plane,
  638. symbolSize: [65, 35],
  639. },
  640. {
  641. value: 80,
  642. symbol: pathSymbols.train,
  643. symbolSize: [50, 30],
  644. },
  645. ],
  646. },
  647. ],
  648. }
  649. UserSourceChart.setOption(option)
  650. state.charts.push(UserSourceChart)
  651. }
  652. const initUserSurnameChart = () => {
  653. const userSurnameChart = echarts.init(chartRefs.value[3] as HTMLElement)
  654. const data = genData(50)
  655. const option = {
  656. tooltip: {
  657. trigger: 'item',
  658. formatter: '{a} <br/>{b} : {c} ({d}%)',
  659. },
  660. legend: {
  661. type: 'scroll',
  662. orient: 'vertical',
  663. right: 10,
  664. top: 20,
  665. bottom: 20,
  666. data: data.legendData,
  667. textStyle: {
  668. color: '#73767a',
  669. },
  670. },
  671. series: [
  672. {
  673. name: t('dashboard.full name'),
  674. type: 'pie',
  675. radius: '55%',
  676. center: ['40%', '50%'],
  677. data: data.seriesData,
  678. emphasis: {
  679. itemStyle: {
  680. shadowBlur: 10,
  681. shadowOffsetX: 0,
  682. shadowColor: 'rgba(0, 0, 0, 0.5)',
  683. },
  684. },
  685. },
  686. ],
  687. }
  688. function genData(count: any) {
  689. // prettier-ignore
  690. const nameList = [
  691. '赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危'
  692. ];
  693. const legendData = []
  694. const seriesData = []
  695. for (var i = 0; i < count; i++) {
  696. var name = Math.random() > 0.65 ? makeWord(4, 1) + '·' + makeWord(3, 0) : makeWord(2, 1)
  697. legendData.push(name)
  698. seriesData.push({
  699. name: name,
  700. value: Math.round(Math.random() * 100000),
  701. })
  702. }
  703. return {
  704. legendData: legendData,
  705. seriesData: seriesData,
  706. }
  707. function makeWord(max: any, min: any) {
  708. const nameLen = Math.ceil(Math.random() * max + min)
  709. const name = []
  710. for (var i = 0; i < nameLen; i++) {
  711. name.push(nameList[Math.round(Math.random() * nameList.length - 1)])
  712. }
  713. return name.join('')
  714. }
  715. }
  716. userSurnameChart.setOption(option)
  717. state.charts.push(userSurnameChart)
  718. }
  719. const echartsResize = () => {
  720. nextTick(() => {
  721. for (const key in state.charts) {
  722. state.charts[key].resize()
  723. }
  724. })
  725. }
  726. const onChangeWorkState = () => {
  727. const time = parseInt((new Date().getTime() / 1000).toString())
  728. const workingTime = Local.get(WORKING_TIME)
  729. if (state.pauseWork) {
  730. // 继续工作
  731. workingTime.pauseTime += time - workingTime.startPauseTime
  732. workingTime.startPauseTime = 0
  733. Local.set(WORKING_TIME, workingTime)
  734. state.pauseWork = false
  735. startWork()
  736. } else {
  737. // 暂停工作
  738. workingTime.startPauseTime = time
  739. Local.set(WORKING_TIME, workingTime)
  740. clearInterval(workTimer)
  741. state.pauseWork = true
  742. }
  743. }
  744. const startWork = () => {
  745. const workingTime = Local.get(WORKING_TIME) || { date: '', startTime: 0, pauseTime: 0, startPauseTime: 0 }
  746. const currentDate = d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate()
  747. const time = parseInt((new Date().getTime() / 1000).toString())
  748. if (workingTime.date != currentDate) {
  749. workingTime.date = currentDate
  750. workingTime.startTime = time
  751. workingTime.pauseTime = workingTime.startPauseTime = 0
  752. Local.set(WORKING_TIME, workingTime)
  753. }
  754. let startPauseTime = 0
  755. if (workingTime.startPauseTime <= 0) {
  756. state.pauseWork = false
  757. startPauseTime = 0
  758. } else {
  759. state.pauseWork = true
  760. startPauseTime = time - workingTime.startPauseTime // 已暂停时间
  761. }
  762. let workingSeconds = time - workingTime.startTime - workingTime.pauseTime - startPauseTime
  763. state.workingTimeFormat = formatSeconds(workingSeconds)
  764. if (!state.pauseWork) {
  765. workTimer = window.setInterval(() => {
  766. workingSeconds++
  767. state.workingTimeFormat = formatSeconds(workingSeconds)
  768. }, 1000)
  769. }
  770. }
  771. const formatSeconds = (seconds: number) => {
  772. var secondTime = 0 // 秒
  773. var minuteTime = 0 // 分
  774. var hourTime = 0 // 小时
  775. var dayTime = 0 // 天
  776. var result = ''
  777. if (seconds < 60) {
  778. secondTime = seconds
  779. } else {
  780. // 获取分钟,除以60取整数,得到整数分钟
  781. minuteTime = Math.floor(seconds / 60)
  782. // 获取秒数,秒数取佘,得到整数秒数
  783. secondTime = Math.floor(seconds % 60)
  784. // 如果分钟大于60,将分钟转换成小时
  785. if (minuteTime >= 60) {
  786. // 获取小时,获取分钟除以60,得到整数小时
  787. hourTime = Math.floor(minuteTime / 60)
  788. // 获取小时后取佘的分,获取分钟除以60取佘的分
  789. minuteTime = Math.floor(minuteTime % 60)
  790. if (hourTime >= 24) {
  791. // 获取天数, 获取小时除以24,得到整数天
  792. dayTime = Math.floor(hourTime / 24)
  793. // 获取小时后取余小时,获取分钟除以24取余的分;
  794. hourTime = Math.floor(hourTime % 24)
  795. }
  796. }
  797. }
  798. result =
  799. hourTime +
  800. t('dashboard.hour') +
  801. ((minuteTime >= 10 ? minuteTime : '0' + minuteTime) + t('dashboard.minute')) +
  802. ((secondTime >= 10 ? secondTime : '0' + secondTime) + t('dashboard.second'))
  803. if (dayTime > 0) {
  804. result = dayTime + t('dashboard.day') + result
  805. }
  806. return result
  807. }
  808. onActivated(() => {
  809. echartsResize()
  810. })
  811. const intervalRef = ref<any>(null);
  812. onMounted(() => {
  813. fetchDashboard()
  814. fetchAllIns()
  815. fetchHrpatientList()
  816. fetchGetInsType()
  817. intervalRef.value = setInterval(() => {
  818. fetchDashboard()
  819. fetchHrpatientList()
  820. fetchAllIns()
  821. }, 60000);
  822. // startWork()
  823. // initCountUp()
  824. // initUserGrowthChart()
  825. // initFileGrowthChart()
  826. // initUserSourceChart()
  827. // initUserSurnameChart()
  828. // useEventListener(window, 'resize', echartsResize)
  829. })
  830. onBeforeMount(() => {
  831. for (const key in state.charts) {
  832. state.charts[key].dispose()
  833. }
  834. })
  835. onUnmounted(() => {
  836. // alert('onUnmounted')
  837. clearInterval(workTimer)
  838. clearInterval(intervalRef.value)
  839. })
  840. onBeforeUnmount(() => {
  841. // alert('onBeforeUnmount')
  842. })
  843. watch(
  844. () => navTabs.state.tabFullScreen,
  845. () => {
  846. echartsResize()
  847. }
  848. )
  849. </script>
  850. <style scoped lang="scss">
  851. .welcome {
  852. background: #e1eaf9;
  853. border-radius: 6px;
  854. display: flex;
  855. align-items: center;
  856. padding: 15px 20px !important;
  857. box-shadow: 0 0 30px 0 rgba(82, 63, 105, 0.05);
  858. .welcome-img {
  859. height: 100px;
  860. margin-right: 10px;
  861. user-select: none;
  862. }
  863. .welcome-title {
  864. font-size: 1.5rem;
  865. line-height: 30px;
  866. color: var(--ba-color-primary-light);
  867. }
  868. .welcome-note {
  869. padding-top: 6px;
  870. font-size: 15px;
  871. color: var(--el-text-color-primary);
  872. }
  873. }
  874. .working {
  875. height: 130px;
  876. display: flex;
  877. justify-content: center;
  878. flex-wrap: wrap;
  879. height: 100%;
  880. position: relative;
  881. &:hover {
  882. .working-coffee {
  883. -webkit-transform: translateY(-4px) scale(1.02);
  884. -moz-transform: translateY(-4px) scale(1.02);
  885. -ms-transform: translateY(-4px) scale(1.02);
  886. -o-transform: translateY(-4px) scale(1.02);
  887. transform: translateY(-4px) scale(1.02);
  888. z-index: 999;
  889. }
  890. }
  891. .working-coffee {
  892. transition: all 0.3s ease;
  893. width: 80px;
  894. }
  895. .working-text {
  896. display: block;
  897. width: 100%;
  898. font-size: 15px;
  899. text-align: center;
  900. color: var(--el-text-color-primary);
  901. }
  902. .working-opt {
  903. position: absolute;
  904. top: -40px;
  905. right: 10px;
  906. background-color: rgba($color: #000000, $alpha: 0.3);
  907. padding: 10px 20px;
  908. border-radius: 20px;
  909. color: var(--ba-bg-color-overlay);
  910. transition: all 0.3s ease;
  911. cursor: pointer;
  912. opacity: 0;
  913. z-index: 999;
  914. &:active {
  915. background-color: rgba($color: #000000, $alpha: 0.6);
  916. }
  917. }
  918. &:hover {
  919. .working-opt {
  920. opacity: 1;
  921. top: 0;
  922. }
  923. .working-done {
  924. opacity: 1;
  925. top: 50px;
  926. }
  927. }
  928. }
  929. .small-panel-box {
  930. // margin-top: 20px;
  931. // background: var(--ba-bg-color-overlay)
  932. }
  933. .small-panel {
  934. background-color: var(--ba-vars-color-gray);
  935. border-radius: var(--el-border-radius-base);
  936. padding: 15px 0;
  937. // margin-bottom: 20px;
  938. text-align: center;
  939. .small-panel-title {
  940. // color: #92969a;
  941. // color: var(--ba-vars-color-main-primary);
  942. font-size: 15px;
  943. font-weight: 500;
  944. }
  945. .small-panel-content {
  946. display: flex;
  947. align-items: flex-end;
  948. justify-content: center;
  949. margin-top: 5px;
  950. color: #2c3f5d;
  951. .content-left {
  952. font-size: 24px;
  953. color: #2B47A2;
  954. font-weight: var(--el-font-weight-primary);
  955. .icon {
  956. margin-right: 10px;
  957. }
  958. span {
  959. display: inline-block;
  960. font-size: 28px;
  961. }
  962. }
  963. .content-right {
  964. font-size: 18px;
  965. margin-left: auto;
  966. }
  967. .color-success {
  968. color: var(--el-color-success);
  969. }
  970. .color-warning {
  971. color: var(--el-color-warning);
  972. }
  973. .color-danger {
  974. color: var(--el-color-danger);
  975. }
  976. .color-info {
  977. color: var(--el-text-color-secondary);
  978. }
  979. .text {
  980. font-size: 16px!important;
  981. }
  982. }
  983. }
  984. .ins-panel{
  985. border: 1px solid #2B47A2;
  986. margin-bottom: 20px;
  987. background-color: #fff;
  988. .small-panel-title {
  989. color: #2B47A2;
  990. }
  991. }
  992. .is-active {
  993. .small-panel {
  994. text-align: left;
  995. padding: 15px;
  996. // background: var(--ba-vars-color-tabs)
  997. }
  998. .small-panel:hover {
  999. background: var(--ba-vars-color-tabs-active);
  1000. cursor: pointer;
  1001. }
  1002. .small-panel-title {
  1003. // margin-bottom: 10px;
  1004. // color: var(--ba-vars-color-main-primary);
  1005. font-weight: 500;
  1006. }
  1007. .small-panel-type {
  1008. line-height: 20px;
  1009. margin: 5px 0;
  1010. }
  1011. }
  1012. .seamless {
  1013. width: 100%;
  1014. height: 220px;
  1015. overflow: hidden;
  1016. }
  1017. :deep .top-table .el-table__body-wrapper {
  1018. display: none;
  1019. }
  1020. :deep .bottom-table .el-table__header-wrapper {
  1021. display: none;
  1022. }
  1023. .growth-chart {
  1024. margin-bottom: 20px;
  1025. }
  1026. .user-growth-chart,
  1027. .file-growth-chart {
  1028. height: 260px;
  1029. }
  1030. .new-user-growth {
  1031. height: 300px;
  1032. }
  1033. .user-source-chart,
  1034. .user-surname-chart {
  1035. height: 400px;
  1036. }
  1037. .new-user-item {
  1038. display: flex;
  1039. align-items: center;
  1040. padding: 20px;
  1041. margin: 10px 15px;
  1042. box-shadow: 0 0 30px 0 rgba(82, 63, 105, 0.05);
  1043. background-color: var(--ba-bg-color-overlay);
  1044. .new-user-avatar {
  1045. height: 48px;
  1046. width: 48px;
  1047. border-radius: 50%;
  1048. }
  1049. .new-user-base {
  1050. margin-left: 10px;
  1051. color: #2c3f5d;
  1052. .new-user-name {
  1053. font-size: 15px;
  1054. }
  1055. .new-user-time {
  1056. font-size: 13px;
  1057. }
  1058. }
  1059. .new-user-arrow {
  1060. margin-left: auto;
  1061. }
  1062. }
  1063. :deep(.el-card) {
  1064. margin-bottom: 10px;
  1065. box-shadow: none;
  1066. }
  1067. :deep(.el-card__body) {
  1068. padding: 10px;
  1069. }
  1070. @media screen and (max-width: 425px) {
  1071. .welcome-img {
  1072. display: none;
  1073. }
  1074. }
  1075. @media screen and (max-width: 1200px) {
  1076. .lg-mb-20 {
  1077. margin-bottom: 20px;
  1078. }
  1079. }
  1080. html.dark {
  1081. .welcome {
  1082. background-color: var(--ba-bg-color-overlay);
  1083. }
  1084. .small-panel {
  1085. background-color: var(--ba-bg-color-overlay);
  1086. .small-panel-content {
  1087. color: var(--el-text-color-regular);
  1088. }
  1089. }
  1090. .new-user-item {
  1091. .new-user-base {
  1092. color: var(--el-text-color-regular);
  1093. }
  1094. }
  1095. }
  1096. .panel-title-box {
  1097. display: flex;
  1098. justify-content: space-between;
  1099. }
  1100. .title {
  1101. border-left: 2px solid #C66237;
  1102. padding: 0px 5px;
  1103. margin-bottom: 10px;
  1104. font-weight: 600;
  1105. font-size: 16px;
  1106. .more {
  1107. color: var(--ba-vars-color-main-primary);
  1108. font-size: 14px;
  1109. text-decoration: underline;
  1110. cursor: pointer;
  1111. }
  1112. }
  1113. :deep(.el-tooltip__trigger) {
  1114. background: #fff!important;
  1115. }
  1116. :deep(.el-input-group__append) {
  1117. background: #fff;
  1118. }
  1119. .el-button :deep(.el-icon) {
  1120. color: var(--ba-vars-color-main-primary);
  1121. }
  1122. :deep(.el-radio-button.is-active) {
  1123. --el-radio-button-checked-bg-color: var(--ba-vars-color-main-primary)
  1124. }
  1125. </style>