LogMonitorDetail.vue 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <div class="main_container custom_container">
  3. <div class="page_item top_header">
  4. <el-button class="button_default_background" @click="router.go(-1)">
  5. <el-icon class="img"><ArrowLeftBold /></el-icon>
  6. 返回
  7. </el-button>
  8. <div class="people_info">
  9. <div>
  10. <span class="label">学校:</span>
  11. <span class="value">{{ detailParams.schoolName }}</span>
  12. </div>
  13. <div>
  14. <span class="label">账户:</span>
  15. <span class="value">{{ detailParams.userAccount }}</span>
  16. </div>
  17. <div><span class="label">姓名:</span>
  18. <span class="value">{{ detailParams.userName }}</span>
  19. </div>
  20. </div>
  21. <div class="page_search" >
  22. <div class="search_content">
  23. <div class="content_left">
  24. <FormSearchGroup :searchList="peopleLogSearchList" @searchChange="handleSearchChange"></FormSearchGroup>
  25. </div>
  26. <div class="content_right">
  27. <div class="desc">
  28. 默认展示最近3天操作记录
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. <div class="page_jg_20"></div>
  35. <div class="page_item end_item">
  36. <HonorTimeLine :honorList="peopleLogList"></HonorTimeLine>
  37. </div>
  38. </div>
  39. </template>
  40. <script setup lang="ts">
  41. import { ref, reactive, onMounted } from 'vue';
  42. import { useRoute, useRouter } from 'vue-router';
  43. import { ArrowLeftBold } from '@element-plus/icons-vue';
  44. import { ElMessage } from 'element-plus';
  45. import FormSearchGroup from '@/baseComponents/FormSearchGroup.vue';
  46. import { peopleLogSearchList } from './formSearchGroup';
  47. import HonorTimeLine from '@/baseComponents/HonorTimeLine.vue';
  48. import { getLogDetailApi } from '@/api/logMonitor';
  49. const route = useRoute()
  50. const router = useRouter()
  51. const detailParams = reactive({
  52. schoolId: 0,
  53. userId: 0,
  54. accountTypeCode: 0,
  55. moduleCode: 0,
  56. schoolName: '',
  57. userAccount: '',
  58. userName: '',
  59. })
  60. // 详情搜索参数
  61. const detailSearchParams = reactive({
  62. startTime: '',
  63. endTime: '',
  64. })
  65. const peopleLogList = ref<any[]>([])
  66. // 获取日志详情
  67. const getLogDetailData = async () => {
  68. try {
  69. const params = {
  70. schoolId: detailParams.schoolId,
  71. userId: detailParams.userId,
  72. accountTypeCode: detailParams.accountTypeCode,
  73. moduleCode: detailParams.moduleCode,
  74. startTime: detailSearchParams.startTime,
  75. endTime: detailSearchParams.endTime,
  76. }
  77. const res = await getLogDetailApi(params)
  78. const data = res.data || res
  79. peopleLogList.value = (data || []).map((item: any, index: number) => ({
  80. id: String(index),
  81. awardDatetime: item.createTime || '',
  82. certPicUrl: '',
  83. honorTypeName: '',
  84. honorName: item.operation || '',
  85. teacherName: item.ip || '',
  86. radioData: [],
  87. inputData: [],
  88. createdAt: item.createTime || '',
  89. reviewStatus: '',
  90. }))
  91. } catch (err) {
  92. console.error('getLogDetailApi 请求失败:', err)
  93. }
  94. }
  95. // 处理搜索变化
  96. const handleSearchChange = (data: Record<string, any>, key: string) => {
  97. if (key === 'dateRange') {
  98. const range = data.dateRange
  99. if (Array.isArray(range) && range.length === 2 && range[0] && range[1]) {
  100. const start = new Date(range[0])
  101. const end = new Date(range[1])
  102. const diffDays = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24))
  103. if (diffDays > 30) {
  104. ElMessage.warning('日志选择最大范围30天')
  105. return
  106. }
  107. detailSearchParams.startTime = formatDateTime(start, true)
  108. detailSearchParams.endTime = formatDateTime(end, false)
  109. } else {
  110. detailSearchParams.startTime = ''
  111. detailSearchParams.endTime = ''
  112. }
  113. }
  114. getLogDetailData()
  115. }
  116. // 格式化日期时间,isStart为true时返回 00:00:00,为false时返回 23:59:59
  117. const formatDateTime = (date: Date, isStart: boolean) => {
  118. if (!date) return ''
  119. const year = date.getFullYear()
  120. const month = String(date.getMonth() + 1).padStart(2, '0')
  121. const day = String(date.getDate()).padStart(2, '0')
  122. const time = isStart ? '00:00:00' : '23:59:59'
  123. return `${year}-${month}-${day} ${time}`
  124. }
  125. // 获取默认日期范围(最近3天)
  126. const getDefaultDateRange = () => {
  127. const end = new Date()
  128. const start = new Date()
  129. start.setDate(start.getDate() - 2)
  130. return [start, end]
  131. }
  132. // 初始化
  133. onMounted(() => {
  134. detailParams.schoolId = Number(route.query.schoolId) || 0
  135. detailParams.userId = Number(route.query.userId) || 0
  136. detailParams.accountTypeCode = Number(route.query.accountTypeCode) || 0
  137. detailParams.moduleCode = Number(route.query.moduleCode) || 0
  138. detailParams.schoolName = (route.query.schoolName as string) || ''
  139. detailParams.userAccount = (route.query.userAccount as string) || ''
  140. detailParams.userName = (route.query.userName as string) || ''
  141. // 默认最近3天
  142. const defaultRange = getDefaultDateRange()
  143. peopleLogSearchList.value[0].defaultValue = defaultRange
  144. detailSearchParams.startTime = formatDateTime(defaultRange[0], true)
  145. detailSearchParams.endTime = formatDateTime(defaultRange[1], false)
  146. getLogDetailData()
  147. })
  148. </script>
  149. <style lang="scss" scoped>
  150. .top_header{
  151. display: flex;
  152. align-items: center;
  153. justify-content: space-between;
  154. gap:20px;
  155. padding:10px 20px;
  156. .people_info{
  157. flex-shrink: 0;
  158. display: flex;
  159. gap:20px;
  160. font-size: 14px;
  161. .label{
  162. color:#333;
  163. font-weight: 600;
  164. }
  165. .value{
  166. color: #999;
  167. }
  168. }
  169. .page_search{
  170. .search_content{
  171. justify-content: flex-end;
  172. gap:20px;
  173. .content_right{
  174. .desc{
  175. font-size: 14px;
  176. }
  177. }
  178. }
  179. }
  180. }
  181. </style>