index.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. <template>
  2. <div :class="{'ibps-fixed-toolbar':checkMode}">
  3. <van-sticky>
  4. <van-nav-bar
  5. :title="generateTitle($route.name,$route.params.title||$route.meta.title)"
  6. :left-text="$t('common.button.back')"
  7. :right-text="$utils.isNotEmpty(listData)?rightText:''"
  8. left-arrow
  9. @click-left="$router.push({ name: 'dashboard' })"
  10. @click-right="toCheckMode()"
  11. />
  12. <van-search v-model="subject" show-action placeholder="请输入搜索关键词" @search="onSearch">
  13. <!-- <template #left>
  14. <van-icon name="bars" :class="{'ibps-active':$utils.isNotEmpty(typeId)}" class="ibps-pr-5"
  15. @click="clickType" />
  16. </template> -->
  17. <template #action>
  18. <!-- <van-icon name="filter-o" :class="{'ibps-active':stateActive}" @click="clickMoreSearch" /> -->
  19. </template>
  20. </van-search>
  21. </van-sticky>
  22. <!-- 内容展示区 -->
  23. <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
  24. <van-list v-model="loading" :finished="finished" @load="loadData">
  25. <van-checkbox-group v-model="checkedIds">
  26. <van-cell v-for="(item,index) in listData" :key="item.id+index" :title="item.shi_wu_ming_cheng" @click="onClick(item,index)">
  27. <template slot="icon">
  28. <van-checkbox v-if="checkMode" ref="checkboxes" :name="item.id_" class="ibps-mr-10" />
  29. <ibps-avatar
  30. v-else
  31. :icon="_randomIcon(4)"
  32. :text="item.name"
  33. :bg-color="_randomColor(1)"
  34. radius="4"
  35. icon-prefix="ibps-icon"
  36. class="ibps-mr-10"
  37. @click="overlayShow(item)"
  38. />
  39. <!-- <van-icon name="notes-o" size="1.5rem" color="#1E90FF" /> -->
  40. </template>
  41. <template #label>
  42. <van-row @click="overlayShow(item)">
  43. <van-col span="24">{{ item.shi_wu_shuo_ming_==''?'/':item.shi_wu_shuo_ming_==null?'/':item.shi_wu_shuo_ming_ }}</van-col>
  44. </van-row>
  45. </template>
  46. <!-- 插入内容 -->
  47. <span>{{ item.create_time_|formatRelativeTime }}</span>
  48. <div>
  49. <!-- 系统消息 -->
  50. <van-icon name="bell" size="1.3rem" color="#1E90FF" @click="sendSystemInfo(item)" />
  51. </div>
  52. <div>
  53. <!-- 短信催办 -->
  54. <van-icon name="comment-o" size="1.3rem" color="#1E90FF" @click="sendSmsInfo(item)" />
  55. </div>
  56. </van-cell>
  57. </van-checkbox-group>
  58. <ibps-list-result-page :result-type="resultType" :error-type="errorType" :result-message="resultMessage" />
  59. </van-list>
  60. </van-pull-refresh>
  61. <ibps-toolbar v-show="checkMode" :actions="mainActions" />
  62. <!-- 点击搜索的右边显示 -->
  63. <ibps-more-search
  64. :show="moreSearchPopup"
  65. :search-forms="searchForms"
  66. @callback="onMoreSearch"
  67. @close="show => moreSearchPopup = show"
  68. @reset-form="resetForm"
  69. />
  70. <van-divider v-if="footText">到底了~</van-divider>
  71. <van-empty v-if="noData" description="暂无数据" />
  72. <van-popup v-model="reminderSon" position="bottom" :style="{height:'100%',width:'100%'}">
  73. <Reminder :son-data="sonData" @son="son" />
  74. </van-popup>
  75. </div>
  76. </template>
  77. <script>
  78. import { mapState } from 'vuex'
  79. import ActionUtils from '@/utils/action'
  80. import i18n from '@/utils/i18n'
  81. import random from '@/mixins/random'
  82. import bpmnStatus from '@/mixins/bpmnStatus'
  83. import IbpsMoreSearch from '@/components/ibps-more-search'
  84. import IbpsTypeTree from '@/business/platform/cat/type/tree'
  85. import IbpsAvatar from '@/components/ibps-avatar'
  86. import IbpsToolbar from '@/components/ibps-toolbar'
  87. import IbpsListResultPage from '@/components/ibps-list-result-page'
  88. import IbpsBpmnFormrenderDialog from '@/business/platform/bpmn/form/dialog'
  89. import Reminder from './reminder.vue'
  90. import { sendSmsList } from './sendSms'
  91. import { Notify } from 'vant'
  92. export default {
  93. components: {
  94. IbpsMoreSearch,
  95. IbpsTypeTree,
  96. IbpsAvatar,
  97. IbpsToolbar,
  98. IbpsListResultPage,
  99. IbpsBpmnFormrenderDialog,
  100. Reminder
  101. },
  102. mixins: [random, bpmnStatus],
  103. data() {
  104. const { userId, userList = [], deptList = [], menus, userInfo } = this.$store.getters
  105. return {
  106. reminderSon: false,
  107. sonData: '',
  108. userId: userId,
  109. footText: false,
  110. showPop: false,
  111. noData: false,
  112. showConfirmationBoxList: true,
  113. countTotal: {},
  114. examPopup: '',
  115. ReachBottomShow: false,
  116. moreSearchPopup: false,
  117. searchForms: {
  118. forms: [
  119. // { prop: 'Q^examName_^SL', label: '考试名称', fieldType: 'text' },
  120. // { prop: 'Q^bankName^SL', label: '题库名称', fieldType: 'text' },
  121. { prop: 'examName', label: '考试名称', fieldType: 'text' },
  122. { prop: 'bankName', label: '题库名称', fieldType: 'text' },
  123. {
  124. prop: 'examType', label: '考试类型', fieldType: 'checker', cols: 2, valueKey: 'value', options: [
  125. { value: 'trainingExam', label: '培训考试' },
  126. { value: 'POCTtraining', label: 'POCT培训' },
  127. { value: 'selfAssessment', label: '自主考核' },
  128. { value: 'routine', label: '常规' }
  129. ]
  130. },
  131. { prop: ['startDateDL', 'startDateDG'], label: '开始时间', fieldType: 'dateRange', options: { datefmt: 'yyyy-MM-dd' }},
  132. { prop: ['limitDateDL', 'limitDateDG'], label: '限考时间', fieldType: 'dateRange', options: { datefmt: 'yyyy-MM-dd' }}
  133. // { prop: ['Q^startDate^DL^yyyy-MM-dd', 'Q^startDate^DG^yyyy-MM-dd'], label: '开始时间', fieldType: 'dateRange', options: { datefmt: 'yyyy-MM-dd' }},
  134. // { prop: ['Q^limitDate^DL^yyyy-MM-dd', 'Q^limitDate^DG^yyyy-MM-dd'], label: '限考时间', fieldType: 'dateRange', options: { datefmt: 'yyyy-MM-dd' }}
  135. ]
  136. },
  137. mainActions: [{
  138. 'name': '信息催办',
  139. 'type': 'primary',
  140. 'callback': this.batchReminders
  141. },
  142. {
  143. 'name': '消息催办',
  144. 'type': 'default',
  145. 'callback': this.smsReminders
  146. }],
  147. stateActive: false,
  148. subject: '',
  149. moreSubject: '',
  150. subjectTitle: '',
  151. typeId: '',
  152. moreParams: {},
  153. listData: [],
  154. pagination: {},
  155. sorts: {},
  156. loading: false,
  157. finished: false,
  158. refreshing: false,
  159. resultType: 'init',
  160. errorType: null,
  161. resultMessage: null,
  162. checkMode: false,
  163. checkedIds: [],
  164. proInstId: '',
  165. defId: '',
  166. formrenderVisible: false,
  167. formrenderTitle: '',
  168. typeTreePopup: false,
  169. keyword: '',
  170. name: '全部',
  171. current: 0,
  172. startTime: [],
  173. endTime: []
  174. }
  175. },
  176. computed: {
  177. ...mapState('ibps/user', [
  178. 'info'
  179. ]),
  180. rightText() {
  181. return this.checkMode ? this.$t('common.button.cancel') : this.$t('common.button.manage')
  182. },
  183. selectedIds() {
  184. return this.checkedIds.join(',')
  185. }
  186. },
  187. beforeRouteLeave(to, from, next) {
  188. if (this.showPop === true) {
  189. // this.showConfirmationBoxList = true
  190. this.$refs.childPop.parentSubmit()
  191. this.showPop = false
  192. next(false)
  193. } else {
  194. next()
  195. }
  196. },
  197. methods: {
  198. sendFunction(listData) {
  199. const sendNotice = (req, ups) => {
  200. req.forEach((item, i) => {
  201. this.$common.sendMsg(item)
  202. })
  203. updateTimes(ups)
  204. }
  205. // 更新数据并重新渲染
  206. const updateTimes = req => {
  207. const params = {
  208. tableName: 't_gqswb',
  209. updList: req
  210. }
  211. this.$common.request('update', JSON.stringify(params)).then(() => {
  212. Notify({ type: 'success', message: '消息催办成功!' })
  213. this.onRefreshPage()
  214. })
  215. // this.$common.request('update', JSON.stringify(params)).then(() => {
  216. // template.$message.success('消息催办成功')
  217. // template.handleAction('search', position, [], [], 0, { button_type: 'search' })
  218. // })
  219. }
  220. const msgContent = {
  221. soon: '即将超时,请及时处理!',
  222. overtime: '已超时,请及时处理!'
  223. }
  224. const msgTitle = {
  225. soon: '计划事务即将到期提醒',
  226. overtime: '事务超时提醒'
  227. }
  228. const noticeList = []
  229. const upList = []
  230. let flag = false
  231. let msg = ''
  232. const currentTime = new Date(new Date().getTime() + 28800000).toJSON().slice(0, 16).replace('T', ' ')
  233. listData.forEach(item => {
  234. const notice = {
  235. subject: msgTitle[item.guo_qi_zhuang_tai],
  236. content: `${item.shi_wu_ming_cheng}【${item.shi_wu_shuo_ming_}】${msgContent[item.guo_qi_zhuang_tai]}`,
  237. receiverId: item.chu_li_ren_id_,
  238. canreplay: '0'
  239. }
  240. const up = {
  241. where: {
  242. id_: item.id_
  243. },
  244. param: {
  245. ti_xing_ci_shu_: parseInt(item.ti_xing_ci_shu_) + 1,
  246. ti_xing_shi_jian_: currentTime
  247. }
  248. }
  249. noticeList.push(notice)
  250. upList.push(up)
  251. // 校验提醒时间 (间隔不足2小时不允许发送)
  252. const D = new Date(item.ti_xing_shi_jian_).getTime()
  253. const N = new Date(currentTime).getTime()
  254. if (N - D < 7200000) {
  255. flag = true
  256. msg = `事务【${item.shi_wu_ming_cheng}】上次消息催办时间为${item.ti_xing_shi_jian_},距今不足两小时,请勿频繁催办!`
  257. }
  258. })
  259. if (flag) {
  260. Notify({ type: 'primary', message: msg })
  261. return
  262. }
  263. // updateTimes(upList)
  264. sendNotice(noticeList, upList)
  265. },
  266. overlayShow(item) {
  267. this.reminderSon = true
  268. this.sonData = item
  269. },
  270. son() {
  271. this.reminderSon = false
  272. },
  273. onClick(item, index) {
  274. if (this.checkMode) {
  275. this.$refs.checkboxes[index].toggle()
  276. }
  277. },
  278. // 信息批量催办
  279. batchReminders() {
  280. // console.log('进入催办函数', this.checkedIds)
  281. if (this.checkedIds.length === 0) {
  282. this.$notify({
  283. type: 'warning',
  284. message: this.$t('common.dialog.selectedRecords')
  285. })
  286. return
  287. }
  288. this.getSMSInfo(this.checkedIds).then(res => {
  289. this.sendFunction(res)
  290. })
  291. },
  292. // 消息批量催办
  293. smsReminders() {
  294. if (this.checkedIds.length === 0) {
  295. this.$notify({
  296. type: 'warning',
  297. message: this.$t('common.dialog.selectedRecords')
  298. })
  299. return
  300. }
  301. this.getSMSInfo(this.checkedIds).then(res => {
  302. res.forEach(item => {
  303. this.smsFunction(item)
  304. })
  305. })
  306. },
  307. // 查询所有详细信息
  308. getSMSInfo(list) {
  309. const sql = `select * from t_gqswb`
  310. return new Promise((resolve, reject) => {
  311. this.$common.request('sql', sql).then(res => {
  312. const listData = []
  313. res.variables.data.forEach(item => {
  314. if (list.includes(item.id_)) {
  315. listData.push(item)
  316. }
  317. })
  318. resolve(listData)// 将处理后的数据作为参数传递给resolve
  319. }).catch(err => {
  320. reject(err)
  321. })
  322. })
  323. },
  324. // 单条数据催办
  325. sendSystemInfo(item) {
  326. this.sendFunction([item])
  327. },
  328. // 单条短信信息发布
  329. sendSmsInfo(item) {
  330. // console.log('发送短信消息', item)
  331. this.smsFunction(item)
  332. // sendSmsList().then(res=>{
  333. // console.log('发送短信成功', res);
  334. // })
  335. },
  336. // 短信催办函数
  337. smsFunction(item) {
  338. if (item.chu_li_ren_dian_h) {
  339. const obj = {
  340. sig: item.id_,
  341. list: [
  342. { chu_li_ren_: item.chu_li_ren_ming_, chu_li_ren_dian_h: item.chu_li_ren_dian_h, ren_wu_ming_cheng: item.shi_wu_ming_cheng }
  343. ]
  344. }
  345. // 获取当时时间
  346. const currentTime = new Date(new Date().getTime() + 28800000).toJSON().slice(0, 16).replace('T', ' ')
  347. const D = new Date(item.duan_xin_shi_jian).getTime()
  348. const N = new Date(currentTime).getTime()
  349. if (N - D < 7200000) {
  350. Notify({ type: 'primary', message: `事务【${item.shi_wu_ming_cheng}】上次信息催办时间为${item.duan_xin_shi_jian},距今不足两小时,请勿频繁催办!` })
  351. return
  352. }
  353. sendSmsList(obj).then((res) => {
  354. // console.log('短信催办成功', res)
  355. const up = {
  356. tableName: 't_gqswb',
  357. updList: [
  358. {
  359. where: {
  360. id_: item.id_
  361. },
  362. param: {
  363. duan_xin_ci_shu_: parseInt(item.duan_xin_ci_shu_) + 1,
  364. duan_xin_shi_jian: this.getCurrentDateTime()
  365. }
  366. }]
  367. }
  368. this.$common.request('update', JSON.stringify(up)).then(() => {
  369. // 更改数据库信息成功
  370. console.log('更改数据库信息成功')
  371. Notify({ type: 'success', message: '短信催办成功!' })
  372. this.onRefreshPage()
  373. })
  374. })
  375. } else {
  376. Notify({ type: 'danger', message: '还未上传手机号' })
  377. }
  378. },
  379. getCurrentDateTime() {
  380. const now = new Date()
  381. const year = now.getFullYear()
  382. const month = ('0' + (now.getMonth() + 1)).slice(-2) // 月份从0开始,所以加1,并补零
  383. const day = ('0' + now.getDate()).slice(-2) // 补零
  384. const hours = ('0' + now.getHours()).slice(-2) // 补零
  385. const minutes = ('0' + now.getMinutes()).slice(-2) // 补零
  386. const seconds = ('0' + now.getSeconds()).slice(-2) // 补零
  387. return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
  388. },
  389. updataSet(v) {
  390. this.showPop = v
  391. },
  392. generateTitle(name, title) { // generateTitle by vue-i18n
  393. return i18n.generateTitle(name, title)
  394. },
  395. toCheckMode() {
  396. if (this.$utils.isEmpty(this.listData)) {
  397. return
  398. }
  399. if (this.checkMode) {
  400. // this.show = true
  401. this.checkedIds = []
  402. }
  403. this.checkMode = !this.checkMode
  404. },
  405. clickType() {
  406. this.typeTreePopup = true
  407. },
  408. onSearch() {
  409. this.stateActive = false
  410. ActionUtils.initListData(this)
  411. this.current = 0
  412. this.listData = []
  413. this.loadData()
  414. },
  415. clickMoreSearch() {
  416. this.moreSearchPopup = true
  417. this.stateActive = false
  418. },
  419. clickTypeNode(data) {
  420. this.typeId = data.id
  421. this.onMoreSearch({})
  422. },
  423. // 高级查询
  424. onMoreSearch(params) {
  425. if (this.$utils.isNotEmpty(this.typeId)) {
  426. params['Q^type_id_^SL'] = this.typeId
  427. }
  428. this.moreParams = params
  429. this.onSearch()
  430. if (this.$utils.isNotEmpty(params)) {
  431. this.stateActive = true
  432. }
  433. },
  434. resetForm() {
  435. this.typeId = ''
  436. },
  437. // 下拉刷新
  438. onRefresh() {
  439. this.footText = false
  440. this.noData = false
  441. this.refreshing = true
  442. this.finished = false
  443. this.loading = true
  444. this.onSearch()
  445. },
  446. onRefreshPage() {
  447. this.checkedIds = []
  448. this.checkMode = false
  449. this.onRefresh()
  450. },
  451. /**
  452. * 加载数据
  453. */
  454. loadData() {
  455. this.loading = true
  456. let page = 0
  457. if (this.current === 0) {
  458. page = 0
  459. } else {
  460. page = this.current * 10
  461. }
  462. const key = this.subject
  463. const sql = `select * from t_gqswb where t_gqswb.shi_wu_ming_cheng like'%` + key + `%' ORDER BY t_gqswb.create_time_ DESC LIMIT ${page},10 `
  464. this.$common.request('sql', sql).then(res => {
  465. if (this.current === 0 && res.variables.data.length === 0) {
  466. this.finished = true
  467. this.noData = true
  468. this.footText = false
  469. }
  470. const data = res.variables.data
  471. this.listData.push(...data)
  472. this.refreshing = false
  473. if (this.listData.length !== 0 && (this.listData.length) % 10 !== 0) {
  474. this.footText = true
  475. this.noData = false
  476. this.finished = true
  477. return
  478. } else {
  479. this.current++
  480. }
  481. this.loading = false
  482. }).catch(err => {
  483. console.log(err)
  484. })
  485. },
  486. // 获取格式化参数
  487. getSearcFormData() {
  488. let params = {}
  489. if (this.$utils.isNotEmpty(this.subject)) {
  490. params['Q^subject_^SL'] = this.subject
  491. }
  492. if (this.$utils.isNotEmpty(this.moreParams)) {
  493. params = Object.assign(params, this.moreParams)
  494. }
  495. return ActionUtils.formatParams(
  496. params,
  497. this.pagination,
  498. this.sorts)
  499. },
  500. transformTime(timeStamp) {
  501. const hours = Math.floor(parseInt(timeStamp) / 3600000)
  502. const minutes = Math.floor((parseInt(timeStamp) % 3600000) / 60000)
  503. return hours + '小时' + minutes + '分钟'
  504. }
  505. }
  506. }
  507. </script>
  508. <style scoped lang="scss">
  509. .examRow {
  510. padding: 2% 0;
  511. .popupTitle {
  512. text-align: center;
  513. font-size: 14px;
  514. color: #555;
  515. }
  516. .popupContent {
  517. text-align: left;
  518. font-size: 14px;
  519. color: #777;
  520. }
  521. }
  522. .examRowto {
  523. margin: 10% 0;
  524. .van-col {
  525. text-align: center;
  526. .van-button {
  527. width: 80%;
  528. font-size: 16px;
  529. }
  530. }
  531. }
  532. </style>