dataListModal.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. <template>
  2. <!-- 弹窗组件 -->
  3. <el-dialog v-model="dialogVisible" title="数据信息(23)" width="860px" @close="onClose">
  4. <!-- 弹窗头部:搜索区域 -->
  5. <div class="dialog-header">
  6. <el-form :inline="true" :model="searchForm" @keyup.enter="handleSearch">
  7. <el-form-item label="关键词">
  8. <el-input
  9. v-model="searchForm.keyWord"
  10. placeholder="请输入关键词查找"
  11. />
  12. </el-form-item>
  13. <el-form-item label="时间范围">
  14. <el-date-picker
  15. v-model="searchForm.timeRange"
  16. type="datetimerange"
  17. value-format="YYYY-MM-DD HH:mm:ss"
  18. start-placeholder="选择开始时间"
  19. end-placeholder="选择结束时间"
  20. style="width: 200px;"
  21. />
  22. </el-form-item>
  23. <el-form-item>
  24. <el-button type="primary" icon="search" @click="handleSearch">
  25. 查询
  26. </el-button>
  27. <el-button @click="resetQuery" icon="Refresh">重置</el-button>
  28. </el-form-item>
  29. </el-form>
  30. </div>
  31. <!-- 弹窗内容:富文本信息列表 -->
  32. <div class="dialog-content">
  33. <div v-loading="loading">
  34. <div
  35. v-for="(item, index) in dataList"
  36. :key="item.id"
  37. class="data-item"
  38. :class="{ 'even': index % 2 === 0, 'odd': index % 2 === 1 }"
  39. title="点击查看数据详情"
  40. @click="handleOpenDialog(item)"
  41. >
  42. <div class="rich-content" v-html="item.msgData"></div>
  43. <div class="item-time">{{ formatTime(item.reportTime) }}</div>
  44. </div>
  45. <!-- 无数据提示 -->
  46. <el-empty v-if="dataList.length === 0" description="暂无数据" />
  47. </div>
  48. </div>
  49. <!-- 弹窗页脚:分页器 -->
  50. <div class="dialog-footer">
  51. <el-pagination
  52. @current-change="handleCurrentChange"
  53. @size-change="handleSizeChange"
  54. :current-page="pagination.current"
  55. :page-size="pagination.size"
  56. :total="pagination.total"
  57. layout="total, prev, pager, next, jumper"
  58. background
  59. />
  60. </div>
  61. </el-dialog>
  62. <dataInfoModal ref="richContentDialogRef"></dataInfoModal>>
  63. </template>
  64. <script lang="ts" setup>
  65. import { ref, reactive } from 'vue'
  66. import { useI18n } from 'vue-i18n'
  67. import { getDataPage } from '/@/api/marketing/data';
  68. // 使用国际化
  69. const { t } = useI18n()
  70. // 详情弹窗
  71. const dataInfoModal = defineAsyncComponent(() => import('./dataInfoModal.vue'))
  72. const richContentDialogRef = ref()
  73. const handleOpenDialog = (item: any) => {
  74. richContentDialogRef.value.openDialog(
  75. item.msgData,
  76. {
  77. createTime: item.reportTime
  78. }
  79. )
  80. }
  81. // 弹窗可见性
  82. const dialogVisible = ref(false)
  83. // 加载状态
  84. const loading = ref(false)
  85. // 搜索表单
  86. const searchForm = reactive({
  87. keyWord: '',
  88. timeRange: null as null | [Date, Date]
  89. })
  90. // 清空搜索条件
  91. const resetQuery = () => {
  92. searchForm.keyWord = ''
  93. searchForm.timeRange = null
  94. pagination.current = 1
  95. dataList.value = []
  96. fetchData();
  97. }
  98. const clientID = ref('')
  99. // 数据列表
  100. const dataList = ref<any[]>([])
  101. // 分页信息
  102. const pagination = reactive({
  103. current: 1,
  104. size: 5, // 每页5条信息
  105. total: 0
  106. })
  107. // 打开弹窗方法
  108. const openDialog = (id: string) => {
  109. dialogVisible.value = true
  110. clientID.value = id
  111. fetchData()
  112. }
  113. // 关闭弹窗
  114. const onClose = () => {
  115. // 重置表单
  116. searchForm.keyWord = ''
  117. searchForm.timeRange = null
  118. pagination.current = 1
  119. dataList.value = []
  120. }
  121. // 格式化时间
  122. const formatTime = (time: string | Date) => {
  123. if (!time) return '--'
  124. const date = new Date(time)
  125. return date.toLocaleString()
  126. }
  127. // 搜索处理
  128. const handleSearch = () => {
  129. pagination.current = 1
  130. fetchData()
  131. }
  132. // 获取数据方法(需要根据实际API调整)
  133. const fetchData = async () => {
  134. loading.value = true
  135. try {
  136. // 这里需要替换为实际的API调用
  137. // 示例数据结构,根据实际API调整
  138. const params = {
  139. keyWord: searchForm.keyWord,
  140. startTime: searchForm.timeRange ? searchForm.timeRange[0] : null,
  141. endTime: searchForm.timeRange ? searchForm.timeRange[1] : null,
  142. current: pagination.current,
  143. size: pagination.size,
  144. clientID: clientID.value
  145. }
  146. // 模拟API调用
  147. const res = await getDataPage(params)
  148. dataList.value = res.data.records
  149. pagination.total = res.data.total
  150. } catch (error) {
  151. console.error('获取数据失败:', error)
  152. } finally {
  153. loading.value = false
  154. }
  155. }
  156. // 分页变化处理
  157. const handleCurrentChange = (val: number) => {
  158. pagination.current = val
  159. fetchData()
  160. }
  161. // 每页大小变化处理
  162. const handleSizeChange = (val: number) => {
  163. pagination.size = val
  164. pagination.current = 1
  165. fetchData()
  166. }
  167. // 暴露方法给父组件
  168. defineExpose({
  169. openDialog
  170. })
  171. </script>
  172. <style scoped lang="scss">
  173. .dialog-header {
  174. margin-bottom: 20px;
  175. padding-bottom: 15px;
  176. border-bottom: 1px solid #eee;
  177. }
  178. .dialog-content {
  179. min-height: 300px;
  180. max-height: 400px;
  181. overflow-y: auto;
  182. }
  183. .data-item {
  184. padding: 15px;
  185. margin-bottom: 15px;
  186. border-radius: 4px;
  187. position: relative;
  188. cursor: pointer;
  189. &.even {
  190. background-color: #fafafa;
  191. }
  192. &.odd {
  193. background-color: #fff;
  194. }
  195. &:last-child {
  196. margin-bottom: 0;
  197. }
  198. }
  199. .rich-content {
  200. margin-bottom: 10px;
  201. line-height: 1.6;
  202. max-height: 150px;
  203. overflow-y: hidden;
  204. :deep(h4) {
  205. margin: 0 0 10px 0;
  206. color: #333;
  207. }
  208. :deep(p) {
  209. margin: 0;
  210. color: #666;
  211. }
  212. }
  213. .item-time {
  214. text-align: right;
  215. font-size: 12px;
  216. color: #999;
  217. }
  218. .dialog-footer {
  219. margin-top: 20px;
  220. padding-top: 15px;
  221. border-top: 1px solid #eee;
  222. display: flex;
  223. justify-content: center;
  224. }
  225. :deep(.el-pagination) {
  226. margin: 0;
  227. }
  228. </style>