index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <template>
  2. <div>
  3. <div class="app-container">
  4. <div v-show="!dialog.visible && !knowledgeDetailState.show">
  5. <transition name="fade">
  6. <div v-show="showSearch">
  7. <el-form ref="queryFormRef" :model="queryParams">
  8. <el-row :gutter="20">
  9. <!-- 第一行 -->
  10. <el-col :span="6">
  11. <el-form-item label="事件类型:" prop="eventType">
  12. <el-select v-model="queryParams.eventType" placeholder="全部" clearable>
  13. <el-option label="全部" value=""></el-option>
  14. <el-option v-for="item in eventTypeSelection" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
  15. </el-select>
  16. </el-form-item>
  17. </el-col>
  18. <el-col :span="6">
  19. <el-form-item label="发布日期:" prop="publishDate">
  20. <el-date-picker
  21. v-model="queryParams.publishDate"
  22. type="daterange"
  23. range-separator="-"
  24. start-placeholder="开始日期"
  25. end-placeholder="结束日期"
  26. value-format="YYYY-MM-DD"
  27. ></el-date-picker>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="6">
  31. <el-form-item>
  32. <el-input v-model="queryParams.query" placeholder="请输入报告的名称" clearable @keyup.enter="handleQuery" />
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="6">
  36. <el-form-item>
  37. <el-button type="primary" @click="handleQuery">搜索</el-button>
  38. <el-button @click="resetQuery">重置</el-button>
  39. </el-form-item>
  40. </el-col>
  41. </el-row>
  42. </el-form>
  43. </div>
  44. </transition>
  45. <el-row :gutter="10" class="mb8">
  46. <el-col :span="1.5">
  47. <el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
  48. </el-col>
  49. <el-col :span="1.5">
  50. <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate(selectedRow)">修改</el-button>
  51. </el-col>
  52. <el-col :span="1.5">
  53. <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete(selectedRow)">删除</el-button>
  54. </el-col>
  55. <el-col :span="1.5">
  56. <el-button type="warning" plain icon="Download" @click="handleExport">导出</el-button>
  57. </el-col>
  58. <!-- <right-toolbar v-model:showSearch="showSearch" @query-table="getList"></right-toolbar>-->
  59. </el-row>
  60. <!-- 表格组件 -->
  61. <el-table v-loading="loading" :data="demoList" @selection-change="handleSelectionChange">
  62. <el-table-column type="selection" width="55" align="center" />
  63. <el-table-column label="报告编号" align="center" prop="reportId" />
  64. <el-table-column label="报告名称" align="center" prop="reportName" />
  65. <el-table-column label="主题词" align="center" prop="subject" />
  66. <el-table-column label="事件类型" align="center" prop="eventType">
  67. <template #default="scope">
  68. <dict-tag :options="mm_event_type" :value="scope.row.eventType" />
  69. </template>
  70. </el-table-column>
  71. <el-table-column label="摘要" align="center" prop="summary" />
  72. <el-table-column label="来源单位" align="center" prop="publishingUnit" />
  73. <el-table-column label="发布日期" align="center" prop="publishDate" />
  74. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  75. <template #default="scope">
  76. <el-text class="common-btn-text-primary" @click="handleView(scope.row)">查看</el-text>
  77. <el-text class="common-btn-text-primary" @click="handleUpdate(scope.row)">修改</el-text>
  78. <el-text class="common-btn-text-danger" @click="handleDelete(scope.row)">删除</el-text>
  79. </template>
  80. </el-table-column>
  81. </el-table>
  82. <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
  83. </div>
  84. <!-- 新增/修改弹窗 -->
  85. <div v-show="dialog.visible" class="common-dialog">
  86. <div class="common-dialog-content">
  87. <div class="common-dialog-title-box">
  88. <i class="common-dialog-title-icon" />
  89. <div>{{ dialog.title }}</div>
  90. </div>
  91. <div class="common-dialog-box">
  92. <el-form ref="demoFormRef" :model="form" :rules="rules" label-width="80px">
  93. <el-form-item label="报告名称:" prop="reportName">
  94. <el-input v-model="form.reportName" placeholder="请输入报告名称" style="width: 468px !important" />
  95. </el-form-item>
  96. <el-form-item label="主题词:" prop="subject">
  97. <el-input v-model="form.subject" placeholder="请输入主题词" style="width: 468px !important" />
  98. </el-form-item>
  99. <el-form-item label="事件类型:" prop="eventType">
  100. <el-select v-model="form.eventType" placeholder="请选择事件类型" clearable style="width: 468px !important">
  101. <el-option v-for="item in eventTypeSelection" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
  102. </el-select>
  103. </el-form-item>
  104. <el-form-item label="摘要:" prop="summary">
  105. <el-input v-model="form.summary" placeholder="请输入摘要" style="width: 468px !important" />
  106. </el-form-item>
  107. <el-form-item label="来源单位:" prop="publishingUnit">
  108. <el-input v-model="form.publishingUnit" placeholder="请输入来源单位" style="width: 468px !important" />
  109. </el-form-item>
  110. <el-form-item label="发布日期:" prop="publishDate">
  111. <el-date-picker v-model="form.publishDate" type="datetime" placeholder="选择发布日期" style="width: 468px !important"></el-date-picker>
  112. </el-form-item>
  113. <el-col :span="1.5">
  114. <!-- 使用分片上传组件,每个分片 -->
  115. <!-- <chunk-upload ref="chunkUploadRef" :max-file-size="50 * 1024 * 1024" :max-files="5" />-->
  116. <FileUpload v-model="form.fileNames" />
  117. </el-col>
  118. </el-form>
  119. </div>
  120. <div class="common-dialog-footer" style="display: flex; justify-content: center">
  121. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确定</el-button>
  122. <el-button @click="cancel">取消</el-button>
  123. </div>
  124. </div>
  125. </div>
  126. </div>
  127. <KnowledgeDetail v-if="knowledgeDetailState.show" :reportId="knowledgeDetailState.reportId" @close="handleKnowledgeDetailClose"></KnowledgeDetail>
  128. </div>
  129. </template>
  130. <script setup lang="ts">
  131. import { ref, reactive, onMounted } from 'vue';
  132. import { ElMessage } from 'element-plus';
  133. import { fetchReports, addReport, updateReport, deleteReport } from '@/api/knowledge';
  134. import { AddReportParams, QueryParams, ReportItem } from '@/api/knowledge/types';
  135. // import ChunkUpload from '@/components/ChunkUpload/index.vue';
  136. import { getDicts } from '@/api/system/dict/data';
  137. import router from '@/router';
  138. import axios, { AxiosError, isAxiosError } from 'axios';
  139. import KnowledgeDetail from './detail.vue';
  140. const demoFormRef = ref(null);
  141. const demoList = ref<ReportItem[]>([]);
  142. const buttonLoading = ref(false);
  143. const loading = ref(true);
  144. const showSearch = ref(true);
  145. const ids = ref<string[]>([]);
  146. const single = ref(true);
  147. const multiple = ref(true);
  148. const total = ref(0);
  149. const selectedRow = ref<ReportItem | null>(null);
  150. let proxy = getCurrentInstance()?.proxy;
  151. const { mm_event_type } = toRefs<any>(proxy?.useDict('mm_event_type'));
  152. const chunkUploadRef = ref(null);
  153. // 这是是查询条件
  154. const queryParams = reactive<QueryParams>({
  155. query: '',
  156. pageNum: 1,
  157. pageSize: 10,
  158. eventType: '',
  159. publishDate: ['', ''],
  160. subject: '',
  161. sortBy: 'publishDate',
  162. sortOrder: 'desc',
  163. publishDateRange: ''
  164. });
  165. // 表单数据
  166. const form = reactive<AddReportParams>({
  167. reportName: '',
  168. subject: '',
  169. eventType: '',
  170. summary: '',
  171. publishingUnit: '',
  172. publishDate: '',
  173. fileNames: []
  174. });
  175. const rules = reactive({
  176. reportName: [{ required: true, message: '报告名称不能为空', trigger: 'blur' }],
  177. subject: [{ required: true, message: '主题词不能为空', trigger: 'blur' }],
  178. eventType: [{ required: true, message: '事件类型不能为空', trigger: 'blur' }],
  179. summary: [{ required: true, message: '摘要不能为空', trigger: 'blur' }],
  180. publishingUnit: [{ required: true, message: '来源单位不能为空', trigger: 'blur' }],
  181. publishDate: [{ required: true, message: '发布日期不能为空', trigger: 'blur' }]
  182. });
  183. const eventTypeSelection = ref([]);
  184. const dialog = reactive({
  185. visible: false,
  186. title: ''
  187. });
  188. let knowledgeDetailState = reactive({
  189. show: false,
  190. reportId: ''
  191. });
  192. // getLists是获取列表数据的方法
  193. const getList = async () => {
  194. // 开始加载数据
  195. loading.value = true;
  196. try {
  197. // 这里格式化日期范围参数
  198. // 将-分割转换为/分割
  199. const [startDate, endDate] = queryParams.publishDate;
  200. const formattedStartDate = startDate ? startDate.replace(/-/g, '/') : '';
  201. const formattedEndDate = endDate ? endDate.replace(/-/g, '/') : '';
  202. const publishDateRange = formattedStartDate && formattedEndDate ? `${formattedStartDate}-${formattedEndDate}` : '';
  203. // 构建新的请求参数对象
  204. const requestParams = {
  205. ...queryParams,
  206. publishDateRange, // 添加新的日期范围参数
  207. publishDate: undefined // 移除原来的 publishDate 参数
  208. };
  209. // 发送请求
  210. const response = await fetchReports(requestParams);
  211. if (response && response.code === 200) {
  212. // demoLIst是ref对象,需要通过.value赋值
  213. demoList.value = response.data.map((item: ReportItem) => {
  214. return {
  215. ...item,
  216. publishDate: item.publishDate.replace('T', ' ')
  217. };
  218. });
  219. total.value = response.total;
  220. queryParams.pageNum = response.currentPage; // 确保currentPage赋值
  221. queryParams.pageSize = response.pageSize; // 确保pageSize赋值
  222. } else {
  223. console.error('数据格式不匹配:', response);
  224. throw new Error(response.msg || '响应数据格式不正确');
  225. }
  226. } catch (error) {
  227. console.error('获取数据时出错:', error);
  228. ElMessage.error('获取数据失败');
  229. } finally {
  230. loading.value = false;
  231. }
  232. };
  233. // 查询
  234. const handleQuery = () => {
  235. queryParams.pageNum = 1;
  236. getList();
  237. };
  238. // 重置查询条件
  239. const resetQuery = () => {
  240. queryParams.pageNum = 1;
  241. queryParams.pageSize = 10;
  242. queryParams.eventType = '';
  243. queryParams.publishDate = ['', ''];
  244. queryParams.subject = '';
  245. queryParams.sortBy = 'publishDate'; // 重置排序字段
  246. queryParams.sortOrder = 'desc'; // 重置排序方式
  247. queryParams.query = '';
  248. getList();
  249. };
  250. // 多选框选中数据
  251. const handleSelectionChange = (selection: ReportItem[]) => {
  252. ids.value = selection.map((item) => item.reportId);
  253. selectedRow.value = selection.length === 1 ? selection[0] : null;
  254. single.value = selection.length != 1;
  255. multiple.value = !selection.length;
  256. };
  257. // 新增报告
  258. const handleAdd = () => {
  259. resetForm();
  260. dialog.visible = true;
  261. dialog.title = '添加报告';
  262. };
  263. // 修改报告
  264. const handleUpdate = (row: ReportItem) => {
  265. if (row) {
  266. selectedRow.value = row;
  267. resetForm();
  268. Object.assign(form, row);
  269. dialog.visible = true;
  270. dialog.title = '修改报告';
  271. }
  272. };
  273. // 删除报告
  274. const handleDelete = async (row: ReportItem) => {
  275. ElMessageBox.confirm('此操作将永久删除该报告, 是否继续?', '提示', {
  276. confirmButtonText: '确定',
  277. cancelButtonText: '取消',
  278. type: 'warning'
  279. })
  280. .then(() => {
  281. deleteReport(row.reportId);
  282. ElMessage({
  283. type: 'success',
  284. message: '报告已删除'
  285. });
  286. getList();
  287. })
  288. .catch(() => {
  289. ElMessage({
  290. type: 'info',
  291. message: '已取消删除'
  292. });
  293. });
  294. /*
  295. try {
  296. await deleteReport(row.reportId);
  297. ElMessage.success('删除成功');
  298. getList();
  299. } catch (error) {
  300. ElMessage.error('删除失败');
  301. }
  302. */
  303. };
  304. // 详情页
  305. const handleView = (row: ReportItem) => {
  306. knowledgeDetailState.reportId = row.reportId;
  307. knowledgeDetailState.show = true;
  308. //router.push({
  309. // path: `/knowledge/knowledge-management/detail`,
  310. // query: { reportID: row.reportId }
  311. //});
  312. };
  313. const handleKnowledgeDetailClose = () => {
  314. knowledgeDetailState.show = false;
  315. }
  316. // 格式化日期
  317. const formatDate = (date: Date): string => {
  318. const yyyy = date.getFullYear();
  319. const mm = String(date.getMonth() + 1).padStart(2, '0'); // 月份以0为基数
  320. const dd = String(date.getDate()).padStart(2, '0');
  321. const hh = String(date.getHours()).padStart(2, '0');
  322. const min = String(date.getMinutes()).padStart(2, '0');
  323. const ss = String(date.getSeconds()).padStart(2, '0');
  324. return `${yyyy}-${mm}-${dd} ${hh}:${min}:${ss}`;
  325. };
  326. // 提交表单
  327. const submitForm = () => {
  328. demoFormRef.value?.validate(async (valid: boolean) => {
  329. if (valid) {
  330. buttonLoading.value = true;
  331. try {
  332. // 格式化日期为后端所需的格式
  333. form.publishDate = formatDate(new Date(form.publishDate));
  334. // 打印发送的数据,检查格式是否正确
  335. console.log(dialog.title, '提交给后端的 JSON 数据:', JSON.stringify(form, null, 2));
  336. if (dialog.title === '修改报告' && selectedRow.value) {
  337. const updateData = {
  338. ...form,
  339. reportId: selectedRow.value.reportId
  340. };
  341. console.log('modify:', updateData)
  342. await updateReport(updateData);
  343. ElMessage.success('更新成功');
  344. } else {
  345. await addReport(form);
  346. ElMessage.success('添加成功');
  347. }
  348. dialog.visible = false;
  349. getList(); // 刷新列表
  350. } catch (error) {
  351. if (isAxiosError(error)) {
  352. console.error('后端响应错误:', error.response?.data);
  353. ElMessage.error(`操作失败: ${error.response?.data.message || '未知错误'}`);
  354. } else {
  355. console.error('提交失败:', error);
  356. ElMessage.error('操作失败,无法连接到服务器');
  357. }
  358. } finally {
  359. buttonLoading.value = false;
  360. }
  361. }
  362. });
  363. };
  364. // 重置表单
  365. const resetForm = () => {
  366. Object.assign(form, {
  367. reportName: '',
  368. subject: '',
  369. eventType: '',
  370. summary: '',
  371. publishingUnit: '',
  372. publishDate: '',
  373. fileNames: [] // 也可以清空上传的文件名列表
  374. });
  375. demoFormRef.value?.resetFields();
  376. };
  377. // 取消按钮
  378. const cancel = () => {
  379. resetForm();
  380. dialog.visible = false;
  381. };
  382. const handleExport = () => {
  383. ElMessage.success('导出成功');
  384. };
  385. onMounted(() => {
  386. getList();
  387. getDicts('mm_event_type').then((res) => {
  388. eventTypeSelection.value = res.data;
  389. });
  390. });
  391. </script>