|
@@ -1,153 +1,239 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <div v-show="!fillingAddState.show && !tableDetailsState.show" class="app-container">
|
|
|
- <div>
|
|
|
- <transition name="fade">
|
|
|
- <div v-show="showSearch">
|
|
|
- <el-form ref="queryFormRef" :model="queryParams">
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item label="联系人姓名:" prop="table_name" label-width="auto">
|
|
|
- <el-input v-model="queryParams.table_name" placeholder="请输入联系人姓名"></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item label="联系电话:" prop="table_name" label-width="auto">
|
|
|
- <el-input v-model="queryParams.table_name" placeholder="请输入联系电话"></el-input>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item label="选择填报人:" prop="table_name" label-width="auto"> </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-form-item label="截止时间:" prop="release_time">
|
|
|
- <el-date-picker
|
|
|
- v-model="selectedTime"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- @change="handleTimeChange"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="6">
|
|
|
- <el-button type="primary" @click="handleQuery">查询</el-button>
|
|
|
- <el-button type="primary" @click="resetQuery">重置</el-button>
|
|
|
- <el-button type="primary" @click="exportTableData()">导出</el-button>
|
|
|
- <el-button type="primary" @click="handleAdd()">新增</el-button>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-form>
|
|
|
- </div>
|
|
|
- </transition>
|
|
|
- <!-- 表格组件 -->
|
|
|
- <el-table ref="multipleTable" v-loading="loading" :data="tableData" @selection-change="handleSelectionChange"> </el-table>
|
|
|
- <pagination v-show="total > 0" v-model:page="queryParams.page" v-model:limit="queryParams.pageSize" :total="total" @pagination="tableData" />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="app-container p-2">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :lg="30" :xs="24" style="">
|
|
|
+ <el-row :span="24" :gutter="10">
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="联系人姓名:" prop="table_name" label-width="auto">
|
|
|
+ <el-input v-model="table_name" placeholder="请输入联系人姓名"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="联系电话:" prop="table_name" label-width="auto">
|
|
|
+ <el-input v-model="table_phone" placeholder="请输入联系电话"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="选择填报人:" prop="table_name" label-width="auto">
|
|
|
+ <el-select v-model="selectedReporter" placeholder="请选择填报人">
|
|
|
+ <el-option v-for="reporter in reporters" :key="reporter.id" :label="reporter.name" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-form-item label="截止时间:" prop="release_time">
|
|
|
+ <el-date-picker v-model="selectedTime" type="date" placeholder="选择截止时间" @change="handleTimeChange" />
|
|
|
+ <span class="label">前报送该表</span>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleReport()"> 智能识别 </el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleSaveTemporarily">暂存</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleSave()"> 发布 </el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="danger" @click="handleReturn()"> 返回 </el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-col>
|
|
|
+ <el-row :gutter="20" class="mb8">
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleImportExcel">导入Excel文件</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleNewTemplate">空白模板</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="1.5">
|
|
|
+ <el-button type="primary" @click="handleReload">重新加载</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-col :lg="30" :xs="24">
|
|
|
+ <el-table :data="tableData" border>
|
|
|
+ <el-table-column v-for="header in editableHeaders" :key="header" :label="header" :prop="header">
|
|
|
+ <template #header="{ column }">
|
|
|
+ <span
|
|
|
+ class="editable-header"
|
|
|
+ contenteditable="true"
|
|
|
+ @blur="saveHeader(column.label, $event.target.innerText)"
|
|
|
+ v-text="column.label"
|
|
|
+ ></span>
|
|
|
+ </template>
|
|
|
+ <template #default="{ row, $index }">
|
|
|
+ <span
|
|
|
+ class="editable-span"
|
|
|
+ contenteditable="true"
|
|
|
+ @blur="saveEdit($index, header, $event.target.innerText)"
|
|
|
+ v-text="row[header]"
|
|
|
+ ></span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
</div>
|
|
|
- <FillingAdd v-if="fillingAddState.show" :event-id="fillingAddState.eventId" @close="handleCancel" />
|
|
|
- <TableDetails v-if="tableDetailsState.show" :event-id="tableDetailsState.eventId" @close="handleCancel" />
|
|
|
</template>
|
|
|
+
|
|
|
<script setup lang="ts">
|
|
|
-import { onMounted, reactive, ref } from 'vue';
|
|
|
-import FillingAdd from './fillingAdd.vue';
|
|
|
-import TableDetails from './tableDetails.vue';
|
|
|
-import { ElButton, ElCol } from 'element-plus';
|
|
|
+import { ref, onMounted } from 'vue';
|
|
|
+import { ElTable, ElButton, ElCol, ElRow, ElTableColumn } from 'element-plus';
|
|
|
+import * as XLSX from 'xlsx';
|
|
|
|
|
|
-const loading = ref(true);
|
|
|
-const showSearch = ref(true);
|
|
|
-const selectedTime = ref([]);
|
|
|
-const ids = ref<Array<number | string>>([]);
|
|
|
-const total = ref(0);
|
|
|
-const tableData = ref([]);
|
|
|
-const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
-const initFormData = reactive({
|
|
|
- table_id: '',
|
|
|
- table_name: '',
|
|
|
- filling_time: '',
|
|
|
- release_time: '',
|
|
|
- release_status: '',
|
|
|
- task_status: ''
|
|
|
-});
|
|
|
-const data = reactive({
|
|
|
- form: { ...initFormData },
|
|
|
- queryParams: {
|
|
|
- page: 1,
|
|
|
- pageSize: 10,
|
|
|
- table_name: '',
|
|
|
- release_status: '',
|
|
|
- task_status: ''
|
|
|
- }
|
|
|
+const emits = defineEmits(['close']);
|
|
|
+const detailData = ref({
|
|
|
+ title: '测试表单',
|
|
|
+ start: '2024-10-15 17:02:22',
|
|
|
+ end: '2024-10-15 18:00:00'
|
|
|
});
|
|
|
|
|
|
-const { queryParams, form } = toRefs(data);
|
|
|
+const editableHeaders = ref(['时间', '地点', '损坏程度', '救援人员', '物资']);
|
|
|
+const tableData = ref([]);
|
|
|
|
|
|
-let fillingAddState = reactive({
|
|
|
- show: false,
|
|
|
- eventId: ''
|
|
|
+// 初始化表格数据
|
|
|
+onMounted(() => {
|
|
|
+ loadFromLocalStorage();
|
|
|
});
|
|
|
|
|
|
-let tableDetailsState = reactive({
|
|
|
- show: false,
|
|
|
- eventId: ''
|
|
|
-});
|
|
|
+// 加载数据
|
|
|
+function loadFromLocalStorage() {
|
|
|
+ const storedData = localStorage.getItem('tableData');
|
|
|
+ if (storedData) {
|
|
|
+ tableData.value = JSON.parse(storedData);
|
|
|
+ } else {
|
|
|
+ tableData.value = [
|
|
|
+ {
|
|
|
+ 时间: '2024-01-01',
|
|
|
+ 地点: '某地',
|
|
|
+ 损坏程度: '轻度',
|
|
|
+ 救援人员: '张三, 李四',
|
|
|
+ 物资: '食品, 水'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ 时间: '2024-01-02',
|
|
|
+ 地点: '某地',
|
|
|
+ 损坏程度: '中度',
|
|
|
+ 救援人员: '王五, 赵六',
|
|
|
+ 物资: '帐篷, 医疗用品'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-const handleCancel = () => {
|
|
|
- fillingAddmState.show = false;
|
|
|
- tableDetailsState.show = false;
|
|
|
-};
|
|
|
-const handleAdd = () => {
|
|
|
- fillingAddState.eventId = null; // 表示新增记录
|
|
|
- fillingAddState.show = true;
|
|
|
-};
|
|
|
-const handleView = (row) => {
|
|
|
- if (row) {
|
|
|
- tableDetailsState.eventId = row.id;
|
|
|
- tableDetailsState.show = true;
|
|
|
+function saveEdit(rowIndex, header, value) {
|
|
|
+ tableData.value[rowIndex][header] = value;
|
|
|
+}
|
|
|
+
|
|
|
+function saveHeader(header, newValue) {
|
|
|
+ const index = editableHeaders.value.indexOf(header);
|
|
|
+ if (index !== -1) {
|
|
|
+ editableHeaders.value.splice(index, 1, newValue);
|
|
|
}
|
|
|
-};
|
|
|
+}
|
|
|
|
|
|
-// 初始化数据
|
|
|
-onMounted(() => {
|
|
|
- tableData.value = staticData;
|
|
|
- total.value = staticData.length;
|
|
|
- loading.value = false;
|
|
|
-});
|
|
|
-const handleQuery = () => {
|
|
|
- queryParams.value.page = 1;
|
|
|
- fetchWorkrData();
|
|
|
-};
|
|
|
-// 重置查询条件
|
|
|
-const resetQuery = () => {
|
|
|
- queryParams.value = { page: 1, pageSize: 10, table_name: '', release_status: '', task_status: '' };
|
|
|
- selectedTime.value = [];
|
|
|
- handleQuery();
|
|
|
+const handleNewTemplate = () => {
|
|
|
+ tableData.value = [];
|
|
|
+ for (let i = 0; i < 10; i++) {
|
|
|
+ tableData.value.push({
|
|
|
+ 时间: '',
|
|
|
+ 地点: '',
|
|
|
+ 损坏程度: '',
|
|
|
+ 救援人员: '',
|
|
|
+ 物资: ''
|
|
|
+ });
|
|
|
+ }
|
|
|
+ alert('空白模板已创建');
|
|
|
};
|
|
|
-const handleSelectionChange = (selection) => {
|
|
|
- ids.value = selection.map((item) => item.id);
|
|
|
+
|
|
|
+const handleImportExcel = () => {
|
|
|
+ const input = document.createElement('input');
|
|
|
+ input.type = 'file';
|
|
|
+ input.accept = '.xlsx';
|
|
|
+ input.onchange = async (e) => {
|
|
|
+ const file = e.target.files[0];
|
|
|
+ const reader = new FileReader();
|
|
|
+ reader.onload = async () => {
|
|
|
+ const data = await new Promise((resolve, reject) => {
|
|
|
+ const result = XLSX.read(reader.result);
|
|
|
+ resolve(result);
|
|
|
+ });
|
|
|
+ reader.readAsArrayBuffer(file);
|
|
|
+ };
|
|
|
+ const workbook = XLSX.utils.read(data);
|
|
|
+ const firstSheetName = workbook.SheetNames[0];
|
|
|
+ const worksheet = workbook.Sheets[firstSheetName];
|
|
|
+ const data = XLSX.utils.sheet_to_json(worksheet);
|
|
|
+ tableData.value = data;
|
|
|
+ alert('Excel文件已导入');
|
|
|
+ };
|
|
|
+ input.click();
|
|
|
};
|
|
|
|
|
|
-const handleTimeChange = (value) => {
|
|
|
- selectedTimeLabel.value = value ? `${value[0]} 至 ${value[1]}` : '请选择时间';
|
|
|
+const handleReload = () => {
|
|
|
+ tableData.value = [];
|
|
|
+ alert('表格已清空');
|
|
|
};
|
|
|
|
|
|
-const exportTableData = () => {
|
|
|
- const dataForExport = tableData.value.map((item) => ({
|
|
|
- table_id: item.table_id,
|
|
|
- table_name: item.table_name,
|
|
|
- release_time: item.release_time,
|
|
|
- release_status: item.release_status,
|
|
|
- filling_time: item.filling_time,
|
|
|
- status: item.status
|
|
|
- }));
|
|
|
+const handleSaveTemporarily = () => {
|
|
|
+ localStorage.setItem('tableData', JSON.stringify(tableData.value));
|
|
|
+ alert('数据已暂存');
|
|
|
+};
|
|
|
|
|
|
- // 使用 xlsx库创建一个工作簿和工作表,然后填入数据
|
|
|
- const workbook = XLSXLSX.utils.book_new();
|
|
|
- XLSX.utils.sheet_add_aoa(workbook, dataForExport, { name: 'sheet1' });
|
|
|
+const handleReport = () => console.log('上报');
|
|
|
|
|
|
- // 生成Excel文件并下载
|
|
|
- XLSX.utils.save_a(workbook, 'tableData.xlsx');
|
|
|
+const handleSave = () => {
|
|
|
+ // 保存本地状态
|
|
|
+ localStorage.setItem('tableData', JSON.stringify(tableData.value));
|
|
|
+ alert('数据已保存');
|
|
|
+};
|
|
|
+const handleReturn = () => {
|
|
|
+ emits('close');
|
|
|
};
|
|
|
</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.app-container {
|
|
|
+ font-family: Avenir, Helvetica, Arial, sans-serif;
|
|
|
+ -webkit-font-smoothing: antialiased;
|
|
|
+ -moz-osx-font-smoothing: grayscale;
|
|
|
+ text-align: center;
|
|
|
+ color: #2c3e50;
|
|
|
+}
|
|
|
+.report-period {
|
|
|
+ margin-top: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+}
|
|
|
+.editable-span {
|
|
|
+ cursor: pointer;
|
|
|
+ display: inline-block;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+}
|
|
|
+.editable-span[contenteditable='true'] {
|
|
|
+ white-space: normal;
|
|
|
+ outline: none; /* 移除编辑时的焦点边框 */
|
|
|
+}
|
|
|
+.editable-span[contenteditable='true']:empty::before {
|
|
|
+ content: attr(data-placeholder); /* 可选:为空时显示占位符 */
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+.editable-header {
|
|
|
+ cursor: pointer;
|
|
|
+ display: inline-block;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+}
|
|
|
+.editable-header[contenteditable='true'] {
|
|
|
+ white-space: normal;
|
|
|
+ outline: none; /* 移除编辑时的焦点边框 */
|
|
|
+}
|
|
|
+.editable-header[contenteditable='true']:empty::before {
|
|
|
+ content: attr(data-placeholder); /* 可选:为空时显示占位符 */
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+</style>
|