Prechádzať zdrojové kódy

消息推送新增查看编辑页面完成

fjc 1 rok pred
rodič
commit
3ce1f38bbf

+ 12 - 1
.env.development

@@ -20,7 +20,18 @@ VITE_DROP_CONSOLE = true
 # VITE_PROXY=[["/skyeye-admin-api","http://192.168.13.68/skyeye-admin-api"],[],["/eye_api_bak","http://192.168.13.68/eye_api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"]]
 # 中建材 staff
 #VITE_PROXY=[["/skyeye-admin-api","http://192.168.13.68:70/skyeye-admin-api"],["/eye_api_bak","http://192.168.13.68:70/eye_api"],["/push_stream_host","http://192.168.13.68:70/push_stream_host"],["/skyeye-login","http://192.168.13.68:70/skyeye-login"],["/ws_api_bak","ws://192.168.13.68:70/ws_api_bak"]]
-VITE_PROXY=[["/skyeye-admin-api","http://192.168.13.68/skyeye-admin-api"],[],["/eye_api_bak","http://192.168.13.68/eye_api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]
+
+
+
+
+# VITE_PROXY=[["/skyeye-admin-api","http://192.168.13.68/skyeye-admin-api"],[],["/eye_api_bak","http://192.168.13.68/eye_api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]
+# VITE_PROXY=[["/skyeye-admin-api","http://192.168.23.182:8800/api"],[],["/eye_api_bak","http://192.168.23.182:8800"],["/push_stream_host","http://192.168.23.182/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.23.182/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]
+VITE_PROXY=[["/skyeye-admin-api","http://192.168.22.234:8243/api"],[],["/eye_api_bak","http://192.168.22.234:8243"],["/push_stream_host","http://192.168.22.234/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.22.234/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]
+
+
+
+
+
 # VITE_PROXY=[["/skyeye-admin-api","http://192.168.22.163:8800/api"],[],["/eye_api_bak","http://192.168.22.163:8800/api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"]]
 #VITE_PROXY=[["/skyeye-admin-api","http://192.168.22.121:8800/api"],["/eye_api_bak","http://192.168.22.121:8800/api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]
 # VITE_PROXY=[["/skyeye-admin-api","http://192.168.22.163:8800/api"],[],["/eye_api_bak","http://192.168.22.163:8800/api"],["/push_stream_host","http://192.168.13.68/push_stream_host"],["/skyeye-login","http://192.168.13.68/skyeye-login"],["/ws_api_bak","ws://192.168.13.68/ws_api_bak"],["/skyeye-file-upload","http://192.168.13.68/skyeye-file-upload"]]

+ 36 - 0
src/api/sendMessage/sendMessage.ts

@@ -0,0 +1,36 @@
+import { http } from '@/utils/http/axios';
+
+// 新增消息
+export function addMassage(params?) {
+  return http.request({
+    url: '/reportMessage/addReportConfig',
+    method: 'POST',
+    params,
+  });
+}
+
+// 查询消息
+export function searchMassage(params?) {
+  return http.request({
+    url: '/reportMessage/queryReportConfigDetail',
+    method: 'GET',
+    params,
+  });
+}
+
+// 编辑消息
+export function editMassage(params?) {
+  return http.request({
+    url: '/reportMessage/modifyReportConfig',
+    method: 'POST',
+    params,
+  });
+}
+
+// 查询分组
+export function searchGroup() {
+  return http.request({
+    url: '/userGroup/ToPushObjectqueryUserGroupList',
+    method: 'POST',
+  });
+}

+ 73 - 0
src/views/message/CustomSelectTree.vue

@@ -0,0 +1,73 @@
+<template>
+  <div>
+    <!-- v-model="userList" -->
+    <el-select
+      v-model="prop.form.customPushConfigList[index].customUserList"
+      value-key="id"
+      multiple
+      placeholder="请选择人员"
+      @click="dialogVisible = !disableType.contentDisable"
+      :disabled="disableType.contentDisable"
+    >
+      <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
+      </el-option>
+    </el-select>
+    <el-dialog
+      v-model="dialogVisible"
+      title="添加组内成员"
+      align-center
+      :close-on-click-modal="false"
+      style="height: 583px"
+      :width="731"
+      :destroy-on-close="true"
+    >
+      <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted } from 'vue';
+import SelectTree from './persongroup/components/SelectTree.vue';
+interface UserList {
+  id: string;
+  name: string;
+  userId: number;
+}
+const dialogVisible = ref<boolean>(false);
+// const userList = ref<UserList[]>([]);
+const selectedUser = ref<UserList[]>([]);
+
+const prop = defineProps(['form', 'disableType', 'index'])
+// const userIDList = ref()
+
+const handleCancle = () => {
+  dialogVisible.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  console.log("selectedUser.value", selectedUser.value);
+  prop.form.customPushConfigList[prop.index].customUserList.length = 0
+  prop.form.customPushConfigList[prop.index].customUserList.push(...selectedUser.value);
+  dialogVisible.value = false;
+};
+  onMounted(()=>{
+    if(prop.form.customPushConfigList[prop.index].customUserList.length > 0){
+      // selectedUser.value = prop.form.customUserList.value
+      selectedUser.value = prop.form.customPushConfigList[prop.index].customUserList
+      // console.log("prop.form.customPushConfigList[prop.index].customUserList.value", prop.form.customPushConfigList[prop.index].customUserList);
+      // console.log("selectedUser.value", selectedUser.value);
+      
+    }
+  })
+</script>
+
+<style lang="scss" scoped>
+::v-deep .el-dialog__body {
+  height: 527px;
+}
+::v-deep .el-select__selection {
+    max-height: 100px;
+    overflow-y: auto;
+}
+</style>

+ 20 - 13
src/views/message/SelectTree.vue

@@ -1,11 +1,13 @@
 <template>
   <div>
+    <!-- v-model="userList" -->
     <el-select
-      v-model="userList"
+      v-model="prop.form.customUserList.value"
       value-key="id"
       multiple
       placeholder="请选择人员"
-      @click="dialogVisible = true"
+      @click="dialogVisible = !disableType.contentDisable"
+      :disabled="disableType.contentDisable"
     >
       <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
       </el-option>
@@ -25,7 +27,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, watch } from 'vue';
+import { ref, onMounted } from 'vue';
 import SelectTree from './persongroup/components/SelectTree.vue';
 interface UserList {
   id: string;
@@ -33,28 +35,33 @@ interface UserList {
   userId: number;
 }
 const dialogVisible = ref<boolean>(false);
-const userList = ref<UserList[]>([]);
+// const userList = ref<UserList[]>([]);
 const selectedUser = ref<UserList[]>([]);
+
+const prop = defineProps(['form', 'disableType'])
+// const userIDList = ref()
+
 const handleCancle = () => {
   dialogVisible.value = false;
 };
 const handleSubmit = (selectedData: UserList[]) => {
   selectedUser.value = selectedData;
-  userList.value = selectedData;
+  prop.form.customUserList.value = selectedUser.value;
   dialogVisible.value = false;
 };
-watch(
-  () => userList.value,
-  (newUserList) => {
-    const ids = newUserList.map((user) => user.id);
-    selectedUser.value = selectedUser.value.filter((user) => ids.includes(user.id));
-  },
-  { immediate: true },
-);
+  onMounted(()=>{
+    if(prop.form.customUserList.value.length > 0){
+      selectedUser.value = prop.form.customUserList.value
+    }
+  })
 </script>
 
 <style lang="scss" scoped>
 ::v-deep .el-dialog__body {
   height: 527px;
 }
+::v-deep .el-select__selection {
+    max-height: 100px;
+    overflow-y: auto;
+}
 </style>

+ 187 - 0
src/views/message/reportmessage/CustomReport.vue

@@ -0,0 +1,187 @@
+<template>
+  <div class="reportCard" v-for="(item, index) in prop.form.customPushConfigList">
+    <a v-if="!disableType.contentDisable">
+        <el-icon class="cardIcon"
+          color="rgb(216,216,216)"
+          v-if="prop.form.customPushConfigList.length != 1"
+          @click="deleteReportCard(index)"
+        >
+        <CircleCloseFilled />
+      </el-icon>
+    </a>
+
+    <el-form-item label="统计区间:" required>
+      <el-form-item 
+        :prop="`customPushConfigList[` + index + `].customStartTime`"
+        :rules="[{ required: true, message: '请选择推统计区间', trigger: 'change'}]"
+        >
+          <el-col :span="22">
+              <el-date-picker
+                v-model="item.daterange"
+                type="daterange"
+                range-separator="至"
+                start-placeholder="开始日期"
+                end-placeholder="结束日期"
+                size="default"
+                value-format="YYYY-MM-DD"
+                :disabled="disableType.contentDisable"
+              />
+          </el-col>
+      </el-form-item>
+    </el-form-item>
+
+    <el-form-item label="推送时间:" required>
+      <el-form-item 
+        :prop="`customPushConfigList[` + index + `].pushDay`"
+        :rules="{ required: true, message: '请选择推送日期', trigger: 'change' }"
+        >
+          <el-col :span="22">
+            <el-date-picker
+              v-model="item.pushDay"
+              type="date"
+              placeholder="选择日期"
+              size="default"
+              style="width: 146.5px; height: 32px;"
+              value-format="YYYY-MM-DD"
+              :disabled="disableType.contentDisable"
+            />
+          </el-col>
+      </el-form-item>
+
+      <el-col class="text-center" :span="2">
+        <span class="text-gray-500">—</span>
+      </el-col>
+
+      <el-form-item 
+        :prop="`customPushConfigList[` + index + `].pushTime`"
+        :rules="{ required: true, message: '请选择推送时间', trigger: 'change' }"
+        >
+          <el-col :span="22">
+            <el-time-picker
+                v-model="item.pushTime"
+                placeholder="09:00"
+                value-format="HH:mm:ss"
+                style="width: 146.5px; height: 32px;" 
+                :disabled="disableType.contentDisable"
+            />
+          </el-col>
+      </el-form-item>
+    </el-form-item>
+
+    <el-form-item label="推送对象:" required 
+      :prop="`customPushConfigList[` + index + `].recipientType`"
+      :rules="{ required: true, message: '请选择推送对象', trigger: 'change' }"
+      >
+        <el-radio-group 
+          v-model="item.recipientType"
+          :disabled="disableType.contentDisable"
+        >
+          <el-radio value="1">全员</el-radio>
+          <el-radio value="2">分组</el-radio>
+          <el-radio value="3">自定义</el-radio>
+        </el-radio-group>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="item.recipientType === '2'"
+      label="选择分组:"
+      required
+      :prop="`customPushConfigList[` + index + `].userGroupList`"
+      :rules="{ required: true, message: '请选择分组', trigger: 'change' }"
+    >
+        <el-col :span="10">
+          <el-select
+            v-model="item.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 240px"
+            :disabled="disableType.contentDisable"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.userGroupId"
+              :label="item.name"
+              :value="item.userGroupId"
+            />
+          </el-select>
+        </el-col>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="item.recipientType === '3'"
+      label="选择人员:"
+      required
+      :prop="`customPushConfigList[` + index + `].customUserList`"
+      :rules="{ required: true, message: '请选择推送人员', trigger: [, 'change'] }"
+      >
+        <el-col :span="18">
+          <CustomSelectTree :form="form" :disableType="disableType" :index="index" :statisticType="5"/>
+        </el-col>
+    </el-form-item>
+  </div>
+  <el-button type="primary" @click="addCustom" class="addButton" :disabled="disableType.contentDisable">新建自定义</el-button>
+</template>
+
+<script lang="ts" setup>
+  import { ref, reactive, onMounted } from 'vue';
+  import { computeCustom, createCustomReport } from './class.ts';
+  import {CircleCloseFilled} from '@element-plus/icons-vue'
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import CustomSelectTree from '../CustomSelectTree.vue';
+
+  const prop = defineProps(['form', 'disableType'])
+  const emit = defineEmits(['customPropsChange']);
+
+  if (prop.form.customPushConfigList.length === 0){
+    prop.form.customPushConfigList = reactive<computeCustom[]>([])
+    const defaultReport = createCustomReport()
+    prop.form.customPushConfigList.push(defaultReport)
+  }
+
+  
+  const options =  ref()
+  
+  const addCustom = () => {
+    prop.form.customPushConfigList.push(createCustomReport())
+  };
+
+  const deleteReportCard = (index) => {
+    prop.form.customPushConfigList.splice(index, 1);
+  };
+
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
+</script>
+
+<style scoped>
+  .reportCard{
+    margin-left: 87px;
+    background-color: #FAFAFA;
+    padding-top: 12px;
+    width: 530px;
+    position: relative;
+  }
+
+  .addButton{
+    margin-top: 16px;
+    margin-bottom: 32px;
+    margin-left: 87px;
+    width: 124px;
+    height: 32px;
+    background: #FFFFFF;
+    border-radius: 4px;
+    border: 1px dashed #1790FF;
+    color: #1890FF;
+  }
+
+  .cardIcon{
+    position: absolute;
+    right: 0px;
+    top: 0px;
+    width: 14px;
+    height: 14px;
+  }
+</style>

+ 119 - 0
src/views/message/reportmessage/MonthReport.vue

@@ -0,0 +1,119 @@
+<template>
+  <div class="reportCard">
+    <el-form-item label="推送时间:" required>
+      <el-form-item 
+        prop="dayOfMonthList[0]"
+        >
+          <el-col :span="22">
+            <el-select 
+              v-model="form.dayOfMonthList[0]" 
+              placeholder="每月1日" 
+              style="width: 146.5px; height: 32px;"
+             :disabled="disableType.contentDisable"
+            >
+              <el-option
+                v-for="item in dayArray"
+                :key="item.id"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-col>
+      </el-form-item>
+
+      <el-col class="text-center" :span="2">
+        <span class="text-gray-500">—</span>
+      </el-col>
+
+      <el-form-item 
+        prop="pushTimeList[0]" 
+        :rules="{ required: true, message: '请选择时间', trigger: 'blur' }"
+        >
+          <el-col :span="22">
+            <el-time-picker v-model="form.pushTimeList[0]" 
+            placeholder="09:00" 
+            value-format="HH:mm:ss" 
+            style="width: 146.5px; height: 32px;" 
+            :disabled="disableType.contentDisable"
+            />
+          </el-col>
+      </el-form-item>
+    </el-form-item>
+
+    <el-form-item label="推送对象:" required prop="recipientType">
+      <el-radio-group v-model="form.recipientType" :disabled="disableType.contentDisable">
+        <el-radio :value="1">全员</el-radio>
+        <el-radio :value="2">分组</el-radio>
+        <el-radio :value="3">自定义</el-radio>
+      </el-radio-group>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="form.recipientType === 2"
+      label="选择分组:"
+      required
+      prop="userGroupList"
+      >
+        <el-col :span="10">
+          <el-select
+            v-model="form.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 240px"
+            :disabled="disableType.contentDisable"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.userGroupId"
+              :label="item.name"
+              :value="item.userGroupId"
+            />
+          </el-select>
+        </el-col>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="form.recipientType === 3"
+      label="选择人员:"
+      required
+      prop="customUserList.value"
+      :rules="{ required: true, message: '请选择推送人员', trigger: ['change'] }"
+      >
+        <el-col :span="18">
+          <SelectTree :form="form" :disableType="disableType"/>
+        </el-col>
+    </el-form-item>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, onMounted } from 'vue';
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import SelectTree from '../SelectTree.vue';
+
+  defineProps(['form', 'disableType'])
+  const options =  ref()
+
+  const dayArray = Array.from({ length: 31 }, (_, index) => ({
+    id: index + 1,
+    value: `${index + 1}`,
+    label: `${index + 1} 日`
+  }));
+
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
+</script>
+
+<style scoped>
+  .reportCard{
+    margin-left: 87px;
+    background-color: #FAFAFA;
+    padding-top: 12px;
+    width: 530px;
+  }
+
+
+</style>

+ 380 - 0
src/views/message/reportmessage/ReportOperation.vue

@@ -0,0 +1,380 @@
+
+<template>
+  <div class="page">
+    <div class="top">
+      <div class="topLeft">
+        <a style="color: #303133;" @click="clickBack"><el-icon><Back /></el-icon><span>返回</span></a>
+      </div>
+      <div class="topRight">
+        <span class="topText" v-if="form.type === 1">新建报表配置</span>
+        <span class="topText" v-if="form.type === 2">查看报表配置</span>
+        <span class="topText" v-if="form.type === 3">编辑报表配置</span>
+      </div>
+    </div>
+
+    
+    <div class="right">
+      <TemplateExample :form="form" :disableType="disableType"></TemplateExample>
+    </div>
+
+
+    <div class="left">
+      <el-form
+        ref="ruleFormRef"
+        style="max-width: 1000px"
+        :model="form"
+        :rules="rules"
+        label-width="auto"
+        class="demo-ruleForm"
+        :size="formSize"
+        status-icon
+      >
+        <!-- <el-form-item 
+          v-if="form.type === 3"
+          label="指定人员:"
+          required
+          :prop="'designatedUserList'"
+          :rules="{ required: true, message: '请选择人员', trigger: 'change' }"
+        >
+          <el-col :span="10">
+            <SelectTree />
+          </el-col>
+        </el-form-item> -->
+        <el-form-item 
+          v-if="form.type === 3"
+          label="选择人员:"
+          required
+          prop="customUserList.value"
+          :rules="{ required: true, message: '请选择推送人员', trigger: ['change'] }"
+          >
+            <el-col :span="18">
+              <SelectTree :form="form" :disableType="disableType"/>
+            </el-col>
+        </el-form-item>
+
+        <el-form-item label="统计时间段" prop="statisticType" required>
+          <el-radio-group v-model="form.statisticType"  :disabled="disableType.statisticTypeDisable">
+            <el-tooltip :visible="weekVisible" placement="top">
+              <template #content>
+                <span>自然周数据(周一至周日),<br>每次将推送上一周数据</span>
+              </template>
+              <el-radio :value="1" @mouseenter="weekVisible = true" @mouseleave="weekVisible = false">周报</el-radio>
+            </el-tooltip>
+
+            <el-tooltip :visible="monthVisible" placement="top">
+              <template #content>
+                <span>自然月数据(每月第一天至最后一天),<br>每次将推送上个月数据</span>
+              </template>
+              <el-radio :value="2" @mouseenter="monthVisible = true" @mouseleave="monthVisible = false">月报</el-radio>
+            </el-tooltip>
+
+            <el-tooltip :visible="seasonVisible" placement="top">
+              <template #content>
+                <span>自然季数据,<br>每次将推送上个季度数据</span>
+              </template>
+              <el-radio :value="3" @mouseenter="seasonVisible = true" @mouseleave="seasonVisible = false">季报</el-radio>
+            </el-tooltip>
+
+            <el-tooltip :visible="yearVisible" placement="top">
+              <template #content>
+                <span>整年数据,<br>每次将推送上一年数据</span>
+              </template>
+              <el-radio :value="4" @mouseenter="yearVisible = true" @mouseleave="yearVisible = false">年报</el-radio>
+            </el-tooltip>
+
+            <el-tooltip :visible="customVisible" placement="top">
+              <template #content>
+                <span>根据个人需求按开始和结束日期进行统计</span>
+              </template>
+              <el-radio el-radio :value="5" @mouseenter="customVisible = true" @mouseleave="customVisible = false">自定义</el-radio>
+            </el-tooltip>
+
+          </el-radio-group>
+        </el-form-item>
+ 
+
+        <div v-if="form.statisticType === 1">
+          <WeekReport :form="form" :disableType="disableType"></WeekReport>
+        </div>
+
+        <div v-if="form.statisticType === 2">
+          <MonthReport :form="form" :disableType="disableType"></MonthReport>
+        </div>
+
+        <div v-if="form.statisticType === 4">
+          <YearReport :form="form" :disableType="disableType"></YearReport>
+        </div>
+
+        <div v-if="form.statisticType === 5">
+        
+          <CustomReport ref="CustomReportComponent" :form="form" :disableType="disableType"></CustomReport>
+        </div>
+
+        <el-form-item label="推送渠道" prop="pushChannel" required>
+          <el-checkbox-group v-model="form.pushChannel" :disabled="disableType.contentDisable">
+            <el-col :span="2">
+              <el-checkbox :value="1" name="channel"> 平台推送 </el-checkbox>
+            </el-col>
+            <el-col :span="2">
+              <el-checkbox :value="2" name="channel"> 蓝信推送 </el-checkbox>
+            </el-col>
+          </el-checkbox-group>
+        </el-form-item>
+
+        <el-form-item label="操作人">
+          <el-input
+            style="width: 240px"
+            disabled
+            :placeholder="operater"
+          />
+        </el-form-item>
+
+        <el-form-item>
+          <el-button type="primary" @click="submitForm(ruleFormRef)" :disabled="disableType.contentDisable"> 确定 </el-button>
+          <el-button @click="resetForm(ruleFormRef)" :disabled="disableType.contentDisable">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+
+</template>
+
+<script lang="ts" setup>
+  import { reactive, ref, watch, onBeforeMount, nextTick  } from 'vue';
+  import type { FormInstance } from 'element-plus';
+  import TemplateExample from './TemplateExample.vue';
+  import WeekReport from './WeekReport.vue';
+  import MonthReport from './MonthReport.vue';
+  import YearReport from './YearReport.vue';
+  import CustomReport from './CustomReport.vue';
+  import { reportMessage, toReportMessage, reportMessageToFinal } from './class.ts';
+  import { addMassage, searchMassage, editMassage } from '@/api/sendMessage/sendMessage';
+  import { ElMessage } from 'element-plus';
+  import { storeToRefs } from 'pinia';
+  import {useUserStore} from '@/store/modules/user';
+  import { useRoute, useRouter } from 'vue-router';
+  import SelectTree from '../SelectTree.vue';
+  import { Back } from '@element-plus/icons-vue'
+
+  
+  const useUser = useUserStore();
+  const {info} = storeToRefs(useUser)
+  let operater = info.value.nickname
+
+
+  const weekVisible = ref(false)  // 控制Tooltip显示
+  const monthVisible = ref(false)  // 控制Tooltip显示
+  const seasonVisible = ref(false)  // 控制Tooltip显示
+  const yearVisible = ref(false)  // 控制Tooltip显示
+  const customVisible = ref(false)  // 控制Tooltip显示
+
+
+  let disableType = ref({"statisticTypeDisable": false, "contentDisable": false})  // 控制是否可编辑
+
+
+  const formSize = ref('default'); // 校验表单
+  const ruleFormRef = ref();
+  
+
+  // let pageType = 3  // 功能类型:1是新增,2是查询,3是编辑
+  // let reportType = 1  // 报表类型:1是违规报警,2是平台访问,3是指定人员访问
+  const route = useRoute()
+  const router = useRouter()
+  const pageType = ref<number>(route.query.operationType ? Number(route.query.operationType) : 0);
+  const reportType = ref<number>(route.query.type ? Number(route.query.type) : 0);
+  const statisticType = ref<number>(route.query.statisticType ? Number(route.query.statisticType) : 0)
+  let queryType = {"type": reportType.value, "statisticType": statisticType.value}
+  
+
+  const form = reactive<reportMessage>({
+    type: 0,
+    statisticType: 0,
+    monthAndDayList: [''],
+    dayOfWeek: '',
+    monthList: [''],
+    dayOfMonthList: [''],
+    pushTimeList: [],
+    pushChannel: [],
+    userGroupList: [],
+    designatedUserList: [],
+    recipientType: undefined,
+    customPushConfigList: [],
+    customUserList: []
+  });
+  const rules = reactive({
+    statisticType: [{ required: true, message: '请选择统计时间段', trigger: 'change, blur' }],
+    pushChannel: [{ required: true, message: '请选择推送渠道', trigger: 'change' }],
+    dayOfWeek: [{ required: true, message: '请选择推送日期', trigger: 'change' }],
+    dayOfMonthList: [{ required: true, message: '请选择推送日', trigger: 'change' }],
+    recipientType: [{ required: true, message: '请选择推送对象', trigger: ['blur', 'change'] }],
+    userGroupList: [{ required: true, message: '请选择推送分组', trigger: 'change' }],
+    // customUserList: [{ required: true, message: '请选择推送人员', trigger: 'change, blur' }],
+  });
+
+  const CustomReportComponent = ref()  // 自定义组件
+
+  const submitForm = async (formEl: FormInstance | undefined) => {
+    if (!formEl) return
+    await formEl.validate((valid, fields) => {
+      if (valid) {
+        console.log('submit!')
+        let submitForm = reportMessageToFinal(form)
+        console.log("submitForm", submitForm);
+        if (pageType.value != 3){
+          addMassage(submitForm).then((res) => {
+            console.log("新增res", res);
+            
+            ElMessage.success('新增');
+            return res;
+          });
+        }
+        else{
+          editMassage(submitForm).then((res) => {
+            console.log("修改res", res);
+            
+            ElMessage.success('修改');
+            return res;
+          });
+        }
+        
+      } else {
+        console.log('error submit!', fields)
+      }
+    })
+  };
+
+  const resetForm = (formEl: FormInstance | undefined) => {
+    if (!formEl) return;
+    formEl.resetFields();
+  };
+
+  const clickBack = () => {
+    router.back()
+  };
+
+  watch(form, () => {
+    console.log(`form newvalue:`, form);
+})
+  // watch(() => form.customUserList, (customUserListNewValue) => {
+  //     console.log(`customUserList`, customUserListNewValue);
+  // })
+
+
+  const getDisableType = (pageType) => {
+      if (pageType === 1){
+        // return {"statisticTypeDisable": false, "contentDisable": false}  // 新增
+        disableType.value.statisticTypeDisable = false
+        disableType.value.contentDisable = false
+      }
+      else if (pageType === 2){
+        // return {"statisticTypeDisable": true, "contentDisable": true}  // 查询
+        disableType.value.statisticTypeDisable = true
+        disableType.value.contentDisable = true
+      }
+      else if (pageType === 3){
+        // return {"statisticTypeDisable": true, "contentDisable": false}  // 编辑
+        disableType.value.statisticTypeDisable = true
+        disableType.value.contentDisable = false
+      }
+  };
+
+
+  onBeforeMount(()=>{
+    if (pageType.value === 1){  // 新增
+      getDisableType(1)
+    }
+    if (pageType.value === 2){  // 查询
+      getDisableType(2)
+      searchMassage(queryType).then((res) => {
+        console.log("res", res);
+        toReportMessage(form, res)
+        return res;
+      });
+    }
+    if (pageType.value === 3){  // 编辑
+      getDisableType(3)
+      searchMassage(queryType).then((res) => {
+        console.log("res", res);
+        toReportMessage(form, res)
+        return res;
+      });
+    }
+    form.type = reportType.value
+  })
+
+  // const options =  ref([
+  //   {
+  //     value: 1,
+  //     label: '分组1',
+  //   },
+  //   {
+  //     value: 2,
+  //     label: '分组2',
+  //   },
+  //   {
+  //     value: 3,
+  //     label: '分组3',
+  //   },
+  // ])
+</script>
+
+<style scoped>
+  .page {
+    position: relative;
+    /* height: calc(100vh - 64px - 12px); */
+    height: calc(100vh - 64px - 12px);
+    background-color: #ffffff;
+  }
+
+  .left{
+    float: left;
+    height: calc(100vh - 111px);
+    width: 669px;
+    margin-left: 41px;
+    padding-top: 20px;
+    border-right: 1px solid rgba(0,0,0,0.06);
+  }
+
+  .right{
+    float: right;
+    height: 294px;
+    width: 448px;
+    /* margin-right: 59px; */
+    margin-right: 12%;
+    margin-top: 20px;
+    background: #FFFFFF;
+    border-radius: 4px 4px 0px 0px;
+    border: 1px solid #E9E9E9;
+  }
+
+  .top{
+    height: 34.5px;
+    border-bottom: 1px solid #E9E9E9;
+  }
+
+  .topLeft{
+    display: inline-block;
+    height: 34.5px;
+    margin-left: 20px;
+    margin-top: 7px;
+  }
+
+  .topRight{
+    display: inline-block;
+    height: 34.5px;
+
+  }
+
+  .topText{
+    display: inline-block;
+    width: 245;
+    height: 34px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 400;
+    font-size: 14px;
+    color: #303133;
+    text-align: left;
+    font-style: normal;
+    margin-left: 20px;
+  }
+</style>

+ 142 - 0
src/views/message/reportmessage/TemplateExample.vue

@@ -0,0 +1,142 @@
+<template>
+    <div v-if="form.type === 1">
+        <div class="exampleTitleDiv"><span class="exampleTitle"><b>违规报警数据示例</b></span></div>
+
+        <div class="reportblock">
+            <div>
+                <div class="exampleContentTitle">报表标题:</div>
+                <div class="reportTitle"> 【数据报表-违规报警数据】 </div>
+            </div>
+
+            <div style="height: 189px;">
+                <div class="exampleContentTitle" style="float: left; margin-top: 0px;">内容示例:</div>
+                <div class="reportTitle">
+                    【统计时间段】 xxxx-xx-xx - xxxx-xx-xx <br />
+                    【累计报警次数】 XX次 <br />
+                    【报警类型排行TOP5】 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) 报警问题: 发生XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2) 报警问题: 发生XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3) 报警问题: 发生XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4) 报警问题: 发生XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(5) 报警问题: 发生XX次 <br />
+                </div>
+            </div>
+        </div>
+    </div>
+
+    
+    <div v-if="form.type === 2">
+        <div class="exampleTitleDiv"><span class="exampleTitle"><b>平台访问数据内容示例</b></span></div>
+
+        <div class="reportblock">
+            <div>
+                <div class="exampleContentTitle">报表标题:</div>
+                <div class="reportTitle"> 【数据报表-平台访问数据】 </div>
+            </div>
+
+            <div style="height: 189px;">
+                <div class="exampleContentTitle" style="float: left; margin-top: 0px;">内容示例:</div>
+                <div class="reportTitle">
+                    【统计时间段】 xxxx-xx-xx - xxxx-xx-xx <br />
+                    【平台累计访问次数】 XX次 <br />
+                    【车间访问数量排行TOP5】 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) 车间一:  被访问XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2) 车间二:  被访问XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3) 车间三:  被访问XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4) 车间四:  被访问XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(5) 车间五:  被访问XX次 <br />
+                </div>
+            </div>
+        </div>
+    </div>
+
+    
+    <div v-if="form.type === 3">
+        <div class="exampleTitleDiv"><span class="exampleTitle"><b>人员访问数据内容示例</b></span></div>
+
+        <div class="reportblock">
+            <div>
+                <div class="exampleContentTitle">报表标题:</div>
+                <div class="reportTitle"> 【数据报表-人员访问数据】 </div>
+            </div>
+
+            <div style="height: 189px;">
+                <div class="exampleContentTitle" style="float: left; margin-top: 0px;">内容示例:</div>
+                <div class="reportTitle">
+                    【统计时间段】 xxxx-xx-xx - xxxx-xx-xx <br />
+                    【人员平台访问数据】 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(1) 人员1:  访问XX次, 其中访问车间1XX次<br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2) 人员2:  访问XX次, 其中访问车间1XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(3) 人员3:  访问XX次, 其中访问车间1XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(4) 人员4:  访问XX次, 其中访问车间1XX次 <br />
+                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(5) 人员5:  访问XX次, 其中访问车间1XX次 <br />
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script lang="ts" setup>
+  const prop = defineProps(['form', 'disableType'])
+</script>
+
+<style>
+
+.exampleTitleDiv{
+    width: 448px;
+    height: 44px;
+    background: #FAFAFA;
+    border-radius: 3px 3px 0px 0px;
+    border: 1px solid #E9E9E9;
+  }
+
+  .exampleTitle{
+    display: inline-block;
+    width: 182px;
+    height: 22px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 500;
+    font-size: 14px;
+    color: rgba(0,0,0,0.85);
+    line-height: 22px;
+    text-align: left;
+    font-style: normal;
+    margin-left: 24px;
+    margin-top: 11px;
+  }
+
+  .exampleContentTitle{
+    display: inline-block;
+    width: 70px;
+    height: 22px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 400;
+    font-size: 14px;
+    color: #303133;
+    line-height: 22px;
+    text-align: left;
+    font-style: normal;
+    text-transform: none;
+    margin-left: 24px;
+    margin-top: 16px;
+  }
+
+  .reportblock {
+    background: #FFFFFF;
+    border-radius: 4px 4px 0px 0px;
+    /* border: 1px solid #E9E9E9; */
+  }
+
+  .reportTitle {
+    display: inline-block;
+    width: 245;
+    height: 22px;
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 400;
+    font-size: 14px;
+    color: rgba(0,0,0,0.45);
+    line-height: 22px;
+    text-align: left;
+    font-style: normal;
+  }
+</style>

+ 116 - 0
src/views/message/reportmessage/WeekReport.vue

@@ -0,0 +1,116 @@
+<template>
+  <div class="reportCard">
+    <el-form-item label="推送时间:" required>
+      <el-form-item 
+        prop="dayOfWeek"
+        >
+          <el-col :span="22">
+            <el-select 
+              v-model="form.dayOfWeek" 
+              placeholder="每周一" 
+              style="width: 146.5px; height: 32px;"
+              :disabled="disableType.contentDisable"
+            >
+              <el-option label="周一" :value="1" />
+              <el-option label="周二" :value="2" />
+              <el-option label="周三" :value="3" />
+              <el-option label="周四" :value="4" />
+              <el-option label="周五" :value="5" />
+              <el-option label="周六" :value="6" />
+              <el-option label="周日" :value="7" />
+            </el-select>
+          </el-col>
+      </el-form-item>
+
+      <el-col class="text-center" :span="2">
+        <span class="text-gray-500">—</span>
+      </el-col>
+
+      <el-form-item 
+        prop="pushTimeList[0]" 
+        :rules="{ required: true, message: '请选择时间', trigger: 'blur' }"
+        >
+          <el-col :span="22">
+            <el-time-picker 
+              v-model="form.pushTimeList[0]" 
+              placeholder="09:00" 
+              value-format="HH:mm:ss" 
+              style="width: 146.5px; height: 32px;" 
+              :disabled="disableType.contentDisable"
+            />
+          </el-col>
+      </el-form-item>
+    </el-form-item>
+
+    <el-form-item label="推送对象:" required prop="recipientType">
+      <el-radio-group 
+        v-model="form.recipientType" 
+        :disabled="disableType.contentDisable"
+      >
+        <el-radio :value="1">全员</el-radio>
+        <el-radio :value="2">分组</el-radio>
+        <el-radio :value="3">自定义</el-radio>
+      </el-radio-group>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="form.recipientType === 2"
+      label="选择分组:"
+      required
+      prop="userGroupList"
+      >
+        <el-col :span="10">
+          <el-select
+            v-model="form.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 240px"
+            :disabled="disableType.contentDisable"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.userGroupId"
+              :label="item.name"
+              :value="item.userGroupId"
+            />
+          </el-select>
+        </el-col>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="form.recipientType === 3"
+      label="选择人员:"
+      required
+      prop="customUserList.value"
+      :rules="{ required: true, message: '请选择推送人员', trigger: ['change'] }"
+      >
+        <el-col :span="18">
+          <SelectTree :form="form" :disableType="disableType"/>
+        </el-col>
+    </el-form-item>
+  </div>
+</template>
+
+<script lang="ts" setup>
+  import { ref, onMounted } from 'vue';
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import SelectTree from '../SelectTree.vue';
+
+  const prop = defineProps(['form', 'disableType'])
+  const options =  ref()
+
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
+</script>
+
+<style scoped>
+  .reportCard{
+    margin-left: 87px;
+    background-color: #FAFAFA;
+    padding-top: 12px;
+    width: 530px;
+  }
+</style>

+ 152 - 0
src/views/message/reportmessage/YearReport.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="reportCard">
+      <el-form-item label="推送时间:" required>
+        <el-form-item 
+          prop="monthAndDayList[0]"
+          :rules="{ required: true, message: '请选择时间', trigger: 'change', }"
+          >
+            
+          <el-col :span="22">
+            <el-cascader
+              v-model="prop.form.monthAndDayList"
+              :options="yearArray"
+              @change="handleChange"
+              placeholder="每年1月1日"
+              style="width: 145.5px;"
+             :disabled="disableType.contentDisable"
+            />
+          </el-col>
+        </el-form-item>
+
+        <el-col class="text-center" :span="2">
+          <span class="text-gray-500">-</span>
+        </el-col>
+
+        <el-form-item 
+          prop="pushTimeList[0]" 
+          :rules="{ required: true, message: '请选择时间', trigger: 'blur' }"
+          >
+            <el-col :span="22">
+              <el-time-picker
+               v-model="prop.form.pushTimeList[0]"
+                  placeholder="09:00"
+                  value-format="HH:mm:ss"
+                  style="width: 126.5px; height: 32px;"
+                  :disabled="disableType.contentDisable"
+                  />
+            </el-col>
+        </el-form-item>
+    </el-form-item>
+
+    <el-form-item label="推送对象:" required prop="recipientType">
+      <el-radio-group
+         v-model="prop.form.recipientType"
+          :disabled="disableType.contentDisable"
+        >
+        <el-radio :value="1">全员</el-radio>
+        <el-radio :value="2">分组</el-radio>
+        <el-radio :value="3">自定义</el-radio>
+      </el-radio-group>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="prop.form.recipientType === 2"
+      label="选择分组:"
+      required
+      prop="userGroupList"
+      >
+        <el-col :span="10">
+          <el-select
+            v-model="prop.form.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 240px"
+            :disabled="disableType.contentDisable"
+          >
+            <el-option
+              v-for="item in options"
+              :key="item.userGroupId"
+              :label="item.name"
+              :value="item.userGroupId"
+            />
+          </el-select>
+        </el-col>
+    </el-form-item>
+
+    <el-form-item 
+      v-if="form.recipientType === 3"
+      label="选择人员:"
+      required
+      prop="customUserList.value"
+      :rules="{ required: true, message: '请选择推送人员', trigger: ['change'] }"
+      >
+        <el-col :span="18">
+          <SelectTree :form="form" :disableType="disableType"/>
+        </el-col>
+    </el-form-item>
+  </div>
+  
+</template>
+
+<script lang="ts" setup>
+  import { ref, onMounted, } from 'vue';
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import SelectTree from '../SelectTree.vue';
+
+  const prop = defineProps(['form', 'disableType'])
+  const options =  ref()
+
+  const handleChange = () => {
+    if (prop.form.monthList.length === 0){
+      prop.form.monthList.push(prop.form.monthAndDayList[0])
+      prop.form.dayOfMonthList.push(prop.form.monthAndDayList[1])
+    }
+    else{
+      if (prop.form.statisticType != 3){  // 非季报
+        prop.form.monthList.length = 0
+        prop.form.monthList.push(prop.form.monthAndDayList[0])
+        prop.form.dayOfMonthList.length = 0
+        prop.form.dayOfMonthList.push(prop.form.monthAndDayList[1])
+      }
+      // prop.form.monthList.splice(0, 1);
+      // prop.form.monthList.push(prop.form.monthAndDayList[0])
+      // prop.form.dayOfMonthList.splice(0, 1);
+      // prop.form.dayOfMonthList.push(prop.form.monthAndDayList[1])
+    }
+  }
+
+
+  // 默认每年2月都是29天,如果2月选了29日则后端再判断当年或明年2月具体有多少天
+  const monthMap = {"1":31, "2":29, "3":31, "4":30, "5":31, "6":30, "7":31, "8":31, "9":30, "10":31, "11":30, "12":31}
+  const yearArray = Array.from({ length: 12 }, (_, index) => ({
+    id: index + 1,
+    value: `${index + 1}`,
+    label: `${index + 1} 月`,
+    children: Array.from({ length: monthMap[index + 1] }, (_, dayIndex) => ({
+        id: dayIndex + 1,
+        value: `${dayIndex + 1}`,
+        label: `${dayIndex + 1} 日`  
+      }))
+    
+  }));
+
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
+</script>
+
+<style scoped>
+  .reportCard{
+    margin-left: 87px;
+    background-color: #FAFAFA;
+    padding-top: 12px;
+    width: 530px;
+    .el-sellect{
+
+    }
+  }
+
+
+</style>

+ 240 - 0
src/views/message/reportmessage/class.ts

@@ -0,0 +1,240 @@
+import { reactive, computed } from 'vue';
+
+export enum type {
+    violationAlarm = 1,
+    platformStatistics = 2,
+    personnelStatistics = 3,
+  }
+
+export enum StatisticType {
+    none = 0,
+    week = 1,
+    month = 2,
+    year = 4,
+    custom = 5,
+  }
+
+export interface finalReportMessage {
+    type: number;
+    statisticType: StatisticType;
+    dayOfWeek: ''
+    monthList: [string];
+    dayOfMonthList: [string];
+    pushTimeList: [];
+    pushChannel: [];
+    userGroupList: [];
+    designatedUserList: [];
+    customUserList: [];
+    recipientType: number;
+    customPushConfigList: finalCustom[];
+}  
+
+export interface reportMessage {
+    type: number;
+    statisticType: StatisticType;
+    dayOfWeek: ''
+    monthList: [string];
+    monthAndDayList?: [string],
+    dayOfMonthList: [string];
+    pushTimeList: [];
+    pushChannel: [];
+    userGroupList: [];
+    designatedUserList: [];
+    customUserList: [];
+    recipientType: number|undefined;
+    customPushConfigList: computeCustom[]|any;
+}
+
+export interface finalCustom {  // 最终返回给接口的自定义报告类
+    customStartTime: string;
+    customEndTime: string;
+    customUserList: [];
+    pushTime: string;
+    recipientType: string;
+    userGroupList: [];
+}
+
+export interface computeCustom {  // 临时自定义报告类,daterange用于给customStartTime和customEndTime提供计算值,pushDay和pushTime用于给finalPushTime提供计算值
+    daterange: null;
+    customStartTime: any;
+    customEndTime: any;
+    pushDay: null;
+    pushTime: null;
+    finalPushTime: any;
+    recipientType: string;
+    userGroupList: [];
+    customUserList: [];
+}
+
+interface UserList {
+    id: string;
+    userNickname: string;
+    userId: number;
+  }
+
+export const createCustomReport = () => {
+    const newCustomReport = reactive<computeCustom>({
+        daterange: null,
+        customStartTime: computed(() => newCustomReport.daterange === null? null : newCustomReport.daterange[0]),
+        customEndTime: computed(() => newCustomReport.daterange === null? null : newCustomReport.daterange[1]),
+        pushDay: null,
+        pushTime: null,
+        finalPushTime: computed(() => {
+            return (newCustomReport.pushDay === null) || (newCustomReport.pushTime === null)? null :newCustomReport.pushDay + ' ' + newCustomReport.pushTime;
+        }),
+        recipientType: '',
+        userGroupList: [],
+        customUserList: [],
+    })
+    return newCustomReport
+};
+
+export const toFinalCustom = (computeCustom: computeCustom) => {
+     return reactive<finalCustom>({
+        customStartTime: computeCustom.customStartTime,
+        customEndTime: computeCustom.customEndTime,
+        customUserList: computeCustom.customUserList,
+        pushTime: computeCustom.finalPushTime,
+        recipientType: computeCustom.recipientType,
+        userGroupList: computeCustom.userGroupList,
+    })
+};
+
+export const toReportMessage = (form: reportMessage, receivedData: finalReportMessage) => {
+    form.type = receivedData.type
+    form.statisticType = receivedData.statisticType
+    form.dayOfWeek = receivedData.dayOfWeek
+    form.monthList = receivedData.monthList
+    form.dayOfMonthList = receivedData.dayOfMonthList
+    form.pushTimeList = receivedData.pushTimeList
+    form.pushChannel = receivedData.pushChannel
+    form.userGroupList = receivedData.userGroupList
+    form.designatedUserList = receivedData.designatedUserList
+    form.customUserList.value = receivedData.customUserList
+    form.recipientType = receivedData.recipientType
+    form.customPushConfigList = []
+    
+    if(form.customUserList.value.length > 0){
+        form.customUserList.value = form.customUserList.value.map((user) => {
+            return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+        })
+    }
+    
+    if(receivedData.customPushConfigList[0].customUserList.length > 0){
+        for (let index in form.customPushConfigList) {
+            let userInfo = receivedData.customPushConfigList[index].customUserList.map((user:UserList) => {
+                return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+            })
+            form.customPushConfigList[index]['customUserList'].push(userInfo)
+        }
+    }
+    if(receivedData.statisticType === 2){
+        form.dayOfMonthList.push(receivedData.dayOfMonthList[0].toString())
+    }
+    if(receivedData.statisticType === 4){
+        form.monthAndDayList?.push(receivedData.monthList[0].toString())
+        form.monthAndDayList?.push(receivedData.dayOfMonthList[0].toString())
+    }
+    if(receivedData.statisticType === 5){
+        let tempconfig = {}
+        let customPushConfigList: any[] = []
+        for (let config of receivedData.customPushConfigList) {
+            tempconfig['daterange'] = [config.customStartTime.split(" ")[0], config.customEndTime.split(" ")[0]]
+            const customStartTime = computed(() => tempconfig['daterange'][0])
+            const customEndTime = computed(() => tempconfig['daterange'][1])
+            let _ = customStartTime.value
+            let __ = customEndTime.value
+            // console.log("customStartTime", customStartTime.value);  // 不使customStartTime.value用会报错,离谱,后续再研究
+            // console.log("customEndTime", customEndTime.value);
+            // tempconfig['customEndTime'] = tempconfig['daterange'][1]
+            tempconfig['customStartTime'] = customStartTime
+            tempconfig['customEndTime'] = customEndTime
+            tempconfig['pushDay'] = config.pushTime.split(" ")[0]
+            tempconfig['pushTime'] = config.pushTime.split(" ")[1]
+            tempconfig['recipientType'] = config.recipientType.toString()
+            tempconfig['userGroupList'] = config.userGroupList
+            tempconfig['pushTime'] = config.pushTime.split(" ")[1]
+            tempconfig['customUserList'] = config.customUserList.map((user:UserList) => {
+                return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+            })
+            customPushConfigList.push(tempconfig)
+            tempconfig = {}
+            
+            // if(receivedData.customPushConfigList[0].customUserList.length > 0){
+            //     for (let index in form.customPushConfigList) {
+            //         // console.log("form.customPushConfigList[index][customConfig']", form.customPushConfigList[index]["customUserList"]);
+            //         // for (let userIndex in form.customPushConfigList[index]["customUserList"]){
+            //         //     console.log("userindex", userIndex);
+            //         //     // console.log("form.customPushConfigList[index][customConfig']", form.customPushConfigList[index]["customUserList"][0]);
+                        
+            //         //     console.log("aaa",form.customPushConfigList[index]["customUserList"].map((user:UserList) => {
+            //         //         return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+            //         //     }))
+            //         // }
+            //         // console.log("form.customPushConfigList[index].customUserList", form.customPushConfigList[index].customUserList);
+            //         // console.log("form.customPushConfigList[index].customUserList",form.customPushConfigList[index].customUserList.map((user:UserList) => {
+            //         //     return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+            //         // }));
+            //         let userInfo = receivedData.customPushConfigList[index].customUserList.map((user:UserList) => {
+            //             return {"id": `u${user.userId}`, "name": user.userNickname, "userId": user.userId}
+            //         })
+            //         form.customPushConfigList[index]['customUserList'].push(userInfo)
+            //     }
+            // }
+        }
+        for (let index in customPushConfigList){
+            const finalPushTime = computed(() => customPushConfigList[index]['pushDay'] + ' ' + customPushConfigList[index]['pushTime'])
+            customPushConfigList[index]['finalPushTime'] = finalPushTime
+        }
+        form.customPushConfigList = customPushConfigList
+    }
+};
+
+export const reportMessageToFinal = (form) => {  // 临时表单转为只存在后端需要字段的表单
+    let tempCustom = {}
+    let customPushConfigList: any[] = []
+    if (form.customPushConfigList.length > 0){
+        if (!form.customPushConfigList[0].daterange){  // 如果有值则表示用户填了自定义的表单
+            return
+        }
+        else{
+            for (let config of form.customPushConfigList) {
+                console.log("form.customPushConfigList", config);
+                for(let key in config){
+                    if (key === 'daterange' || key === 'pushDay' || key === 'pushTime') {
+                        continue   
+                    }
+                    else if(key === 'finalPushTime'){
+                        tempCustom['pushTime'] = config[key]
+                    }
+                    else if(key === 'customUserList'){
+                        console.log("key", key);
+                        console.log("config[key]", config[key]);
+                        
+                        tempCustom['customUserList'] = config[key].map((user) => user.userId)
+                    }
+                    else{
+                        tempCustom[key] = config[key]
+                    }
+                }
+                customPushConfigList.push(tempCustom)
+                tempCustom = {}
+            }
+        }
+    }
+
+    return {
+        "type": form.type,
+        "statisticType": form.statisticType,
+        "dayOfWeek": form.dayOfWeek,
+        "monthList": form.monthList,
+        "dayOfMonthList": form.dayOfMonthList,
+        "pushTimeList": form.pushTimeList,
+        "pushChannel": form.pushChannel,
+        "userGroupList": form.userGroupList,
+        "recipientType": form.recipientType,
+        "customPushConfigList": customPushConfigList,
+        "designatedUserList": form.designatedUserList,
+        "customUserList": form.customUserList.value?.map((user) => user.userId)
+    }
+};

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 454 - 0
vite.config.ts.timestamp-1724225267534-70b77886d070a.mjs