index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <template>
  2. <div id="DataLog">
  3. <div class="top">
  4. <h2>数据同步日志</h2>
  5. <div class="serve-updata">
  6. <span> 中台状态 </span>
  7. <el-popover placement="bottom" width="200" trigger="hover">
  8. <div>
  9. <div><span class="status-1"></span><span>:正常</span></div>
  10. <div><span class="status-2"></span><span>:异常</span></div>
  11. </div>
  12. <i slot="reference" className="infomations el-icon-information"></i> </el-popover
  13. >:
  14. <div ref="status" class="state"></div>
  15. <el-button @click="queryIsOnline" type="text">刷新</el-button>
  16. </div>
  17. </div>
  18. <div>
  19. <div v-if="isShowTable" class="screen">
  20. <p>筛选条件</p>
  21. <ul class="screen-list">
  22. <li>
  23. <span>操作符:</span>
  24. <el-select v-model="operationValue" :clearable="true" @change="operationChange" placeholder="请选择">
  25. <el-option v-for="item in operation" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  26. </el-select>
  27. </li>
  28. <li>
  29. <span>对象类型:</span>
  30. <el-select v-model="objTypeValue" :clearable="true" @change="objTypeChange" placeholder="请选择">
  31. <el-option v-for="item in objType" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  32. </el-select>
  33. </li>
  34. <li v-if="objClassify.length">
  35. <span>对象分类:</span>
  36. <el-select v-model="objClassifyValue" :clearable="true" @change="objClassChange" placeholder="请选择">
  37. <el-option v-for="item in objClassify" :key="item.value" :label="item.label" :value="item.value"> </el-option>
  38. </el-select>
  39. </li>
  40. </ul>
  41. <el-table
  42. v-loading="loading"
  43. element-loading-text="拼命加载中"
  44. style="width: 100%"
  45. :data="data"
  46. :stripe="true"
  47. :maxHeight="620"
  48. @sort-change="handleSort"
  49. >
  50. <el-table-column label="对象id" :width="370">
  51. <template slot-scope="scope">
  52. <span style="margin-left: 10px">{{ scope.row.objId ? scope.row.objId : "--" }}</span>
  53. </template>
  54. </el-table-column>
  55. <el-table-column label="时间" sortable="custom">
  56. <template slot-scope="scope">
  57. <span style="margin-left: 10px">{{ scope.row.createTime ? scope.row.createTime : "--" }}</span>
  58. </template>
  59. </el-table-column>
  60. <el-table-column label="名称" :width="120">
  61. <template slot-scope="scope">
  62. <span style="margin-left: 10px">{{ scope.row.name ? scope.row.name : "--" }}</span>
  63. </template>
  64. </el-table-column>
  65. <el-table-column label="本地名称" :width="120">
  66. <template slot-scope="scope">
  67. <span style="margin-left: 10px">{{ scope.row.localName ? scope.row.localName : "--" }}</span>
  68. </template>
  69. </el-table-column>
  70. <el-table-column label="本地编码" :width="120">
  71. <template slot-scope="scope">
  72. <span style="margin-left: 10px">{{ scope.row.localId ? scope.row.localId : "--" }}</span>
  73. </template>
  74. </el-table-column>
  75. <el-table-column label="对象类型">
  76. <template slot-scope="scope">
  77. <span style="margin-left: 10px">{{ scope.row.objName ? scope.row.objName : "--" }}</span>
  78. </template>
  79. </el-table-column>
  80. <el-table-column label="操作类型">
  81. <template slot-scope="scope">
  82. <span style="margin-left: 10px">{{ typeObj[scope.row.type] ? typeObj[scope.row.type] : "--" }}</span>
  83. </template>
  84. </el-table-column>
  85. <el-table-column label="对象分类">
  86. <template slot-scope="scope">
  87. <span style="margin-left: 10px">
  88. {{
  89. scope.row.classCode && scope.row.classCodeName
  90. ? `${scope.row.classCodeName} - ${scope.row.classCode}`
  91. : scope.row.classCode
  92. ? scope.row.classCode
  93. : "--"
  94. }}
  95. </span>
  96. </template>
  97. </el-table-column>
  98. <el-table-column label="报错信息">
  99. <template slot-scope="scope">
  100. <span style="margin-left: 10px">{{ scope.row.error ? scope.row.error : "--" }}</span>
  101. </template>
  102. </el-table-column>
  103. <el-table-column fixed="right" label="操作" width="180">
  104. <template slot-scope="scope">
  105. <el-button @click.native.prevent="queryRecordSyn(scope.row)"> 重新同步 </el-button>
  106. <el-button @click.native.prevent="hideMsg(scope.row)"> 忽略 </el-button>
  107. </template>
  108. </el-table-column>
  109. </el-table>
  110. <!-- {/* 分页 */} -->
  111. <div class="pages">
  112. <el-pagination
  113. layout="total, sizes, prev, pager, next, jumper"
  114. :total="this.pageObj.total"
  115. :pageSizes="[15, 30, 50, 100]"
  116. @size-change="onSizeChange"
  117. @current-change="onCurrentChange"
  118. :pageSize="pageObj.pageSize"
  119. :currentPage="pageObj.pageNumber"
  120. />
  121. </div>
  122. </div>
  123. <div v-else class="no-data">
  124. <img src="@/assets/image/no-data.png" />
  125. </div>
  126. </div>
  127. </div>
  128. </template>
  129. <script>
  130. import { mapGetters } from 'vuex'
  131. import {
  132. queryGroupCode,
  133. queryTableList,
  134. queryobjType,
  135. queryIsOnline,
  136. queryRecordSyn,
  137. queryRecordUpdata,
  138. } from "@/api/synclog";
  139. export default {
  140. data() {
  141. return {
  142. groupCode: "", //集团id
  143. isShowTable: false, //是否显示table
  144. data: [],
  145. objClassify: [],
  146. //对象类型
  147. objType: [
  148. {
  149. value: "building",
  150. label: "建筑",
  151. },
  152. {
  153. value: "floor",
  154. label: "楼层",
  155. },
  156. {
  157. value: "equipment",
  158. label: "设备",
  159. },
  160. {
  161. value: "component",
  162. label: "部件",
  163. },
  164. {
  165. value: "space",
  166. label: "空间",
  167. },
  168. {
  169. value: "system",
  170. label: "系统",
  171. },
  172. {
  173. value: "shaft",
  174. label: "竖井",
  175. },
  176. ],
  177. typeObj: { // 操作符类型
  178. create: "创建",
  179. update: "修改",
  180. delete: "删除",
  181. },
  182. //操作下拉框
  183. operation: [
  184. {
  185. value: "create",
  186. label: "创建",
  187. },
  188. {
  189. value: "update",
  190. label: "修改",
  191. },
  192. {
  193. value: "delete",
  194. label: "删除",
  195. },
  196. ],
  197. objClassifyValue: "", //对象分类状态
  198. operationValue: "", //操作符状态
  199. objTypeValue: "", //对象类型状态
  200. loading: false, //是否加载
  201. order: "lastUpdate asc, objId asc", //顺序
  202. pageObj: {
  203. total: 0, //总计
  204. pageSize: 15, //每页数量
  205. pageNumber: 1, //第几页
  206. },
  207. };
  208. },
  209. computed: {
  210. ...mapGetters("layout", ["projectId"])
  211. },
  212. created() {
  213. this.getData();
  214. },
  215. methods: {
  216. // 项目id请求接口
  217. getData() {
  218. // 判断项目id是否为真
  219. this.loading = true;
  220. this.groupCode = "";
  221. queryGroupCode({ projectId: this.projectId }, res => {
  222. if (res.content.length) {
  223. // 允许显示table
  224. this.isShowTable = true;
  225. this.groupCode = res.content[0].groupCode;
  226. this.getTable();
  227. this.queryIsOnline();
  228. } else {
  229. this.isShowTable = false;
  230. this.projectId = "";
  231. this.loading = false;
  232. this.$message({
  233. showClose: true,
  234. message: "项目id不存在!请重新输入",
  235. type: "error",
  236. duration: 3000,
  237. });
  238. }
  239. }, () => {
  240. this.loading = false;
  241. this.isShowTable = false;
  242. this.projectId = "";
  243. this.$message({
  244. showClose: true,
  245. message: "接口报错;请联系运维人员",
  246. type: "error",
  247. duration: 3000,
  248. });
  249. })
  250. },
  251. // 中台是否在线
  252. queryIsOnline() {
  253. const data = {
  254. projectId: this.projectId,
  255. groupCode: this.groupCode,
  256. };
  257. this.loading = true;
  258. queryIsOnline(data, res => {
  259. this.$message({
  260. showClose: true,
  261. message: res.message,
  262. type: res.result,
  263. duration: 3000,
  264. });
  265. this.loading = false;
  266. if (res.result == "success") {
  267. this.$refs.status.style.background = "#19F704";
  268. } else {
  269. this.$refs.status.style.background = "#4a4a4a";
  270. }
  271. }, () => {
  272. this.loading = false;
  273. this.$message({
  274. showClose: true,
  275. message: error,
  276. type: "error",
  277. duration: 3000,
  278. });
  279. });
  280. },
  281. // 获取对象类型下拉框
  282. getObjTypeList() {
  283. const data = {
  284. projectId: this.projectId,
  285. objType: this.objTypeValue,
  286. };
  287. queryobjType(data, res => {
  288. const objClassify = res.content.map((item) => {
  289. return {
  290. value: item.code,
  291. label: item.name,
  292. };
  293. });
  294. this.objClassify = objClassify;
  295. });
  296. },
  297. // 对象类型发生变化
  298. objTypeChange(val) {
  299. this.objTypeValue = val;
  300. this.objClassifyValue = "";
  301. if (val == "equipment" || val == "space" || val == "system" || val == "component") {
  302. this.getObjTypeList();
  303. } else {
  304. this.objClassify = [];
  305. }
  306. this.getTable();
  307. },
  308. // change变化触发获取tablelist
  309. operationChange(val) {
  310. this.operationValue = val;
  311. this.getTable();
  312. },
  313. // 对象类型编号
  314. objClassChange(val) {
  315. this.objClassifyValue = val;
  316. this.getTable();
  317. },
  318. // 请求table
  319. getTable() {
  320. this.loading = true;
  321. if (this.projectId) {
  322. // 请求table以及中台状态接口
  323. //对象类型
  324. const objectType = this.objTypeValue
  325. ? `;objectType='${this.objTypeValue}'`
  326. : "";
  327. // 对象分类
  328. const classCodeName = this.objClassifyValue
  329. ? `;classCode='${this.objClassifyValue}'`
  330. : "";
  331. // 操作符状态
  332. const type = this.operationValue
  333. ? `;type='${this.operationValue}'`
  334. : "";
  335. const postParam = {
  336. order: this.order,
  337. pageNumber: this.pageObj.pageNumber,
  338. pageSize: this.pageObj.pageSize,
  339. filters: `projectId='${this.projectId}';sign=2${type}${classCodeName}${objectType}`,
  340. };
  341. queryTableList(postParam, res => {
  342. this.isShowTable = true;
  343. this.data = res.content;
  344. this.loading = false;
  345. this.pageObj = Object.assign(this.pageObj, {
  346. total: res.total,
  347. pageNumber: res.pageNumber,
  348. pageSize: res.pageSize,
  349. });
  350. }, () => {
  351. this.isShowTable = false;
  352. this.loading = false;
  353. this.data = [];
  354. })
  355. } else {
  356. this.isShowTable = false;
  357. }
  358. },
  359. // 输入改变输入参数
  360. onChange(key, value) {
  361. this[key] = value;
  362. // this.forceUpdate();
  363. },
  364. // 忽略该条信息
  365. hideMsg(res) {
  366. const data = {
  367. content: [
  368. {
  369. ...Object.assign(res, {
  370. sign: 3,
  371. }),
  372. },
  373. ],
  374. };
  375. this.loading = true;
  376. queryRecordUpdata(data, res => {
  377. if (res.result == "success")
  378. this.$message({
  379. showClose: true,
  380. message: "忽略完成",
  381. type: "success",
  382. duration: 3000,
  383. });
  384. this.getTable();
  385. }, () => {
  386. this.$message({
  387. showClose: true,
  388. message: "忽略失败,请重新同步或联系管理人员!",
  389. type: "error",
  390. duration: 3000,
  391. });
  392. this.loading = false;
  393. })
  394. },
  395. // 同步信息
  396. queryRecordSyn(res) {
  397. const data = {
  398. content: [
  399. {
  400. ...res,
  401. },
  402. ],
  403. };
  404. this.loading = true;
  405. queryRecordSyn(data, res => {
  406. if (res.result == "success")
  407. this.$message({
  408. showClose: true,
  409. message: "同步完成!",
  410. type: "success",
  411. duration: 3000,
  412. });
  413. this.getTable();
  414. }, () => {
  415. this.$message({
  416. showClose: true,
  417. message: "同步失败,请重新同步或联系管理人员!",
  418. type: "error",
  419. duration: 3000,
  420. });
  421. this.loading = false;
  422. })
  423. },
  424. // 改变pageSize
  425. onSizeChange(val) {
  426. this.pageObj = Object.assign(this.pageObj, {
  427. pageSize: val,
  428. });
  429. this.getTable();
  430. },
  431. // 改变当前页
  432. onCurrentChange(val) {
  433. this.pageObj = Object.assign(this.pageObj, {
  434. pageNumber: val,
  435. });
  436. this.getTable();
  437. },
  438. // 时间排序
  439. handleSort(data) {
  440. if (data.order == "descending") {
  441. this.order = "lastUpdate desc, objId desc";
  442. } else {
  443. this.order = "lastUpdate asc, objId asc";
  444. }
  445. this.getTable();
  446. },
  447. },
  448. watch: {
  449. projectId() {
  450. this.getData();
  451. }
  452. },
  453. };
  454. </script>
  455. <style lang="less">
  456. #DataLog {
  457. padding: 20px 20px;
  458. box-sizing: border-box;
  459. }
  460. .pages {
  461. float: right;
  462. margin-top: 12px;
  463. margin-right: 24px;
  464. }
  465. .top {
  466. display: flex;
  467. align-items: center;
  468. justify-content: space-between;
  469. }
  470. .top .serve-updata {
  471. display: flex;
  472. align-items: center;
  473. margin-right: 12px;
  474. }
  475. .top .serve-updata .state {
  476. width: 20px;
  477. height: 20px;
  478. /* background: ; */
  479. border-radius: 50% 50%;
  480. margin-left: 6px;
  481. margin-right: 6px;
  482. }
  483. .status-1 {
  484. background: #19f704;
  485. border-radius: 50% 50%;
  486. width: 12px;
  487. height: 12px;
  488. display: inline-block;
  489. }
  490. .status-2 {
  491. display: inline-block;
  492. width: 12px;
  493. height: 12px;
  494. background: #4a4a4a;
  495. border-radius: 50% 50%;
  496. }
  497. .project {
  498. display: flex;
  499. width: 300px;
  500. align-items: center;
  501. justify-content: space-between;
  502. margin-bottom: 24px;
  503. }
  504. .project p {
  505. width: 90px;
  506. }
  507. .screen {
  508. margin-bottom: 12px;
  509. }
  510. .screen .screen-list {
  511. display: flex;
  512. align-items: center;
  513. padding: 12px;
  514. }
  515. .screen ul li {
  516. margin-left: 12px;
  517. }
  518. .infomations {
  519. cursor: pointer;
  520. }
  521. .no-data {
  522. width: 100%;
  523. min-height: 600px;
  524. display: flex;
  525. justify-content: center;
  526. align-items: center;
  527. }
  528. </style>