index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. <template>
  2. <div class="tab-content" >
  3. <div class="search">
  4. <el-cascader
  5. :options="deviceOptions"
  6. clearable
  7. v-model="deviceList"
  8. :props="optionProps"
  9. @change="handleChangeDevice"
  10. class="item"
  11. ></el-cascader>
  12. <admSearch @SearchValue="searchValue" class="item"/>
  13. <el-upload
  14. style="float: right"
  15. action="https://jsonplaceholder.typicode.com/posts/"
  16. :show-file-list="false"
  17. multiple
  18. >
  19. <el-button>上传Excle</el-button>
  20. </el-upload>
  21. <el-button style="float: right; margin-right: 12px" @click="handleClickDownload">下载模板</el-button>
  22. </div>
  23. <div v-loading="loading" style="height: calc(100% - 100px); padding: 0 12px; position: relative">
  24. <template style="height: 100%" v-if="tableData.length">
  25. <admMultiTable
  26. ref="table"
  27. @handleCurrentEdit="handleCurrentEdit"
  28. :isDynamicMap="false"
  29. :currentHeader="currentHeader"
  30. :headersStage="headersStage"
  31. :tableData="tableData"
  32. />
  33. <Pagination
  34. v-if="tableData.length"
  35. :paginationList="paginationList"
  36. @handleCurrentChange="handleCurrentChange"
  37. @handleSizeChange="handleSizeChange"
  38. />
  39. </template>
  40. <div v-else class="void align">
  41. <svg-icon name="void" :width="String(120)" :height="String(123)"/>
  42. <p class="void-title">暂无内容</p>
  43. <p class="void-tips">可点击左上角筛选</p>
  44. </div>
  45. </div>
  46. <!--编辑 设备-->
  47. <el-dialog title="编辑设备" :visible.sync="dialogVisible">
  48. <template>
  49. <baseDataForm :objectHeaders="headersStage" :currRowContent="currRowContent" ref="baseDataForm"/>
  50. <span slot="footer" class="dialog-footer">
  51. <el-button @click="dialogVisible = false">取消</el-button>
  52. <el-button type="primary" @click="handleDataForm">完成</el-button>
  53. </span>
  54. </template>
  55. </el-dialog>
  56. </div>
  57. </template>
  58. <script lang="ts">
  59. import { Vue, Component, Ref } from "vue-property-decorator";
  60. import { allDevice, dictInfo } from "@/api/equipComponent";
  61. import { queryEquip, updateEquip } from "@/api/datacenter";
  62. import { AdmMultiTable, AdmSearch, Pagination, baseDataForm } from "@/views/maintain/components/index";
  63. import { UserModule } from "@/store/modules/user";
  64. import tools from "@/utils/maintain";
  65. @Component({
  66. name: "EquipTab",
  67. components: {
  68. AdmMultiTable,
  69. AdmSearch,
  70. Pagination,
  71. baseDataForm
  72. },
  73. })
  74. export default class EquipTab extends Vue {
  75. // 信息点输入组组件
  76. @Ref("baseDataForm") readonly baseDataForm!: baseDataForm;
  77. // 项目id
  78. private get projectId(): string {
  79. return UserModule.projectId;
  80. }
  81. // 设备类型
  82. private get deviceType(): string {
  83. const length = this.deviceList.length;
  84. return length ? this.deviceList[length - 1] : "";
  85. }
  86. // 设备关键字
  87. private keyWord = "";
  88. // 设备类下拉绑定值
  89. private deviceList: any = [];
  90. // 设备筛选
  91. private deviceOptions: any[] = [];
  92. // 下拉框映射
  93. private optionProps: any = {
  94. value: "code",
  95. label: "name",
  96. children: "children",
  97. };
  98. // 表格数据加载loading
  99. private loading = false;
  100. // 表格数据
  101. private tableData: any[] = [];
  102. // 阶段信息
  103. private currentHeader = "运维阶段维护";
  104. // 表头阶段信息结合
  105. private headersStage: any = {};
  106. // 信息点集合(表头)
  107. private all: any = [];
  108. // 输入类型选项
  109. private codeToDataSource: any = {};
  110. // 分页
  111. private paginationList = {
  112. page: 1,
  113. size: 50,
  114. sizes: [10, 30, 50, 100, 150, 200],
  115. total: 0,
  116. };
  117. // 当前编辑行的数据
  118. private currRowContent: any = {};
  119. // 弹窗开关
  120. private dialogVisible = false;
  121. // created钩子
  122. created() {
  123. this.getDeviceOptions();
  124. }
  125. /**
  126. * 设备类数据
  127. */
  128. private async getDeviceOptions() {
  129. const res = await allDevice({});
  130. if (res.result === "success") {
  131. this.deviceOptions = res.content;
  132. }
  133. }
  134. /**
  135. * 获取设备数据(信息点和实例数据)
  136. */
  137. private getEquipData() {
  138. if (this.deviceType) {
  139. this.loading = true;
  140. let param = {
  141. category: this.deviceType,
  142. };
  143. let param2 = {
  144. filters: `classCode='${ this.deviceType }'`,
  145. pageNumber: this.paginationList.page,
  146. pageSize: this.paginationList.size,
  147. orders: "createTime desc, id asc",
  148. projectId: this.projectId,
  149. };
  150. if (this.keyWord != "") {
  151. param2.filters += `;codeName contain '${ this.keyWord }' or systemCategory contain '${ this.keyWord }' or bimTypeId contain '${ this.keyWord }' or localId contain '${ this.keyWord }'`;
  152. }
  153. let promise = new Promise((resolve) => {
  154. dictInfo(param).then((res: any) => {
  155. resolve(res);
  156. });
  157. });
  158. let promise2 = new Promise((resolve) => {
  159. queryEquip(param2).then((res: any) => {
  160. resolve(res);
  161. });
  162. });
  163. Promise.all([promise, promise2]).then((res: any[]) => {
  164. this.loading = false;
  165. // 获取运维阶段名称
  166. this.currentHeader = res[0]?.dictStages.find((item: any) => {
  167. return item.code === "moms";
  168. })?.name;
  169. this.headersStage = this.informationArrangement(res[0]); // 重组表头数据
  170. this.tableData = res[1]?.content ? res[1].content : []; // 主体数据
  171. this.paginationList.total = res[1]?.total ? res[1].total : 0;
  172. });
  173. } else {
  174. this.tableData = [];
  175. }
  176. }
  177. /**
  178. * 获取系统实例数据
  179. */
  180. private async getExampleData() {
  181. if (this.deviceType) {
  182. this.loading = true;
  183. let params = {
  184. filters: `classCode='${ this.deviceType }'`,
  185. pageNumber: this.paginationList.page,
  186. pageSize: this.paginationList.size,
  187. orders: "createTime desc, id asc",
  188. projectId: this.projectId,
  189. };
  190. if (this.keyWord != "") {
  191. params.filters += `;codeName contain '${ this.keyWord }' or systemCategory contain '${ this.keyWord }' or bimTypeId contain '${ this.keyWord }' or localId contain '${ this.keyWord }'`;
  192. }
  193. const res = await queryEquip(params);
  194. if (res.result === "success") {
  195. setTimeout(() => {
  196. this.tableData = res?.content ? res.content : []; // 主体数据
  197. this.paginationList.total = res?.total ? res.total : 0;
  198. this.loading = false;
  199. });
  200. }
  201. } else {
  202. this.tableData = [];
  203. }
  204. }
  205. /**
  206. * 信息点重组
  207. */
  208. private informationArrangement(data: any): any {
  209. if (data?.basicInfos && data?.dictStages) {
  210. const base: any[] = [];
  211. data.dictStages.forEach((item: any) => {
  212. if (this.currentHeader === item.name) {
  213. item?.infos.forEach((val: any) => {
  214. base.push(val);
  215. });
  216. }
  217. });
  218. // 信息点集合
  219. this.all = [...data.basicInfos, ...base];
  220. this.codeToDataSource = {};
  221. this.all.forEach((item: any) => {
  222. if (item.dataSource) {
  223. try {
  224. this.codeToDataSource[item.code] = {};
  225. item.dataSource.forEach((dic: any) => {
  226. this.codeToDataSource[item.code][dic.code] = dic.name;
  227. });
  228. } catch (e) {
  229. console.log(e);
  230. }
  231. }
  232. });
  233. return {
  234. basicInfos: {
  235. name: "基础信息台账",
  236. data: data.basicInfos,
  237. },
  238. dictStages: {
  239. name: this.currentHeader,
  240. data: base,
  241. },
  242. };
  243. } else {
  244. return {};
  245. }
  246. }
  247. /**
  248. * 切换设备类型
  249. */
  250. private handleChangeDevice() {
  251. this.paginationList.page = 1;
  252. this.paginationList.size = 50;
  253. this.getEquipData();
  254. }
  255. /**
  256. * 检索设备关键字
  257. */
  258. private searchValue(val: string) {
  259. this.keyWord = val;
  260. this.getExampleData();
  261. }
  262. /**
  263. * 下载模板
  264. */
  265. private handleClickDownload() {
  266. console.log("下载模板");
  267. }
  268. /**
  269. * 上传Excle
  270. */
  271. /**
  272. * 切换页码
  273. */
  274. private handleCurrentChange(val: number) {
  275. this.paginationList.page = val;
  276. this.getExampleData();
  277. }
  278. /**
  279. * 切换每页显示数量
  280. */
  281. private handleSizeChange(val: number) {
  282. this.paginationList.size = val;
  283. this.getExampleData();
  284. }
  285. /**
  286. * 编辑当前行
  287. */
  288. handleCurrentEdit(val: any) {
  289. this.currRowContent = val;
  290. this.dialogVisible = true;
  291. }
  292. /**
  293. * 添加/编辑 事件处理
  294. */
  295. private handleDataForm() {
  296. this.baseDataForm.submitForm(this.handleDataFormSave);
  297. }
  298. /**
  299. * 更新设备数据
  300. */
  301. private async handleDataFormSave() {
  302. let from = tools.formatData(this.baseDataForm.form);
  303. if (from?.id) {
  304. const param = {
  305. content: [from],
  306. };
  307. const res = await updateEquip(param);
  308. if (res.result === "success") {
  309. this.$message.success("更新成功");
  310. this.dialogVisible = false;
  311. this.getExampleData();
  312. }
  313. }
  314. }
  315. }
  316. </script>
  317. <style lang="scss" scoped>
  318. .tab-content {
  319. height: 100%;
  320. border: 1px solid #e1e7ea;
  321. border-top: none;
  322. padding-bottom: 12px;
  323. .search {
  324. padding: 12px;
  325. & > .item {
  326. margin-right: 12px;
  327. }
  328. }
  329. }
  330. // 数据暂未
  331. .align {
  332. height: 100%;
  333. display: flex;
  334. align-items: center;
  335. justify-content: center;
  336. flex-direction: column;
  337. flex-wrap: wrap;
  338. }
  339. ::v-deep .el-dialog {
  340. .el-dialog__body {
  341. padding: 20px;
  342. max-height: 550px !important;
  343. min-height: 100px;
  344. overflow-y: auto;
  345. overflow-x: hidden;
  346. }
  347. }
  348. ::v-deep .el-select,
  349. .el-date-editor.el-input,
  350. .el-date-editor.el-input__inner {
  351. width: 100%;
  352. }
  353. ::v-deep .el-dialog__header {
  354. border-bottom: 1px solid #d8d8d8;
  355. }
  356. </style>