소스 검색

填报管理xiafa

yangyuxuan 3 달 전
부모
커밋
7a3b1eeee2
4개의 변경된 파일448개의 추가작업 그리고 16개의 파일을 삭제
  1. 2 0
      src/api/dataFilling/fillingManage.ts
  2. 0 13
      src/types/components.d.ts
  3. 429 0
      src/views/dataFilling/fillingIssued.vue
  4. 17 3
      src/views/dataFilling/fillingManage.vue

+ 2 - 0
src/api/dataFilling/fillingManage.ts

@@ -43,3 +43,5 @@ export const fillingRelease = (reportId) => {
     method: 'put'
   });
 };
+
+

+ 0 - 13
src/types/components.d.ts

@@ -27,7 +27,6 @@ declare module 'vue' {
     ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
     ElBadge: typeof import('element-plus/es')['ElBadge']
     ElButton: typeof import('element-plus/es')['ElButton']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCheckboxButton: typeof import('element-plus/es')['ElCheckboxButton']
     ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
     ElCol: typeof import('element-plus/es')['ElCol']
@@ -44,21 +43,15 @@ declare module 'vue' {
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
     ElIcon: typeof import('element-plus/es')['ElIcon']
-    ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
-    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElPopover: typeof import('element-plus/es')['ElPopover']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
     ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElSlider: typeof import('element-plus/es')['ElSlider']
     ElStep: typeof import('element-plus/es')['ElStep']
     ElSteps: typeof import('element-plus/es')['ElSteps']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
@@ -69,11 +62,8 @@ declare module 'vue' {
     ElTabs: typeof import('element-plus/es')['ElTabs']
     ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
-    ElTimeline: typeof import('element-plus/es')['ElTimeline']
-    ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     ElTree: typeof import('element-plus/es')['ElTree']
-    ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']
@@ -85,9 +75,6 @@ declare module 'vue' {
     HikvisionPlayer: typeof import('./../components/HKVideo/hikvision-player.vue')['default']
     HKVideo: typeof import('./../components/HKVideo/index.vue')['default']
     IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
-    IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
-    IEpCaretTop: typeof import('~icons/ep/caret-top')['default']
-    IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default']
     IFrame: typeof import('./../components/iFrame/index.vue')['default']
     ImagePreview: typeof import('./../components/ImagePreview/index.vue')['default']
     ImageUpload: typeof import('./../components/ImageUpload/index.vue')['default']

+ 429 - 0
src/views/dataFilling/fillingIssued.vue

@@ -0,0 +1,429 @@
+<!--<script setup lang="ts">-->
+
+<!--</script>-->
+
+<!--<template>-->
+
+<!--</template>-->
+
+<!--<style scoped lang="scss">-->
+
+<!--</style>-->
+<template>
+  <div class="app-container p-2">
+    <el-row :gutter="20" class="mb8" style="margin-top: 5px">
+      <el-col :span="1.5">
+        <el-upload class="upload-demo" :http-request="handleFileUpload" :before-upload="beforeUpload" :file-list="fileList" accept=".xlsx, .xls">
+          <template #trigger>
+            <el-button size="big" type="primary">选择Excel文件</el-button>
+          </template>
+        </el-upload>
+      </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="handleNewTemplate">重新加载</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" @click="handleSaveTemporarily(1)">暂存</el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="primary" @click="handleSave(formRef,2)"> 发布 </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button type="danger" @click="handleReturn()"> 返回 </el-button>
+      </el-col>
+    </el-row>
+    <el-form :model="form" :rules="rules" ref="formRef">
+      <el-row :gutter="20">
+        <el-col :lg="30" :xs="24" style="margin-top: -10px">
+          <el-row :span="24" :gutter="10">
+            <!-- 联系人姓名 -->
+            <el-col :span="8">
+              <el-form-item label="联系人姓名:" prop="creator_name" label-width="auto">
+                <el-input v-model="form.creator_name" placeholder="请输入联系人姓名" style="width: 300px"></el-input>
+              </el-form-item>
+            </el-col>
+            <!-- 联系电话 -->
+            <el-col :span="8">
+              <el-form-item label="联&nbsp系&nbsp电&nbsp话:" prop="creator_phone" label-width="auto">
+                <el-input v-model="form.creator_phone" placeholder="请输入联系电话" style="width: 300px"></el-input>
+              </el-form-item>
+            </el-col>
+            <!-- 截止时间 -->
+            <el-col :span="8">
+              <el-form-item label="截&nbsp止&nbsp时&nbsp间&nbsp:" prop="end_time">
+                <el-date-picker v-model="form.end_time" value-format="YYYY-MM-DD HH:mm:ss" time-format="HH:mm" type="datetime" placeholder="选择截止时间" style="width: 300px" @change="handleTimeChange" />
+              </el-form-item>
+            </el-col>
+            <!-- 操作按钮 -->
+            <el-col :span="8">
+              <el-form-item label="表&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp名:" prop="table_name" label-width="auto">
+                <el-input v-model="form.table_name" placeholder="请输入表名" style="width: 300px"></el-input>
+              </el-form-item>
+            </el-col>
+            <!-- 选择填报人 -->
+            <el-col :span="16">
+              <el-form-item label="选择填报人:" prop="user_ids" label-width="auto" style="font-weight: bold;">
+                <div>
+                  <el-tag
+                    v-for="tag in selectedReporter"
+                    :key="tag"
+                    closable
+                    :disable-transitions="false"
+                    @close="handleClose(tag)"
+                    style="margin-right: 10px"
+                  >
+                    {{ tag.label }}
+                  </el-tag>
+                </div>
+                <el-button @click="showSelect">点击选择</el-button>
+              </el-form-item>
+            </el-col>
+            <!--                    <el-col :span="8">-->
+            <!--                      <el-button type="primary" @click="handleReport()"> 智能识别 </el-button>-->
+            <!--                    </el-col>-->
+          </el-row>
+        </el-col>
+      </el-row>
+    </el-form>
+
+    <div style="height: 350px">
+      <hot-table v-if="showTable" ref="wrapper" :data="hotData" :settings="hotSettings" />
+    </div>
+  </div>
+  <informantSelect
+    v-model="isShowSelect"
+    :tree-data="treeData"
+    :default-check-data="selectContactSelectData"
+    @confirm="handleContactSelectData"  />
+</template>
+
+<script setup lang="ts">
+import { onMounted, ref } from 'vue';
+import { ElButton, ElCol, ElDatePicker, ElFormItem, ElInput, ElOption, ElRow, ElSelect, ElTable, ElTableColumn } from 'element-plus';
+import * as XLSX from 'xlsx';
+import { fillingAdd, fillingList } from '@/api/dataFilling/fillingManage';
+import { HotTable } from '@handsontable/vue3';
+import Handsontable from 'handsontable';
+import 'handsontable/languages';
+import 'handsontable/dist/handsontable.full.css';
+import { registerAllModules } from 'handsontable/registry';
+import informantSelect from './informantSelect.vue'
+import { getPhoneList } from '@/api/informationissue/informationissue';
+import { deepClone } from '@/utils';
+import { createWarehousingEntry } from '@/api/comprehensiveGuarantee/materialReserveManagement/InboundManagement';
+import { validatePhone } from '@/utils/validate';
+registerAllModules();
+
+const props = defineProps<{
+  id: string | number;
+}>();
+const fileList = ref([]);
+const { proxy } = getCurrentInstance();
+const emits = defineEmits(['close','confirm']);
+const formRef = ref('');
+const detailData = ref({
+  title: '表单数据',
+  start: '2024-10-15 17:02:22',
+  end: '2024-10-15 18:00:00'
+});
+const hotData = ref([]);
+const field_names = ref([]);
+const selectedReporter = ref(null);
+const isShowSelect = ref(false);
+let treeData = ref([]);
+
+// 初始化表格数据
+onMounted(() => {
+  fetchTreeData();
+  fetchData();
+});
+
+const showTable = ref(false);
+const handleNewTemplate = () => {
+  showTable.value = true;
+  created();
+};
+
+const form = ref({
+  table_name: "",
+  end_time: "",
+  status: "0",
+  issued_status: "",
+  period_type: "",
+  creator_name: "",
+  creator_phone: "",
+  field_names: [],
+  user_ids: []
+})
+const rules = {
+  table_name: [{ required: true, message: '表名不能为空', trigger: 'blur' }],
+  end_time: [{ required: true, message: '截止时间不能为空', trigger: 'blur' }],
+  creator_name: [{ required: true, message: '联系人姓名不能为空', trigger: 'blur' }],
+  creator_phone: [
+    { required: true, message: '联系电话不能为空', trigger: 'blur' },
+    { validator: validatePhone, message: '请输入正确格式的联系电话', trigger: 'blur' }
+  ],
+  user_ids: [{ required: true, message: '请选择填报人', trigger: 'blur' }],
+}
+const handleSaveTemporarily = async (statuCode) => {
+  if (hotData.value && hotData.value[0] && hotData.value[0].length > 0) {
+    const data2 = [];
+    hotData.value[0].forEach((item) => {
+      if (!!item) {
+        data2.push(item);
+      }
+    })
+    form.value.field_names = data2;
+  }
+  form.value.issued_status = statuCode;
+  fillingAdd(form.value).then(() => {
+    proxy.$modal.msgSuccess('暂存成功');
+    emits('close');
+  });
+};
+
+const handleSave = async (formEl,statuCode) => {
+  if (!formEl) return;
+  await formEl.validate((valid, fields) => {
+    if (valid) {
+      const data2 = [];
+      hotData.value[0].forEach((item) => {
+        if (!!item) {
+          data2.push(item);
+        }
+      })
+      form.value.field_names = data2;
+      form.value.issued_status = statuCode;
+      fillingAdd(form.value).then((res) => {
+        proxy.$modal.msgSuccess('发布成功');
+        emits('close');
+      });
+    } else {
+      nextTick(() => {
+        let isError = document.getElementsByClassName('is-error');
+        isError[0].scrollIntoView({
+          // 滚动到指定节点
+          // 值有start,center,end,nearest,当前显示在视图区域中间
+          block: 'center',
+          // 值有auto、instant,smooth,缓动动画(当前是慢速的)
+          behavior: 'smooth'
+        });
+      });
+      proxy.$modal.msgError('表单校验失败');
+      return false;
+    }
+  });
+
+};
+
+const handleReturn = () => {
+  emits('close');
+};
+
+const created = () => {
+  let data = [];
+  for (let i = 0; i < 10; i++) {
+    let arr = [];
+    for (let x = 0; x < 10; x++) {
+      arr.push('');
+    }
+    data.push(arr);
+  }
+  showTable.value = false;
+  nextTick(() => {
+    hotData.value = data;
+    showTable.value = true;
+  });
+};
+const hotSettings = reactive({
+  language: 'zh-CN',
+  colHeaders: true,
+  rowHeaders: true,
+  autoColumnSize: true,
+  width: '100%', // auto  or  100%
+  height: '100%', // auto  or  100%
+  licenseKey: 'non-commercial-and-evaluation', // 隐藏版权文字
+  colWidths: 129, // 默认单元格宽度
+  rowHeights: 28, // 默认单元格高度
+  wordWrap: true, // 单元格文字是否换行展示
+  contextMenu: {
+    // 自定义右键菜单
+    items: {
+      'row_above': {
+        name: '向上插一行'
+      },
+      'row_below': {
+        name: '向下插一行'
+      },
+      'col_left': {
+        name: '向左插一列'
+      },
+      'col_right': {
+        name: '向右插一列'
+      },
+      'hsep1': '---------', // 分隔线
+      'remove_row': {
+        name: '删除当前行'
+      },
+      'remove_col': {
+        name: '删除当前列'
+      },
+      'clear_column': {
+        name: '清空当前列'
+      },
+      'hsep2': '---------', // 必须和上次的变量名不一样
+      'undo': {
+        name: '撤销'
+      },
+      'cut': {
+        name: '剪切'
+      },
+      'copy': {
+        name: '复制'
+      },
+      'alignment': {
+        name: '对齐'
+      },
+      'hsep3': '---------',
+      'commentsAddEdit': {
+        // 必须开启 comments: true
+        name: '添加备注'
+      },
+      'commentsRemove': {
+        // 必须开启 comments: true
+        name: '删除备注'
+      },
+      'freeze_column': {
+        // 必须开启 manualColumnFreeze: true
+        name: '固定列'
+      },
+      'unfreeze_column': {
+        // 必须开启 manualColumnFreeze: true
+        name: '取消固定列'
+      }
+    }
+  }
+});
+const beforeUpload = (file) => {
+  const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.type === 'application/vnd.ms-excel';
+  if (!isExcel) {
+    proxy.$modal.msgError('只能上传xlsx/xls文件!');
+  }
+  return isExcel;
+};
+const handleFileUpload = ({ file }) => {
+  const reader = new FileReader();
+  reader.onload = (event) => {
+    showTable.value = false;
+    nextTick(() => {
+      const data = new Uint8Array(event.target.result);
+      const workbook = XLSX.read(data, { type: 'array' });
+      const firstSheetName = workbook.SheetNames[0];
+      const worksheet = workbook.Sheets[firstSheetName];
+      const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
+      hotData.value = jsonData.slice(1); // 假设第一行是标题行,我们跳过它
+      showTable.value = true;
+    });
+  };
+  reader.readAsArrayBuffer(file);
+  fileList.value = [];
+  return { success: true, file }; // 告诉 el-upload 上传成功(尽管实际上没有发送到服务器)
+};
+
+const showSelect = () => {
+  isShowSelect.value = true;
+}
+
+const fetchTreeData = async () => {
+  try {
+    const response = await getPhoneList({});
+    if (response && response.data) {
+      treeData.value = response.data;
+    }
+  } catch (error) {
+    console.error('Failed to fetch information:', error);
+  }
+};
+
+const selectContactSelectData = ref([]);
+const handleContactSelectData = (data) => {
+  console.log('handleContactSelectData:', data);
+  selectContactSelectData.value = data;
+  // data.user_ids = data;
+  selectedReporter.value = data;
+  const data1 = [];
+  selectContactSelectData.value.forEach((item) => {
+    data1.push(item.id);
+  })
+  form.value.user_ids = data1;
+};
+
+const handleClose = (tag: string) => {
+  selectedReporter.value.splice(selectedReporter.value.indexOf(tag), 1)
+}
+
+const fetchData = () => {
+  fillingList(props.id).then((res) => {
+    form.value.creator_name = res.report_info.creator_name;
+    form.value.creator_phone = res.report_info.creator_phone;
+    form.value.end_time = res.report_info.end_time;
+    form.value.table_name = res.report_info.table_name;
+    form.value.user_ids = res.report_info.user_ids;
+  })
+}
+</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;
+}
+.upload-demo {
+  display: inline-block;
+  margin-bottom: 20px;
+}
+.flex {
+  flex-wrap: wrap;
+}
+</style>

+ 17 - 3
src/views/dataFilling/fillingManage.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <div v-show="!fillingAddState.show && !tableDetailsState.show" class="app-container">
+    <div v-show="!fillingAddState.show && !tableDetailsState.show && !issuedState.show" class="app-container">
       <div>
         <transition name="fade">
           <div v-show="showSearch">
@@ -114,6 +114,7 @@
       </div>
     </div>
     <FillingAdd v-if="fillingAddState.show" :event-id="fillingAddState.eventId" @close="handleCancel" />
+    <fillingIssued v-if="issuedState.show" :id="issuedState.id" @close="handleEditClose" @confirm="handleSure" @refresh="fetchFillList"></fillingIssued>
     <TableDetails v-if="tableDetailsState.show" :event-id="tableDetailsState.eventId" @close="handleCancel" />
   </div>
 </template>
@@ -121,6 +122,7 @@
 <script setup lang="ts">
 import { onMounted, reactive, ref, toRefs } from 'vue';
 import FillingAdd from './fillingAdd.vue';
+import fillingIssued from './fillingIssued.vue';
 import TableDetails from './tableDetails.vue';
 import { ElButton, ElCol } from 'element-plus';
 import { fillingSelect, fillingRelease } from '@/api/dataFilling/fillingManage';
@@ -155,6 +157,10 @@ const options1 = [
     value: '2',
     label: '已发布',
   }]
+let issuedState = reactive({
+  show: false,
+  id: ''
+});
 const initFormData = reactive({
   table_id: '',
   table_name: '',
@@ -272,8 +278,8 @@ const handlePagination = ({ page, limit }) => {
 };
 
 const handleIssue = (row) => {
-  fillingAddState.show = true;
-  fillingAddState.eventId = row.id;
+  issuedState.show = true;
+  issuedState.id = row.report_id;
   // 检查是否有report_id
   // if (!row.report_id) {
   //   console.error('报告ID不存在,无法下发');
@@ -290,4 +296,12 @@ const handleIssue = (row) => {
   //     console.error('下发操作失败:', error);
   //   });
 };
+const handleEditClose = () => {
+  issuedState.show = false;
+};
+const handleSure = () => {
+  issuedState.show = false;
+  queryParams.value.page = 1;
+  fetchFillList();
+}
 </script>