index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <div class="app-container snapshotManagement">
  3. <div class="snapshotManagement-page" v-if="pageType == 1">
  4. <div class="title-box">
  5. <el-form :model="queryParams" class="form-box" ref="queryForm" :inline="true" label-width="70px">
  6. <div class="form-button-max-big-box">
  7. <div class="form-button-big-box" style="margin-left:10px;">
  8. <p class="text-p" :class="queryParams.rectifyStatus==''?'checkDiv':''" @click="topLeftClickType('')">全部</p>
  9. <p class="text-p" :class="queryParams.rectifyStatus=='0'?'checkDiv':''" @click="topLeftClickType('0')">待整改</p>
  10. <p class="text-p" :class="queryParams.rectifyStatus=='1'?'checkDiv':''" @click="topLeftClickType('1')">已整改</p>
  11. <p class="text-p" :class="queryParams.rectifyStatus=='2'?'checkDiv':''" @click="topLeftClickType('2')">暂无法整改</p>
  12. </div>
  13. </div>
  14. <!--与我相关-->
  15. <div class="form-button-max-big-box-me">
  16. <div class="form-button-big-box-me">
  17. <div :class="queryParams.myRelated==1?'checkDiv-me':''" @click="topRightClickType">
  18. <p class="text-p-me">与我有关{{correlationNum}}</p>
  19. <p class="el-icon-check icon-p-me" v-if="queryParams.myRelated==1"></p>
  20. </div>
  21. </div>
  22. </div>
  23. <el-form-item label="关键字" prop="searchValue">
  24. <el-input
  25. maxLength="30"
  26. v-model="queryParams.searchValue"
  27. placeholder="实验室/房间号/上报人"
  28. clearable
  29. style="width: 180px"/>
  30. </el-form-item>
  31. <el-form-item label="学院" prop="deptId" label-width="40px">
  32. <el-select v-model="queryParams.deptId" clearable placeholder="学院" style="width: 130px">
  33. <el-option
  34. v-for="item in deptSelectList"
  35. :key="item.deptId"
  36. :label="item.deptName"
  37. :value="item.deptId">
  38. </el-option>
  39. </el-select>
  40. </el-form-item>
  41. <el-form-item label="上报时间" prop="dateRange" label-width="70px">
  42. <el-date-picker
  43. :clearable="false"
  44. v-model="dateRange"
  45. size="small"
  46. style="width: 220px"
  47. value-format="yyyy-MM-dd"
  48. type="daterange"
  49. range-separator="-"
  50. start-placeholder="开始日期"
  51. end-placeholder="结束日期"
  52. ></el-date-picker>
  53. </el-form-item>
  54. <el-form-item>
  55. <p class="inquire-button-one" @click="handleQuery" style="margin-right:10px;">查询</p>
  56. <p class="reset-button-one" @click="resetQuery">重置</p>
  57. </el-form-item>
  58. <el-form-item style="float: right;" v-hasPermi="['safety:rectifyClap:add']">
  59. <el-col :span="1.5">
  60. <p class="inquire-button-one"
  61. style="width:70px;margin-right:0;"
  62. @click="addButton"
  63. >随手拍</p>
  64. </el-col>
  65. </el-form-item>
  66. <el-form-item style="float: right;">
  67. <el-col :span="1.5">
  68. <p class="add-button-one-90"
  69. style="width:80px;"
  70. @click="goPage(2)"
  71. >上报记录</p>
  72. </el-col>
  73. </el-form-item>
  74. </el-form>
  75. </div>
  76. <div class="content-box">
  77. <el-table border :data="tableList" ref="multipleTable" @sort-change="sortChange">
  78. <el-table-column label="序号" align="center" type="index" width="60" />
  79. <el-table-column label="学院" align="center" prop="deptName" show-overflow-tooltip/>
  80. <el-table-column label="实验室" align="center" prop="subName" show-overflow-tooltip width="220">
  81. <template slot-scope="scope">{{scope.row.roomNum?scope.row.subName+'-'+scope.row.roomNum:scope.row.subName}}</template>
  82. </el-table-column>
  83. <el-table-column label="安全责任人" align="center" prop="safetyPeople" show-overflow-tooltip width="120"/>
  84. <el-table-column label="上报人" align="center" prop="createName" show-overflow-tooltip width="90"/>
  85. <el-table-column label="上报时间" sortable="custom" align="center" prop="createTime" show-overflow-tooltip width="157"/>
  86. <el-table-column label="隐患描述" align="center" prop="hazardDescribe" show-overflow-tooltip width="280"/>
  87. <el-table-column label="整改人" align="center" prop="rectifyPeople" show-overflow-tooltip width="100"/>
  88. <el-table-column label="整改时间" sortable="custom" align="center" prop="rectifyTime" show-overflow-tooltip width="157"/>
  89. <el-table-column label="整改状态" align="center" prop="rectifyStatus" show-overflow-tooltip width="120">
  90. <template slot-scope="scope">
  91. {{scope.row.rectifyStatus==0?'待整改':(scope.row.rectifyStatus==1?'已整改':(scope.row.rectifyStatus==2?'暂无法整改':''))}}
  92. </template>
  93. </el-table-column>
  94. <el-table-column label="操作" align="center" prop="deptName" width="70">
  95. <template slot-scope="scope">
  96. <div class="table-button-box">
  97. <p class="table-button-null"></p>
  98. <p class="table-button-p" @click="goPage(3,scope.row)" v-hasPermi="['safety:rectifyClap:query']">详情</p>
  99. <p class="table-button-null"></p>
  100. </div>
  101. </template>
  102. </el-table-column>
  103. </el-table>
  104. <pagination :page-sizes="[20, 30, 40, 50]"
  105. v-show="total>0"
  106. :total="total"
  107. :page.sync="queryParams.pageNum"
  108. :limit.sync="queryParams.pageSize"
  109. @pagination="getList"/>
  110. </div>
  111. </div>
  112. <listPage v-if="pageType == 2"></listPage>
  113. <infoPage v-if="pageType == 3" :infoPropsData="infoPropsData"></infoPage>
  114. <el-dialog class="safetyHazard-info-dialog-box" @close="outDialog"
  115. :close-on-click-modal="false"
  116. v-loading="loading"
  117. title="随手拍上报" :visible.sync="addDialogType" v-if="addDialogType"
  118. width="787px" append-to-body>
  119. <div>
  120. <el-form ref="addDialogForm" :model="addDialogForm" :rules="rules" label-width="140px">
  121. <el-form-item label="学院:" prop="deptId">
  122. <el-select v-model="addDialogForm.deptId" @change="dialogDeptChange" placeholder="请选择学院" style="width:548px;">
  123. <el-option
  124. v-for="item in deptSelectList"
  125. :key="item.deptId"
  126. :label="item.deptName"
  127. :value="item.deptId">
  128. </el-option>
  129. </el-select>
  130. </el-form-item>
  131. <el-form-item label="实验室:" prop="subId">
  132. <el-select
  133. style="width:548px;"
  134. v-model="addDialogForm.subId"
  135. filterable
  136. remote
  137. reserve-keyword
  138. placeholder="搜索选择实验室"
  139. @change="dialogSubChange"
  140. :remote-method="getSelectList"
  141. :loading="dialogLoading">
  142. <el-option
  143. v-for="item in dialogSubList"
  144. :key="item.id"
  145. :label="item.name"
  146. :value="item.id">
  147. </el-option>
  148. </el-select>
  149. </el-form-item>
  150. <el-form-item label="隐患描述:" prop="hazardDescribe">
  151. <el-input
  152. type="textarea"
  153. :autosize="{ minRows: 4, maxRows: 4}"
  154. placeholder="请输入隐患描述"
  155. v-model="addDialogForm.hazardDescribe"
  156. maxlength="100"
  157. resize="none"
  158. show-word-limit
  159. style="width:548px;">
  160. </el-input>
  161. </el-form-item>
  162. <el-form-item label="隐患照片:" prop="imgDtoList">
  163. <div class="snapshotManagement-for-img-box" v-for="(img,imgIndex) in addDialogForm.imgDtoList" :key="imgIndex">
  164. <img class="for-img" :src="img.fileUrl">
  165. <p class="for-del-button el-icon-circle-close" @click="delImg(imgIndex)"></p>
  166. </div>
  167. <el-upload
  168. v-if="addDialogForm.imgDtoList.length<5"
  169. style="display: inline-block;overflow: hidden"
  170. class="avatar-uploader"
  171. :action="uploadImgUrl"
  172. :show-file-list="false"
  173. :on-success="(res)=>handleAvatarSuccess(res)"
  174. :headers="headers"
  175. :before-upload="(res)=>beforeAvatarUpload(res)">
  176. <p class="el-icon-plus up-img-p" style="display: inline-block"></p>
  177. </el-upload>
  178. <p class="dialog-material-text">支持jpg/png/bmp/gif格式,最多上传5张</p>
  179. </el-form-item>
  180. </el-form>
  181. </div>
  182. <div slot="footer" class="dialog-footer dialog-footer-box" style="display: flex">
  183. <p class="dialog-footer-button-null"></p>
  184. <p class="dialog-footer-button-info" @click="outDialog">取消</p>
  185. <p class="dialog-footer-button-primary" @click="upDialogButton">确定</p>
  186. <p class="dialog-footer-button-null"></p>
  187. </div>
  188. </el-dialog>
  189. </div>
  190. </template>
  191. <script>
  192. import { securityCheckClapList,checkClapAdd } from '@/api/safetyCheck/index'
  193. import { getSubjectDictByViolation } from "@/api/laboratory/violation";
  194. import { listDepartments } from "@/api/system/dept";
  195. import listPage from './listPage.vue'
  196. import infoPage from './infoPage.vue'
  197. import { getToken } from "@/utils/auth";
  198. export default {
  199. name: 'index',
  200. components: {
  201. listPage,
  202. infoPage
  203. },
  204. data(){
  205. return{
  206. loading:false,
  207. uploadImgUrl: this.uploadUrl(), // 上传的图片服务器地址
  208. headers: {
  209. Authorization: "Bearer " + getToken(),
  210. },
  211. pageType:1,
  212. deptSelectList:[],
  213. queryParams:{
  214. pageNum:1,
  215. pageSize:20,
  216. deptId:'',
  217. searchValue:'',
  218. rectifyStatus:'',
  219. upTimeOrder:"",
  220. zgTimeOrder:"",
  221. myRelated:1,
  222. },
  223. dateRange:[],
  224. tableList:[],
  225. total:0,
  226. correlationNum:'',
  227. //新增窗口
  228. addDialogType:false,
  229. addDialogForm:{
  230. deptId:"",
  231. deptName:"",
  232. subId:"",
  233. subName:"",
  234. hazardDescribe:"",
  235. imgDtoList:[],
  236. },
  237. rules:{
  238. deptId: [
  239. { required: true, message: "请选择学院", trigger: "change" },
  240. ],
  241. subId: [
  242. { required: true, message: "请选择实验室", trigger: "change" },
  243. ],
  244. imgDtoList: [
  245. { required: true, message: "请上传隐患照片", trigger: "change" },
  246. ],
  247. },
  248. dialogDeptOptions:[],
  249. dialogLoading:false,
  250. dialogSubList:[],
  251. dialogSubListData:[],
  252. suffixName:"",
  253. //详情
  254. infoPropsData:{}
  255. }
  256. },
  257. created(){
  258. },
  259. mounted(){
  260. this.listDepartments();
  261. this.getList();
  262. },
  263. methods:{
  264. //获取相关数量
  265. getCorrelationNum(){
  266. securityCheckClapList({
  267. pageNum:1,
  268. pageSize:20,
  269. upTimeOrder:"",
  270. zgTimeOrder:"",
  271. myRelated:1,
  272. deptId:this.queryParams.deptId,
  273. searchValue:this.queryParams.searchValue,
  274. rectifyStatus:this.queryParams.rectifyStatus,
  275. beginTime:this.dateRange[0]?this.dateRange[0]:'',
  276. endTime:this.dateRange[1]?this.dateRange[1]:'',
  277. }).then(response => {
  278. this.$set(this,'correlationNum',response.data.total>999?' 999+':(response.data.total<1?'':' '+response.data.total));
  279. });
  280. },
  281. //与我相关按钮
  282. topRightClickType(){
  283. this.$set(this.queryParams,'myRelated',this.queryParams.myRelated==1?0:1);
  284. this.handleQuery();
  285. },
  286. goPage(type,data){
  287. if(this.pageType != type){
  288. if (type==1){
  289. this.$set(this,'pageType',type);
  290. } else if(type==2){
  291. this.$set(this,'pageType',type);
  292. } else if(type==3){
  293. this.$set(this,'infoPropsData',data);
  294. this.$set(this,'pageType',type);
  295. } else if(type==4){
  296. this.$set(this,'pageType',1);
  297. this.getList();
  298. }
  299. }
  300. },
  301. //范围选择
  302. topLeftClickType(type){
  303. if(this.queryParams.rectifyStatus !== type){
  304. this.$set(this.queryParams,'rectifyStatus',type);
  305. this.handleQuery();
  306. }
  307. },
  308. //时间排序方法
  309. sortChange(val){
  310. if(val.prop == 'rectifyTime'){
  311. this.$set(this.queryParams,'zgTimeOrder',val.order=='ascending'?'1':(val.order=='descending'?'2':''));
  312. this.$set(this.queryParams,'upTimeOrder','');
  313. this.handleQuery();
  314. }else if(val.prop == 'createTime'){
  315. this.$set(this.queryParams,'upTimeOrder',val.order=='ascending'?'1':(val.order=='descending'?'2':''));
  316. this.$set(this.queryParams,'zgTimeOrder','');
  317. this.handleQuery();
  318. }
  319. },
  320. //获取数据列表
  321. getList(){
  322. let obj = JSON.parse(JSON.stringify(this.queryParams))
  323. if(this.dateRange[0]){
  324. obj.beginTime = this.dateRange[0]
  325. }else{
  326. obj.beginTime = ""
  327. }
  328. if(this.dateRange[1]){
  329. obj.endTime = this.dateRange[1]
  330. }else{
  331. obj.endTime = ""
  332. }
  333. this.getCorrelationNum();
  334. securityCheckClapList(obj).then(response => {
  335. this.total = response.data.total;
  336. this.tableList = response.data.records;
  337. });
  338. },
  339. /** 搜索按钮操作 */
  340. handleQuery() {
  341. this.$set(this.queryParams,'pageNum',1);
  342. this.getList();
  343. },
  344. /** 重置按钮操作 */
  345. resetQuery() {
  346. this.$set(this,'dateRange',[]);
  347. this.$set(this,'queryParams',{
  348. pageNum:1,
  349. pageSize:20,
  350. deptId:'',
  351. searchValue:'',
  352. rectifyStatus:'',
  353. upTimeOrder:"",
  354. zgTimeOrder:"",
  355. myRelated:1,
  356. });
  357. this.handleQuery();
  358. },
  359. /*==========上传相关==========*/
  360. handleAvatarSuccess(res) {
  361. this.$set(this,'loading',false);
  362. if(this.addDialogForm.imgDtoList.length>4){
  363. this.msgError('最多只可上传5张')
  364. return
  365. }
  366. let suffixName= this.upDataName.split('.')[this.upDataName.split('.').length - 2]
  367. //判断文件名中是否有逗号和分号
  368. if(suffixName.indexOf(',')==-1 && suffixName.indexOf(';')==-1){
  369. }else{
  370. this.msgError('文件名里包含逗号或分号,请修改后重新上传!')
  371. return
  372. }
  373. let obj ={
  374. fileName:this.upDataName,
  375. fileUrl:res.data.url,
  376. };
  377. this.addDialogForm.imgDtoList.push(obj);
  378. this.$forceUpdate()
  379. },
  380. beforeAvatarUpload(file) {
  381. if(this.addDialogForm.imgDtoList.length>4){
  382. this.msgError('最多只可上传5张')
  383. return false
  384. }
  385. let type = false;
  386. if (file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif' || file.type == 'image/bmp') {
  387. if(file.size> 2100000){
  388. this.msgError('上传图片大小不能超过2M')
  389. return false
  390. }
  391. this.$set(this,'loading',true);
  392. this.upDataName = file.name;
  393. type = true;
  394. }else{
  395. this.msgError('仅支持jpg/png/bmp/gif格式')
  396. type = false;
  397. }
  398. return type;
  399. },
  400. //删除照片
  401. delImg(imgIndex){
  402. this.addDialogForm.imgDtoList.splice(imgIndex,1);
  403. },
  404. /**************** 新增窗口 ******************/
  405. //提交
  406. upDialogButton(){
  407. this.$refs["addDialogForm"].validate(valid => {
  408. if (valid) {
  409. checkClapAdd(this.addDialogForm).then(response => {
  410. this.msgSuccess(response.msg);
  411. this.outDialog();
  412. this.getList();
  413. });
  414. }
  415. })
  416. },
  417. addButton(){
  418. this.$set(this,'addDialogForm',{
  419. deptId:"",
  420. deptName:"",
  421. subId:"",
  422. subName:"",
  423. hazardDescribe:"",
  424. imgDtoList:[],
  425. });
  426. this.$set(this,'addDialogType',true);
  427. },
  428. outDialog(){
  429. this.$set(this,'addDialogType',false);
  430. },
  431. //选中院系
  432. dialogDeptChange(val){
  433. let self = this;
  434. let obj = {
  435. deptId:val,
  436. }
  437. getSubjectDictByViolation(obj).then(response => {
  438. this.$set(this,'dialogSubListData',response.data);
  439. this.$set(this,'dialogSubList',response.data);
  440. for(let i=0;i<self.deptSelectList.length;i++){
  441. if(val == self.deptSelectList[i].deptId){
  442. self.$set(self.addDialogForm,'deptName',self.deptSelectList[i].deptName);
  443. }
  444. }
  445. this.$set(this.addDialogForm,'subId','');
  446. this.$set(this.addDialogForm,'subName','');
  447. });
  448. },
  449. //实验室选中
  450. dialogSubChange(val){
  451. let self = this;
  452. for(let i=0;i<self.dialogSubList.length;i++){
  453. if(val == self.dialogSubList[i].id){
  454. self.$set(self.addDialogForm,'subName',self.dialogSubList[i].name);
  455. }
  456. }
  457. },
  458. /** 实验室-本地懒加载 */
  459. getSelectList(val) {
  460. let self = this;
  461. let list = [];
  462. for(let i=0;i<self.dialogSubListData.length;i++){
  463. if(self.dialogSubListData[i].name.indexOf(val) != -1){
  464. list.push(self.dialogSubListData[i]);
  465. }
  466. }
  467. this.dialogSubList = JSON.parse(JSON.stringify(list))
  468. },
  469. //获取学院列表
  470. listDepartments(){
  471. listDepartments().then(response => {
  472. this.deptSelectList = response.data;
  473. });
  474. },
  475. }
  476. }
  477. </script>
  478. <style scoped lang="scss">
  479. .snapshotManagement{
  480. flex: 1;
  481. display: flex !important;
  482. flex-direction: column;
  483. overflow: hidden;
  484. .snapshotManagement-page{
  485. flex: 1;
  486. display: flex !important;
  487. flex-direction: column;
  488. overflow: hidden;
  489. .title-box{
  490. padding-top:20px;
  491. border-bottom:1px solid #dedede;
  492. .form-button-max-big-box{
  493. display: inline-block;
  494. margin-left:10px;
  495. .form-button-big-box{
  496. display: flex;
  497. p:nth-child(1){
  498. border-top-left-radius: 4px;
  499. border-bottom-left-radius: 4px;
  500. border-top:1px solid #E0E0E0;
  501. border-bottom:1px solid #E0E0E0;
  502. }
  503. p:nth-child(2){
  504. border-top:1px solid #E0E0E0;
  505. border-bottom:1px solid #E0E0E0;
  506. }
  507. p:nth-child(3){
  508. border-top:1px solid #E0E0E0;
  509. border-bottom:1px solid #E0E0E0;
  510. }
  511. p:nth-child(4){
  512. border-top-right-radius: 4px;
  513. border-bottom-right-radius: 4px;
  514. border-top:1px solid #E0E0E0;
  515. border-bottom:1px solid #E0E0E0;
  516. border-right:1px solid #E0E0E0;
  517. }
  518. p{
  519. height:40px;
  520. width:80px;
  521. line-height: 40px;
  522. text-align: center;
  523. color:#666666;
  524. font-size:14px;
  525. font-weight:500;
  526. cursor: pointer;
  527. border-left:1px solid #E0E0E0;
  528. }
  529. .checkDiv{
  530. color:#fff!important;
  531. border:1px solid #0183FA!important;
  532. background-color: #0183FA;
  533. }
  534. }
  535. }
  536. .form-button-max-big-box-me{
  537. margin-left:10px;
  538. display: inline-block;
  539. .form-button-big-box-me{
  540. display: flex;
  541. div{
  542. position: relative;
  543. height:40px;
  544. width:130px;
  545. line-height: 40px;
  546. text-align: center;
  547. color:#999;
  548. font-size:14px;
  549. border:1px solid #999;
  550. border-radius:4px;
  551. font-weight:500;
  552. cursor: pointer;
  553. .icon-p-me{
  554. width:15px;
  555. height:15px;
  556. line-height:15px;
  557. text-align: center;
  558. position: absolute;
  559. right:0;
  560. bottom:0;
  561. color:#fff;
  562. background: #0183fa;
  563. border-top-left-radius:4px;
  564. }
  565. }
  566. .checkDiv-me{
  567. color:#0183FA!important;
  568. border:1px solid #0183FA!important;
  569. }
  570. }
  571. }
  572. }
  573. .content-box{
  574. flex: 1;
  575. display: flex;
  576. flex-direction: column;
  577. padding:20px;
  578. overflow: hidden;
  579. }
  580. }
  581. }
  582. ::v-deep .snapshotManagement-for-img-box{
  583. width:80px;
  584. height:80px;
  585. border-radius:4px;
  586. display: inline-block;
  587. overflow: hidden;
  588. margin-right:20px;
  589. position: relative;
  590. .for-img{
  591. width:80px;
  592. height:80px;
  593. display: inline-block;
  594. overflow: hidden;
  595. }
  596. .for-del-button{
  597. background: rgba(0,0,0,0.7);
  598. width:20px;
  599. height:20px;
  600. line-height: 20px;
  601. text-align: center;
  602. color:#fff;
  603. border-bottom-left-radius:4px;
  604. cursor: pointer;
  605. position: absolute;
  606. top:0;
  607. right:0;
  608. }
  609. }
  610. ::v-deep .up-img-p{
  611. height:80px;
  612. width:80px;
  613. line-height:80px;
  614. text-align: center;
  615. font-size:16px;
  616. border-radius:4px;
  617. border:1px dashed #E0E0E0;
  618. }
  619. </style>