index.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. <template>
  2. <div class="home">
  3. <div class="second">
  4. <div class="topPanel">
  5. <!-- 原始数据 -->
  6. <div class="tPanel">
  7. <el-table size="mini" :data="originalList">
  8. <el-table-column prop="resultDataName" label="数据" align="center">
  9. <template slot-scope="scope">
  10. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  11. <span class="file" @click="handleFile(scope.row.resultDataId, scope.row.processType)">{{
  12. scope.row.resultDataName }}</span>
  13. </el-tooltip>
  14. </template>
  15. </el-table-column>
  16. <el-table-column prop="processStatus" label="状态" align="center">
  17. <template slot-scope="scope">
  18. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  19. </template>
  20. </el-table-column>
  21. </el-table>
  22. </div>
  23. <!-- 去噪 -->
  24. <div class="tPanel">
  25. <el-table size="mini" :data="denoisingList">
  26. <el-table-column prop="resultDataName" label="数据" align="center">
  27. <template slot-scope="scope">
  28. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  29. <span class="file" @click="handleFile(scope.row.resultDataId, scope.row.processType)">{{
  30. scope.row.resultDataName }}</span>
  31. </el-tooltip>
  32. </template>
  33. </el-table-column>
  34. <el-table-column prop="processStatus" label="状态" align="center">
  35. <template slot-scope="scope">
  36. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  37. </template>
  38. </el-table-column>
  39. </el-table>
  40. </div>
  41. <!-- 特征提取 -->
  42. <div class="tPanel">
  43. <el-table size="mini" :data="featureExtractionList">
  44. <el-table-column prop="resultDataName" label="数据" align="center">
  45. <template slot-scope="scope">
  46. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  47. <span class="file" @click="handleFile(scope.row.resultDataId, scope.row.processType)">{{
  48. scope.row.resultDataName }}</span>
  49. </el-tooltip>
  50. </template>
  51. </el-table-column>
  52. <el-table-column prop="processStatus" label="状态" align="center">
  53. <template slot-scope="scope">
  54. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  55. </template>
  56. </el-table-column>
  57. </el-table>
  58. </div>
  59. <!-- 故障预测 -->
  60. <div class="tPanel">
  61. <el-table size="mini" :data="faultPredictionList">
  62. <el-table-column prop="resultDataName" label="数据" align="center">
  63. <template slot-scope="scope">
  64. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  65. <span class="file" @click="imgShow(scope.row.dataPath, scope.row.dataType)">{{
  66. scope.row.resultDataName }}</span>
  67. </el-tooltip>
  68. </template>
  69. </el-table-column>
  70. <el-table-column prop="processStatus" label="状态" align="center">
  71. <template slot-scope="scope">
  72. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  73. </template>
  74. </el-table-column>
  75. </el-table>
  76. </div>
  77. </div>
  78. <div class="step">
  79. <div class="yuan">
  80. <div class="img yuanBg odd">
  81. <div class="tag">原始数据</div>
  82. </div>
  83. </div>
  84. <div class="one">
  85. <div class="img oneBg even" @click="handleProcess(2)">
  86. <div class="tag">补全</div>
  87. </div>
  88. </div>
  89. <div class="two">
  90. <div class="img twoBg odd" @click="handleProcess(1)">
  91. <div class="tag">去噪</div>
  92. </div>
  93. </div>
  94. <div class="three">
  95. <div class="img threeBg even" @click="handleProcess(3)">
  96. <div class="tag">扩充</div>
  97. </div>
  98. </div>
  99. <div class="four">
  100. <div class="img fourBg odd" @click="handleProcess(4)">
  101. <div class="tag">特征提取</div>
  102. </div>
  103. </div>
  104. <div class="five">
  105. <div class="img fiveBg even" @click="handleProcess(5)">
  106. <div class="tag">退化评估</div>
  107. </div>
  108. </div>
  109. <div class="six">
  110. <div class="img sixBg odd noAfter" style="content: none;" @click="handleProcess(6)">
  111. <div class="tag">故障预测</div>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="bottomPanel">
  116. <!-- 补全 -->
  117. <div class="bPanel">
  118. <el-table size="mini" :data="completionList">
  119. <el-table-column prop="resultDataName" label="数据" align="center">
  120. <template slot-scope="scope">
  121. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  122. <span class="file" @click="handleFile(scope.row.resultDataId, scope.row.processType)">{{
  123. scope.row.resultDataName }}</span>
  124. </el-tooltip>
  125. </template>
  126. </el-table-column>
  127. <el-table-column prop="processStatus" label="状态" align="center">
  128. <template slot-scope="scope">
  129. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  130. </template>
  131. </el-table-column>
  132. </el-table>
  133. </div>
  134. <!-- 扩充 -->
  135. <div class="bPanel">
  136. <el-table size="mini" :data="expansionList">
  137. <el-table-column prop="resultDataName" label="数据" align="center">
  138. <template slot-scope="scope">
  139. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  140. <span class="file" @click="handleFile(scope.row.resultDataId, scope.row.processType)">{{
  141. scope.row.resultDataName }}</span>
  142. </el-tooltip>
  143. </template>
  144. </el-table-column>
  145. <el-table-column prop="processStatus" label="状态" align="center">
  146. <template slot-scope="scope">
  147. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  148. </template>
  149. </el-table-column>
  150. </el-table>
  151. </div>
  152. <!-- 退化评估 -->
  153. <div class="bPanel">
  154. <el-table size="mini" :data="assessmentList">
  155. <el-table-column prop="resultDataName" label="数据" align="center">
  156. <template slot-scope="scope">
  157. <el-tooltip class="item" effect="dark" :content="scope.row.resultDataName" placement="top">
  158. <span class="file" @click="imgShow(scope.row.dataPath, scope.row.dataType)">{{
  159. scope.row.resultDataName }}</span>
  160. </el-tooltip>
  161. </template>
  162. </el-table-column>
  163. <el-table-column prop="processStatus" label="状态" align="center">
  164. <template slot-scope="scope">
  165. <dict-tag :options="dict.type.biz_process_status" :value="scope.row.processStatus" />
  166. </template>
  167. </el-table-column>
  168. </el-table>
  169. </div>
  170. <div>
  171. </div>
  172. </div>
  173. </div>
  174. <div class="first">
  175. <h4 style="margin:13px 0px 0px 20px;color: #fff;">算法统计</h4>
  176. <div class="chart">
  177. <RingChart />
  178. <BarChart width="700px" />
  179. </div>
  180. </div>
  181. <el-dialog :title="title" :visible.sync="dialogVisible" width="30%" :close-on-click-modal="false">
  182. <el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
  183. <el-form-item v-if="dialogType === 4" label="选择数据类型" label-width="120px">
  184. <el-radio-group v-removeAriaHidden v-model="type">
  185. <el-radio :label="1">去噪</el-radio>
  186. <el-radio :label="3">扩充</el-radio>
  187. <!-- <el-radio :label="4">特征提取</el-radio> -->
  188. </el-radio-group>
  189. </el-form-item>
  190. <el-form-item label="数据" prop="processType">
  191. <el-select v-model="form.processedDataId" placeholder="请选择执行的数据">
  192. <el-option v-for="(item, index) in optionalData" :key="index" :label="item.dataName"
  193. :value="item.id"></el-option>
  194. </el-select>
  195. </el-form-item>
  196. <el-form-item label="算法" prop="processType">
  197. <el-select v-model="form.processAlgId" placeholder="请选择执行的算法">
  198. <el-option v-for="(item, index) in optionalAglo" :key="index" :label="item.algName"
  199. :value="item.id"></el-option>
  200. </el-select>
  201. </el-form-item>
  202. </el-form>
  203. <span slot="footer" class="dialog-footer">
  204. <el-button @click="dialogVisible = false">取 消</el-button>
  205. <el-button type="primary" @click="submitHandle()">确 定</el-button>
  206. </span>
  207. </el-dialog>
  208. <el-dialog title="数据展示" :visible.sync="fileShowVisible" width="80%" :close-on-click-modal="false">
  209. <el-button v-if="fileType !== '4' && fileType !== '5'" style="margin-left:50px;" type="text"
  210. @click="changeShow">{{
  211. isTableShow ?
  212. '表格展示'
  213. :
  214. '曲线展示'
  215. }}</el-button>
  216. <div v-if="isTableShow && fileType !== '5'">
  217. <vxe-table border="none" size="mini" show-overflow highlight-hover-row height="400"
  218. :row-config="{ isHover: true, isCurrent: true }" :sort-config="{ trigger: 'cell' }" :data="completionData">
  219. <vxe-table-column v-for="(item, index) in completionHeadData" :key="index" align="center"
  220. :field="'val' + index" :title="item"></vxe-table-column>
  221. </vxe-table>
  222. </div>
  223. <div v-if="!isTableShow && fileType !== '5'" ref="completionChartRef" style="width: 100%; height: 400px;"></div>
  224. <ImagePreview v-if="fileType === '5'" :src="imgPreviewUrl"></ImagePreview>
  225. </el-dialog>
  226. </div>
  227. </template>
  228. <script>
  229. import CountTo from 'vue-count-to'
  230. import RingChart from '@/views/homePage/ringChart'
  231. import BarChart from '@/views/dashboard/BarChart'
  232. import { getAlgConfigByType } from "@/api/system/algConfig";
  233. import { getDataProcessByType, addProcess } from "@/api/system/process";
  234. import { getDataByType, getData } from "@/api/system/data";
  235. import * as echarts from 'echarts';
  236. export default {
  237. name: 'Index',
  238. dicts: ['biz_process_status'],
  239. components: {
  240. CountTo,
  241. RingChart,
  242. BarChart,
  243. },
  244. data() {
  245. return {
  246. loading: true,
  247. rules: {},
  248. title: '选择数据',
  249. baseUrl: process.env.VUE_APP_BASE_API,
  250. dialogVisible: false,
  251. fileShowVisible: false,
  252. originalList: [],
  253. denoisingList: [],
  254. completionList: [],
  255. expansionList: [],
  256. featureExtractionList: [],
  257. assessmentList: [],
  258. faultPredictionList: [],
  259. optionalData: [],
  260. optionalAglo: [],
  261. form: {
  262. processedDataId: null,
  263. processAlgId: null
  264. },
  265. // 对话框展示数据内容
  266. completionData: [],
  267. completionHeadData: [],
  268. isTableShow: false,
  269. resultFileId: null,
  270. // filePath: null,
  271. fileType: null,
  272. chart: null,
  273. imgPreviewUrl: null,
  274. type: 1,
  275. dialogType: null
  276. }
  277. },
  278. created() {
  279. this.getTableData();
  280. },
  281. beforeDestroy() {
  282. if (this.chart != null && this.chart != "" && this.chart != undefined) {
  283. this.chart.dispose();
  284. this.chart = null
  285. }
  286. },
  287. watch: {
  288. fileShowVisible(value) {
  289. if (!value) {
  290. this.isTableShow = false
  291. }
  292. },
  293. type(value) {
  294. getDataByType(value).then(res => {
  295. this.optionalData = res.data;
  296. });
  297. getAlgConfigByType(value).then(res => {
  298. this.optionalAglo = res.data;
  299. });
  300. }
  301. },
  302. methods: {
  303. getTableData() {
  304. getDataProcessByType(0).then(res => {
  305. this.originalList = res.data
  306. })
  307. getDataProcessByType(1).then(res => {
  308. this.denoisingList = res.data
  309. })
  310. getDataProcessByType(2).then(res => {
  311. this.completionList = res.data
  312. })
  313. getDataProcessByType(3).then(res => {
  314. this.expansionList = res.data
  315. })
  316. getDataProcessByType(4).then(res => {
  317. this.featureExtractionList = res.data
  318. })
  319. getDataProcessByType(5).then(res => {
  320. this.assessmentList = res.data
  321. })
  322. getDataProcessByType(6).then(res => {
  323. this.faultPredictionList = res.data
  324. })
  325. },
  326. goTarget(href) {
  327. window.open(href, '_blank')
  328. },
  329. handleSetLineChartData(type) {
  330. this.$emit('handleSetLineChartData', type)
  331. },
  332. handleProcess(type) {
  333. this.dialogVisible = true;
  334. this.dialogType = type
  335. const relation = [[2, 0], [1, 2], [3, 1], [4, 1], [4, 3], [5, 4], [6, 4]]
  336. const match = relation.find(item => item[0] === type)[1];
  337. getDataByType(match).then(res => {
  338. this.optionalData = res.data;
  339. });
  340. getAlgConfigByType(match).then(res => {
  341. this.optionalAglo = res.data;
  342. });
  343. },
  344. submitHandle() {
  345. addProcess(this.form).then(response => {
  346. this.$modal.msgSuccess("开始执行");
  347. this.dialogVisible = false;
  348. this.getTableData()
  349. this.form = {
  350. processedDataId: null,
  351. processAlgId: null
  352. }
  353. this.optionalData = [];
  354. this.optionalAglo = [];
  355. });
  356. },
  357. handleFile(resultDataId, processType) {
  358. this.loading = true
  359. this.resultFileId = resultDataId
  360. this.fileType = processType
  361. getData(resultDataId).then(res => {
  362. const url = `${process.env.VUE_APP_BASE_API}${res.data.dataPath}`;
  363. this.fetchLogFile(url)
  364. .then((text) => {
  365. if (this.chart != null && this.chart != "" && this.chart != undefined) {
  366. this.chart.dispose();
  367. this.chart = null
  368. }
  369. switch (res.data.dataType) {
  370. case '0':
  371. const originalData = this.handleFileData(text)
  372. const originalContent = originalData.contentData
  373. const originalHead = originalData.headData
  374. this.fileShowVisible = true
  375. this.loading = false
  376. this.$nextTick(() => {
  377. this.handleChartOption(originalContent, originalHead, true)
  378. })
  379. break;
  380. case '1':
  381. const returnData = this.handleFileData(text)
  382. const contentData = returnData.contentData
  383. const headData = returnData.headData
  384. this.fileShowVisible = true
  385. this.loading = false
  386. this.$nextTick(() => {
  387. this.handleChartOption(contentData, headData, false)
  388. })
  389. break;
  390. case '2':
  391. const completionData = this.handleFileData(text)
  392. const completionContent = completionData.contentData
  393. const completionlHead = completionData.headData
  394. this.fileShowVisible = true
  395. this.$nextTick(() => {
  396. this.handleChartOption(completionContent, completionlHead, false)
  397. })
  398. break;
  399. case '3':
  400. const ExtractionData = this.handleFileData(text)
  401. const ExtractionContent = ExtractionData.contentData
  402. const ExtractionHead = ExtractionData.headData
  403. this.fileShowVisible = true
  404. this.$nextTick(() => {
  405. this.handleChartOption(ExtractionContent, ExtractionHead, false)
  406. })
  407. break;
  408. case '4':
  409. const assessmentData = this.handleFileData(text)
  410. const assessmentcontent = assessmentData.contentData
  411. const assessmenthead = assessmentData.headData
  412. this.fileShowVisible = true
  413. this.$nextTick(() => {
  414. this.handleChartOption(assessmentcontent, assessmenthead, false)
  415. })
  416. break;
  417. case '5':
  418. break;
  419. case '6':
  420. break;
  421. default:
  422. break;
  423. }
  424. })
  425. .catch((error) => {
  426. console.error("Failed to fetch the log file:", error);
  427. this.$modal.msgSuccess("文件读取错误");
  428. });
  429. });
  430. },
  431. // 读取文件内容
  432. async fetchLogFile(url) {
  433. try {
  434. const response = await fetch(url, { method: "GET" });
  435. if (!response.ok) {
  436. throw new Error(`HTTP error! status: ${response.status}`);
  437. }
  438. return await response.text();
  439. } catch (error) {
  440. throw error;
  441. }
  442. },
  443. // 对数据的处理(不包含时间)
  444. handleFileData(fileData) {
  445. // 每行数据转换成数组、过滤出存在的空白行、将没行数据按照,号分割
  446. const data = fileData.split("\r\n").filter(line => line.trim() !== '').map(row => row.split(','));
  447. const headData = data[0];
  448. const contentData = Array.from({ length: headData.length }, () => []);
  449. for (let i = 1; i < data.length; i++) { // 从 1 开始,跳过表头
  450. data[i].forEach((value, index) => {
  451. contentData[index].push(Number(value));
  452. });
  453. }
  454. return { contentData, headData }
  455. },
  456. // 对数据的处理(包含时间)
  457. handleDataIncludeTime(fileData) {
  458. data = fileData.split("\r\n").filter(line => line.trim() !== '').map(row => row.split(','));
  459. data[0].shift();
  460. const completionHead = data[0];
  461. const completionContent = Array.from({ length: completionHead.length }, () => []);
  462. const timeData = []
  463. for (let i = 1; i < data.length; i++) {
  464. data[i].forEach((value, index) => {
  465. if (index === 0) {
  466. timeData.push(value)
  467. } else {
  468. completionContent[index - 1].push(Number(value));
  469. }
  470. });
  471. }
  472. return { contentData: completionContent, headData: completionHead, timeData }
  473. },
  474. // 图表设置
  475. handleChartOption(content, head, ismarkPoint) {
  476. const color = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']
  477. this.chart = echarts.init(this.$refs.completionChartRef);
  478. // series数据
  479. let series
  480. if (ismarkPoint) {
  481. series = content.map((lineData, index) => ({
  482. name: `${head[index]}`,
  483. type: 'line',
  484. data: lineData,
  485. stack: 'Total',
  486. connectNulls: true, // 连接相邻的非空数据点
  487. markPoint: {
  488. data: lineData.map((value, idx) => ({
  489. value: value === 0 ? '缺失' : null,
  490. xAxis: idx,
  491. // yAxis: lineData[idx-1],
  492. yAxis: value,
  493. itemStyle: { color: color[index] } // 高亮显示缺失值
  494. })).filter(point => point.value)
  495. }
  496. }));
  497. } else {
  498. series = content.map((lineData, index) => ({
  499. name: `${head[index]}`,
  500. type: 'line',
  501. data: lineData,
  502. stack: 'Total',
  503. connectNulls: true,
  504. }));
  505. }
  506. const option = {
  507. tooltip: {
  508. trigger: 'axis'
  509. },
  510. legend: {
  511. data: head,
  512. textStyle: {//图例文字的样式
  513. color: '#fff'
  514. }
  515. },
  516. color: color,
  517. xAxis: {
  518. type: 'category',
  519. data: content[0].map((_, index) => index),
  520. name: 'Index'
  521. },
  522. yAxis: {
  523. type: 'value',
  524. name: 'Value'
  525. },
  526. dataZoom: [
  527. {
  528. type: 'slider',
  529. start: 0,
  530. end: 100
  531. },
  532. {
  533. type: 'inside',
  534. start: 0,
  535. end: 100
  536. }
  537. ],
  538. series: series
  539. };
  540. this.chart.setOption(option);
  541. },
  542. // 切换表格/曲线展示
  543. changeShow() {
  544. this.isTableShow = !this.isTableShow
  545. if (!this.isTableShow) {
  546. this.handleFile(this.resultFileId)
  547. } else {
  548. this.tableShow(this.resultFileId)
  549. }
  550. },
  551. tableShow(id) {
  552. // const url = `${process.env.VUE_APP_BASE_API}${path}`;
  553. getData(id).then(res => {
  554. const url = `${process.env.VUE_APP_BASE_API}${res.data.dataPath}`;
  555. this.fetchLogFile(url)
  556. .then((text) => {
  557. const data = text.split("\r\n").filter(line => line.trim() !== '').map(row => row.split(','));
  558. this.completionHeadData = data.shift();
  559. this.completionData = data.map(row => {
  560. const rowData = {};
  561. for (let i = 0; i < this.completionHeadData.length; i++) {
  562. rowData[`val${i}`] = (row[i]) === 0 ? null : (row[i]);
  563. }
  564. return rowData;
  565. })
  566. })
  567. })
  568. },
  569. imgShow(url, dataType) {
  570. this.fileType = dataType
  571. this.imgPreviewUrl = url
  572. this.fileShowVisible = true
  573. }
  574. }
  575. }
  576. </script>
  577. <style scoped lang="scss">
  578. .home {
  579. width: 100%;
  580. min-height: calc(100vh - 84px);
  581. overflow: hidden;
  582. }
  583. .first {
  584. width: 97%;
  585. height: 210px;
  586. margin: 20px;
  587. // background-color: white;
  588. border-radius: 15px;
  589. overflow: hidden;
  590. }
  591. .chart {
  592. display: flex;
  593. justify-content: space-around;
  594. margin-left: 30px;
  595. }
  596. .second {
  597. width: 97%;
  598. height: 440px;
  599. margin: 50px 20px;
  600. // overflow: hidden;
  601. display: flex;
  602. flex-direction: column;
  603. .step {
  604. width: 100%;
  605. height: 120px;
  606. display: flex;
  607. justify-content: space-around;
  608. .yuan,
  609. .one,
  610. .two,
  611. .three,
  612. .four,
  613. .five,
  614. .six,
  615. .final {
  616. width: 12%;
  617. height: 100%;
  618. text-align: center;
  619. }
  620. .item {
  621. margin-top: 10px;
  622. margin-right: 40px;
  623. }
  624. .img {
  625. width: 40%;
  626. height: 95%;
  627. margin: 0 auto;
  628. position: relative;
  629. }
  630. .img::after {
  631. content: "";
  632. position: absolute;
  633. top: 50%;
  634. transform: translateX(26%);
  635. width: 200%;
  636. height: 1px;
  637. // background-color: #546882;
  638. background-color: #00aaff;
  639. box-shadow: 0 5px 15px rgba(0, 170, 255, 0.5);
  640. }
  641. .noAfter::after {
  642. content: none;
  643. }
  644. .odd::before {
  645. content: "";
  646. position: absolute;
  647. transform: translateY(-50%);
  648. width: 1px;
  649. height: 50%;
  650. // background-color: #546882;
  651. background-color: #00aaff;
  652. box-shadow: 0 5px 15px rgba(0, 170, 255, 0.5);
  653. }
  654. .even::before {
  655. content: "";
  656. position: absolute;
  657. bottom: 0;
  658. transform: translateY(50%);
  659. width: 1px;
  660. height: 50%;
  661. // background-color: #546882;00aaff
  662. background-color: #00aaff;
  663. box-shadow: 0 5px 15px rgba(0, 170, 255, 0.5);
  664. }
  665. .yuanBg {
  666. background: url("../assets/images/yuan.png") no-repeat center / contain;
  667. }
  668. .oneBg {
  669. background: url("../assets/images/one.png") no-repeat center / contain;
  670. }
  671. .twoBg {
  672. background: url("../assets/images/two.png") no-repeat center / contain;
  673. }
  674. .threeBg {
  675. background: url("../assets/images/three.png") no-repeat center / contain;
  676. }
  677. .fourBg {
  678. background: url("../assets/images/four.png") no-repeat center / contain;
  679. }
  680. .fiveBg {
  681. background: url("../assets/images/five.png") no-repeat center / contain;
  682. }
  683. .sixBg {
  684. background: url("../assets/images/six.png") no-repeat center / contain;
  685. }
  686. .tag {
  687. color: #fff;
  688. background: linear-gradient(to right, rgba(8, 200, 236, 0), rgba(8, 200, 236, 0.8), rgba(8, 200, 236, 0.8), rgba(8, 200, 236, 0));
  689. position: absolute;
  690. top: -15px;
  691. left: 100%;
  692. }
  693. }
  694. .topPanel {
  695. width: 100%;
  696. height: 37%;
  697. display: flex;
  698. justify-content: space-between;
  699. margin-bottom: 1.5%;
  700. }
  701. .bottomPanel {
  702. width: 100%;
  703. height: 37%;
  704. display: flex;
  705. justify-content: space-around;
  706. margin-left: 6%;
  707. margin-top: 1%;
  708. }
  709. .tPanel,
  710. .bPanel {
  711. // position: relative;
  712. width: 18%;
  713. height: 95%;
  714. overflow: auto;
  715. border: 2px solid transparent;
  716. background-clip: padding-box;
  717. box-shadow: 0 0 10px rgba(63, 155, 255, 0.5);
  718. border-radius: 5%;
  719. }
  720. }
  721. .file {
  722. cursor: pointer;
  723. white-space: nowrap;
  724. /* 禁止文本换行 */
  725. overflow: hidden;
  726. /* 隐藏超出范围的内容 */
  727. text-overflow: ellipsis;
  728. }
  729. .file:hover {
  730. color: #00aaff;
  731. }
  732. .square {
  733. width: 90px;
  734. height: 50px;
  735. line-height: 50px;
  736. text-align: center;
  737. border-radius: 12px;
  738. font-size: 14px;
  739. border: 2px solid grey;
  740. }
  741. .diamond {
  742. height: 100px;
  743. width: 100px;
  744. transform: rotateZ(45deg) skew(-20deg, -20deg);
  745. position: relative;
  746. border: 2px solid grey;
  747. .diamond-p {
  748. position: absolute;
  749. width: 140px;
  750. top: 14%;
  751. left: -17%;
  752. transform: skew(20deg, 20deg) rotateZ(-45deg);
  753. }
  754. }
  755. ::-webkit-scrollbar {
  756. display: none;
  757. }
  758. ::v-deep .el-table__empty-block {
  759. background-color: #0b333f !important;
  760. border: #0b333f;
  761. }
  762. ::v-deep .vxe-body--row {
  763. background-color: #0b333f;
  764. color: white;
  765. }
  766. ::v-deep .vxe-table--body :hover {
  767. background-color: #0b333f;
  768. }
  769. ::v-deep .vxe-header--row {
  770. background-color: #1e262f;
  771. color: white;
  772. }
  773. </style>