ソースを参照

填报管理新增

yangyuxuan 7 ヶ月 前
コミット
94dcfdbf12

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

@@ -47,6 +47,8 @@ declare module 'vue' {
     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']
@@ -54,8 +56,10 @@ declare module 'vue' {
     ElSwitch: typeof import('element-plus/es')['ElSwitch']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
+    ElTree: typeof import('element-plus/es')['ElTree']
     ElUpload: typeof import('element-plus/es')['ElUpload']
     ExcelEditor: typeof import('./../components/ExcelEditor/index.vue')['default']
     FileUpload: typeof import('./../components/FileUpload/index.vue')['default']

+ 70 - 18
src/views/dataFilling/fillingAdd.vue

@@ -12,7 +12,7 @@
         <el-button type="primary" @click="handleNewTemplate">空白模板</el-button>
       </el-col>
       <el-col :span="1.5">
-        <el-button type="primary" @click="handleReload">重新加载</el-button>
+        <el-button type="primary" @click="handleNewTemplate">重新加载</el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="primary" @click="handleSaveTemporarily">暂存</el-button>
@@ -35,18 +35,11 @@
           </el-col>
           <!-- 联系电话 -->
           <el-col :span="8">
-            <el-form-item label="联系电话:" prop="table_phone" label-width="auto">
+            <el-form-item label="联&nbsp&nbsp&nbsp话:" prop="table_phone" label-width="auto">
               <el-input v-model="creator_phone" placeholder="请输入联系电话" style="width: 300px"></el-input>
             </el-form-item>
           </el-col>
-          <!-- 选择填报人 -->
-          <el-col :span="8">
-            <el-form-item label="选择填报人:" prop="table_name" label-width="auto">
-              <el-select v-model="selectedReporter" placeholder="请选择填报人" style="width: 300px">
-                <el-option v-for="reporter in reporters" :key="reporter.id" :label="reporter.name" :value="reporter.id" />
-              </el-select>
-            </el-form-item>
-          </el-col>
+
           <!-- 截止时间 -->
           <el-col :span="8">
             <el-form-item label="截&nbsp止&nbsp时&nbsp间&nbsp:" prop="release_time">
@@ -56,13 +49,30 @@
           </el-col>
           <!-- 操作按钮 -->
           <el-col :span="8">
-            <el-form-item label="表&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp名:" prop="table_name" label-width="auto">
+            <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="table_name" placeholder="请输入表名" style="width: 300px"></el-input>
             </el-form-item>
           </el-col>
-          <!--          <el-col :span="1.5">-->
-          <!--            <el-button type="primary" @click="handleReport()"> 智能识别 </el-button>-->
-          <!--          </el-col>-->
+          <!-- 选择填报人 -->
+          <el-col :span="16">
+            <el-form-item label="选择填报人:" prop="selectedName" label-width="auto" style="font-weight: bold;">
+              <div class="flex gap-2">
+                <el-tag
+                  v-for="tag in selectedReporter"
+                  :key="tag"
+                  closable
+                  :disable-transitions="false"
+                  @close="handleClose(tag)"
+                >
+                  {{ tag.label }}
+                </el-tag>
+              </div>
+              <el-button @click="showSelect" style="margin-left: 10px">点击选择</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>
@@ -70,6 +80,11 @@
       <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">
@@ -82,6 +97,8 @@ 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';
 registerAllModules();
 
 const fileList = ref([]);
@@ -98,6 +115,7 @@ const editableHeaders = ref([]);
 const creator_name = ref('');
 const creator_phone = ref('');
 const selectedReporter = ref(null);
+const selectedName =ref();
 const reporters = ref([]); // 确保这个数组被正确初始化
 const selectedTime = ref(null);
 const table_name = ref('');
@@ -106,9 +124,13 @@ const status = ref(0); // 假设这是一个选择器或输入框
 const issued_status = ref(0); // 假设这是一个选择器或输入框
 const period_type = ref(''); // 假设这是一个输入框或选择器
 const creator_id = ref(null); // 这通常是用户ID,可能需要从登录信息中获取
+const isShowSelect = ref(false);
+let treeData = ref([]);
 
 // 初始化表格数据
-onMounted(() => {});
+onMounted(() => {
+  fetchTreeData();
+});
 
 function saveEdit(rowIndex, header, value) {
   field_names.value[rowIndex][header] = value;
@@ -141,7 +163,7 @@ const handleImportExcel = () => {
 };
 
 const handleReload = () => {
-  field_names.value = [];
+  hotData.value = [];
   alert('表格已清空');
 };
 
@@ -157,8 +179,8 @@ const handleSave = async () => {
   const data = {
     table_name: table_name.value,
     data_table_name: data_table_name.value,
-    start_time: selectedTime.value ? selectedTime.value.startOfDay.format() : '',
-    end_time: selectedTime.value ? selectedTime.value.endOfDay.format() : '',
+    start_time: selectedTime.value,
+    end_time: selectedTime.value,
     status: status.value,
     issued_status: issued_status.value,
     period_type: period_type.value,
@@ -298,6 +320,33 @@ const handleFileUpload = ({ 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 handleClose = (tag: string) => {
+  selectedReporter.value.splice(selectedReporter.value.indexOf(tag), 1)
+}
 </script>
 
 <style scoped>
@@ -347,4 +396,7 @@ const handleFileUpload = ({ file }) => {
   display: inline-block;
   margin-bottom: 20px;
 }
+.flex {
+  flex-wrap: wrap;
+}
 </style>

+ 221 - 0
src/views/dataFilling/informantSelect.vue

@@ -0,0 +1,221 @@
+<!--<template>-->
+<!--  <div class="common-dialog">-->
+<!--    选择填报人-->
+<!--  </div>-->
+
+
+<!--</template>-->
+
+<!--<script setup lang="ts">-->
+
+<!--</script>-->
+
+
+
+<!--<style scoped lang="scss">-->
+
+<!--</style>-->
+
+<template>
+  <el-dialog v-model="visible" title="选择消息接收人" width="780px" append-to-body @close="closeDialog">
+    <div class="container">
+      <div class="left-content">
+        <div>人员选择列表</div>
+        <el-input v-model="filterText" placeholder="输入关键字进行搜索" class="input" />
+        <el-tree
+          ref="treeRef"
+          class="filter-tree"
+          :data="treeData"
+          show-checkbox
+          :props="defaultProps"
+          :filter-node-method="filterNode"
+          :default-checked-keys="defaultCheckData"
+          node-key="uuid"
+          @check-change="handleCheckChange"
+        >
+          <template #default="{ node, data }">
+            <div class="custom-tree-node">
+              <img class="icon" :src="getImage(data)" alt="" />
+              <span>{{ node.label }}</span>
+            </div>
+          </template>
+        </el-tree>
+      </div>
+      <div class="right-content">
+        <div style="display: flex">
+          已选择:
+          <div v-show="checkData.length > 0">{{ checkData.length }}人</div>
+        </div>
+        <div class="select-box">
+          <div v-for="(item, index) in checkData" :key="index" class="select-item">
+            <div class="item-left">
+              <img class="icon" :src="getImage(item)" alt="" />
+              {{ item.label }}
+            </div>
+            <i class="icon-close" @click="uncheckNodeById(item.id, index)" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <template #footer>
+      <div class="dialog-footer">
+        <el-button @click="closeDialog">取 消</el-button>
+        <el-button type="primary" @click="confirm">确 定</el-button>
+      </div>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup name="Contact">
+import { deepClone } from '@/utils/index';
+import userImg from '@/assets/images/user.png';
+import fileImg from '@/assets/images/file.png';
+import { getPhoneList} from '@/api/informationissue/informationissue';
+const props = defineProps({
+  modelValue: Boolean,
+  treeData: Array,
+  defaultCheckData: Array
+});
+const emits = defineEmits(['update:modelValue', 'confirm']);
+let visible = ref(false);
+const treeRef = ref();
+let filterText = ref('');
+let defaultProps = reactive({
+  children: 'children',
+  label: 'label'
+});
+let checkData = ref([]);
+watch(filterText, (val) => {
+  treeRef.value.filter(val);
+});
+const initData = () => {
+  if (!!props.defaultCheckData) {
+    props.defaultCheckData.forEach((item) => {
+      treeRef.value.setChecked(item.uuid, true, true);
+    });
+    checkData.value = deepClone(props.defaultCheckData);
+  }
+};
+watch(
+  () => props.modelValue,
+  () => {
+    if (!!props.modelValue) {
+      initData();
+    }
+    visible.value = props.modelValue;
+  },
+  {
+    immediate: true
+  }
+);
+const filterNode = (value, data) => {
+  if (!value) return true;
+  return data.label.indexOf(value) !== -1;
+};
+const getImage = (item) => {
+  if (item.img) {
+    return item.img;
+  } else if (item.deptType) {
+    return fileImg;
+  } else {
+    return userImg;
+  }
+};
+const handleCheckChange = () => {
+  const data = [];
+  const treeData = treeRef.value.getCheckedNodes(false, false);
+  treeData.forEach((item) => {
+    if (!item.deptType) {
+      if (!data.some((obj) => obj.id === item.id)) {
+        data.push(item);
+      }
+    }
+  });
+  checkData.value = data;
+};
+const uncheckNodeById = (nodeId, index) => {
+  const nodes = treeRef.value.getCheckedNodes();
+  checkData.value.splice(index, 1);
+  nodes.forEach((item) => {
+    if (item.id === nodeId) {
+      treeRef.value.setChecked(item.uuid, false, true);
+    }
+  });
+};
+const closeDialog = () => {
+  emits('update:modelValue', false);
+  treeRef.value.setCheckedKeys([], false);
+  checkData.value = [];
+};
+const confirm = () => {
+  const data = deepClone(checkData.value);
+  closeDialog();
+  emits('confirm', data);
+};
+</script>
+
+<style lang="scss" scoped>
+.container {
+  display: flex;
+  .left-content {
+    flex: 1;
+    border: 1px solid #dcdfe6;
+    border-radius: 5px;
+    height: 400px;
+    overflow-y: auto;
+    padding: 10px;
+    .input {
+      margin: 15px 0 5px;
+    }
+    .filter-tree {
+      :deep(.el-tree-node__content) {
+        height: 45px;
+      }
+      .custom-tree-node {
+        display: flex;
+        width: 100%;
+      }
+    }
+  }
+  .right-content {
+    margin-left: 20px;
+    width: 300px;
+    flex-shrink: 0;
+    border: 1px solid #dcdfe6;
+    border-radius: 5px;
+    height: 400px;
+    overflow-y: auto;
+    padding: 10px;
+    .select-box {
+      .select-item {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 10px 0;
+        .item-left {
+          display: flex;
+          align-items: center;
+        }
+        .icon-close {
+          width: 12px;
+          height: 12px;
+          background: url('@/assets/images/close2.png') no-repeat;
+          background-size: 100% 100%;
+          cursor: pointer;
+          &:hover {
+            background: url('@/assets/images/close3.png') no-repeat;
+            background-size: 100% 100%;
+          }
+        }
+      }
+    }
+  }
+}
+.icon {
+  width: 20px;
+  height: 20px;
+  margin-right: 8px;
+  object-fit: cover;
+}
+</style>

+ 4 - 4
src/views/informationissue/informationApproval.vue

@@ -21,7 +21,7 @@
                         <el-option v-for="option in opt_info_type" :key="option.value" :label="option.text" :value="option.value"></el-option>
                       </el-select>
                     </el-form-item>
-                    
+
                     <el-form-item label="发布单位:" prop="publish_group">
                       <el-input v-model="formData.publish_group" disabled placeholder="请输入发布单位" style="width: 468px !important" />
                     </el-form-item>
@@ -32,7 +32,7 @@
                         <el-radio value="1">自定义模板</el-radio>
                       </el-radio-group>
                     </el-form-item>
-                    
+
                     <el-form-item v-if="formData.template_type === '0'" label="预设模板:" prop="template_type">
                       <el-select v-model="formData.template_id" disabled placeholder="请选择预设模板" style="width: 300px !important">
                         <el-option v-for="option in presetTemplates" :key="option.value" :label="option.label" :value="option.value"></el-option>
@@ -66,8 +66,8 @@
                   </div>
                   <h4>推送配置</h4>
                   <div class="box1">
-                    
-                    
+
+
                     <el-form-item label="发布名单:" prop="releaseList" style="width: 468px !important"
                       ><span class="highlight-text">已选择{{ formData.user_count }}人</span>
                     </el-form-item>

+ 5 - 5
src/views/informationissue/informationDetail.vue

@@ -17,7 +17,7 @@
                 <el-option v-for="option in opt_info_type" :key="option.value" :label="option.text" :value="option.value"></el-option>
               </el-select>
             </el-form-item>
-            
+
             <el-form-item label="发布单位:" prop="publish_group">
               <el-input v-model="formData.publish_group" disabled placeholder="请输入发布单位" style="width: 468px !important" />
             </el-form-item>
@@ -28,7 +28,7 @@
                 <el-radio value="1">自定义模板</el-radio>
               </el-radio-group>
             </el-form-item>
-            
+
             <el-form-item v-if="formData.template_type === '0'" label="预设模板:" prop="template_type">
               <el-select v-model="formData.template_id" disabled placeholder="请选择预设模板" style="width: 300px !important">
                 <el-option v-for="option in presetTemplates" :key="option.value" :label="option.label" :value="option.value"></el-option>
@@ -39,11 +39,11 @@
             <el-form-item v-if="formData.template_type === '1'" prop="template_url">
               <el-input v-model="formData.template_url" placeholder="请输入自定义详情页面链接地址" style="width: 468px !important" />
             </el-form-item>
-            
+
             <el-form-item label="信息内容:" prop="content">
               <el-input v-model="formData.content" type="textarea" :rows="6" disabled placeholder="请输入信息内容" style="width: 468px !important"></el-input>
             </el-form-item>
-            
+
             <el-form-item label="查看附件:">
               <div>
                 <div v-for="(file, index) in formData.attachs" :key="index" @click="viewFile(file)" style="color: #2C81FF;text-decoration: underline;cursor:pointer">
@@ -51,7 +51,7 @@
                 </div>
               </div>
             </el-form-item>
-            
+
           </div>
           <h4 class="common-dialog-title">推送配置</h4>
           <div class="box1">

+ 3 - 3
src/views/informationissue/informationView.vue

@@ -65,7 +65,7 @@
                         <el-radio value="1">自定义模板</el-radio>
                       </el-radio-group>
                     </el-form-item>
-                    
+
                     <el-form-item v-if="formData.template_type === '0'" label="预设模板:" prop="template_type">
                       <el-select v-model="formData.template_id" disabled placeholder="请选择预设模板" style="width: 300px !important">
                         <el-option v-for="option in presetTemplates" :key="option.value" :label="option.label" :value="option.value"></el-option>
@@ -76,7 +76,7 @@
                     <el-form-item v-if="formData.template_type === '1'" prop="template_url">
                       <el-input v-model="formData.template_url" placeholder="请输入自定义详情页面链接地址" style="width: 468px !important" />
                     </el-form-item>
-                    
+
                     <el-form-item label="信息内容:" prop="content">
                       <el-input
                         v-model="formData.content"
@@ -118,7 +118,7 @@
                     <el-form-item label="消息反馈方式:" prop="response_type" style="width: 468px !important">
                       <el-select v-model="displayFeedbackText" disabled placeholder="请选择消息反馈方式"> </el-select>
                     </el-form-item>
-                    
+
                   </div>
                   <h4 class="common-dialog-title">审核配置</h4>
                   <div class="box1">