index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. <template>
  2. <div>
  3. <div class="topBox">
  4. <NavBar />
  5. <van-row>
  6. <van-col span="24">
  7. <org-tree v-model="cascaderValue" :name="'sss'" @changeItem="getDataList"></org-tree>
  8. </van-col>
  9. </van-row>
  10. <van-row>
  11. <van-col span="12"
  12. >
  13. <!-- <van-field
  14. v-model="fieldValue"
  15. label-width="3em"
  16. clearable
  17. :disabled="showStatus"
  18. label="状态"
  19. placeholder=""
  20. @click="showStatus = true"
  21. ><van-icon name="arrow-down" slot="button"
  22. /></van-field> -->
  23. <van-cell title="状态" @click="showStatus = true" is-link arrow-direction="down" :value="fieldValue" />
  24. <van-popup v-model="showStatus" round position="bottom">
  25. <van-picker
  26. title="状态"
  27. show-toolbar
  28. :columns="columns"
  29. @confirm="onConfirm"
  30. @cancel="onCancel"
  31. confirm-button-text="确定"
  32. @change="onChange"
  33. :close-on-click-overlay="false"
  34. />
  35. </van-popup>
  36. </van-col>
  37. <van-col span="12">
  38. <!-- <van-field
  39. v-model="currentDate"
  40. clearable
  41. label-width="3em"
  42. label="月份"
  43. placeholder=""
  44. :disabled="showDate"
  45. @click="showDate = true"
  46. >
  47. <van-icon name="arrow-down" slot="button"
  48. /></van-field> -->
  49. <van-cell title="月份" @click="showDate = true" is-link arrow-direction="down" :value="currentDate" />
  50. <van-popup v-model="showDate" round position="bottom">
  51. <van-datetime-picker
  52. v-model="presentDate"
  53. @cancel="onCancel"
  54. @confirm="onDateConfirm"
  55. confirm-button-text="确定"
  56. type="year-month"
  57. :formatter="formatter"
  58. title="月份"
  59. />
  60. </van-popup>
  61. </van-col>
  62. </van-row>
  63. <!-- <van-row>
  64. <van-col span="24"
  65. ><van-field
  66. v-model="typeName"
  67. label-width="3em"
  68. clearable
  69. label="类型"
  70. :disabled="typeStatus"
  71. placeholder=""
  72. @click="typeStatus = true"
  73. >
  74. <van-icon name="arrow-down" slot="button" />
  75. </van-field>
  76. <van-popup v-model="typeStatus" round position="bottom">
  77. <van-picker
  78. title="类型"
  79. show-toolbar
  80. :columns="typeColumns"
  81. @confirm="onConfirmHandler"
  82. @cancel="onCancel"
  83. @change="onChange"
  84. confirm-button-text="确定"
  85. :close-on-click-overlay="false"
  86. />
  87. </van-popup>
  88. </van-col>
  89. </van-row> -->
  90. </div>
  91. <!-- //卡片内容区域 -->
  92. <div class="navBarclas">
  93. <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
  94. <van-panel :title="item.title" v-for="item in taskList" :key="item.id" class="card" status="状态">
  95. <template #header>
  96. <div class="titleClass">
  97. <div class="title">{{ item.title }}</div>
  98. <div>
  99. <van-button type="info" v-if="isSign(item)" size="small" @click="trainSign(item.id)"
  100. >培训登记</van-button
  101. >
  102. <van-button type="info" v-if="isSignature(item)" size="small" @click="signature(item.id)"
  103. >签名</van-button
  104. >
  105. </div>
  106. </div>
  107. </template>
  108. <div>
  109. <div class="mainItem" @click="goInfo(item.id)">
  110. <div>单位名称</div>
  111. <div>{{ item.orgName }}</div>
  112. </div>
  113. <div class="mainItem" @click="goInfo(item.id)">
  114. <div>培训状态</div>
  115. <div v-if="item.status == 0" class="wj-title-blue">{{ item.statusText }}</div>
  116. <div v-else-if="item.status == 1" class="wj-title-orange">{{ item.statusText }}</div>
  117. <div v-else-if="item.status == 2" class="wj-title-green">{{ item.statusText }}</div>
  118. <div v-else-if="item.status == 3" class="wj-title-red">{{ item.statusText }}</div>
  119. <div v-else class="wj-title-blue">{{ item.statusText }}</div>
  120. </div>
  121. <div class="mainItem">
  122. <div>签名情况</div>
  123. <div class="condition" @click="signatureCondition(item.id)">{{ item.signNums }}</div>
  124. </div>
  125. </div>
  126. </van-panel>
  127. </van-list>
  128. </div>
  129. <!-- 卡片弹框 -->
  130. <van-dialog
  131. v-model="conditionShow"
  132. title="签名情况"
  133. show-confirm-button
  134. confirm-button-text="关闭"
  135. @closed="beforeClose"
  136. >
  137. <div class="conditionCls">
  138. <div class="title">已签名人员({{ participationList.num }}人):</div>
  139. <div class="people">{{ participationList.list }}</div>
  140. <div class="title">未签名人员({{ absenceList.num }}人):</div>
  141. <div class="people">{{ absenceList.list }}</div>
  142. </div>
  143. </van-dialog>
  144. </div>
  145. </template>
  146. <script>
  147. import NavBar from '@/components/NavBar'
  148. import { Col, Row, Cascader, Dialog, DatetimePicker, Icon, Picker } from 'vant'
  149. import { gettrainingList, getsignUserList } from '@/api/training.js'
  150. import { deptTreeList } from '@/api/toConsult.js'
  151. import OrgTree from '@/components/orgTree'
  152. import { newDateMonth } from '@/utils/date.js'
  153. export default {
  154. data() {
  155. return {
  156. orgName: '',
  157. orgShow: false,
  158. presentDate: '', //默认时间
  159. pageNum: 1,
  160. loading: false, //加载状态
  161. finished: false, //是否全部加载完毕
  162. participationList: {
  163. list: [], // 参与人员
  164. num: 0 //人数
  165. },
  166. absenceList: {
  167. list: [],
  168. num: 0
  169. }, // 缺席人员
  170. orgName: JSON.parse(sessionStorage.getItem('SET_USER_ORGNAME')) || '', //机构名称
  171. cascaderValue: '', //机构ID
  172. show: false, //机构弹框显示隐藏
  173. fieldNames: {
  174. text: 'name',
  175. value: 'id',
  176. children: 'children'
  177. },
  178. taskList: [], //列表数据
  179. typeValue: ' ', //类型值
  180. typeName: '全部', //类型名称
  181. value1: JSON.parse(sessionStorage.getItem('SET_USER_ID')) || '', //输入框model
  182. typeStatus: false, //类型显示隐藏
  183. showStatus: false, //状态显示隐藏
  184. showDate: false, //月份显示隐藏
  185. fieldValue: '全部', //状态名称
  186. statusValue: ' ', //状态值
  187. columns: ['全部', '待登记', '待提交', '待签名', '已逾期', '已完成'], //状态数组
  188. typeColumns: ['全部', '每月安全培训教育', '专项安全培训教育'], //类型数组
  189. currentDate: newDateMonth(), //月份值
  190. conditionShow: false //机构弹框显示隐藏
  191. }
  192. },
  193. components: {
  194. NavBar,
  195. OrgTree,
  196. Dialog,
  197. Icon,
  198. DatetimePicker,
  199. Picker,
  200. Col,
  201. Row,
  202. Cascader
  203. },
  204. created() {
  205. this.presentDate = new Date(+newDateMonth().split('-')[0], +newDateMonth().split('-')[1] - 1)
  206. },
  207. mounted() {
  208. this.init()
  209. this.cascaderValue = JSON.parse(window.sessionStorage.getItem('SET_USER_ORGID')) + ''
  210. },
  211. methods: {
  212. //日期选择组件formatter
  213. formatter(type, val) {
  214. if (type === 'month') {
  215. return `${val}月`;
  216. } else if (type === 'year') {
  217. return `${val}年`;
  218. }
  219. return val;
  220. },
  221. //机构搜索
  222. getDataList(val) {
  223. this.cascaderValue = val.id
  224. this.orgName = val.name
  225. this.selectListAppHandler()
  226. },
  227. //判断是否展示签名按钮
  228. isSignature(list) {
  229. let falg = false
  230. let timefalg = false
  231. //value1 当前登陆用户ID
  232. //当前时间再时间范围内且签名是待签名状态且签名列表存在当前登录人未签名的情况才可以进行签名
  233. if (list.startDate && list.endDate && list.status == 1) {
  234. let date = new Date().getTime()
  235. let startDate = Date.parse(new Date(list.startDate))
  236. let endDate = Date.parse(new Date(list.endDate))
  237. if (date >= startDate && date <= endDate) {
  238. console.log(list.id, 'ssss')
  239. timefalg = true
  240. }
  241. if (!list.planId) {
  242. timefalg = true
  243. }
  244. }
  245. if (list.userList && list.userList.length > 0) {
  246. list.userList.forEach(item => {
  247. if (this.value1 == item.userId && item.sign === 0 && item.type == 1) {
  248. falg = true
  249. }
  250. })
  251. }
  252. if (falg && timefalg) {
  253. return true
  254. }
  255. },
  256. //判断是否展示登记按钮
  257. isSign(list) {
  258. let falg = false
  259. let timefalg = false
  260. //value1 当前登陆用户ID
  261. let date = new Date().getTime()
  262. let startDate = Date.parse(new Date(list.startDate))
  263. let endDate = Date.parse(new Date(list.endDate))
  264. //任务处于待培训状态,且任务在规定完成时间范围内,登录人所在机构和与任务培训机构一致才显示
  265. if (list.startDate && list.endDate && (list.status == 0 || list.status == 4)) {
  266. if (date >= startDate && date <= endDate) {
  267. timefalg = true
  268. }
  269. }
  270. //cascaderValue 当前机构ID
  271. // 当前用户角色ID
  272. let orgId = JSON.parse(window.sessionStorage.getItem('SET_USER_ORGID')) + ''
  273. if (orgId == list.orgId) {
  274. falg = true
  275. }
  276. if (date > endDate) {
  277. //当前时间大于结束时间表示已超期
  278. timefalg = false
  279. falg = false
  280. }
  281. if (falg && timefalg) {
  282. return true
  283. }
  284. },
  285. //初始化
  286. init() {
  287. // this.selectListAppHandler()
  288. },
  289. selectListAppHandler(type = 0, callback = () => {}) {
  290. let obj = {
  291. isAppSelect: 1,
  292. pageNum: this.pageNum,
  293. pageSize: 10
  294. }
  295. if (!type) {
  296. obj.pageNum = 1
  297. this.pageNum = 1
  298. this.taskList = []
  299. }
  300. if (this.statusValue) {
  301. obj.status = this.statusValue
  302. }
  303. obj.orgId = this.cascaderValue || JSON.parse(window.sessionStorage.getItem('SET_USER_ORGID')) + '' || ''
  304. if (this.currentDate) {
  305. obj.date = this.currentDate + '-01'
  306. }
  307. if (this.typeValue) {
  308. obj.type = this.typeValue
  309. }
  310. //获取任务列表
  311. gettrainingList(obj).then(res => {
  312. let { code, rows, msg,total } = res
  313. if (code == 200) {
  314. if (type) {
  315. this.taskList.push(...rows)
  316. if (this.taskList.length >= total) {
  317. //已加载完全部数据
  318. this.finished = true
  319. } else {
  320. callback()
  321. }
  322. } else {
  323. this.taskList.push(...rows)
  324. this.finished = false
  325. this.loading = false
  326. if (this.taskList.length >= total) {
  327. //已加载完全部数据
  328. this.finished = true
  329. }
  330. // this.taskList = rows || []
  331. }
  332. } else {
  333. this.finished = true
  334. this.taskList = []
  335. }
  336. })
  337. },
  338. // 开始调阅事件
  339. startMonitorHandler(taskId) {
  340. this.taskId = taskId
  341. this.showDialog = true
  342. },
  343. //已调阅事件
  344. endMonitorHandler(status, taskId) {
  345. // 0待调阅,1调阅中,2已调阅,3已超期
  346. //跳转详情
  347. if (status <= 1) return
  348. this.$router.push('/consultInfo/' + taskId)
  349. },
  350. //搜索选择状态时触发
  351. onConfirm(value, index) {
  352. this.fieldValue = value
  353. switch (value) {
  354. case '待登记':
  355. this.statusValue = '0'
  356. break
  357. case '待签名':
  358. this.statusValue = '1'
  359. break
  360. case '已完成':
  361. this.statusValue = '2'
  362. break
  363. case '已逾期':
  364. this.statusValue = '3'
  365. break
  366. case '待提交':
  367. this.statusValue = '4'
  368. break
  369. case '全部':
  370. this.statusValue = ' '
  371. break
  372. }
  373. this.selectListAppHandler()
  374. this.showStatus = false
  375. },
  376. //类型确认框
  377. onConfirmHandler(value, index) {
  378. this.typeName = value
  379. switch (value) {
  380. case '每月安全培训教育':
  381. this.typeValue = '0'
  382. break
  383. case '专项安全培训教育':
  384. this.typeValue = '1'
  385. break
  386. case '全部':
  387. this.typeValue = ' '
  388. break
  389. }
  390. this.typeStatus = false
  391. this.selectListAppHandler()
  392. },
  393. //月份选中触发
  394. onDateConfirm() {
  395. this.currentDate = this.newDate(this.presentDate)
  396. this.showDate = false
  397. this.selectListAppHandler()
  398. },
  399. //日期转换
  400. newDate(time) {
  401. var date = new Date(time)
  402. var y = date.getFullYear()
  403. var m = date.getMonth() + 1
  404. m = m < 10 ? '0' + m : m
  405. var d = date.getDate()
  406. d = d < 10 ? '0' + d : d
  407. return y + '-' + m
  408. },
  409. //onLoad下拉刷新
  410. onLoad() {
  411. this.loading = true
  412. this.selectListAppHandler(1, () => {
  413. this.pageNum++
  414. this.loading = false
  415. })
  416. },
  417. //查看签名情况
  418. signatureCondition(id) {
  419. this.conditionShow = true
  420. getsignUserList(id).then(res => {
  421. console.log(res, 'ssss')
  422. let { meg, code, data } = res
  423. data.map(item => {
  424. if (item.sign != 1) {
  425. this.absenceList.list.push(item.userName)
  426. this.absenceList.num++
  427. } else {
  428. this.participationList.list.push(item.userName)
  429. this.participationList.num++
  430. }
  431. })
  432. this.absenceList.list = this.absenceList.list.join(',')
  433. this.participationList.list = this.participationList.list.join(',')
  434. })
  435. },
  436. //培训登记跳转
  437. trainSign(id) {
  438. this.$router.push('/Addtraining/' + id)
  439. },
  440. //签名
  441. signature(id) {
  442. this.$router.push('/personnelSignature/' + id + '_edit')
  443. },
  444. //关闭弹框
  445. beforeClose() {
  446. console.log('sssssssss')
  447. ;(this.participationList = {
  448. list: [], // 参与人员
  449. num: 0 //人数
  450. }),
  451. (this.absenceList = {
  452. list: [],
  453. num: 0
  454. })
  455. },
  456. //跳转详情
  457. goInfo(id) {
  458. this.$router.push('/personnelSigninfo/' + id + '_info')
  459. },
  460. onChange(picker, value, index) {},
  461. onCancel() {
  462. this.show = false
  463. this.typeStatus = false
  464. this.showDate = false
  465. this.showStatus = false
  466. }
  467. }
  468. }
  469. </script>
  470. <style lang="scss" scoped>
  471. .popup {
  472. height: 40vh;
  473. }
  474. .navBarclas {
  475. height: calc(100vh - 330px);
  476. overflow: scroll;
  477. }
  478. .btnf_box {
  479. background-color: #fff;
  480. }
  481. .card {
  482. margin: 20px;
  483. margin-bottom: 0px;
  484. box-shadow: 0 8px 12px #ebedf0;
  485. }
  486. .btn {
  487. float: right;
  488. margin-top: 24px;
  489. margin-right: 20px;
  490. box-sizing: border-box;
  491. }
  492. .titleClass {
  493. display: flex;
  494. align-items: center;
  495. height: 100%;
  496. padding: 20px;
  497. border-bottom: 1px solid #ccc;
  498. .title {
  499. font-size: 30px;
  500. flex: 1;
  501. line-height: 50px;
  502. }
  503. }
  504. .mainItem {
  505. display: flex;
  506. font-size: 28px;
  507. padding: 20px;
  508. justify-content: space-between;
  509. .condition {
  510. color: #1989fa;
  511. text-decoration: underline;
  512. }
  513. }
  514. .conditionCls {
  515. .title {
  516. color: #1989fa;
  517. margin-left: 30px;
  518. // margin-top: 30px;
  519. }
  520. .people {
  521. margin-left: 80px;
  522. margin-bottom: 30px;
  523. margin-top: 30px;
  524. }
  525. }
  526. .topBox {
  527. // overflow: hidden;
  528. }
  529. :deep.van-field--disabled {
  530. color: #323233;
  531. }
  532. :deep.van-field--disabled .van-field__label {
  533. color: #323233;
  534. }
  535. :deep .van-field__control[disabled] {
  536. color: #323233;
  537. -webkit-text-fill-color: #323233;
  538. }
  539. .van-cell__value{
  540. color: black;
  541. text-align: left;
  542. }
  543. </style>