index.vue 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <template>
  2. <el-main class="home-container">
  3. <el-card class="home-top" shadow="never">
  4. <el-row justify="space-between">
  5. <el-col :md="12" :xs="24">
  6. <img src="img/logo.png">
  7. <div class="app-name">{{ $CONFIG.APP_NAME }}</div>
  8. </el-col>
  9. <el-col :md="10" :xs="24">
  10. <p>{{ day }}</p>
  11. <div class="app-time"><span>{{ time }}</span>{{ week }}</div>
  12. </el-col>
  13. </el-row>
  14. </el-card>
  15. <el-card class="home-menu" shadow="never">
  16. <template #header>设备预警</template>
  17. <el-row :gutter="40">
  18. <el-col :md="6" :xs="24" v-for="item in equipmentItem" :key="item.name">
  19. <div class="menu-item" @click="$router.push(item.path)">
  20. <sc-iconify :icon="item.meta.icon" size="26"></sc-iconify>
  21. <div class="menu-item__tooltip"><scTooltip :content="item.title"></scTooltip></div>
  22. <el-badge :value="36" :max="99"></el-badge>
  23. </div>
  24. </el-col>
  25. </el-row>
  26. </el-card>
  27. <el-card class="home-menu data-mock-card" shadow="never">
  28. <template #header>数据管理
  29. <el-input v-model="queryName" clearable placeholder="输入名称"></el-input>
  30. </template>
  31. <el-row v-if="$store.state.project.projectId" v-loading="loading" :gutter="40">
  32. <el-col v-if="!acceptItem.length" :xs="24">
  33. <el-empty description="暂无应用项">
  34. <el-button type="primary" @click="$router.push('/project/maintenance')">维护应用项</el-button>
  35. </el-empty>
  36. </el-col>
  37. <el-col v-else :md="6" :xs="24" v-for="item in filterAcceptItem" :key="item.id">
  38. <div :class="['menu-item', item.beginTime && 'has-time']" @click="formatAcceptRoute(item.name) && $router.push(formatAcceptRoute(item.name).path)">
  39. <div class="menu-item__content">
  40. <sc-iconify :icon="XEUtils.get(formatAcceptRoute(item.name), 'meta.icon')" size="26"></sc-iconify>
  41. <div class="menu-item__tooltip"><scTooltip :content="item.name"></scTooltip></div>
  42. </div>
  43. <div v-if="item.beginTime" class="diagnosis">{{ $TOOL.dateFormat(item.beginTime, "YY.M.D") }}<span>-{{ item.endTime && $TOOL.dateFormat(item.endTime, "YY.M.D") || "至今" }}</span></div>
  44. </div>
  45. <div class="tags-bottom">
  46. <!-- 新增标签 -->
  47. <el-scrollbar height="36px">
  48. <el-tag v-for="(tagItem, tagIndex) in XEUtils.get(diagnosisDic, `${XEUtils.get(formatAcceptRoute(item.name), 'name')}`, [])" :key="tagIndex" :type="tagItem.type" effect="plain" round>{{ tagItem.name }}</el-tag>
  49. </el-scrollbar>
  50. </div>
  51. </el-col>
  52. </el-row>
  53. <!-- 全部项目展示dataMock路由 -->
  54. <el-row v-else :gutter="40">
  55. <el-col :md="6" :xs="24" v-for="item in filterDataMock" :key="item.id">
  56. <div class="menu-item" @click="$router.push(item.path)">
  57. <div class="menu-item__content">
  58. <sc-iconify :icon="XEUtils.get(item, 'meta.icon')" size="26"></sc-iconify>
  59. <div class="menu-item__tooltip"><scTooltip :content="item.title"></scTooltip></div>
  60. </div>
  61. </div>
  62. <div class="tags-bottom">
  63. <!-- 新增标签 -->
  64. <el-scrollbar height="36px">
  65. <el-tag v-for="(tagItem, tagIndex) in XEUtils.get(diagnosisDic, item.name, [])" :key="tagIndex" :type="tagItem.type" effect="plain" round>{{ tagItem.name }}</el-tag>
  66. </el-scrollbar>
  67. </div>
  68. </el-col>
  69. </el-row>
  70. </el-card>
  71. </el-main>
  72. </template>
  73. <script setup>
  74. import XEUtils from "xe-utils";
  75. import API from "@/api";
  76. import STORE from "@/store";
  77. import TOOL from "@/utils/tool";
  78. import userRoutes from "@/config/route";
  79. import { diagnosisDic } from "./main"; // 诊断对象
  80. const day = ref("");
  81. const time = ref("");
  82. const week = ref("");
  83. // 数据管理与模拟路由
  84. const queryName = ref("");
  85. const loading = ref(false);
  86. const acceptItem = ref([]);
  87. const dataMockRoute = ref(XEUtils.map(XEUtils.get(userRoutes.find(item => item.name == "dataMock"), "children", []), item => ({ ...item, title: XEUtils.last(XEUtils.get(item, "meta.title", "").split("-")) })));
  88. const formatAcceptRoute = name => XEUtils.find(dataMockRoute.value, item => item.title == name);
  89. const filterAcceptItem = computed(() => XEUtils.filter(acceptItem.value, item => item.name.includes(queryName.value)));
  90. const filterDataMock = computed(() => XEUtils.filter(dataMockRoute.value, item => item.title.includes(queryName.value)));
  91. // 设备预警 --> 路由
  92. const equipmentItem = ref(XEUtils.map(XEUtils.get(userRoutes.find(item => item.name == "equipment"), "children", []), item => ({ ...item, title: XEUtils.last(XEUtils.get(item, "meta.title", "").split("-")) })));
  93. const showTime = () => {
  94. day.value = TOOL.dateFormat(new Date(), "YYYY年MM月DD日");
  95. time.value = TOOL.dateFormat(new Date(), "HH:mm:ss");
  96. week.value = TOOL.dateFormat(new Date(), "dddd");
  97. }
  98. const projectChange = projectId => {
  99. projectId && getItems(projectId);
  100. if (!projectId) {
  101. acceptItem.value = [];
  102. }
  103. }
  104. const getItems = projectId => {
  105. // 先查询当前项目的应用项
  106. loading.value = true;
  107. API.project.info.bindItem.get({ projectId }).then(res => {
  108. loading.value = false;
  109. const sortArr = XEUtils.orderBy(XEUtils.get(res, "data", []), [["item.itemCategory", "asc"], ["item.createTime", "asc"]]);
  110. acceptItem.value = XEUtils.map(sortArr, item => ({ ...item, name: XEUtils.get(item, "item.acceptItem", "") }));
  111. }).catch(() => loading.value = false);
  112. // 再查询每一项应用项的诊断结果
  113. }
  114. onMounted(() => {
  115. showTime();
  116. setInterval(() => showTime(), 1000);
  117. });
  118. watch(() => STORE.state.project.projectId, value => projectChange(value), { immediate: true });
  119. </script>
  120. <style lang="scss" scoped>
  121. .home-container {
  122. height: 100%;padding: calc(var(--el-main-padding) + 15px);background:#f5f7f9;
  123. .el-card {
  124. background: transparent;margin-bottom: 0;border: none;
  125. :deep(.el-card__header) {display: flex;align-items: center;padding: 22px 0 10px;background: transparent;border-bottom: none;font-size: 20px;}
  126. .el-input, .el-select {width: 180px;margin-left: 10px;}
  127. }
  128. .home-menu :deep(.el-card__body) {padding: 0;
  129. .el-col {margin-bottom: 20px;}
  130. .el-dropdown {width: 100%;}
  131. .menu-item {cursor: pointer;position: relative;display: flex;align-items: center;width: calc(100% - 2px);padding: 25px;background-color: #fff;border-radius: 10px;font-size: 16px;}
  132. .menu-item:hover {box-shadow: 1px 0 #dbdbdb, 0 1px #dbdbdb, 1px 1px #dbdbdb, 1px 0 #dbdbdb inset, 0 1px #dbdbdb inset;}
  133. .sc-iconify-icon {margin-right: 20px;color: var(--el-color-primary);}
  134. .menu-item__tooltip {display: flex;width: calc(100% - 26px - 20px);}
  135. .el-badge {position: absolute;right: 5px;top: 5px;}
  136. .tags-bottom {margin-top: 10px;white-space: nowrap;overflow-x: auto;}
  137. .el-tag + .el-tag {margin-left: 6px;}
  138. }
  139. .data-mock-card :deep(.el-card__body) .menu-item {
  140. flex-direction: column;align-items: unset;padding: 25px;
  141. .menu-item__content {display: flex;align-items: center;}
  142. .diagnosis {margin-top: 13px;line-height: 1;font-size: 12px;color: #999;}
  143. }
  144. .data-mock-card :deep(.el-card__body) .menu-item.has-time {padding: 15px 25px 10px;}
  145. .home-top {
  146. padding: 12px;background: linear-gradient(to right, #8E54E9, #4776E6);border-radius: 15px;color: #fff;
  147. .el-col {display: flex;flex-direction: column;justify-content: center;}
  148. .el-col:first-child {align-items: center;}
  149. .el-col img {width: 80px;}
  150. .el-col .app-name {margin-top: 15px;font-size: 30px;font-weight: 700;}
  151. .el-col p {margin: 8px 0 4px;font-size: 25px;font-weight: 400;opacity: 0.7;}
  152. .el-col .app-time {font-size: 20px;font-weight: 700;}
  153. .el-col .app-time span {display: inline-block;width: 240px;font: 50px calculator-all;letter-spacing: 12px;}
  154. }
  155. }
  156. @media (max-width: 992px) {
  157. .home-container .home-top .el-col:first-child {align-items: unset;}
  158. .home-container .home-top .el-col + .el-col {margin-top: 20px;}
  159. }
  160. </style>