index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. <template>
  2. <div class="custom-config">
  3. <div class="form-wrapper">
  4. <div class="btns" style="margin-bottom: 10px">
  5. <el-button class="buttons" size="mini" round @click="handleInsert">
  6. 新增记录
  7. </el-button>
  8. <el-button class="buttons" size="mini" round @click="export2Excel">
  9. 批量导出</el-button
  10. >
  11. <el-button class="buttons" size="mini" round @click="outExe">
  12. 模板下载</el-button
  13. >
  14. <el-upload
  15. style="display: inline; margin-left: 10px"
  16. :action="url + 'alertrule/import'"
  17. :show-file-list="false"
  18. :on-success="handleSuccess"
  19. :on-progress="handleProgress"
  20. :on-error="handleError"
  21. >
  22. <el-button
  23. class="buttons"
  24. size="mini"
  25. round
  26. @click="exportShow = true"
  27. >
  28. 批量导入</el-button
  29. >
  30. </el-upload>
  31. </div>
  32. <div class="search-wrapper">
  33. <el-select
  34. v-model="query.category"
  35. size="mini"
  36. class="search-item"
  37. popper-class="select"
  38. @change="categorychanged"
  39. >
  40. <el-option key="1" label="风机报警" value="windturbine"></el-option>
  41. <!-- <el-option
  42. key="2"
  43. label="升压站报警"
  44. value="booststation"
  45. ></el-option> -->
  46. <el-option key="3" label="光伏报警" value="inverter"></el-option>
  47. </el-select>
  48. <el-select
  49. v-model="query.wpId"
  50. clearable
  51. size="mini"
  52. class="search-item"
  53. :placeholder="'全部场站'"
  54. popper-class="select"
  55. @change="changeStation"
  56. >
  57. <el-option
  58. v-for="item in stationList"
  59. :key="item.id"
  60. :value="item.id"
  61. :label="item.aname"
  62. ></el-option>
  63. </el-select>
  64. <el-select
  65. v-model="query.relatedparts"
  66. clearable
  67. size="mini"
  68. class="search-item"
  69. placeholder="所属部件"
  70. >
  71. <el-option
  72. v-for="item in fetchList"
  73. :key="item.id"
  74. :label="item.name"
  75. :value="item.nemCode"
  76. >
  77. </el-option>
  78. </el-select>
  79. <el-select
  80. v-model="query.enabled"
  81. clearable
  82. size="mini"
  83. class="search-item"
  84. placeholder="是否可用"
  85. >
  86. <el-option
  87. v-for="item in state.isEnabled"
  88. :key="item.id"
  89. :label="item.name"
  90. :value="item.id"
  91. >
  92. </el-option>
  93. </el-select>
  94. <el-select
  95. v-model="query.modelId"
  96. clearable
  97. size="mini"
  98. class="search-item"
  99. placeholder="全部机型"
  100. popper-class="select"
  101. >
  102. <el-option
  103. v-for="item in modelList"
  104. :key="item.id"
  105. :value="item.id"
  106. :label="item.aname"
  107. ></el-option>
  108. </el-select>
  109. <!-- <el-select
  110. v-model="query.rank"
  111. clearable
  112. size="mini"
  113. class="search-item"
  114. placeholder="全部级别"
  115. popper-class="select"
  116. >
  117. <el-option
  118. v-for="item in state.rankList"
  119. :key="item.id"
  120. :value="item.id"
  121. :label="item.name"
  122. ></el-option>
  123. </el-select> -->
  124. <el-input
  125. placeholder="请输入名称"
  126. v-model="query.name"
  127. size="mini"
  128. class="search-item"
  129. clearable
  130. ></el-input>
  131. <el-button class="buttons" round size="mini" @click="getData"
  132. >搜索</el-button
  133. >
  134. </div>
  135. </div>
  136. <div class="table-wrapper">
  137. <div class="leftContent">
  138. <span>{{ pageTitle }}</span>
  139. </div>
  140. <el-table
  141. :data="state.tableData"
  142. stripe
  143. height="calc(100% - 42px - 45px)"
  144. >
  145. <el-table-column
  146. v-for="item in state.tableHeader"
  147. :key="item.code"
  148. :label="item.title"
  149. :align="
  150. item.code == 'description' ||
  151. item.code == 'expression' ||
  152. item.code == 'name' ||
  153. item.code == 'modelId' ||
  154. item.code == 'relatedPartsName'
  155. ? 'left'
  156. : 'center'
  157. "
  158. :prop="item.code"
  159. :minWidth="item.width ? item.width : 60"
  160. show-overflow-tooltip
  161. >
  162. <template #default="scope">
  163. <span v-if="item.code == 'rank'">
  164. {{ rankConvert(scope.row.rank) }}
  165. </span>
  166. <span v-else-if="item.code == 'category'">
  167. {{ categoryConvert(scope.row.category) }}
  168. </span>
  169. <span v-else-if="item.code == 'enable'">
  170. {{ enabledConvert(scope.row.enable) }}
  171. </span>
  172. <span v-else>
  173. {{ scope.row[item.code] }}
  174. </span>
  175. </template>
  176. </el-table-column>
  177. <el-table-column label="操作" align="center" width="100">
  178. <template #default="scope">
  179. <el-button
  180. type="text"
  181. style="color: #05bb4c"
  182. size="mini"
  183. @click="handleEditClick(scope.row)"
  184. >编辑</el-button
  185. >
  186. </template>
  187. </el-table-column>
  188. </el-table>
  189. <div class="pagination">
  190. <el-pagination
  191. :current-page="query.pageNum"
  192. :page-size="query.pageSize"
  193. :total="total"
  194. layout="total, sizes, prev, pager, next"
  195. :page-sizes="[22, 50, 100, 200, 500]"
  196. @size-change="
  197. (value) => {
  198. query.pageSize = value;
  199. query.pageNum = 1;
  200. getData();
  201. }
  202. "
  203. @current-change="handlePageChange"
  204. ></el-pagination>
  205. </div>
  206. </div>
  207. <customcomponents
  208. @close="dialogclose"
  209. :isVisible="state.visible"
  210. :dialogOptions="state.form"
  211. :rankList="state.rankList"
  212. :modelListAll="state.modelListAll"
  213. :fetchListAll="state.fetchListAll"
  214. />
  215. </div>
  216. </template>
  217. <script setup>
  218. import {
  219. custombj_fetchTableData,
  220. getStationinfo,
  221. fetchRelatePartAndAlarmType,
  222. fetchModel,
  223. fetchBooststation,
  224. custombj_importTemplate,
  225. getWpList,
  226. } from "@/api/zhbj/index.js";
  227. import { outExportExcel } from "@/tools/excel/exportExcel.js"; //引入文件
  228. import {
  229. ref,
  230. onMounted,
  231. provide,
  232. computed,
  233. reactive,
  234. watch,
  235. nextTick,
  236. } from "vue";
  237. import { useStore } from "vuex";
  238. import { useRouter } from "vue-router";
  239. import { ElMessageBox, ElMessage } from "element-plus";
  240. import customcomponents from "@/views/IntegratedAlarm/alarmConfig/components/custom_components.vue";
  241. const pageTitle = "预警配置";
  242. const store = useStore();
  243. const token = { token: store.state.user.authToken };
  244. const url = process.env.VUE_APP_ALARM;
  245. const router = useRouter();
  246. const query = reactive({
  247. pageNum: 1,
  248. pageSize: 22,
  249. name: "",
  250. wpId: "",
  251. rank: "",
  252. modelId: "",
  253. category: "windturbine",
  254. enabled: "",
  255. relatedparts: "",
  256. });
  257. const state = reactive({
  258. tableData: [],
  259. fetchListAll: [], //部件及预警类型
  260. modelListAll: {}, //型号所有列表
  261. isEnabled: [
  262. {
  263. id: false,
  264. name: "否",
  265. },
  266. {
  267. id: true,
  268. name: "是",
  269. },
  270. ],
  271. rankList: [
  272. {
  273. id: 1,
  274. name: "低",
  275. },
  276. {
  277. id: 2,
  278. name: "中低",
  279. },
  280. {
  281. id: 3,
  282. name: "中",
  283. },
  284. {
  285. id: 4,
  286. name: "中高",
  287. },
  288. {
  289. id: 5,
  290. name: "高",
  291. },
  292. ],
  293. visible: false,
  294. form: {},
  295. tableHeader: [
  296. { title: "编码", code: "id" },
  297. { title: "场站", code: "stationName", width: "100" },
  298. { title: "机型", code: "modelId" },
  299. { title: "规则名称", code: "name", width: "150" },
  300. { title: "表达式", code: "expression", width: "150" },
  301. { title: "描述", code: "description", width: "150" },
  302. { title: "所属部件", code: "relatedPartsName" },
  303. // { title: "级别", code: "rank" },
  304. { title: "类型", code: "category" },
  305. { title: "是否启用", code: "enable" },
  306. ],
  307. tableHeader1: [
  308. { title: "编码", code: "id" },
  309. { title: "升压站", code: "stationName" },
  310. { title: "规则名称", code: "name" },
  311. { title: "表达式", code: "expression" },
  312. { title: "描述", code: "description" },
  313. // { title: "级别", code: "rank" },
  314. { title: "类型", code: "category" },
  315. { title: "是否启用", code: "enable" },
  316. ],
  317. });
  318. //型号列表
  319. const modelList = computed(() => {
  320. if (query.wpId == "") {
  321. return [];
  322. } else {
  323. return state.modelListAll[query.wpId];
  324. }
  325. });
  326. //部件列表
  327. const fetchList = computed(() => {
  328. if (query.wpId == "") {
  329. return [];
  330. } else {
  331. if (query.wpId.includes("FDC")) {
  332. return state.fetchListAll?.fjbj;
  333. } else {
  334. return state.fetchListAll?.gfbj;
  335. }
  336. }
  337. });
  338. // 场站列表/升压站列表
  339. const stationList = ref([]);
  340. let total = ref(0);
  341. onMounted(() => {
  342. getWpArray();
  343. getfetchRelatePart();
  344. getequipmentmodel_list();
  345. getData();
  346. });
  347. const dialogclose = () => {
  348. state.visible = false;
  349. state.form = {};
  350. getData();
  351. };
  352. const getWpArray = async () => {
  353. const { data } = await getWpList(query.category);
  354. stationList.value = data;
  355. };
  356. const getData = async () => {
  357. const { data } = await custombj_fetchTableData(query);
  358. state.tableData = data.records;
  359. total.value = data.total;
  360. };
  361. //所属部件
  362. const getfetchRelatePart = async () => {
  363. const { data } = await fetchRelatePartAndAlarmType();
  364. state.fetchListAll = data;
  365. // if (router && router.currentRoute.value.query.name) {
  366. // let queryName = router.currentRoute.value.query.name;
  367. // query.relatedparts = queryName;
  368. // }
  369. // getData();
  370. };
  371. // 机型
  372. const getequipmentmodel_list = async () => {
  373. const { data } = await fetchModel();
  374. state.modelListAll = data;
  375. };
  376. const handleEditClick = (row) => {
  377. let obj = Object.assign({}, row);
  378. state.form = obj;
  379. state.visible = true;
  380. };
  381. const handleInsert = () => {
  382. state.form = {
  383. category: "windturbine",
  384. enable: true,
  385. stationId: "",
  386. expression: "",
  387. };
  388. state.visible = true;
  389. };
  390. //changeStation
  391. const changeStation = async () => {
  392. query.modelId = "";
  393. query.relatedparts = "";
  394. };
  395. //categorychanged
  396. const categorychanged = async () => {
  397. getWpArray();
  398. this.clean();
  399. getData();
  400. };
  401. // 分页导航
  402. const handlePageChange = (val) => {
  403. query.pageNum = val;
  404. getData();
  405. };
  406. // 批量导出
  407. const export2Excel = async () => {
  408. let tableHeader = [];
  409. let tableKey = [];
  410. const { data } = await custombj_fetchTableData({
  411. pageNum: 1,
  412. pageSize: total.value,
  413. ...query,
  414. });
  415. ElMessage.success(`导出成功!`);
  416. if (query.category == "windturbine") {
  417. tableHeader = state.tableHeader.map((item) => item.title);
  418. tableKey = state.tableHeader.map((item) => item.code);
  419. } else if (query.category == "booststation") {
  420. tableHeader = state.tableHeader1.map((item) => item.title);
  421. tableKey = state.tableHeader1.map((item) => item.code);
  422. }
  423. outExportExcel(
  424. tableHeader,
  425. tableKey,
  426. data.records.map((item) => {
  427. return {
  428. ...item,
  429. category: categoryConvert(item.category),
  430. enable: enabledConvert(item.enable),
  431. };
  432. }),
  433. "自定义预警配置导出excel"
  434. );
  435. };
  436. // 模板下载
  437. const outExe = () => {
  438. custombj_importTemplate().then((response) => {
  439. const link = document.createElement("a");
  440. const blob = new Blob([response], {
  441. type: "application/vnd.ms-excel",
  442. });
  443. link.style.display = "none";
  444. link.href = URL.createObjectURL(blob);
  445. link.download = "自定义报警模板.xlsx";
  446. document.body.appendChild(link);
  447. link.click();
  448. document.body.removeChild(link);
  449. });
  450. };
  451. // 批量导入
  452. const handleSuccess = (response) => {
  453. if (response.code == "200") {
  454. ElMessage.success("导入成功!");
  455. getData();
  456. } else {
  457. ElMessage.error(response.msg);
  458. }
  459. };
  460. // 批量导入中
  461. const handleProgress = (response) => {};
  462. // 批量导入失败
  463. const handleError = (response) => {
  464. ElMessage.success("导入失败!");
  465. };
  466. // 清空字段
  467. const clean = () => {
  468. query.modelId = "";
  469. query.relatedparts = "";
  470. query.wpId = "";
  471. query.enabled = "";
  472. query.rank = "";
  473. query.name = "";
  474. query.pageNum = 1;
  475. state.tableData = [];
  476. total.value = 0;
  477. };
  478. const rankConvert = (val) => {
  479. if (val == 1) {
  480. return "低";
  481. } else if (val == 2) {
  482. return "中低";
  483. } else if (val == 3) {
  484. return "中";
  485. } else if (val == 4) {
  486. return "中高";
  487. } else if (val == 5) {
  488. return "高";
  489. }
  490. };
  491. // 类型
  492. const categoryConvert = (val) => {
  493. if (val === "windturbine") {
  494. return "风机";
  495. } else if (val === "inverter") {
  496. return "光伏";
  497. }
  498. };
  499. // 状态
  500. const enabledConvert = (val) => {
  501. if (val === false) {
  502. return "停用";
  503. } else if (val === true) {
  504. return "启用";
  505. }
  506. };
  507. </script>
  508. <style scoped lang="less">
  509. .custom-config {
  510. height: 100%;
  511. width: 100%;
  512. padding: 0 20px;
  513. padding-bottom: 10px;
  514. .form-wrapper {
  515. display: flex;
  516. padding-top: 10px;
  517. justify-content: space-between;
  518. .search-wrapper::v-deep {
  519. display: flex;
  520. align-items: center;
  521. font-size: 14px;
  522. font-family: Microsoft YaHei;
  523. font-weight: 400;
  524. color: #b3b3b3;
  525. margin-bottom: 10px;
  526. .search-item {
  527. margin-right: 10px;
  528. max-width: 190px;
  529. }
  530. }
  531. .btns {
  532. display: flex;
  533. justify-content: flex-end;
  534. margin-right: 10px;
  535. // position: absolute;
  536. // right: 0;
  537. // top: 53px;
  538. .el-button + .el-button {
  539. margin-left: 10px;
  540. }
  541. }
  542. .buttons {
  543. background-color: rgba(5, 187, 76, 0.2);
  544. border: 1px solid #3b6c53;
  545. color: #b3b3b3;
  546. font-size: 14px;
  547. &:hover {
  548. background-color: rgba(5, 187, 76, 0.5);
  549. color: #ffffff;
  550. }
  551. }
  552. }
  553. }
  554. .table-wrapper {
  555. height: calc(100% - 43px);
  556. width: 100%;
  557. .leftContent {
  558. width: 242px;
  559. height: 41px;
  560. display: flex;
  561. align-items: center;
  562. background: url("~@/assets/imgs/title_left_bg1.png") no-repeat;
  563. span {
  564. font-size: 16px;
  565. font-family: Microsoft YaHei;
  566. font-weight: 400;
  567. color: #05bb4c;
  568. margin-left: 25px;
  569. }
  570. }
  571. .el-table::v-deep {
  572. .el-table__body-wrapper {
  573. height: calc(100% - 45px) !important;
  574. }
  575. }
  576. .pagination-wrapper ::v-deep {
  577. text-align: right;
  578. margin-top: 10px;
  579. }
  580. }
  581. </style>