util.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. import { getData } from '@/api/platform/desktop/column'
  2. import { getFile } from '@/utils/avatar'
  3. import { mapState } from 'vuex'
  4. import { taskTypeOptions, dashboardStatus, genderOptions, favoritesOptions, noticeOptions, unreadMessageOptions, imgOptionsData } from '@/business/platform/bpmn/constants'
  5. import ActionUtils from '@/utils/action'
  6. import Utils from '@/utils/util'
  7. import { findAllByCurrUserId, saveCalendarInfos, removeCalendarInfos } from '@/api/detection/newHomeApi'
  8. import { delQuickNavigation, addQuickNavigation, getQuickNavigation } from '@/api/platform/message/innerMessage'
  9. import { add, isObject } from 'lodash'
  10. const defaultRouterAlias = '/router-alias/'
  11. import newPng from '@/assets/images/homepage/new.png'
  12. /**
  13. * 创建组件
  14. */
  15. export function buildComponent (name, column, preview) {
  16. try {
  17. return {
  18. name: name,
  19. components: {},
  20. props: {
  21. params: {
  22. type: Object,
  23. default: () => {}
  24. },
  25. height: {
  26. type: Number,
  27. default: column.height || 300
  28. },
  29. visible: {
  30. type: Boolean,
  31. default: false
  32. }
  33. },
  34. filters: {
  35. filterStatus (val, type) {
  36. if (Utils.isEmpty(val)) {
  37. return ''
  38. }
  39. const typeMap = {
  40. pending: taskTypeOptions,
  41. already: dashboardStatus,
  42. myRequest: dashboardStatus,
  43. gender: genderOptions,
  44. favorites: favoritesOptions,
  45. notice: noticeOptions,
  46. unreadMessage: unreadMessageOptions
  47. }
  48. if (!typeMap[type]) {
  49. return val
  50. }
  51. return typeMap[type].find(x => x['value'] === val) ? typeMap[type].find(x => x['value'] === val).label : val
  52. }
  53. },
  54. data () {
  55. const { first = '', second = '' } = this.$store.getters.level
  56. const { userList = [], deptList = [], menus, userInfo } = this.$store.getters
  57. const t1 = deptList.find(i => i.positionId === first) || {}
  58. const t2 = deptList.find(i => i.positionId === second) || {}
  59. const locationName = second ? t1.positionName + t2.positionName : t1.positionName
  60. return {
  61. userList,
  62. deptList,
  63. menus,
  64. locationName,
  65. newPng,
  66. imgOptionsData,
  67. positions: userInfo.positions,
  68. loading: false,
  69. title: `${column.name}`,
  70. alias: `${column.alias}`,
  71. attrs: this.getAttrs(),
  72. variables: {}, // 一些变量,比如分页信息
  73. data: null,
  74. totality: null,
  75. quickNavigationData: [],
  76. stautusOptions: [],
  77. bpmnFormrenderDialogVisible: false, // 表单
  78. editId: '',
  79. bodyShow: true,
  80. show: false,
  81. showHeight: '',
  82. cardHeight: '100%',
  83. activeName: 'innerMessage',
  84. unreadMessageOption: {},
  85. formName: 'form',
  86. dialogFormVisible: false,
  87. formLabelWidth: '120px',
  88. quickNavform: {
  89. urlName: '',
  90. urlAddr: '',
  91. display: '_blank'
  92. },
  93. defaultForm: {},
  94. pendingTabActiveName: 'user-type',
  95. bodyParams: ActionUtils.formatParams({}, {}, {}),
  96. pendingBusinessOption: {},
  97. bpmn: [],
  98. rules: {
  99. urlName: [
  100. {
  101. required: true,
  102. message: this.$t('validate.required')
  103. }
  104. ],
  105. urlAddr: [
  106. {
  107. required: true,
  108. message: this.$t('validate.required')
  109. }
  110. ],
  111. display: [
  112. {
  113. required: true,
  114. message: this.$t('validate.required')
  115. }
  116. ]
  117. },
  118. calendarDialogForm: {
  119. id: '',
  120. biaoTi: '',
  121. neiRong: '',
  122. kaiShiShiJian: '',
  123. jieShuShiJian: '',
  124. formDate: []
  125. },
  126. colorStatus: ['#e7505a', '#f3c200', '#578ebe', '#1BBC9B']
  127. // const status = ['急', '重', '轻','缓']
  128. }
  129. },
  130. computed: {
  131. ...mapState({
  132. userInfo: state => state.ibps.user.info
  133. })
  134. },
  135. mounted () {
  136. this.defaultForm = JSON.parse(JSON.stringify(this.quickNavform))
  137. this.$nextTick(() => {
  138. this.fetchData()
  139. })
  140. },
  141. methods: {
  142. fetchData (columns, params = {}) {
  143. this.loading = true
  144. this.showHeight = this.getHeight()
  145. const param = Utils.isNotEmpty(columns) && (column.alias === 'unreadMessage' || column.alias === 'pendingBusiness')
  146. ? { dataMode: column.dataMode, dataFrom: column.dataFrom }
  147. : column
  148. if (param.alias === 'myCalendar') {
  149. const { getFormatDate, getDate } = this.$common
  150. findAllByCurrUserId().then(res => {
  151. const { data = [] } = res || {}
  152. this.data = data.map(i => ({
  153. id: i.id,
  154. title: i.title,
  155. content: i.content,
  156. start: i.startTime,
  157. // 日期组件日程显示里,end的时间需要多加一天,end:2024-01-02时,日程条只到2024-01-01的日期位置上
  158. end: getFormatDate('string', 10, getDate('day', 1, i.endTime)),
  159. jieShuShiJian: i.endTime,
  160. zhuangTai: i.emergencyState,
  161. color: this.colorStatus[Number(i.emergencyState) - 1]
  162. }))
  163. }).catch(() => {
  164. this.$message.error('获取日历日程失败!')
  165. })
  166. } else if (param.alias === 'quickNavigation') {
  167. getQuickNavigation().then(res => {
  168. this.quickNavigationData = res.data || []
  169. })
  170. } else {
  171. getData(param, params).then(res => {
  172. let { data } = res || {}
  173. if (Utils.isNotEmpty(data) && Utils.isString(data)) {
  174. data = Utils.parseData(res.data)
  175. }
  176. this.data = data && data.dataResult ? data.dataResult : data
  177. this.totality = data && data.dataResult ? data.pageResult : data
  178. // 公告栏目对数据过滤
  179. if (param.alias === 'notice') {
  180. const deptIds = this.deptList.map(i => i.positionId)
  181. this.data = data.filter(i => deptIds.includes(i.depId))
  182. }
  183. this.variables = res.variables
  184. this.loading = false
  185. }).catch((e) => {
  186. this.loading = false
  187. })
  188. }
  189. },
  190. getPhoto (photo) {
  191. return getFile(photo)
  192. },
  193. getTaskDesc (v) {
  194. if (!v.includes('#')) {
  195. return ''
  196. }
  197. return v.split('#')[1] || ''
  198. },
  199. getTaskInfo (val, arg) {
  200. const arr = val.split('#')
  201. if (!arr[2]) {
  202. return ''
  203. }
  204. const result = JSON.parse(`{${arr[2]}}`)
  205. if (!result.dept) {
  206. return ''
  207. }
  208. const depts = result.dept.split(',')
  209. const deptNames = []
  210. depts.forEach(item => {
  211. const t = this.deptList.find(i => i.positionId === item)
  212. deptNames.push(t ? t.positionName : result.dept)
  213. })
  214. result.deptName = deptNames.join(',')
  215. return result[arg]
  216. },
  217. transformData (val, dataset, from, to) {
  218. if (!val) {
  219. return ''
  220. }
  221. const temp = this[dataset].find(u => u[from] === val)
  222. return temp ? temp[to] : ''
  223. },
  224. getHeightNoUnit () {
  225. // 高度 - header - 边框
  226. if (!this.visible) {
  227. return this.height ? (this.height - 60 - 20) : 150
  228. } else {
  229. return 150
  230. }
  231. },
  232. getHeight (h = 20) {
  233. // 高度 - header - 边框
  234. if (!this.visible) {
  235. return this.height ? `${(this.height - 60 - h)}px` : '150px'
  236. } else {
  237. return '100%'
  238. }
  239. },
  240. getDashboardHeight () {
  241. return this.height ? `${this.height + 20}px` : '150px'
  242. },
  243. getAttrs () {
  244. const item = JSON.parse(JSON.stringify(column))
  245. item.templateHtml = null
  246. return item
  247. },
  248. /**
  249. * 构建首页日期组件的参数
  250. * @param {*} data
  251. * @returns
  252. */
  253. getFullCalendarConfig (data) {
  254. const events = data === null ? [] : Utils.parseJSON(data)
  255. const config = {
  256. height: preview ? '100%' : (this.height ? this.height : 180),
  257. // editable: true, // 允许拖动缩放,不写默认就是false
  258. selectable: true,
  259. dayMaxEvents: 1, // 最多显示3个日程
  260. locale: this.$i18n.locale ? this.$i18n.locale.toLowerCase() : 'zh-cn',
  261. events: events,
  262. buttonText: {
  263. today: '今天',
  264. dayGridMonth: '月',
  265. listMonth: '日程'
  266. // week: '周视图',
  267. // day: '日视图',
  268. // prev: '<i class="icon-chevron-left">后退</i>',
  269. // next: '<i class="icon-chevron-right">前进</i>'
  270. },
  271. dateClick: this.handleDateClick, // 日期点击
  272. eventClick: this.handleEventClick
  273. }
  274. if (preview) {
  275. config.headerToolbar = {
  276. start: '',
  277. center: 'title',
  278. end: 'prev,next,today,dayGridMonth,listMonth'
  279. // end: 'prev,next,today,month,agendaWeek,agendaDay,listWeek'
  280. }
  281. delete config['dayMaxEvents']
  282. }
  283. return config
  284. },
  285. handleDateClick (param) {
  286. this.$emit(
  287. 'open',
  288. 'calendar',
  289. [param.dateStr, param.dateStr],
  290. this.data
  291. )
  292. },
  293. handleEventClick (param) {
  294. this.$emit(
  295. 'open',
  296. 'calendar',
  297. [param.event.startStr, param.event._def.extendedProps.jieShuShiJian],
  298. this.data
  299. )
  300. },
  301. refreshData () {
  302. this.fetchData()
  303. },
  304. /**
  305. * 处理按钮事件
  306. * @param {*} command
  307. * @param {*} position
  308. * @param {*} data
  309. * @param {*} actions
  310. */
  311. handleActionEvent (command, position, data, actions) {
  312. switch (command) {
  313. case 'refresh': // 刷新
  314. this.refreshData()
  315. break
  316. case 'fullscreen': // 全屏
  317. this.handleFullscreen()
  318. break
  319. case 'more': // 更多
  320. this.handleMore()
  321. break
  322. case 'collapse': // 收缩
  323. case 'expansion': // 展开
  324. this.handleCollapseExpand(command, data, actions)
  325. break
  326. case 'add': // 新增
  327. this.getFormData()
  328. break
  329. default:
  330. break
  331. }
  332. },
  333. emitActionEventHandler (command) {
  334. this.$emit('action-event', command, ...Array.from(arguments).slice(1))
  335. },
  336. // 公告栏目点击事件
  337. handleApprove (id) {
  338. this.$emit('action-event', 'approve', id)
  339. },
  340. handleUnreadMessage (id) {
  341. this.$emit('action-event', 'unRead', id)
  342. },
  343. // 处理全屏
  344. handleFullscreen () {
  345. this.emitActionEventHandler('fullscreen', { id: this.attrs.id })
  346. },
  347. openPlate (url) {
  348. const menuMap = {
  349. myTraining: 'rygl/rypx/wdpx',
  350. myTesting: 'rygl/kszx/wdks',
  351. myDevices: 'sbgls/mywh'
  352. }
  353. if (menuMap[url]) {
  354. const alias = menuMap[url].split('/')[0]
  355. const resInfo = this.menus.find(i => i.alias === alias)
  356. this.$store.dispatch('ibps/menu/activeHeaderSet', { activeHeader: resInfo.id, vm: this })
  357. }
  358. this.$router.push(`/${menuMap[url] || url}`)
  359. },
  360. /**
  361. * 处理更多
  362. */
  363. handleMore () {
  364. if (this.attrs.colUrl === '') {
  365. return this.$message.warning('未设置更多路径的url')
  366. }
  367. this.$router.push(`/${this.attrs.colUrl}`)
  368. },
  369. // 未读消息
  370. handleClick (option) {
  371. this.unreadMessageOption = option
  372. option[this.activeName].dataMode = column.dataMode
  373. this.fetchData(option[this.activeName])
  374. },
  375. // 待办事务
  376. handleTabClick (option) {
  377. this.pendingBusinessOption = option
  378. option[this.pendingTabActiveName].dataMode = column.dataMode
  379. this.fetchData(option[this.pendingTabActiveName])
  380. },
  381. handleFlowClick (params) {
  382. params.$alias = this.alias
  383. this.emitActionEventHandler('flow', params)
  384. },
  385. handleCollapseExpand (command, data, actions) {
  386. this.bodyShow = !this.bodyShow
  387. const index = actions.findIndex((action) => action.key === data.key)
  388. actions[index].key = this.bodyShow ? 'collapse' : 'expansion'
  389. if (!this.visible) {
  390. this.emitActionEventHandler(command, {})
  391. return
  392. }
  393. this.showHeight = this.bodyShow ? this.getHeight() : 0
  394. this.$refs['toolbar'].callback(actions)
  395. },
  396. formValidate () {
  397. this.$nextTick(() => {
  398. this.$refs[this.formName].validate(() => {})
  399. })
  400. },
  401. getFormData () {
  402. this.quickNavform = JSON.parse(JSON.stringify(this.defaultForm))
  403. this.formValidate()
  404. this.dialogFormVisible = true
  405. },
  406. handleNavRemove (navId, i) {
  407. this.$confirm('是否确认删除该快捷导航?', '提示', {
  408. confirmButtonText: '确认',
  409. cancelButtonText: '取消',
  410. type: 'warning',
  411. showClose: false,
  412. closeOnClickModal: false
  413. }).then(() => {
  414. delQuickNavigation({ navigateIds: navId }).then(() => {
  415. this.$message.success('删除成功')
  416. this.quickNavigationData.splice(i, 1)
  417. })
  418. })
  419. },
  420. // 错误头像的照片
  421. errorAvatarHandler (data) {
  422. // data.photo = require('https://cube.elemecdn.com/e/fd/0fc7d20532fdaf769a25683617711png.png')
  423. return true
  424. },
  425. close () {
  426. this.$refs[this.formName].resetFields()
  427. this.dialogFormVisible = false
  428. },
  429. saveQuickNav () {
  430. this.$refs[this.formName].validate(valid => {
  431. if (valid) {
  432. addQuickNavigation({ id: '', ...this.quickNavform }).then(() => {
  433. this.$message.success('添加成功!')
  434. this.quickNavigationData.push(this.quickNavform)
  435. this.dialogFormVisible = false
  436. })
  437. } else {
  438. ActionUtils.saveErrorMessage()
  439. }
  440. })
  441. },
  442. // 父组件调用该方法给日程添加数据
  443. async setCalendarEvents (param) {
  444. const { userId = '', name = '' } = this.$store.getters
  445. const form = param.form
  446. const paramObject = {
  447. id: form.id ? form.id : '11111',
  448. // diDian: "string", // 地点
  449. userId: userId, // 用户id
  450. userName: name, // 用户名
  451. title: form.biaoTi, // 标题
  452. content: form.neiRong, // 内容
  453. startTime: form.formDate[0], // 开始时间
  454. endTime: form.formDate[1], // 结束时间
  455. emergencyState: form.zhuangTai // 紧急状态
  456. }
  457. await saveCalendarInfos(paramObject)
  458. this.refreshData()
  459. },
  460. async hanldeCalendardel (param) {
  461. if (param.form.id) {
  462. await removeCalendarInfos({
  463. calendarIds: param.form.id
  464. })
  465. }
  466. this.refreshData()
  467. },
  468. // 公告栏是否显示new图标
  469. showNewIcon (date, days) {
  470. const nowDate = new Date().getTime
  471. const targetDate = new Date(date).getTime
  472. return targetDate + days * 24 * 60 * 60 * 1000 > nowDate
  473. }
  474. },
  475. template: column.templateHtml !== '' ? `${column.templateHtml}` : `<div></div>`
  476. }
  477. } catch (error) {
  478. console.error(error)
  479. }
  480. }