fillingAdd.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. <!-- 联系人姓名 -->
  7. <el-col :span="6">
  8. <el-form-item label="联系人姓名:" prop="table_name" label-width="auto">
  9. <el-input v-model="creator_name" placeholder="请输入联系人姓名"></el-input>
  10. </el-form-item>
  11. </el-col>
  12. <!-- 联系电话 -->
  13. <el-col :span="6">
  14. <el-form-item label="联系电话:" prop="table_phone" label-width="auto">
  15. <el-input v-model="creator_phone" placeholder="请输入联系电话"></el-input>
  16. </el-form-item>
  17. </el-col>
  18. <!-- 选择填报人 -->
  19. <el-col :span="6">
  20. <el-form-item label="选择填报人:" prop="table_name" label-width="auto">
  21. <el-select v-model="selectedReporter" placeholder="请选择填报人">
  22. <el-option v-for="reporter in reporters" :key="reporter.id" :label="reporter.name" :value="reporter.id" />
  23. </el-select>
  24. </el-form-item>
  25. </el-col>
  26. <!-- 截止时间 -->
  27. <el-col :span="6">
  28. <el-form-item label="截止时间:" prop="release_time">
  29. <el-date-picker v-model="selectedTime" type="date" placeholder="选择截止时间" @change="handleTimeChange" />
  30. <span class="label">前报送该表</span>
  31. </el-form-item>
  32. </el-col>
  33. <!-- 操作按钮 -->
  34. <el-col :span="6">
  35. <el-input v-model="table_name" placeholder="请输入表名"></el-input>
  36. </el-col>
  37. <el-col :span="1.5">
  38. <el-button type="primary" @click="handleReport()"> 智能识别 </el-button>
  39. </el-col>
  40. <el-col :span="1.5">
  41. <el-button type="primary" @click="handleSaveTemporarily">暂存</el-button>
  42. </el-col>
  43. <el-col :span="1.5">
  44. <el-button type="primary" @click="handleSave()"> 发布 </el-button>
  45. </el-col>
  46. <el-col :span="1.5">
  47. <el-button type="danger" @click="handleReturn()"> 返回 </el-button>
  48. </el-col>
  49. </el-row>
  50. </el-col>
  51. <el-row :gutter="20" class="mb8">
  52. <el-col :span="1.5">
  53. <el-button type="primary" @click="handleImportExcel">导入Excel文件</el-button>
  54. </el-col>
  55. <el-col :span="1.5">
  56. <el-button type="primary" @click="handleNewTemplate">空白模板</el-button>
  57. </el-col>
  58. <el-col :span="1.5">
  59. <el-button type="primary" @click="handleReload">重新加载</el-button>
  60. </el-col>
  61. </el-row>
  62. <!-- 表格组件 -->
  63. <el-col :lg="30" :xs="24">
  64. <el-table :data="field_names" border>
  65. <el-table-column v-for="header in editableHeaders" :key="header" :label="header" :prop="header">
  66. <template #default="{ row, $index }">
  67. <el-input v-model="row[header]" @blur="saveEdit($index, header, row[header])" />
  68. </template>
  69. </el-table-column>
  70. </el-table>
  71. </el-col>
  72. </el-row>
  73. </div>
  74. </template>
  75. <script setup lang="ts">
  76. import { onMounted, ref } from 'vue';
  77. import { ElButton, ElCol, ElDatePicker, ElFormItem, ElInput, ElOption, ElRow, ElSelect, ElTable, ElTableColumn } from 'element-plus';
  78. import * as XLSX from 'xlsx';
  79. import { fillingAdd } from '@/api/dataFilling/fillingManage';
  80. const emits = defineEmits(['close']);
  81. const detailData = ref({
  82. title: '表单数据',
  83. start: '2024-10-15 17:02:22',
  84. end: '2024-10-15 18:00:00'
  85. });
  86. const field_names = ref([]);
  87. const editableHeaders = ref([]);
  88. const creator_name = ref('');
  89. const creator_phone = ref('');
  90. const selectedReporter = ref(null);
  91. const reporters = ref([]); // 确保这个数组被正确初始化
  92. const selectedTime = ref(null);
  93. const table_name = ref('');
  94. const data_table_name = ref(''); // 假设这是另一个输入字段,需要在模板中添加对应的输入框
  95. const status = ref(0); // 假设这是一个选择器或输入框
  96. const issued_status = ref(0); // 假设这是一个选择器或输入框
  97. const period_type = ref(''); // 假设这是一个输入框或选择器
  98. const creator_id = ref(null); // 这通常是用户ID,可能需要从登录信息中获取
  99. // 初始化表格数据
  100. onMounted(() => {});
  101. function saveEdit(rowIndex, header, value) {
  102. field_names.value[rowIndex][header] = value;
  103. localStorage.setItem('field_names', JSON.stringify(field_names.value));
  104. }
  105. const handleNewTemplate = () => {
  106. // 创建一个新的10x10的数组,每个元素是一个对象,对象的键为列名,值为空字符串
  107. const newHeaders = Array.from({ length: 10 }, (_, index) => `列${String.fromCharCode(65 + index)}`); // 生成列名
  108. field_names.value = Array.from({ length: 10 }, (v, k) => {
  109. const obj = {
  110. 序号: k + 1
  111. };
  112. newHeaders.forEach((header) => {
  113. obj[header] = '';
  114. });
  115. return obj;
  116. });
  117. // 更新editableHeaders
  118. editableHeaders.value = ['序号', ...newHeaders];
  119. alert('空白模板已创建');
  120. };
  121. const handleImportExcel = () => {
  122. const input = document.createElement('input');
  123. input.type = 'file';
  124. input.accept = '.xlsx';
  125. input.onchange = async (e) => {
  126. const file = e.target.files[0];
  127. const reader = new FileReader();
  128. reader.onload = async (e) => {
  129. const data = e.target.result;
  130. const workbook = XLSX.read(data, { type: 'array' });
  131. const firstSheetName = workbook.SheetNames[0];
  132. const worksheet = workbook.Sheets[firstSheetName];
  133. field_names.value = XLSX.utils.sheet_to_json(worksheet);
  134. alert('Excel文件已导入');
  135. };
  136. reader.readAsArrayBuffer(file);
  137. };
  138. input.click();
  139. };
  140. const handleReload = () => {
  141. field_names.value = [];
  142. alert('表格已清空');
  143. };
  144. const handleSaveTemporarily = () => {
  145. localStorage.setItem('field_names', JSON.stringify(field_names.value));
  146. alert('数据已暂存');
  147. };
  148. const handleReport = () => console.log('上报');
  149. const handleSave = async () => {
  150. // 构造要发送的数据对象
  151. const data = {
  152. table_name: table_name.value,
  153. data_table_name: data_table_name.value,
  154. start_time: selectedTime.value ? selectedTime.value.startOfDay.format() : '',
  155. end_time: selectedTime.value ? selectedTime.value.endOfDay.format() : '',
  156. status: status.value,
  157. issued_status: issued_status.value,
  158. period_type: period_type.value,
  159. creator_name: creator_name.value,
  160. creator_id: creator_id.value,
  161. creator_phone: creator_phone.value,
  162. field_names: field_names.value,
  163. user_ids: [] // 这个需要根据实际情况来填充
  164. };
  165. // 保存本地状态
  166. localStorage.setItem('field_names', JSON.stringify(field_names.value));
  167. try {
  168. // 调用fillingAdd接口,传递data作为请求体
  169. const response = await fillingAdd(data);
  170. if (response && response.success) {
  171. alert('数据已成功保存');
  172. } else {
  173. alert('数据保存失败');
  174. }
  175. } catch (error) {
  176. console.error('保存数据失败:', error);
  177. alert('数据保存失败');
  178. }
  179. };
  180. const handleReturn = () => {
  181. emits('close');
  182. };
  183. </script>
  184. <style scoped>
  185. .app-container {
  186. font-family: Avenir, Helvetica, Arial, sans-serif;
  187. -webkit-font-smoothing: antialiased;
  188. -moz-osx-font-smoothing: grayscale;
  189. text-align: center;
  190. color: #2c3e50;
  191. }
  192. .report-period {
  193. margin-top: 10px;
  194. font-size: 14px;
  195. color: #606266;
  196. }
  197. .editable-span {
  198. cursor: pointer;
  199. display: inline-block;
  200. white-space: nowrap;
  201. overflow: hidden;
  202. text-overflow: ellipsis;
  203. }
  204. .editable-span[contenteditable='true'] {
  205. white-space: normal;
  206. outline: none; /* 移除编辑时的焦点边框 */
  207. }
  208. .editable-span[contenteditable='true']:empty::before {
  209. content: attr(data-placeholder); /* 可选:为空时显示占位符 */
  210. color: #999;
  211. }
  212. .editable-header {
  213. cursor: pointer;
  214. display: inline-block;
  215. white-space: nowrap;
  216. overflow: hidden;
  217. text-overflow: ellipsis;
  218. }
  219. .editable-header[contenteditable='true'] {
  220. white-space: normal;
  221. outline: none; /* 移除编辑时的焦点边框 */
  222. }
  223. .editable-header[contenteditable='true']:empty::before {
  224. content: attr(data-placeholder); /* 可选:为空时显示占位符 */
  225. color: #999;
  226. }
  227. </style>