dossierDetail.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <div class="app-container p-2">
  3. <el-row :gutter="20">
  4. <el-col :lg="30" :xs="24" style="">
  5. <el-row :span="24" :gutter="10">
  6. <el-col :span="18" label="任务名称">
  7. <h2 v-if="detailData.title" key="business" style="font-weight: bolder">{{ detailData.title }}</h2>
  8. <p class="report-period">【填报周期】:{{ detailData.start }} 至 {{ detailData.end }}</p>
  9. </el-col>
  10. <el-col v-if="props.collectionStatus === '0'" :span="1.5">
  11. <el-button type="primary" @click="handleWrite()"> 收取 </el-button>
  12. </el-col>
  13. <el-col :span="1.5">
  14. <el-button type="danger" @click="handleReturn()"> 返回 </el-button>
  15. </el-col>
  16. </el-row>
  17. </el-col>
  18. <el-col :lg="30" :xs="24">
  19. <!-- <el-table :data="tableData" border>-->
  20. <!-- <el-table-column v-for="header in editableHeaders" :key="header.prop" :label="header.label" :prop="header.prop">-->
  21. <!-- <template #header="{ column }">-->
  22. <!-- <span class="editable-header" v-text="column.label"></span>-->
  23. <!-- </template>-->
  24. <!-- <template #default="{ row, $index }">-->
  25. <!-- <span class="editable-span" v-text="row[header.prop]"></span>-->
  26. <!-- </template>-->
  27. <!-- </el-table-column>-->
  28. <!-- </el-table>-->
  29. <div :style="{ height: tableHeight + 'px' }">
  30. <hot-table ref="wrapper" :data="tableData" :settings="hotSettings" />
  31. </div>
  32. </el-col>
  33. </el-row>
  34. </div>
  35. </template>
  36. <script setup lang="ts">
  37. import { ref, onMounted } from 'vue';
  38. import { ElTable, ElButton, ElCol, ElRow, ElTableColumn, ElMessageBox } from 'element-plus';
  39. import * as XLSX from 'xlsx';
  40. import { fillDetail, collectList } from '@/api/dataFilling/fileManagement';
  41. import { HotTable } from '@handsontable/vue3';
  42. import 'handsontable/languages';
  43. import 'handsontable/dist/handsontable.full.css';
  44. import { registerAllModules } from 'handsontable/registry';
  45. registerAllModules();
  46. const emits = defineEmits(['close', 'refresh']);
  47. const props = defineProps({
  48. eventId: String,
  49. tableName: String,
  50. collectionStatus: String
  51. });
  52. //初始化表头和表格数据
  53. const editableHeaders = ref([]);
  54. const tableData = ref([]);
  55. const detailData = ref({
  56. title: '',
  57. start: '',
  58. end: ''
  59. });
  60. let tableHeight = window.innerHeight - 230
  61. let wrapper = ref();
  62. onMounted(() => {
  63. fetchFillDetail();
  64. });
  65. const editableHeadersList = ref([]);
  66. const fetchFillDetail = async () => {
  67. try {
  68. const res = await fillDetail({ report_id: props.eventId });
  69. // 动态设置表头
  70. editableHeaders.value = res.columns;
  71. // 转换表格数据格式以匹配表头
  72. detailData.value.start = res.start_time;
  73. detailData.value.end = res.end_time;
  74. editableHeaders.value.forEach((header) => {
  75. editableHeadersList.value.push(header.label)
  76. })
  77. let arr1 = []
  78. // tableData.value = response.tableData;
  79. //如果tableData是空就用下满这段,tableData有数据就用tableData的内容
  80. if (!res.rows || res.rows.length === 0) {
  81. editableHeadersList.value.forEach((item) => {
  82. arr1.push('');
  83. })
  84. tableData.value = [arr1];
  85. wrapper.value.hotInstance.loadData([arr1]);
  86. } else {
  87. tableData.value = res.rows.map((row) => {
  88. const formattedRow = {};
  89. editableHeaders.value.forEach((header) => {
  90. formattedRow[header.prop] = row[header.prop];
  91. });
  92. return formattedRow;
  93. });
  94. wrapper.value.hotInstance.loadData(tableData.value);
  95. }
  96. wrapper.value.hotInstance.loadData(tableData.value);
  97. } catch (error) {
  98. console.error('Error fetching data:', error);
  99. }
  100. };
  101. // //收取
  102. // const handleWrite = () => {
  103. // if (props.eventId && props.eventId !== '') {
  104. // const data = {
  105. // report_id: props.eventId,
  106. // creator_id: 3,
  107. // new_status: 2
  108. // };
  109. // collectList(data)
  110. // .then((response) => {
  111. // if (response.code === 200) {
  112. // console.log(response.msg);
  113. // } else {
  114. // console.error('更新失败', response.msg);
  115. // }
  116. // })
  117. // .catch((error) => {
  118. // console.error('请求失败', error);
  119. // });
  120. // }
  121. // };
  122. // 收取
  123. const handleWrite = () => {
  124. ElMessageBox.confirm('收取后,表格不可再填报,确认是否收取?', '提示', {
  125. confirmButtonText: '确认',
  126. cancelButtonText: '取消',
  127. type: 'warning'
  128. })
  129. .then(() => {
  130. if (props.eventId && props.eventId !== '') {
  131. const data = {
  132. report_id: props.eventId,
  133. creator_id: 3,
  134. new_status: 2
  135. };
  136. collectList(data)
  137. .then((response) => {
  138. if (response.code === 200) {
  139. console.log(response.msg);
  140. // 更新 collectionStatus 为 '2'(已收取)
  141. emits('update:collectionStatus', '2');
  142. } else {
  143. console.error('更新失败', response.msg);
  144. }
  145. })
  146. .catch((error) => {
  147. console.error('请求失败', error);
  148. });
  149. }
  150. })
  151. .catch(() => {
  152. // 用户点击了取消按钮
  153. console.log('取消收取');
  154. });
  155. emits('refresh');
  156. };
  157. const handleReturn = () => {
  158. emits('close');
  159. };
  160. const hotSettings = reactive({
  161. language: 'zh-CN',
  162. readOnly: true,
  163. colHeaders: editableHeadersList,
  164. rowHeaders: true,
  165. autoColumnSize: true,
  166. width: '100%', // auto or 100%
  167. height: '100%', // auto or 100%
  168. licenseKey: 'non-commercial-and-evaluation', // 隐藏版权文字
  169. colWidths: 129, // 默认单元格宽度
  170. rowHeights: 28, // 默认单元格高度
  171. wordWrap: true, // 单元格文字是否换行展示
  172. contextMenu: {
  173. // 自定义右键菜单
  174. items: {
  175. 'row_above': {
  176. name: '向上插一行'
  177. },
  178. 'row_below': {
  179. name: '向下插一行'
  180. },
  181. 'col_left': {
  182. name: '向左插一列'
  183. },
  184. 'col_right': {
  185. name: '向右插一列'
  186. },
  187. 'hsep1': '---------', // 分隔线
  188. 'remove_row': {
  189. name: '删除当前行'
  190. },
  191. 'remove_col': {
  192. name: '删除当前列'
  193. },
  194. 'clear_column': {
  195. name: '清空当前列'
  196. },
  197. 'hsep2': '---------', // 必须和上次的变量名不一样
  198. 'undo': {
  199. name: '撤销'
  200. },
  201. 'cut': {
  202. name: '剪切'
  203. },
  204. 'copy': {
  205. name: '复制'
  206. },
  207. 'alignment': {
  208. name: '对齐'
  209. },
  210. 'hsep3': '---------',
  211. 'commentsAddEdit': {
  212. // 必须开启 comments: true
  213. name: '添加备注'
  214. },
  215. 'commentsRemove': {
  216. // 必须开启 comments: true
  217. name: '删除备注'
  218. },
  219. 'freeze_column': {
  220. // 必须开启 manualColumnFreeze: true
  221. name: '固定列'
  222. },
  223. 'unfreeze_column': {
  224. // 必须开启 manualColumnFreeze: true
  225. name: '取消固定列'
  226. }
  227. }
  228. }
  229. });
  230. </script>
  231. <style scoped>
  232. .app-container {
  233. font-family: Avenir, Helvetica, Arial, sans-serif;
  234. -webkit-font-smoothing: antialiased;
  235. -moz-osx-font-smoothing: grayscale;
  236. color: #2c3e50;
  237. }
  238. .report-period {
  239. margin-top: 10px;
  240. font-size: 14px;
  241. color: #606266;
  242. }
  243. .editable-span {
  244. cursor: default;
  245. }
  246. .editable-header {
  247. cursor: default;
  248. }
  249. </style>