memoManageMixin.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. import {
  2. getMemoList,
  3. getMemoDetail,
  4. addMemo,
  5. updateMemo,
  6. deleteMemo,
  7. deleteMemoBatch,
  8. } from '@/api/memoManage.js'
  9. import { getAuditTaskList } from '@/api/auditInitiation.js'
  10. import moment from 'moment'
  11. export const memoManageMixin = {
  12. data() {
  13. // 表格列配置
  14. const tableColumns = [
  15. {
  16. prop: 'reminderType',
  17. label: '提醒',
  18. width: 80,
  19. headerAlign: 'center',
  20. align: 'center',
  21. slotName: 'reminder-type',
  22. },
  23. {
  24. prop: 'task',
  25. label: '成本监审任务',
  26. width: 160,
  27. headerAlign: 'center',
  28. align: 'center',
  29. },
  30. {
  31. prop: 'memoDate',
  32. label: '日期',
  33. width: 120,
  34. headerAlign: 'center',
  35. align: 'center',
  36. },
  37. {
  38. prop: 'title',
  39. label: '标题',
  40. width: 120,
  41. headerAlign: 'center',
  42. align: 'center',
  43. },
  44. {
  45. prop: 'content',
  46. label: '内容',
  47. minWidth: 200,
  48. headerAlign: 'center',
  49. align: 'center',
  50. },
  51. {
  52. prop: 'action',
  53. label: '操作',
  54. width: 150,
  55. headerAlign: 'center',
  56. align: 'center',
  57. slotName: 'action-buttons',
  58. showOverflowTooltip: false,
  59. },
  60. ]
  61. // 按项目查询标签页的表格列配置(项目名称列宽更大)
  62. const projectTableColumns = [
  63. ...tableColumns.map((col) => {
  64. if (col.prop === 'projectName') {
  65. return { ...col, width: 220 }
  66. } else if (col.prop === 'title') {
  67. return { ...col, width: 200 }
  68. } else if (col.prop === 'content') {
  69. return { ...col, minWidth: 300 }
  70. }
  71. return col
  72. }),
  73. ]
  74. return {
  75. type: 'index', // 列表类型:index-首页列表,memoManage-备忘录列表
  76. dictData: {
  77. reminderType: [],
  78. },
  79. activeTab: 'calendar',
  80. selectedDate: new Date(),
  81. today: new Date(),
  82. // 表格配置
  83. tableColumns,
  84. projectTableColumns,
  85. searchParams: {
  86. year: '',
  87. projectId: '',
  88. content: '',
  89. startTime: '',
  90. endTime: '',
  91. page: 1,
  92. pageSize: 50,
  93. },
  94. listTotal: 0,
  95. memoList: [],
  96. formTitle: '',
  97. formDisabled: false,
  98. formRules: {
  99. projectId: [
  100. {
  101. required: true,
  102. message: '请选择成本监审项目',
  103. trigger: 'change',
  104. },
  105. ],
  106. title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
  107. content: [{ required: true, message: '请输入内容', trigger: 'blur' }],
  108. memoDate: [
  109. { required: true, message: '请选择日期', trigger: 'change' },
  110. ],
  111. startTime: [
  112. { required: true, message: '请选择开始时间', trigger: 'change' },
  113. ],
  114. endTime: [
  115. { required: true, message: '请选择结束时间', trigger: 'change' },
  116. ],
  117. reminderType: [
  118. { required: true, message: '请选择提醒方式', trigger: 'change' },
  119. ],
  120. // attachmentName: [
  121. // { required: true, message: '请上传附件', trigger: 'change' },
  122. // ],
  123. },
  124. editForm: {
  125. attachmentName: '',
  126. attachmentSize: 0,
  127. attachmentUrl: '',
  128. content: '',
  129. memoDate: '',
  130. projectId: 0,
  131. reminderType: '0',
  132. task: '',
  133. startTime: '',
  134. endTime: '',
  135. title: '',
  136. },
  137. // 时间数据字段已移除,改为直接使用editForm中的startTime和endTime
  138. fileList: [],
  139. isEditDialogOpen: false,
  140. auditTaskList: [],
  141. lunarInfo: {},
  142. }
  143. },
  144. computed: {
  145. // 获取指定日期的任务列表
  146. getTasksByDate() {
  147. return (date) => {
  148. const dateStr = moment(date).format('YYYY-MM-DD')
  149. return this.memoList.filter((task) => task.memoDate === dateStr)
  150. }
  151. },
  152. },
  153. watch: {
  154. // // 监听选中日期变化,更新搜索参数
  155. selectedDate: {
  156. handler(newVal) {
  157. if (newVal) {
  158. this.lunarInfo = this.getLunarInfo(this.selectedDate)
  159. this.searchParams.memoDate = moment(newVal).format('YYYY-MM-DD')
  160. this.handleSearch()
  161. }
  162. },
  163. deep: true,
  164. },
  165. },
  166. methods: {
  167. // 优化后的获取详情方法,不再接收单个item参数
  168. async getTasksByDateList() {
  169. if (this.memoList.length > 0) {
  170. try {
  171. // 使用Promise.all并行获取所有备忘录的详情
  172. const detailPromises = this.memoList.map(async (memo, index) => {
  173. try {
  174. const params = {
  175. id: memo.id,
  176. }
  177. const res = await getMemoDetail(params)
  178. if (res.code === 200 && res.value) {
  179. // 更新原数组中的数据
  180. const memoIndex = this.memoList.findIndex(
  181. (item) => item.id === memo.id
  182. )
  183. if (memoIndex !== -1) {
  184. this.memoList[memoIndex] = {
  185. ...this.memoList[memoIndex],
  186. ...res.value,
  187. }
  188. }
  189. // 返回更新后的数据
  190. return {
  191. ...memo,
  192. ...res.value,
  193. }
  194. }
  195. return memo // 如果获取失败,返回原数据
  196. } catch (err) {
  197. console.error('获取备忘录详情失败:', memo.id, err)
  198. return memo // 发生错误时返回原数据
  199. }
  200. })
  201. // 等待所有详情请求完成
  202. this.memoList = await Promise.all(detailPromises)
  203. } catch (error) {
  204. console.error('批量获取备忘录详情失败:', error)
  205. // 发生错误时返回原始列表
  206. }
  207. }
  208. },
  209. // 根据提醒类型获取对应的颜色
  210. getReminderTypeColor(type) {
  211. const colorMap = {
  212. 1: '#c0c4cc', // 不提醒 - 浅灰色
  213. 2: '#f56c6c', // 提前1小时 - 红色
  214. 3: '#e6a23c', // 提前2小时 - 橙色
  215. 4: '#e6a23c', // 提前3小时 - 橙色
  216. 5: '#73c0de', // 提前1天 - 天蓝色
  217. 6: '#98fb98', // 提前2天 - 浅绿色
  218. 7: '#c0c4cc', // 提前3天 - 浅灰色
  219. }
  220. return colorMap[type] || '#c0c4cc'
  221. },
  222. // 时间处理逻辑已移除,改为直接使用editForm中的startTime和endTime
  223. // 优化 saveFiles 方法
  224. saveFiles(data) {
  225. console.log('saveFiles', data)
  226. this.fileList = data
  227. this.editForm.attachmentName = data[0].fileName
  228. this.editForm.attachmentSize = data[0].fileSize
  229. this.editForm.attachmentUrl = data[0].savePath
  230. },
  231. // 优化 removeFile 方法
  232. removeFile(index, removedFile, currentFiles) {
  233. this.fileList = []
  234. this.editForm.attachmentName = ''
  235. this.editForm.attachmentSize = 0
  236. this.editForm.attachmentUrl = ''
  237. },
  238. // 获取监审任务列表
  239. async getAuditTaskList() {
  240. try {
  241. let params = {
  242. projectName: '',
  243. }
  244. const res = await getAuditTaskList(params)
  245. console.log('监审任务列表数据:', res)
  246. if (res.code == 200) {
  247. this.auditTaskList = res.value || []
  248. }
  249. } catch (error) {
  250. console.error('获取监审任务列表数据失败:', error)
  251. }
  252. },
  253. // 日历选择日期
  254. handleDateClick(date, data) {
  255. const dateStr = moment(date).format('YYYY-MM-DD')
  256. // const tasks = this.memoList.filter((task) => task.memoDate === dateStr)
  257. this.searchParams.memoDate = dateStr
  258. this.handleSearch()
  259. // if (tasks.length > 0) {
  260. // this.searchParams.startTime = dateStr
  261. // this.searchParams.endTime = dateStr
  262. // }
  263. },
  264. // 获取提醒类型的文本描述
  265. getReminderTypeText(type) {
  266. const textMap = {
  267. 0: '不提醒',
  268. 1: '提前1小时',
  269. 2: '提前2小时',
  270. 3: '提前3小时',
  271. 4: '提前1天',
  272. 5: '提前2天',
  273. 6: '提前3天',
  274. }
  275. return textMap[type] || '不提醒'
  276. },
  277. /**
  278. * 获取指定日期的农历信息,包括节日和节气信息
  279. * @param {Date} date - 日期对象
  280. * @returns {Object|null} 包含公历农历详细信息的对象,如果超出范围则返回基本信息对象
  281. */
  282. getLunarInfo(date) {
  283. try {
  284. // 从日期对象获取年月日
  285. const year = date.getFullYear()
  286. const month = date.getMonth() + 1 // 月份从1开始
  287. const day = date.getDate()
  288. // 检查是否在solar2lunar支持的范围内 (1900.1.31~3000.12.31)
  289. const isInRange =
  290. (year > 1900 ||
  291. (year === 1900 && month > 1) ||
  292. (year === 1900 && month === 1 && day >= 31)) &&
  293. (year < 3000 ||
  294. (year === 3000 && month < 12) ||
  295. (year === 3000 && month === 12 && day <= 31))
  296. if (window.calendar && window.calendar.solar2lunar && isInRange) {
  297. // 在范围内,调用calendar-converter.js中的solar2lunar函数
  298. const lunarDate = window.calendar.solar2lunar(year, month, day)
  299. if (lunarDate !== -1) {
  300. return lunarDate || { IDayCn: '' }
  301. }
  302. }
  303. // 超出范围时,返回基本日期信息
  304. console.warn(
  305. `日期 ${year}-${month}-${day} 超出了农历转换支持的范围(1900.1.31~3000.12.31)`
  306. )
  307. return this._getBasicDateInfo(year, month, day)
  308. } catch (error) {
  309. // 出错时也返回基本日期信息
  310. return this._getBasicDateInfo(
  311. date.getFullYear(),
  312. date.getMonth() + 1,
  313. date.getDate()
  314. )
  315. }
  316. },
  317. /**
  318. * 获取基本的日期信息,当超出solar2lunar范围时使用
  319. * @private
  320. * @param {number} year - 阳历年
  321. * @param {number} month - 阳历月
  322. * @param {number} day - 阳历日
  323. * @returns {Object} 基本日期信息对象
  324. */
  325. _getBasicDateInfo(year, month, day) {
  326. const dateStr = `${year}-${month}-${day}`
  327. // 创建基本信息对象,格式尽量与solar2lunar返回的一致
  328. return {
  329. date: dateStr,
  330. lunarDate: '超出转换范围',
  331. festival: null,
  332. lunarFestival: null,
  333. lYear: year,
  334. lMonth: month,
  335. lDay: day,
  336. Animal: null,
  337. IMonthCn: '',
  338. IDayCn: '',
  339. cYear: year,
  340. cMonth: month,
  341. cDay: day,
  342. gzYear: '',
  343. gzMonth: '',
  344. gzDay: '',
  345. isToday: false,
  346. isLeap: false,
  347. nWeek: new Date(year, month - 1, day).getDay() || 7, // 周日为7
  348. ncWeek: `星期${
  349. ['日', '一', '二', '三', '四', '五', '六'][
  350. new Date(year, month - 1, day).getDay()
  351. ]
  352. }`,
  353. isTerm: false,
  354. Term: null,
  355. astro: '',
  356. outOfRange: true, // 标记为超出范围
  357. }
  358. },
  359. // 上一个月
  360. handlePrevMonth() {
  361. this.selectedDate = moment(this.selectedDate)
  362. .subtract(1, 'month')
  363. .toDate()
  364. },
  365. // 下一个月
  366. handleNextMonth() {
  367. this.selectedDate = moment(this.selectedDate).add(1, 'month').toDate()
  368. },
  369. // 获取备忘录列表
  370. async handleSearch() {
  371. try {
  372. let params = {
  373. ...this.searchParams,
  374. // memoDate:''
  375. }
  376. let _url = ''
  377. if (this.type === 'memoManage') {
  378. _url = '/api/costProjectMemo/v1/pageList'
  379. } else {
  380. _url = '/api/costProjectMemo/v1/pageIndexList'
  381. }
  382. if (this.activeTab == 'project') {
  383. delete params.memoDate
  384. } else if (this.activeTab == 'calendar') {
  385. params.memoDate = this.searchParams.memoDate
  386. delete params.year
  387. }
  388. const res = await getMemoList(_url, params)
  389. if (res.value && res.value.records.length > 0) {
  390. this.memoList = res.value.records || []
  391. // 只处理day字段,不调用详情接口
  392. this.memoList.forEach((item) => {
  393. const date = new Date(item.memoDate)
  394. item.day = date.getDate()
  395. })
  396. // 在列表数据设置完成后,只调用一次详情接口获取所有需要的详情
  397. await this.getTasksByDateList()
  398. this.listTotal = res.value.total || 0
  399. } else {
  400. this.memoList = []
  401. this.listTotal = 0
  402. }
  403. } catch (error) {
  404. console.error('获取数据失败:', error)
  405. }
  406. },
  407. handleReset() {
  408. this.searchParams = {
  409. page: 1,
  410. pageSize: 10,
  411. startTime: '',
  412. endTime: '',
  413. year: '',
  414. projectId: '',
  415. content: '',
  416. }
  417. this.handleSearch()
  418. },
  419. handleCurrentChange(val) {
  420. this.searchParams.pageNum = val
  421. this.handleSearch()
  422. },
  423. handleSizeChange(val) {
  424. this.searchParams.pageSize = val
  425. this.handleSearch()
  426. },
  427. // 处理分页变化
  428. handlePaginationChange({ currentPage, pageSize }) {
  429. this.searchParams.page = currentPage
  430. this.searchParams.pageSize = pageSize
  431. this.handleSearch()
  432. },
  433. // 初始化日历相关数据
  434. initCalendarData(type) {
  435. this.type = type
  436. this.selectedDate = new Date()
  437. this.lunarInfo = this.getLunarInfo(this.selectedDate)
  438. // this.handleSearch(num)
  439. },
  440. onTabChange(tab) {
  441. this.searchParams.startTime = ''
  442. this.searchParams.endTime = ''
  443. this.searchParams.year = ''
  444. this.searchParams.projectId = ''
  445. this.searchParams.content = ''
  446. this.searchParams.page = 1
  447. if (tab.name == 'calendar') {
  448. this.setCalendarTitle()
  449. this.handleSearch()
  450. } else {
  451. this.handleSearch()
  452. }
  453. },
  454. // prevMonth() {
  455. // console.log('日历切换:上一个月')
  456. // if (this.currentMonth === 1) {
  457. // this.currentYear--
  458. // this.currentMonth = 12
  459. // } else {
  460. // this.currentMonth--
  461. // }
  462. // this.setCalendarTitle()
  463. // },
  464. // nextMonth() {
  465. // console.log('日历切换:下一个月')
  466. // if (this.currentMonth === 12) {
  467. // this.currentYear++
  468. // this.currentMonth = 1
  469. // } else {
  470. // this.currentMonth++
  471. // }
  472. // this.setCalendarTitle()
  473. // },
  474. handleAdd() {
  475. this.getAuditTaskList()
  476. this.formTitle = '添加备忘录'
  477. this.formDisabled = false
  478. this.editForm = {
  479. attachmentName: '',
  480. attachmentSize: 0,
  481. attachmentUrl: '',
  482. content: '',
  483. memoDate: '',
  484. projectId: '',
  485. reminderType: '0',
  486. task: '',
  487. startTime: '',
  488. endTime: '',
  489. title: '',
  490. }
  491. this.fileList = []
  492. this.isEditDialogOpen = true
  493. },
  494. // 获取备忘录详情
  495. async getMemoDetail(row) {
  496. this.getAuditTaskList()
  497. try {
  498. let params = {
  499. id: row.id,
  500. }
  501. const res = await getMemoDetail(params)
  502. if (res.code == 200) {
  503. // 处理时间范围
  504. let startTime = ''
  505. let endTime = ''
  506. const data = { ...row, ...res.value }
  507. if (data.timePeriod) {
  508. const timeRange = data.timePeriod.split('-')
  509. if (timeRange.length === 2) {
  510. startTime = timeRange[0]
  511. endTime = timeRange[1]
  512. }
  513. }
  514. this.editForm = {
  515. ...data,
  516. startTime: startTime,
  517. endTime: endTime,
  518. }
  519. // 删除timePeriod字段避免混淆
  520. delete this.editForm.timePeriod
  521. this.fileList = this.editForm.attachmentUrl
  522. ? [res.value.attachmentUrl]
  523. : []
  524. this.isEditDialogOpen = true
  525. }
  526. } catch (error) {
  527. console.error('获取详情数据失败:', error)
  528. }
  529. },
  530. handleView(row) {
  531. this.formTitle = '查看备忘录详情'
  532. this.formDisabled = true
  533. this.getMemoDetail(row)
  534. },
  535. handleEdit(row) {
  536. this.formTitle = '编辑备忘录'
  537. this.formDisabled = false
  538. this.getMemoDetail(row)
  539. },
  540. handleDelete(row) {
  541. this.$confirm('确定要删除该数据吗?', '提示', {
  542. confirmButtonText: '确定',
  543. cancelButtonText: '取消',
  544. type: 'warning',
  545. })
  546. .then(async () => {
  547. const response = await deleteMemo(row.id)
  548. this.$message.success('删除成功')
  549. // 重新加载数据
  550. this.handleSearch()
  551. })
  552. .catch(() => {
  553. this.$message.info('已取消删除')
  554. })
  555. },
  556. handleSave() {
  557. this.$refs['ruleForm'].validate((valid) => {
  558. if (valid) {
  559. let task = this.auditTaskList.find(
  560. (item) => item.projectId === this.editForm.projectId
  561. )
  562. const formData = {
  563. ...this.editForm,
  564. areaCode: task.areaCode,
  565. }
  566. // 合并开始时间和结束时间为timePeriod格式
  567. formData.timePeriod = `${formData.startTime}-${formData.endTime}`
  568. // 删除单独的时间字段,避免后端接收多余数据
  569. delete formData.startTime
  570. delete formData.endTime
  571. if (formData.id) {
  572. this.updateMemo(formData)
  573. } else {
  574. this.addMemo(formData)
  575. }
  576. } else {
  577. console.log('表单验证失败')
  578. }
  579. })
  580. },
  581. // 添加备忘录
  582. async addMemo(formData) {
  583. try {
  584. const res = await addMemo(formData)
  585. if (res.code == 200) {
  586. this.$message.success('添加成功')
  587. this.handleSearch()
  588. this.isEditDialogOpen = false
  589. }
  590. } catch (error) {
  591. console.error('添加失败:', error)
  592. this.$message.error('添加失败')
  593. }
  594. },
  595. // 更新备忘录
  596. async updateMemo(formData) {
  597. delete formData.day
  598. delete formData.projectName
  599. try {
  600. const res = await updateMemo(formData)
  601. if (res.code == 200) {
  602. this.$message.success('更新成功')
  603. this.handleSearch()
  604. this.isEditDialogOpen = false
  605. }
  606. } catch (error) {
  607. console.error('更新失败:', error)
  608. this.$message.error('更新失败')
  609. }
  610. },
  611. // 设置日历标题
  612. setCalendarTitle() {
  613. // 可以在这里添加设置日历标题的逻辑
  614. let lunarInfo = this.lunarInfo
  615. return `${lunarInfo.cYear}年${lunarInfo.cMonth}月 农历${lunarInfo.gzYear}年【${lunarInfo.Animal}】`
  616. },
  617. },
  618. }