index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <!--
  2. *@description: 可视化进度
  3. *@author: yh Fu
  4. *@date: 2023-12-25 13:27:19
  5. *@version: V1.0.5
  6. -->
  7. <template>
  8. <div class="progresVisualContainer">
  9. <el-radio-group v-model="currentMenu" style="margin-bottom: 20px;" @input="toModule">
  10. <el-radio-button label="0">用料统计</el-radio-button>
  11. <el-radio-button label="1">进度统计</el-radio-button>
  12. <el-radio-button label="2">可视化统计</el-radio-button>
  13. <el-radio-button label="3">可视化进度</el-radio-button>
  14. </el-radio-group>
  15. <div class="topContain">
  16. <el-form :model="searchParam" ref="searchForm" class="searchForm" :rules="searchRules">
  17. <el-form-item label="行政区" prop="district">
  18. <el-select v-model="searchParam.district" placeholder="请选择行政区" clearable
  19. @change="searchParam.areaId = undefined;getAreaList(searchParam.district)"
  20. @clear="searchParam.areaId = undefined;areaList=[];
  21. searchParam.buildingId = undefined;buildingList=[];
  22. searchParam.unitId = undefined;unitList=[]">
  23. <el-option
  24. v-for="dict in dict.type.district"
  25. :key="dict.value"
  26. :label="dict.label"
  27. :value="dict.value"
  28. />
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item label="小区名称" prop="areaId" style="width: 218px;">
  32. <el-select v-model="searchParam.areaId" filterable clearable placeholder="请选择小区"
  33. @change="searchParam.buildingId = undefined;getBuildingList1(searchParam.areaId)"
  34. @clear="searchParam.buildingId = undefined;buildingList=[];
  35. searchParam.unitId = undefined;unitList=[]">
  36. <el-option
  37. v-for="item in areaList"
  38. :key="item.id"
  39. :label="item.name"
  40. :value="item.id">
  41. </el-option>
  42. </el-select>
  43. </el-form-item>
  44. <el-form-item label="楼宇名称" prop="buildingId">
  45. <el-select v-model="searchParam.buildingId" filterable clearable placeholder="请选择楼宇"
  46. @change="searchParam.unitId = undefined;getUnitList1(searchParam.buildingId)"
  47. @clear="searchParam.unitId = undefined;unitList=[]"
  48. >
  49. <el-option
  50. v-for="item in buildingList"
  51. :key="item.id"
  52. :label="item.name"
  53. :value="item.id">
  54. </el-option>
  55. </el-select>
  56. </el-form-item>
  57. <el-form-item label="单元" prop="unitId">
  58. <el-select v-model="searchParam.unitId" placeholder="请选择单元" filterable clearable>
  59. <el-option
  60. v-for="obj in unitList"
  61. :key="obj.id"
  62. :label="obj.name"
  63. :value="obj.id"
  64. ></el-option>
  65. </el-select>
  66. </el-form-item>
  67. <!-- <el-form-item label="工程周期" prop="enginCycle" style="width: 218px;">-->
  68. <!-- <el-select-->
  69. <!-- :disabled="title == '添加用料' "-->
  70. <!-- v-model="searchParam.enginCycle"-->
  71. <!-- placeholder="请填写工程周期"-->
  72. <!-- >-->
  73. <!-- <el-option-->
  74. <!-- v-for="e in dict.type.engin_cycle"-->
  75. <!-- :key="e.value"-->
  76. <!-- :label="e.label"-->
  77. <!-- :value="e.value"-->
  78. <!-- ></el-option>-->
  79. <!-- </el-select>-->
  80. <!-- </el-form-item>-->
  81. </el-form>
  82. <!-- <div style="width: 100%;height: 100%;">
  83. <el-select
  84. v-model="currentCommunity"
  85. placeholder="请选择行政区"
  86. class="projectSelect"
  87. popper-class="projectDropDown"
  88. :popper-append-to-body="false"
  89. >
  90. <el-option
  91. v-for="e in communityOptions"
  92. :key="e.value"
  93. :label="e.label"
  94. :value="e.value">
  95. </el-option>
  96. </el-select>
  97. <el-select
  98. v-model="currentCommunity"
  99. placeholder="请选择小区"
  100. class="projectSelect"
  101. popper-class="projectDropDown"
  102. :popper-append-to-body="false"
  103. >
  104. <el-option
  105. v-for="e in communityOptions"
  106. :key="e.value"
  107. :label="e.label"
  108. :value="e.value">
  109. </el-option>
  110. </el-select>
  111. <el-select
  112. v-model="currentType"
  113. placeholder="请选择工程类型"
  114. class="projectSelect"
  115. popper-class="projectDropDown"
  116. :popper-append-to-body="false"
  117. >
  118. <el-option
  119. v-for="e in typeOptions"
  120. :key="e.value"
  121. :label="e.label"
  122. :value="e.value">
  123. </el-option>
  124. </el-select>
  125. <el-date-picker
  126. v-model="currentDate"
  127. class="projectSelect"
  128. popper-class="projectDropDown"
  129. :popper-append-to-body="false"
  130. type="date"
  131. placeholder="选择日期">
  132. </el-date-picker>
  133. </div> -->
  134. <el-button class="searchBtn" @click="searchCompletionInfo">查询</el-button>
  135. <el-button class="searchBtn">导出</el-button>
  136. <div class="unitStatus">
  137. <div
  138. v-for="(e,idx) in unitStatusOption"
  139. :key="idx"
  140. :style="`background-color:${e.color};width: 22%;height: 35px;position: absolute;right:${idx*130}px;box-shadow:0 5px 5px 0 #CDCDCD`"
  141. >
  142. <div
  143. style="position: relative;left: 107%;width: 116%;top: 20%;"
  144. >
  145. {{ e.label }}
  146. </div>
  147. </div>
  148. </div>
  149. </div>
  150. <!-- 房间集合 -->
  151. <!-- 楼栋 or 单元 -->
  152. <div style="min-width: 1618px;display: flex;overflow: hidden;overflow-x: scroll;align-items: end;">
  153. <div
  154. v-for="(e,idx) in roomsInfo"
  155. :key="idx"
  156. class="buildingContain"
  157. >
  158. <!-- 楼层 -->
  159. <div
  160. v-for="(v,vdx) in e.roomStatusVoList"
  161. :key="vdx"
  162. class="unitFloor"
  163. >
  164. {{ v.notstart || '' }}
  165. <!-- 房间 -->
  166. <div
  167. v-for="(k,kdx) in v"
  168. :key="kdx"
  169. class="room"
  170. @click="toDetail(k)"
  171. :style="`background-color:${k.roomStatus == '未施工' ? '#fec880' : k.roomStatus == '施工中' ? '#5ad3fe' : '#81d9af'};
  172. border: solid 1px ${k.roomStatus == '未施工' ? '#ffa938' : k.roomStatus == '施工中' ? '#30b3e1' : '#62b98f'}`"
  173. >
  174. {{ k.roomName || '' }}
  175. </div>
  176. </div>
  177. <h2 style="text-align: center; font-size: 1.1em;">{{ e.unitName }}</h2>
  178. </div>
  179. </div>
  180. <ConstructionDetails
  181. ref="ConstructionDetails"
  182. :currentCollapses="currentCollapses"
  183. :type="nodeDetailType"
  184. :status="status"
  185. enginType="民用工程"
  186. />
  187. </div>
  188. </template>
  189. <script>
  190. import ConstructionDetails from '@/components/ConstructionDetails'
  191. import {getAreaList} from "@/api/zdsz/area";
  192. import {getBuildingList} from "@/api/zdsz/building";
  193. import {getUnits} from "@/api/zdsz/unit";
  194. import {getDicts} from "@/api/system/dict/data";
  195. import {getObtainRoomcCompletionInformationList, viewQueryProcessSource} from "@/api/zdsz/enginee"
  196. export default {
  197. name: 'ProgreVisual',
  198. components: {
  199. ConstructionDetails
  200. },
  201. dicts: ['district', 'engin_cycle', 'new_built', 'old_renovation'],
  202. data() {
  203. return {
  204. currentMenu: 3, // 0:用料管理 1:进度统计 2:可视化进度
  205. currentCollapses: [],
  206. status: '',
  207. typeOptions: [
  208. {
  209. value: '0',
  210. label: '市政工程'
  211. },
  212. {
  213. value: '1',
  214. label: '工业工程'
  215. },
  216. {
  217. value: '2',
  218. label: '民用工程'
  219. },
  220. {
  221. value: '3',
  222. label: '危险作业'
  223. },
  224. {
  225. value: '4',
  226. label: '顶管工程'
  227. },
  228. {
  229. value: '5',
  230. label: '基建工程'
  231. }
  232. ],
  233. communityOptions: [
  234. {
  235. value: '0',
  236. label: '领秀世家'
  237. },
  238. {
  239. value: '1',
  240. label: '上东府里'
  241. },
  242. {
  243. value: '2',
  244. label: '清华园'
  245. },
  246. {
  247. value: '3',
  248. label: '万科蓝山'
  249. },
  250. {
  251. value: '4',
  252. label: '龙腾香格里'
  253. },
  254. ],
  255. unitStatusOption: [
  256. {
  257. label: '竣工',
  258. color: '#81d9af'
  259. },
  260. {
  261. label: '施工中',
  262. color: '#5ad3fe'
  263. },
  264. {
  265. label: '未施工',
  266. color: '#fec880'
  267. },
  268. ],
  269. currentType: null,
  270. currentCommunity: null,
  271. areaList: [],
  272. buildingList: [],
  273. unitList: [],
  274. info: {
  275. district: undefined,
  276. },
  277. searchParam: {
  278. district: null,
  279. enginCycle: 0,
  280. areaId: null,
  281. buildingId: null,
  282. unitId: null,
  283. },
  284. roomsInfo: [],
  285. updateParams: {},
  286. currentRoomId: null,
  287. currentEnginType: null,
  288. currentEnginClassification: 'indoor_engin',
  289. searchRules: {
  290. district: [
  291. {required: true, message: "行政区不能为空", trigger: ['change']}
  292. ],
  293. areaId: [
  294. {required: true, message: "小区不能为空", trigger: ['change']}
  295. ],
  296. // enginCycle: [
  297. // {required: true, message: "工程周期不能为空", trigger: ['change']}
  298. // ],
  299. }
  300. }
  301. },
  302. methods: {
  303. toDetail(e) {
  304. this.currentRoomId = e.roomId
  305. let dictValue
  306. // 拼接字典
  307. console.log(e)
  308. console.log(e.enginCycle)
  309. e.enginCycle = 0
  310. console.log(this.dict.type[e.enginCycle])
  311. this.dict.type[e.enginCycle].forEach(v => {
  312. if (v.label.includes('室内')) {
  313. this.currentEnginType = e.enginCycle
  314. dictValue = e.enginCycle + '_' + v.value
  315. }
  316. })
  317. // 加工字典
  318. getDicts(dictValue).then(res => {
  319. let dict = []
  320. for (let i = 0; i < res.data.length; i++) {
  321. dict.push({
  322. "label": res.data[i].dictLabel,
  323. "value": res.data[i].dictValue,
  324. })
  325. }
  326. console.log(dict)
  327. setTimeout(() => {
  328. this.$refs.ConstructionDetails.open(dict)
  329. })
  330. })
  331. this.status = 'read-only'
  332. },
  333. viewNodeSource(e) {
  334. let params = {
  335. type: e,
  336. houseId: this.currentRoomId,
  337. enginClassification: this.currentEnginClassification,
  338. enginType: this.currentEnginType
  339. }
  340. viewQueryProcessSource(params).then(res => {
  341. console.log('______', res)
  342. try {
  343. this.updateParams = res.data
  344. this.currentCollapses = res.data.zEngineeringNodeBo.zEngineeringInfoBoList
  345. } catch (error) {
  346. this.currentCollapses = [];
  347. }
  348. console.log('折叠面板info', this.currentCollapses)
  349. })
  350. this.$forceUpdate()
  351. },
  352. // 查询进度
  353. searchCompletionInfo() {
  354. this.$refs.searchForm.validate(valid => {
  355. if (valid) {
  356. // 校验 pass
  357. let params = {
  358. enginCycle: this.searchParam.enginCycle,
  359. areaId: this.searchParam.areaId,
  360. buildingId: this.searchParam.buildingId,
  361. unitId: this.searchParam.unitId,
  362. }
  363. getObtainRoomcCompletionInformationList(params).then(res => {
  364. let info = []
  365. info = res.data
  366. info.forEach(e => {
  367. e.roomStatusVoList = e.roomStatusVoList.reverse()
  368. })
  369. this.roomsInfo = info
  370. })
  371. } else {
  372. this.$message.error('请填写必填项!')
  373. }
  374. })
  375. },
  376. getAreaList(district) {
  377. if (district === undefined || district == null || district === '')
  378. return
  379. console.log(getAreaList)
  380. getAreaList({district: district}).then(res => this.areaList = res.data)
  381. },
  382. getBuildingList1(areaId) {
  383. if (areaId === undefined || areaId == null || areaId === '')
  384. return
  385. getBuildingList({areaId: areaId}).then(res => this.buildingList = res.data)
  386. },
  387. getUnitList1(buildingId) {
  388. if (buildingId === undefined || buildingId == null || buildingId === '')
  389. return
  390. getUnits(buildingId).then(res => this.unitList = res.data)
  391. },
  392. toModule() {
  393. console.log(this.$router)
  394. const currentPage = this.currentMenu == 0 ? 'material_statistics' : this.currentMenu == 1 ? 'progres_statistics' : this.currentMenu == 2 ? 'echarts_statistics' : 'progres_visual'
  395. this.$router.push({
  396. path: `/${currentPage}`
  397. })
  398. }
  399. }
  400. }
  401. </script>
  402. <style lang="scss" scoped>
  403. .progresVisualContainer {
  404. width: 100%;
  405. height: 100%;
  406. padding: 1%;
  407. .topContain {
  408. display: flex;
  409. justify-content: space-between;
  410. width: 60%;
  411. .searchBtn {
  412. height: 100%;
  413. width: 11%;
  414. background-color: #1890FF;
  415. color: #fff;
  416. }
  417. ::v-deep .projectSelect {
  418. width: 20% !important;
  419. .el-input__inner {
  420. background-color: #1890FF;
  421. color: #fff;
  422. }
  423. }
  424. .projectDropDown {
  425. background-color: #1890FF;
  426. .el-select-dropdown__item {
  427. background-color: #1890FF;
  428. color: #fff;
  429. }
  430. ::v-deep .el-select-dropdown__list {
  431. padding-top: 0 !important;
  432. padding-bottom: 0;
  433. }
  434. }
  435. .projectDropDown > ul {
  436. padding-top: 0;
  437. padding-bottom: 0;
  438. }
  439. .unitStatus {
  440. width: 13%;
  441. display: flex;
  442. position: absolute;
  443. right: 7%;
  444. height: 5%;
  445. }
  446. }
  447. }
  448. .buildingContain {
  449. height: 100%;
  450. border: solid 5px #c7eafe;
  451. padding: 10px;
  452. background: #e2f4ff;
  453. .unitFloor {
  454. display: flex;
  455. justify-content: space-around;
  456. //border: 1px solid #000;
  457. .room {
  458. flex: 1;
  459. width: 50px;
  460. height: 25px;
  461. text-align: center;
  462. line-height: 25px;
  463. cursor: pointer;
  464. font-size: 1em;
  465. //box-shadow: inset 0px 0px 10px rgba(0, 0, 0, .6);
  466. }
  467. }
  468. .unitFloor > div:not(:nth-child(1)) {
  469. margin-left: 2%;
  470. }
  471. }
  472. .buildingContain:not(:nth-child(1)) {
  473. margin-left: 5%;
  474. }
  475. .buildingContain .unitFloor:not(:nth-child(1)) {
  476. margin-top: 2%;
  477. }
  478. ::v-deep .searchForm {
  479. display: flex;
  480. .el-form-item {
  481. width: 205px;
  482. }
  483. .el-select {
  484. width: 135px;
  485. }
  486. }
  487. </style>