Просмотр исходного кода

Merge branch 'wyf-dev' into 'all'

Revert "refactor: 消息管理代码重构->fix:样式和文案修改"

See merge request skyeye/skyeye_frontend/skyeye-admin!163
yunfeng wu 1 год назад
Родитель
Сommit
ae5717c05d
46 измененных файлов с 2552 добавлено и 3013 удалено
  1. 0 26
      src/api/message/alarm-messages.ts
  2. 0 0
      src/api/message/message.ts
  3. 0 112
      src/api/message/person-group.ts
  4. 0 73
      src/api/message/report-message.ts
  5. 0 64
      src/api/message/system-notifications.ts
  6. 36 0
      src/api/sendMessage/sendMessage.ts
  7. BIN
      src/assets/images/person-group-empty.png
  8. 82 0
      src/views/message/CustomSelectTree.vue
  9. 75 0
      src/views/message/SelectTree.vue
  10. 2 2
      src/views/message/alarm-config/AlarmConfig.vue
  11. 23 0
      src/views/message/alarmMessages/api/index.ts
  12. 1 5
      src/views/message/alarmMessages/hook/index.ts
  13. 13 0
      src/views/message/api/index.ts
  14. 0 247
      src/views/message/components/PersonFilterSelection.vue
  15. 191 203
      src/views/message/components/PushObject.vue
  16. 76 0
      src/views/message/designatedUserSelectTree.vue
  17. 180 180
      src/views/message/persongroup/UserGroup.vue
  18. 63 0
      src/views/message/persongroup/api/index.ts
  19. 183 207
      src/views/message/persongroup/components/GroupBoard.vue
  20. 138 138
      src/views/message/persongroup/components/SelectTree.vue
  21. 0 0
      src/views/message/persongroup/hook/index.ts
  22. 0 98
      src/views/message/persongroup/hook/usePersonGroupFilterList.ts
  23. 27 27
      src/views/message/persongroup/store/index.ts
  24. 48 48
      src/views/message/persongroup/type.ts
  25. 20 23
      src/views/message/reportmessage/CustomReport.vue
  26. 80 83
      src/views/message/reportmessage/MonthReport.vue
  27. 1 0
      src/views/message/reportmessage/ReportMessage.vue
  28. 8 8
      src/views/message/reportmessage/ReportOperation.vue
  29. 32 40
      src/views/message/reportmessage/WeekReport.vue
  30. 108 118
      src/views/message/reportmessage/YearReport.vue
  31. 38 0
      src/views/message/reportmessage/api/index.ts
  32. 0 87
      src/views/message/reportmessage/components/CustomPersonSelection.vue
  33. 0 86
      src/views/message/reportmessage/components/DefaultPersonSelection.vue
  34. 0 87
      src/views/message/reportmessage/components/DesignatedPersonSelection.vue
  35. 109 109
      src/views/message/reportmessage/components/Form.vue
  36. 45 45
      src/views/message/reportmessage/components/LogForm.vue
  37. 26 18
      src/views/message/reportmessage/overviewColumns.ts
  38. 12 12
      src/views/message/reportmessage/store/useFormList.ts
  39. 336 336
      src/views/message/sysnotion-config/SysnotionConfig.vue
  40. 0 0
      src/views/message/sysnotion-config/api/index.ts
  41. 59 0
      src/views/message/systemNotifications/api/index.ts
  42. 164 164
      src/views/message/systemNotifications/components/WorkShopTree.vue
  43. 152 152
      src/views/message/systemNotifications/components/problemHandleTable.vue
  44. 104 104
      src/views/message/systemNotifications/components/systemNotificationTable.vue
  45. 29 29
      src/views/message/systemNotifications/store/index.ts
  46. 91 82
      src/views/message/systemNotifications/type.ts

+ 0 - 26
src/api/message/alarm-messages.ts

@@ -1,26 +0,0 @@
-import { http } from '@/utils/http/axios';
-
-export function getAlarmMessageList(params) {
-  // 获取报警数据列表
-  return http.request({
-    url: '/alarmMessage/getAlarmMessageList',
-    method: 'get',
-    params,
-  });
-}
-
-export function deleteAlarmMessage(id) {
-  // 删除报警数据
-  return http.request({
-    url: `/alarmMessage/deleteAlarmMessage?id=${id}`,
-    method: 'post',
-  });
-}
-
-export function updateAlarmStatus(params) {
-  // 修改报警数据状态
-  return http.request({
-    url: `/alarmMessage/updateStatus?id=${params.id}&status=${params.status}`,
-    method: 'post',
-  });
-}

src/api/message/alarm-config.ts → src/api/message/message.ts


+ 0 - 112
src/api/message/person-group.ts

@@ -1,112 +0,0 @@
-import { http } from '@/utils/http/axios';
-
-// 已弃用
-export function queryUserTree() {
-  return http.request({
-    url: '/dept/queryUserTree',
-    method: 'get',
-  });
-}
-export interface addUserGroupParams {
-  description?: string;
-  name: string;
-  total: number;
-  userIdList: number[];
-}
-export function addUserGroup(params: addUserGroupParams) {
-  return http.request({
-    url: '/userGroup/addUserGroup',
-    method: 'post',
-    params,
-  });
-}
-export interface queryUserGroupListParams {
-  pageNumber: number;
-  pageSize: number;
-  queryStr?: string;
-}
-export function queryUserGroupList(params: queryUserGroupListParams) {
-  return http.request({
-    url: '/userGroup/queryUserGroupList',
-    method: 'post',
-    params,
-  });
-}
-export function verifyUserGroup(userGroupId: number) {
-  return http.request({
-    url: '/userGroup/verifyUserGroup',
-    method: 'get',
-    params: { userGroupId },
-  });
-}
-export function deleteUserGroup(userGroupId: number) {
-  return http.request({
-    url: `/userGroup/deleteUserGroup?userGroupId=${userGroupId}`,
-    method: 'delete',
-    params: { userGroupId },
-  });
-}
-export function getUserGroupDetail(userGroupId: number) {
-  return http.request({
-    url: '/userGroup/queryUserGroupDetail',
-    method: 'get',
-    params: { userGroupId },
-  });
-}
-export interface modifyUserGroupParams extends addUserGroupParams {
-  userGroupId: number;
-}
-export function modifyUserGroup(params: modifyUserGroupParams) {
-  return http.request({
-    url: '/userGroup/modifyUserGroup',
-    method: 'post',
-    params,
-  });
-}
-export function ToPushObjectqueryUserGroupList() {
-  return http.request({
-    url: '/userGroup/ToPushObjectqueryUserGroupList',
-    method: 'post',
-  });
-}
-export function queryUserGroupDetail(userGroupList: number[]) {
-  return http.request({
-    url: `/alarmMessage/queryUserGroupDetail?userGroupList=${userGroupList}`,
-    method: 'post',
-  });
-}
-
-export interface QueryPersonFilterParams {
-  deptName?: string;
-  nickname?: string;
-  staffNo?: string;
-  pageNumber: number;
-  pageSize: number;
-}
-export function queryPersonFilterList(params: QueryPersonFilterParams) {
-  return http.request({
-    url: '/dept/queryAvailableUserList',
-    method: 'post',
-    params,
-  });
-}
-
-export interface QueryPersonFilterListReturn {
-  total: number;
-  availableUserDTOS: FilterPersonInfo[];
-}
-
-export interface SelectedFilterPersonInfo {
-  id: number;
-  nickname: string;
-  staffNo: string;
-}
-
-export interface FilterPersonInfo extends SelectedFilterPersonInfo {
-  id: number;
-  nickname: string;
-  deptId: number;
-  deptName: string;
-  staffNo: string;
-  checked?: boolean;
-}

+ 0 - 73
src/api/message/report-message.ts

@@ -1,73 +0,0 @@
-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',
-  });
-}
-export function queryReportConfigList(type: number) {
-  return http.request({
-    url: '/reportMessage/queryReportConfigList',
-    method: 'get',
-    params: { type },
-  });
-}
-export function deleteReportConfig(type: number, statisticType: number) {
-  return http.request({
-    url: `/reportMessage/deleteReportConfig?type=${type}&statisticType=${statisticType}`,
-    method: 'post',
-  });
-}
-export interface queryPushRecordsParams {
-  pageNum: number;
-  pageSize: number;
-  statisticType?: number;
-  type?: number;
-}
-export function queryPushRecords(params: queryPushRecordsParams) {
-  return http.request({
-    url: '/reportMessage/queryPushRecords',
-    method: 'post',
-    params,
-  });
-}
-export interface updateStatusParams {
-  type: number;
-  statisticType: number;
-  status: number;
-}
-export function updateStatus(params: updateStatusParams) {
-  return http.request({
-    url: `/reportMessage/updateStatus?statisticType=${params.statisticType}&status=${params.status}&type=${params.type}`,
-    method: 'post',
-  });
-}

+ 0 - 64
src/api/message/system-notifications.ts

@@ -1,64 +0,0 @@
-import { http } from '@/utils/http/axios';
-
-export interface queryParams {
-  content?: string;
-  pageNumber: number;
-  pageSize: number;
-}
-// 获取系统通知数据列表
-export function getSystemMessageList(params: queryParams) {
-  return http.request({
-    url: '/systemMessage/getSystemMessageList',
-    method: 'get',
-    params,
-  });
-}
-// 删除系统消息通知
-export function deleteSystemMessage(id: number) {
-  return http.request({
-    url: `/systemMessage/deleteSystemMessage?id=${id}`,
-    method: 'post',
-  });
-}
-
-// 获取问题处理通知
-export function queryIssueProcessMessage() {
-  return http.request({
-    url: '/issueProcessMessage/queryIssueProcessMessage',
-    method: 'post',
-  });
-}
-
-// 修改推送文案
-export function modifyContent(content: string, id: number) {
-  return http.request({
-    url: `/issueProcessMessage/modifyContent?content=${content}&id=${id}`,
-    method: 'post',
-  });
-}
-
-// 获取车间列表
-export function getList() {
-  return http.request({
-    url: '/scene/getList',
-    method: 'get',
-  });
-}
-
-// 下发车间
-export function modifyWorkshopList(workshopList: number[]) {
-  return http.request({
-    url: '/issueProcessMessage/modifyWorkshopList',
-    method: 'post',
-    params: { workshopList },
-  });
-}
-
-// 查询车间姓名
-export function queryWorkshopNamebyIds(workshopList: number[]) {
-  return http.request({
-    url: '/issueProcessMessage/queryWorkshopNamebyIds',
-    method: 'post',
-    params: { workshopList },
-  });
-}

+ 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',
+  });
+}

BIN
src/assets/images/person-group-empty.png


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

@@ -0,0 +1,82 @@
+<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"
+      class="workShopDialog"
+    >
+      <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted, watch } 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', 'ruleFormRef'])
+// const userIDList = ref()
+
+const handleCancle = () => {
+  dialogVisible.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  prop.form.customPushConfigList[prop.index].customUserList.length = 0
+  prop.form.customPushConfigList[prop.index].customUserList.push(...selectedUser.value)
+  prop.ruleFormRef.validateField(`customPushConfigList[` + prop.index + `].customUserList`)
+  dialogVisible.value = false;
+};
+watch(
+  () => prop.form.customPushConfigList[prop.index].customUserList,
+  (newSelected) => {
+    selectedUser.value = newSelected
+  },
+  { deep: true,immediate: true },
+);
+  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 {
+    min-height: 25px;
+    max-height: 60px;
+    overflow-y: auto;
+  }
+</style>

+ 75 - 0
src/views/message/SelectTree.vue

@@ -0,0 +1,75 @@
+<template>
+  <div>
+    <!-- v-model="userList" -->
+    <el-select
+      v-model="prop.form.customUserList.value"
+      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"
+      class="workShopDialog"
+    >
+      <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onMounted, watch } from 'vue';
+import SelectTree from './persongroup/components/SelectTree.vue';
+interface UserList {
+  id: string;
+  name: string;
+  userId: number;
+}
+const dialogVisible = ref<boolean>(false);
+const selectedUser = ref<UserList[]>([]);
+
+const prop = defineProps(['form', 'disableType']);
+
+const handleCancle = () => {
+  dialogVisible.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  prop.form.customUserList.value = selectedUser.value;
+  dialogVisible.value = false;
+};
+watch(
+  () => prop.form.customUserList.value,
+  (newSelected) => {
+    selectedUser.value = newSelected;
+  },
+  { deep: true, immediate: true },
+);
+onMounted(() => {
+  if (prop.form.customUserList.value.length > 0) {
+    console.log(prop.form.customUserList.value);
+    selectedUser.value = prop.form.customUserList.value;
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+::v-deep .el-dialog__body {
+  height: 527px;
+}
+::v-deep .el-select__selection {
+  min-height: 25px;
+  max-height: 60px;
+  overflow-y: auto;
+}
+</style>

+ 2 - 2
src/views/message/alarm-config/AlarmConfig.vue

@@ -168,7 +168,7 @@
     // type UserGroupVOItem,
     // type CustomUserItem,
     type AvailableAlarmType,
-  } from '@/api/message/alarm-config';
+  } from '@/api/message/message';
   import {
     // AlarmLevel,
     ALARMLEVEL_LIST,
@@ -240,7 +240,7 @@
       AlarmTypes.value.push({
         id: res.violationType,
         name: res.violationName,
-      } as unknown as AvailableAlarmType);
+      } as AvailableAlarmType);
     });
   };
 

+ 23 - 0
src/views/message/alarmMessages/api/index.ts

@@ -0,0 +1,23 @@
+import { http } from '@/utils/http/axios';
+
+export function getAlarmMessageList(params) {  // 获取报警数据列表
+    return http.request({
+        url: '/alarmMessage/getAlarmMessageList',
+        method: 'get',
+        params
+    });
+}
+
+export function deleteAlarmMessage(id) {  // 删除报警数据
+    return http.request({
+        url: `/alarmMessage/deleteAlarmMessage?id=${id}`,
+        method: 'post',
+    });
+}
+
+export function updateAlarmStatus(params) {  // 修改报警数据状态
+    return http.request({
+        url: `/alarmMessage/updateStatus?id=${params.id}&status=${params.status}`,
+        method: 'post',
+    });
+}

+ 1 - 5
src/views/message/alarmMessages/hook/index.ts

@@ -1,9 +1,5 @@
 import { alarmTableData, alarmInfoRes, alarmLevelMapping, pushChannelMapping } from '../type';
-import {
-  getAlarmMessageList,
-  deleteAlarmMessage,
-  updateAlarmStatus,
-} from '@/api/message/alarm-messages';
+import { getAlarmMessageList, deleteAlarmMessage, updateAlarmStatus } from '../api/index';
 import { reactive, ref, onMounted } from 'vue';
 import { defineStore } from 'pinia';
 

+ 13 - 0
src/views/message/api/index.ts

@@ -0,0 +1,13 @@
+import { http } from '@/utils/http/axios';
+export function ToPushObjectqueryUserGroupList() {
+    return http.request({
+        url: '/userGroup/ToPushObjectqueryUserGroupList',
+        method: 'post',
+    });
+}
+export function queryUserGroupDetail(userGroupList: number[]) {
+    return http.request({
+        url: `/alarmMessage/queryUserGroupDetail?userGroupList=${userGroupList}`,
+        method: 'post',
+    });
+}

+ 0 - 247
src/views/message/components/PersonFilterSelection.vue

@@ -1,247 +0,0 @@
-<template>
-  <div class="person-filter-selection">
-    <div class="left">
-      <div class="filter-title">
-        <el-form-item>
-          <el-input
-            v-model="personFilterValue"
-            style="width: 253px"
-            placeholder="请输入搜索的内容"
-            clearable
-          >
-            <template #prepend>
-              <el-select
-                v-model="personFilterType"
-                style="width: 74px"
-                value-key="type"
-                :validate-event="false"
-              >
-                <el-option
-                  v-for="item in FILTER_TYPES"
-                  :key="item.type"
-                  :value="item"
-                  :label="item.label"
-                />
-              </el-select>
-            </template>
-          </el-input>
-          <div style="float: right">
-            <el-button
-              type="primary"
-              @click="debouncedHandleFilter"
-              style="width: 65px; height: 32px; margin: 0 11px 0"
-              >搜 索</el-button
-            >
-          </div>
-        </el-form-item>
-      </div>
-      <!-- 搜索结果展示 -->
-      <div
-        v-if="personFilterList?.availableUserDTOS?.length"
-        class="filter-result"
-        ref="filterResult"
-      >
-        <div
-          class="filter-result-item"
-          v-for="person in personFilterList.availableUserDTOS"
-          :key="person.id"
-        >
-          <el-checkbox
-            v-model="person.checked"
-            :label="person.staffNo + '-' + person.nickname + '&nbsp' + '(' + person.deptName + ')'"
-            @change="handleSelect($event, person)"
-          ></el-checkbox>
-          <!-- <div style="margin-left: 8px">
-            {{ person.staffNo + '-' + person.nickname + '&nbsp' + '(' + person.deptName + ')' }}
-          </div> -->
-        </div>
-        <div
-          id="next-loading"
-          style="text-align: center"
-          v-if="personFilterList.total > personFilterList.availableUserDTOS.length"
-        >
-          <el-icon class="el-input__icon" :size="24">
-            <Loading />
-          </el-icon>
-        </div>
-      </div>
-      <div v-else-if="!personFilterList" class="filter-result-empty">
-        <img src="@/assets/images/person-group-empty.png" alt="" />
-        <div style="position: relative; top: -50px">请选择类型并搜索人员</div>
-      </div>
-      <div v-else class="filter-result-empty">
-        <div>未搜索到相关内容</div><div>请重新搜索</div>
-      </div>
-    </div>
-    <div class="right">
-      <div class="head">
-        <span
-          style="font-weight: 400; font-size: 16px; color: rgba(0, 0, 0, 0.88); line-height: 22px"
-          >已选择:{{ selectedPersonList.length }}人</span
-        >
-      </div>
-      <div class="selected">
-        <el-tag
-          v-for="person in selectedPersonList"
-          :key="person.id"
-          closable
-          @close="handleRemoveSelectedPerson(person.id)"
-        >
-          {{ person.staffNo + '-' + person.nickname }}
-        </el-tag>
-      </div>
-      <div class="footer">
-        <el-button @click="handleCancle"> 取消 </el-button>
-        <el-button type="primary" @click="handleSubmit">提交</el-button>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, onMounted, onBeforeUnmount } from 'vue';
-  import { Loading } from '@element-plus/icons-vue';
-  import { usePersonGroupFilterList } from '../persongroup/hook/usePersonGroupFilterList';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-  import { debounce } from 'lodash-es';
-
-  const {
-    FILTER_TYPES,
-    personFilterType,
-    personFilterValue,
-    personFilterList,
-    selectedPersonList,
-    getPersonFilterList,
-    getNextPersonFilterList,
-    handleAddSelectedPerson,
-    handleRemoveSelectedPerson,
-  } = usePersonGroupFilterList();
-  const emit = defineEmits(['cancel', 'submit']);
-
-  const props = defineProps<{
-    initSelected?: SelectedFilterPersonInfo[];
-  }>();
-
-  onMounted(() => {
-    if (props.initSelected) selectedPersonList.value = [...props.initSelected];
-  });
-
-  let observer: IntersectionObserver;
-
-  const filterResult = ref();
-  const handleFilter = () => {
-    getPersonFilterList().then(() => {
-      filterResult.value.scrollTop = 0;
-      const loading = document.getElementById('next-loading');
-      if (loading) {
-        if (observer) observer.unobserve(loading);
-        observer = new IntersectionObserver(
-          (entries) => {
-            if (entries[0].isIntersecting) {
-              getNextPersonFilterList();
-            }
-          },
-          {
-            threshold: 0.9,
-          },
-        );
-        observer.observe(loading);
-      }
-    });
-  };
-
-  const debouncedHandleFilter = debounce(handleFilter, 500);
-
-  const handleSelect = (v: boolean, person: any) => {
-    if (v) {
-      handleAddSelectedPerson(person);
-    } else {
-      handleRemoveSelectedPerson(person.id);
-    }
-  };
-  const handleCancle = () => {
-    emit('cancel');
-  };
-  const handleSubmit = () => {
-    emit('submit', selectedPersonList.value);
-  };
-
-  onBeforeUnmount(() => {
-    if (observer) {
-      observer.disconnect();
-    }
-  });
-</script>
-
-<style lang="scss" scoped>
-  .person-filter-selection {
-    display: flex;
-    width: 100%;
-    height: 98%;
-    .left {
-      display: flex;
-      flex-direction: column;
-      width: 50%;
-      height: 100%;
-      border-right: 1px solid rgba(0, 0, 0, 0.06);
-      // .filter-title {
-      // }
-      .filter-result {
-        display: flex;
-        flex-direction: column;
-        gap: 8px;
-        height: 392px;
-        overflow: auto;
-        // .filter-result-item {
-        //   display: flex;
-        //   align-items: center;
-        //   font-weight: 500;
-        //   font-size: 14px;
-        //   color: #303133;
-        //   line-height: 22px;
-        // }
-      }
-      .filter-result-empty {
-        display: flex;
-        flex-direction: column;
-        justify-content: center;
-        align-items: center;
-        height: 100%;
-        font-weight: 400;
-        font-size: 14px;
-        color: #999999;
-      }
-    }
-    .right {
-      display: flex;
-      flex-direction: column;
-      flex: 1;
-      height: 100%;
-      position: relative;
-      margin-left: 16px;
-      .head {
-        display: flex;
-        align-items: center;
-        font-weight: 400;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 22px;
-        margin: 6px 0 6px;
-      }
-      .selected {
-        display: flex;
-        flex-wrap: wrap;
-        gap: 8px;
-        overflow-y: auto;
-        max-height: calc(100% - 120px);
-      }
-      .footer {
-        display: flex;
-        gap: 6px;
-        position: absolute;
-        right: 24px;
-        bottom: 20px;
-      }
-    }
-  }
-</style>

+ 191 - 203
src/views/message/components/PushObject.vue

@@ -57,12 +57,7 @@
           @click="userInfo = true"
           :disabled="disabled"
         >
-          <el-option
-            v-for="user in selectedUser"
-            :key="user.id"
-            :label="user.staffNo + '-' + user.nickname"
-            :value="user"
-          >
+          <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
           </el-option>
         </el-select>
       </el-form-item>
@@ -83,220 +78,213 @@
   <el-dialog
     v-model="userInfo"
     class="userInfo"
-    title="添加员"
+    title="添加组内成员"
     align-center
     :close-on-click-modal="false"
     style="height: 583px"
     :width="731"
     :destroy-on-close="true"
   >
-    <!-- <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-    <PersonFilterSelection
-      @cancel="handleCancle"
-      @submit="handleSubmit"
-      :init-selected="selectedUser"
-    />
+    <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
   </el-dialog>
 </template>
 
 <script setup lang="ts">
-  import { onMounted, ref, reactive, watch, watchEffect } from 'vue';
-  // import SelectTree from '../persongroup/components/SelectTree.vue';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-  import PersonFilterSelection from '@/views/message/components/PersonFilterSelection.vue';
-  import Group from './Group.vue';
-  import { recipientTypeName } from '../constant';
-  import { ToPushObjectqueryUserGroupList, queryUserGroupDetail } from '@/api/message/person-group';
-  import type { FormInstance } from 'element-plus';
-  import { GroupData } from '../persongroup/type';
-  const ruleFormRef = ref<FormInstance>();
-  const groupInfo = ref<boolean>(false);
-  const userInfo = ref<boolean>(false);
-  const disabled = ref<boolean>(false);
-  export interface customUserList {
-    userId: number;
-    userLoginName: string;
-    userNickname: string;
-    userNumber: string;
-  }
-  export interface userGroupVOList {
-    userGroupId: number;
-    total: number;
-    operatorName: string;
-    operationTime: string;
-    name: string;
-    description: string;
-  }
-  // interface UserList {
-  //   id: string;
-  //   name: string;
-  //   userId: number;
-  // }
-  const selectedUser = ref<SelectedFilterPersonInfo[]>([]);
-  interface RuleForm {
-    recipientType?: number;
-    userGroupList: number[];
-    customUserList: SelectedFilterPersonInfo[];
-  }
-  const ruleForm = reactive<RuleForm>({
-    userGroupList: [],
-    customUserList: [],
-  });
-  const props = defineProps<{
-    recipientType?: number;
-    userGroupList?: userGroupVOList[];
-    customUserList?: customUserList[];
-    disabled?: boolean;
-  }>();
-  const emit = defineEmits(['submitWithForm']);
-  interface Options {
-    userGroupId?: number;
-    name?: string;
-    description: string;
-    total: number;
-    operatorName: string;
-    operationTime: string;
-  }
-  const options = ref<Options[]>([]);
-  const userGroupInfo = ref<GroupData[]>();
-  const queryGroupInfo = (groupList) => {
-    groupInfo.value = true;
-    queryUserGroupDetail(groupList).then((res) => {
-      userGroupInfo.value = res.map((group) => ({
-        ...group,
-        isExpand: false,
-        isHidden: false,
-      }));
-    });
-  };
-  const submitForm = () => {
-    return ruleFormRef.value!.validate(() => {});
-  };
-  const refreshForm = () => {
-    if (!ruleFormRef.value) return;
-    ruleFormRef.value!.resetFields();
-  };
-  const validateForm = () => {
-    return new Promise((resolve, reject) => {
-      ruleFormRef
-        .value!.validate(() => {})
-        .then((valid) => {
-          if (valid) {
-            const res = getChildValue();
-            emit('submitWithForm', res);
-            resolve(() => {});
-          } else {
-            reject(new Error('error submit!'));
-          }
-        });
-    });
-  };
-  const getChildValue = () => {
-    return {
-      recipientType: ruleForm.recipientType,
-      userGroupList:
-        ruleForm.recipientType === 3
-          ? []
-          : ruleForm.recipientType === 1
-          ? []
-          : ruleForm.userGroupList.map((item) => item),
-      customUserList:
-        ruleForm.recipientType === 2
-          ? []
-          : ruleForm.recipientType === 1
-          ? []
-          : ruleForm.customUserList.map((item) => item.id),
-    };
-  };
-  const handleCancle = () => {
-    userInfo.value = false;
-  };
-  const handleSubmit = (selectedData: SelectedFilterPersonInfo[]) => {
-    selectedUser.value = selectedData;
-    ruleForm.customUserList = selectedUser.value;
-    userInfo.value = false;
-  };
-  const formatCustomUserList = (customList: customUserList[]): SelectedFilterPersonInfo[] => {
-    return customList.map((item) => ({
-      id: item.userId,
-      staffNo: item.userLoginName,
-      nickname: item.userNickname,
+import { onMounted, ref, reactive, watch, watchEffect } from 'vue';
+import SelectTree from '../persongroup/components/SelectTree.vue';
+import Group from './Group.vue';
+import { recipientTypeName } from '../constant';
+import { ToPushObjectqueryUserGroupList, queryUserGroupDetail } from '../api/index';
+import type { FormInstance } from 'element-plus';
+import { GroupData } from '../persongroup/type';
+const ruleFormRef = ref<FormInstance>();
+const groupInfo = ref<boolean>(false);
+const userInfo = ref<boolean>(false);
+const disabled = ref<boolean>(false);
+export interface customUserList {
+  userId: number;
+  userLoginName: string;
+  userNickname: string;
+  userNumber: string;
+}
+export interface userGroupVOList {
+  userGroupId: number;
+  total: number;
+  operatorName: string;
+  operationTime: string;
+  name: string;
+  description: string;
+}
+interface UserList {
+  id: string;
+  name: string;
+  userId: number;
+}
+const selectedUser = ref<UserList[]>([]);
+interface RuleForm {
+  recipientType?: number;
+  userGroupList: number[];
+  customUserList: UserList[];
+}
+const ruleForm = reactive<RuleForm>({
+  userGroupList: [],
+  customUserList: [],
+});
+const props = defineProps<{
+  recipientType?: number;
+  userGroupList?: userGroupVOList[];
+  customUserList?: customUserList[];
+  disabled?: boolean;
+}>();
+const emit = defineEmits(['submitWithForm']);
+interface Options {
+  userGroupId?: number;
+  name?: string;
+  description: string;
+  total: number;
+  operatorName: string;
+  operationTime: string;
+}
+const options = ref<Options[]>([]);
+const userGroupInfo = ref<GroupData[]>();
+const queryGroupInfo = (groupList) => {
+  groupInfo.value = true;
+  queryUserGroupDetail(groupList).then((res) => {
+    userGroupInfo.value = res.map((group) => ({
+      ...group,
+      isExpand: false,
+      isHidden: false,
     }));
-  };
-  defineExpose({
-    submitForm,
-    refreshForm,
-    validateForm,
-    getChildValue,
   });
-  onMounted(() => {
-    ToPushObjectqueryUserGroupList().then((res) => {
-      options.value = res.groupVOList;
-    });
+};
+const submitForm = () => {
+  return ruleFormRef.value!.validate(() => {});
+};
+const refreshForm = () => {
+  if (!ruleFormRef.value) return;
+  ruleFormRef.value!.resetFields();
+};
+const validateForm = () => {
+  return new Promise((resolve, reject) => {
+    ruleFormRef
+      .value!.validate(() => {})
+      .then((valid) => {
+        if (valid) {
+          const res = getChildValue();
+          emit('submitWithForm', res);
+          resolve(() => {});
+        } else {
+          reject(new Error('error submit!'));
+        }
+      });
   });
-  watchEffect(() => {
-    if (props.recipientType) {
-      ruleForm.recipientType = props.recipientType;
-    }
-    if (props.userGroupList) {
-      ruleForm.userGroupList = props.userGroupList.map((item) => item.userGroupId);
-    }
-    if (props.customUserList) {
-      ruleForm.customUserList = formatCustomUserList(props.customUserList);
-      selectedUser.value = formatCustomUserList(props.customUserList);
-    }
-    if (props.disabled) {
-      disabled.value = props.disabled;
-    }
+};
+const getChildValue = () => {
+  return {
+    recipientType: ruleForm.recipientType,
+    userGroupList:
+      ruleForm.recipientType === 3
+        ? []
+        : ruleForm.recipientType === 1
+        ? []
+        : ruleForm.userGroupList.map((item) => item),
+    customUserList:
+      ruleForm.recipientType === 2
+        ? []
+        : ruleForm.recipientType === 1
+        ? []
+        : ruleForm.customUserList.map((item) => item.userId),
+  };
+};
+const handleCancle = () => {
+  userInfo.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  ruleForm.customUserList = selectedUser.value;
+  userInfo.value = false;
+};
+const formatCustomUserList = (customList: customUserList[]): UserList[] => {
+  return customList.map((item) => ({
+    id: `u${item.userId}`,
+    userId: item.userId,
+    name: `${item.userLoginName}-${item.userNickname}`,
+  }));
+};
+defineExpose({
+  submitForm,
+  refreshForm,
+  validateForm,
+  getChildValue,
+});
+onMounted(() => {
+  ToPushObjectqueryUserGroupList().then((res) => {
+    options.value = res.groupVOList;
   });
-  watch(
-    () => ruleForm.customUserList,
-    (newSelected) => {
-      selectedUser.value = newSelected;
-    },
-    { immediate: true },
-  );
+});
+watchEffect(() => {
+  if (props.recipientType) {
+    ruleForm.recipientType = props.recipientType;
+  }
+  if (props.userGroupList) {
+    ruleForm.userGroupList = props.userGroupList.map((item) => item.userGroupId);
+  }
+  if (props.customUserList) {
+    ruleForm.customUserList = formatCustomUserList(props.customUserList);
+    selectedUser.value = formatCustomUserList(props.customUserList);
+  }
+  if (props.disabled) {
+    disabled.value = props.disabled;
+  }
+});
+watch(
+  () => ruleForm.customUserList,
+  (newSelected) => {
+    selectedUser.value = newSelected;
+  },
+  { immediate: true },
+);
 </script>
 
 <style lang="scss" scoped>
-  .userGroupList {
-    margin-left: 12%;
-    width: 88%;
-    max-height: 120px;
-    padding: 12px 17px 12px 12px;
-    background: #fafafa;
-    border-radius: 4px;
-    :deep(.el-form-item) {
-      margin-bottom: 12px !important;
-    }
-    ::v-deep .el-select__selection {
-      min-height: 25px;
-      max-height: 60px;
-      overflow-y: auto;
-    }
-    span {
-      cursor: pointer;
-      margin-left: 80px;
-      font-weight: 400;
-      font-size: 10px;
-      color: #1777ff;
-      line-height: 14px;
-    }
+.userGroupList {
+  margin-left: 12%;
+  width: 88%;
+  max-height: 120px;
+  padding: 12px 17px 12px 12px;
+  background: #fafafa;
+  border-radius: 4px;
+  :deep(.el-form-item) {
+    margin-bottom: 12px !important;
+  }
+  ::v-deep .el-select__selection {
+    min-height: 25px;
+    max-height: 60px;
+    overflow-y: auto;
+  }
+  span {
+    cursor: pointer;
+    margin-left: 80px;
+    font-weight: 400;
+    font-size: 10px;
+    color: #1777ff;
+    line-height: 14px;
+  }
+}
+.customUserList {
+  margin-left: 12%;
+  width: 88%;
+  max-height: 120px;
+  padding: 12px 17px 12px 12px;
+  background: #fafafa;
+  border-radius: 4px;
+  :deep(.el-form-item) {
+    margin-bottom: 12px !important;
   }
-  .customUserList {
-    margin-left: 12%;
-    width: 88%;
-    max-height: 120px;
-    padding: 12px 17px 12px 12px;
-    background: #fafafa;
-    border-radius: 4px;
-    :deep(.el-form-item) {
-      margin-bottom: 12px !important;
-    }
-    ::v-deep .el-select__selection {
-      min-height: 25px;
-      max-height: 60px;
-      overflow-y: auto;
-    }
+  ::v-deep .el-select__selection {
+    min-height: 25px;
+    max-height: 60px;
+    overflow-y: auto;
   }
+}
 </style>

+ 76 - 0
src/views/message/designatedUserSelectTree.vue

@@ -0,0 +1,76 @@
+<template>
+  <div>
+    <!-- v-model="userList" -->
+    <el-select
+      v-model="prop.form.designatedUserList.value"
+      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"
+      class="workShopDialog"
+    >
+      <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref, onBeforeUpdate, watch } from 'vue';
+import SelectTree from './persongroup/components/SelectTree.vue';
+interface UserList {
+  id: string;
+  name: string;
+  userId: number;
+}
+const dialogVisible = ref<boolean>(false);
+const selectedUser = ref<UserList[]>([]);
+
+const prop = defineProps(['form', 'disableType'])
+
+const handleCancle = () => {
+  dialogVisible.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  prop.form.designatedUserList.value = selectedUser.value;
+  dialogVisible.value = false;
+};
+
+watch(
+  () => prop.form.designatedUserList.value,
+  (newSelected) => {
+    selectedUser.value = newSelected
+  },
+  { deep: true,immediate: true },
+);
+
+onBeforeUpdate(()=>{
+    if(prop.form.designatedUserList?.value?.length > 0){
+      selectedUser.value = prop.form.designatedUserList.value
+    }
+  })
+</script>
+
+<style lang="scss" scoped>
+::v-deep .el-dialog__body {
+  height: 527px;
+}
+::v-deep .el-select__selection {
+    min-height: 25px;
+    max-height: 60px;
+    overflow-y: auto;
+  }
+</style>

+ 180 - 180
src/views/message/persongroup/UserGroup.vue

@@ -67,201 +67,201 @@
         :close-on-click-modal="false"
         :destroy-on-close="true"
       >
-        <GroupBoard @close="drawer = false" :drawer-title="drawerTitle" :form-data="formData!" />
+        <GroupBoard @close="drawer = false" :drawer-title="drawerTitle" :form-data="formData" />
       </el-drawer>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import Search from './components/Search.vue';
-  import GroupBoard from './components/GroupBoard.vue';
-  import { h, ref, reactive, onMounted, computed } from 'vue';
-  import { BasicTable, TableActionIcons, BasicColumn } from '@/components/Table';
-  import { userGroupCol } from './overviewColumns';
-  import userGroupList from './store/index';
-  import { storeToRefs } from 'pinia';
-  const userGroup = userGroupList();
-  const { userListData, total, page, pagesize } = storeToRefs(userGroup);
-  const { getUserGroup } = userGroup;
-  import { verifyUserGroup, deleteUserGroup, getUserGroupDetail } from '@/api/message/person-group';
-  import { FormData } from './type';
-  import viewIcon from '@/assets/images/reportmessage/view.png';
-  import editIcon from '@/assets/images/reportmessage/edit.png';
-  import deleteIcon from '@/assets/images/reportmessage/delete.png';
-  import { ElMessage, ElMessageBox } from 'element-plus';
-  import { messageTypeName } from '@/views/message/constant';
-  const drawer = ref(false);
-  const drawerTitle = ref<string>('新建人员分组');
-  const handleCreateGroup = () => {
-    drawer.value = true;
-    drawerTitle.value = '新建人员分组';
-  };
-  const getLabel = (messageType) => {
-    const messageTypeLabel = messageTypeName.find((item) => item.value === messageType)?.label;
-    return `${messageTypeLabel}`;
-  };
-  const errorVisible = ref<boolean>(false);
-  const showAll = ref<boolean>(false);
-  const refGroup = ref<Array<{ type: number; statisticType: number; messageType: number }>>();
-  const actionColumn: BasicColumn = reactive({
-    width: 224,
-    title: '操作',
-    prop: 'action',
-    key: 'action',
-    fixed: 'right',
-    render(record) {
-      return h(TableActionIcons as any, {
-        space: 20,
-        color: '#629bf9',
-        style: 'img',
-        size: 16,
-        actionIcons: [
-          {
-            label: '查看',
-            icon: viewIcon,
-            onClick: handleView.bind(null, record.row),
-          },
-          {
-            label: '编辑',
-            icon: editIcon,
-            onClick: handleEdit.bind(null, record.row),
-          },
-          {
-            label: '删除',
-            icon: deleteIcon,
-            onClick: handleDelete.bind(null, record.row),
-          },
-        ],
-      });
-    },
-  });
-  const handlePageNumChange = (pageNum) => {
-    page.value = pageNum;
-    getUserGroup();
-  };
-  const handlePageSizeChange = (size) => {
-    pagesize.value = size;
-    page.value = 1;
-    getUserGroup();
-  };
-  const formData = ref<FormData>();
-  const handleView = (record: Recordable) => {
-    drawer.value = true;
-    drawerTitle.value = '查看人员分组';
-    getUserGroupDetail(record.userGroupId).then((res) => {
-      formData.value = res;
-    });
-  };
-  const handleEdit = (record: Recordable) => {
-    drawer.value = true;
-    drawerTitle.value = '编辑人员分组';
-    getUserGroupDetail(record.userGroupId).then((res) => {
-      formData.value = res;
+import Search from './components/Search.vue';
+import GroupBoard from './components/GroupBoard.vue';
+import { h, ref, reactive, onMounted, computed } from 'vue';
+import { BasicTable, TableActionIcons, BasicColumn } from '@/components/Table';
+import { userGroupCol } from './overviewColumns';
+import userGroupList from './store/index';
+import { storeToRefs } from 'pinia';
+const userGroup = userGroupList();
+const { userListData, total, page, pagesize } = storeToRefs(userGroup);
+const { getUserGroup } = userGroup;
+import { verifyUserGroup, deleteUserGroup, queryUserGroupDetail } from './api/index';
+import { FormData } from './type';
+import viewIcon from '@/assets/images/reportmessage/view.png';
+import editIcon from '@/assets/images/reportmessage/edit.png';
+import deleteIcon from '@/assets/images/reportmessage/delete.png';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { messageTypeName } from '@/views/message/constant';
+const drawer = ref(false);
+const drawerTitle = ref<string>('新建人员分组');
+const handleCreateGroup = () => {
+  drawer.value = true;
+  drawerTitle.value = '新建人员分组';
+};
+const getLabel = (messageType) => {
+  const messageTypeLabel = messageTypeName.find((item) => item.value === messageType)?.label;
+  return `${messageTypeLabel}`;
+};
+const errorVisible = ref<boolean>(false);
+const showAll = ref<boolean>(false);
+const refGroup = ref<Array<{ type: number; statisticType: number; messageType: number }>>();
+const actionColumn: BasicColumn = reactive({
+  width: 224,
+  title: '操作',
+  prop: 'action',
+  key: 'action',
+  fixed: 'right',
+  render(record) {
+    return h(TableActionIcons as any, {
+      space: 20,
+      color: '#629bf9',
+      style: 'img',
+      size: 16,
+      actionIcons: [
+        {
+          label: '查看',
+          icon: viewIcon,
+          onClick: handleView.bind(null, record.row),
+        },
+        {
+          label: '编辑',
+          icon: editIcon,
+          onClick: handleEdit.bind(null, record.row),
+        },
+        {
+          label: '删除',
+          icon: deleteIcon,
+          onClick: handleDelete.bind(null, record.row),
+        },
+      ],
     });
-  };
-  const handleDelete = (record: Recordable) => {
-    ElMessageBox.confirm('删除之后,该分组将无法恢复', '请确认是否删除', {
-      confirmButtonText: '确定',
-      cancelButtonText: '取消',
-      type: 'warning',
-    })
-      .then(() => {
-        verifyUserGroup(record.userGroupId).then((res) => {
-          const uniqueRes = Array.from(
-            new Map(res.map((item) => [item.messageType, item])).values(),
-          ) as any;
-          refGroup.value = uniqueRes;
-          if (refGroup.value?.length! > 0) {
-            errorVisible.value = true;
-          } else {
-            deleteUserGroup(record.userGroupId).then(() => {
-              ElMessage.success('删除成功');
-              getUserGroup();
-            });
-          }
-        });
-      })
-      .catch(() => {});
-  };
-  const visibleRefGroup = computed(() => {
-    return showAll.value ? refGroup.value : refGroup.value!.slice(0, 3);
+  },
+});
+const handlePageNumChange = (pageNum) => {
+  page.value = pageNum;
+  getUserGroup();
+};
+const handlePageSizeChange = (size) => {
+  pagesize.value = size;
+  page.value = 1;
+  getUserGroup();
+};
+const formData = ref<FormData>();
+const handleView = (record: Recordable) => {
+  drawer.value = true;
+  drawerTitle.value = '查看人员分组';
+  queryUserGroupDetail(record.userGroupId).then((res) => {
+    formData.value = res;
   });
-  onMounted(() => {
-    getUserGroup();
+};
+const handleEdit = (record: Recordable) => {
+  drawer.value = true;
+  drawerTitle.value = '编辑人员分组';
+  queryUserGroupDetail(record.userGroupId).then((res) => {
+    formData.value = res;
   });
+};
+const handleDelete = (record: Recordable) => {
+  ElMessageBox.confirm('删除之后,该分组将无法恢复', '请确认是否删除', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+    .then(() => {
+      verifyUserGroup(record.userGroupId).then((res) => {
+        const uniqueRes = Array.from(
+          new Map(res.map((item) => [item.messageType, item])).values(),
+        ) as any;
+        refGroup.value = uniqueRes;
+        if (refGroup.value?.length! > 0) {
+          errorVisible.value = true;
+        } else {
+          deleteUserGroup(record.userGroupId).then(() => {
+            ElMessage.success('删除成功');
+            getUserGroup();
+          });
+        }
+      });
+    })
+    .catch(() => {});
+};
+const visibleRefGroup = computed(() => {
+  return showAll.value ? refGroup.value : refGroup.value!.slice(0, 3);
+});
+onMounted(() => {
+  getUserGroup();
+});
 </script>
 
 <style lang="scss" scoped>
-  .user-group {
-    position: relative;
-    height: calc(100vh - 64px - 18px);
-    background-color: rgba(255, 255, 255, 1);
-    padding: 21px;
-    .user-list {
-      margin-top: 24px;
-    }
-    ::v-deep .el-pagination {
+.user-group {
+  position: relative;
+  height: calc(100vh - 64px - 18px);
+  background-color: rgba(255, 255, 255, 1);
+  padding: 21px;
+  .user-list {
+    margin-top: 24px;
+  }
+  ::v-deep .el-pagination {
+    position: absolute;
+    bottom: 35px;
+    right: 67px;
+  }
+  .errorDialog {
+    .el-button {
       position: absolute;
-      bottom: 35px;
-      right: 67px;
+      bottom: 5px;
+      right: 24px;
     }
-    .errorDialog {
-      .el-button {
-        position: absolute;
-        bottom: 5px;
-        right: 24px;
-      }
-      .title {
-        font-weight: 400;
-        font-size: 14px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 22px;
-        margin-bottom: 8px;
-      }
-      .list {
-        display: flex;
-        flex-direction: column;
-        gap: 4px;
-        font-weight: 400;
-        font-size: 14px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 22px;
-        max-height: 300px;
-        overflow-y: auto;
-        margin-bottom: 15px;
-        .dot {
-          display: inline-block;
-          width: 8px;
-          height: 8px;
-          background-color: #ff4d4f;
-          border-radius: 50%;
-          margin-right: 8px;
-        }
-      }
-      .more-button {
-        font-weight: 400;
-        font-size: 14px;
-        color: #1890ff;
-        line-height: 20px;
-        text-decoration: underline;
-        cursor: pointer;
-      }
+    .title {
+      font-weight: 400;
+      font-size: 14px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 22px;
+      margin-bottom: 8px;
     }
-    ::v-deep .el-drawer__header {
-      margin: 0;
-      border-bottom: 1px solid rgba(0, 0, 0, 0.06);
-      span {
-        margin-bottom: 20px;
-        font-weight: 500;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 24px;
-      }
-      button {
-        margin-bottom: 20px;
-        color: #000000;
+    .list {
+      display: flex;
+      flex-direction: column;
+      gap: 4px;
+      font-weight: 400;
+      font-size: 14px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 22px;
+      max-height: 300px;
+      overflow-y: auto;
+      margin-bottom: 15px;
+      .dot {
+        display: inline-block;
+        width: 8px;
+        height: 8px;
+        background-color: #ff4d4f;
+        border-radius: 50%;
+        margin-right: 8px;
       }
     }
+    .more-button {
+      font-weight: 400;
+      font-size: 14px;
+      color: #1890ff;
+      line-height: 20px;
+      text-decoration: underline;
+      cursor: pointer;
+    }
+  }
+  ::v-deep .el-drawer__header {
+    margin: 0;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+    span {
+      margin-bottom: 20px;
+      font-weight: 500;
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 24px;
+    }
+    button {
+      margin-bottom: 20px;
+      color: #000000;
+    }
   }
-</style>
+}
+</style>

+ 63 - 0
src/views/message/persongroup/api/index.ts

@@ -0,0 +1,63 @@
+import { http } from '@/utils/http/axios';
+export function queryUserTree() {
+    return http.request({
+        url: '/dept/queryUserTree',
+        method: 'get',
+    });
+}
+export interface addUserGroupParams {
+    description?: string;
+    name: string;
+    total: number;
+    userIdList: number[]
+}
+export function addUserGroup(params: addUserGroupParams) {
+    return http.request({
+        url: '/userGroup/addUserGroup',
+        method: 'post',
+        params,
+    });
+}
+export interface queryUserGroupListParams {
+    pageNumber: number;
+    pageSize: number;
+    queryStr?: string;
+}
+export function queryUserGroupList(params: queryUserGroupListParams) {
+    return http.request({
+        url: '/userGroup/queryUserGroupList',
+        method: 'post',
+        params,
+    });
+}
+export function verifyUserGroup(userGroupId: number) {
+    return http.request({
+        url: '/userGroup/verifyUserGroup',
+        method: 'get',
+        params: { userGroupId },
+    });
+}
+export function deleteUserGroup(userGroupId: number) {
+    return http.request({
+        url: `/userGroup/deleteUserGroup?userGroupId=${userGroupId}`,
+        method: 'delete',
+        params: { userGroupId },
+    });
+}
+export function queryUserGroupDetail(userGroupId: number) {
+    return http.request({
+        url: '/userGroup/queryUserGroupDetail',
+        method: 'get',
+        params: { userGroupId },
+    });
+}
+export interface modifyUserGroupParams extends addUserGroupParams {
+    userGroupId: number;
+}
+export function modifyUserGroup(params: modifyUserGroupParams) {
+    return http.request({
+        url: '/userGroup/modifyUserGroup',
+        method: 'post',
+        params,
+    });
+}

+ 183 - 207
src/views/message/persongroup/components/GroupBoard.vue

@@ -57,13 +57,13 @@
         />
       </el-form-item>
       <el-form-item label="组内成员:" prop="userList" v-if="props.drawerTitle === '查看人员分组'">
-        <el-select v-model="ruleForm.userList" value-key="id" multiple disabled="true">
-          <el-option
-            v-for="user in selectedUser"
-            :key="user.id"
-            :label="user.staffNo + '-' + user.nickname"
-            :value="user"
-          >
+        <el-select
+          v-model="ruleForm.userList"
+          value-key="id"
+          multiple
+          disabled="true"
+        >
+          <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
           </el-option>
         </el-select>
         <p
@@ -83,12 +83,7 @@
           multiple
           @click="dialogVisible = true"
         >
-          <el-option
-            v-for="user in selectedUser"
-            :key="user.id"
-            :label="user.staffNo + '-' + user.nickname"
-            :value="user"
-          >
+          <el-option v-for="user in selectedUser" :key="user.id" :label="user.name" :value="user">
           </el-option>
         </el-select>
         <p
@@ -124,221 +119,202 @@
       :destroy-on-close="true"
       class="workShopDialog"
     >
-      <!-- <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-      <PersonFilterSelection
-        @cancel="handleCancle"
-        @submit="handleSubmit"
-        :init-selected="selectedUser"
-      />
+      <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" />
     </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
-  import { ref, reactive, watch } from 'vue';
-  // import SelectTree from './SelectTree.vue';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-
-  import PersonFilterSelection from '@/views/message/components/PersonFilterSelection.vue';
-  import { storeToRefs } from 'pinia';
-  import { useUserStore } from '@/store/modules/user';
-  import type { FormInstance } from 'element-plus';
-  import { ElMessage, ElMessageBox } from 'element-plus';
-  import { debounce } from 'lodash-es';
-  import {
-    addUserGroup,
-    addUserGroupParams,
-    modifyUserGroup,
-    modifyUserGroupParams,
-  } from '@/api/message/person-group';
-  import { FormData } from '../type';
-  const useUser = useUserStore();
-  const { info } = storeToRefs(useUser);
-  import userGroupList from '../store/index';
-  const userGroup = userGroupList();
-  const { getUserGroup } = userGroup;
-
-  // interface UserList {
-  //   id: string;
-  //   name: string;
-  //   userId: number;
-  // }
-  const selectedUser = ref<SelectedFilterPersonInfo[]>([]);
-  const dialogVisible = ref<boolean>(false);
-  const ruleFormRef = ref<FormInstance>();
-  const ruleForm = reactive({
-    name: '',
-    description: '',
-    userList: [] as SelectedFilterPersonInfo[],
-    operator: info.value.nickname,
+import { ref, reactive, watch } from 'vue';
+import SelectTree from './SelectTree.vue';
+import { storeToRefs } from 'pinia';
+import { useUserStore } from '@/store/modules/user';
+import type { FormInstance } from 'element-plus';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { debounce } from 'lodash-es';
+import {
+  addUserGroup,
+  addUserGroupParams,
+  modifyUserGroup,
+  modifyUserGroupParams,
+} from '../api/index';
+import { FormData } from '../type';
+const useUser = useUserStore();
+const { info } = storeToRefs(useUser);
+import userGroupList from '../store/index';
+const userGroup = userGroupList();
+const { getUserGroup } = userGroup;
+interface UserList {
+  id: string;
+  name: string;
+  userId: number;
+}
+const selectedUser = ref<UserList[]>([]);
+const dialogVisible = ref<boolean>(false);
+const ruleFormRef = ref<FormInstance>();
+const ruleForm = reactive({
+  name: '',
+  description: '',
+  userList: [] as UserList[],
+  operator: info.value.nickname,
+});
+const handleCancle = () => {
+  dialogVisible.value = false;
+};
+const total = ref<number>(0);
+const handleSubmit = (selectedData: UserList[]) => {
+  selectedUser.value = selectedData;
+  ruleForm.userList = selectedData;
+  total.value = ruleForm.userList.length;
+  dialogVisible.value = false;
+};
+const emit = defineEmits(['close']);
+const debounceEmit = debounce((addUserGroupParams) => {
+  addUserGroup(addUserGroupParams)
+    .then(() => {
+      ElMessage({
+        message: '创建分组成功!',
+        type: 'success',
+      });
+      emit('close');
+      getUserGroup();
+    })
+    .catch((e) => console.error(e));
+}, 500);
+const debounceChange = debounce((modifyUserGroupParams) => {
+  modifyUserGroup(modifyUserGroupParams)
+    .then(() => {
+      ElMessage({
+        message: '更新分组成功!',
+        type: 'success',
+      });
+      emit('close');
+      getUserGroup();
+    })
+    .catch((e) => console.error(e));
+}, 500);
+const submitForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.validate((valid) => {
+    if (!valid) return;
+    const params = ref<addUserGroupParams>();
+    params.value = {
+      name: ruleForm.name,
+      description: ruleForm.description,
+      userIdList: ruleForm.userList.map((user) => user.userId),
+      total: total.value,
+    };
+    debounceEmit(params.value);
   });
-  const handleCancle = () => {
-    dialogVisible.value = false;
-  };
-  const total = ref<number>(0);
-  const handleSubmit = (selectedData: SelectedFilterPersonInfo[]) => {
-    selectedUser.value = selectedData;
-    ruleForm.userList = selectedData;
-    total.value = ruleForm.userList.length;
-    dialogVisible.value = false;
-  };
-  const emit = defineEmits(['close']);
-  const debounceEmit = debounce((addUserGroupParams) => {
-    addUserGroup(addUserGroupParams)
-      .then(() => {
-        ElMessage({
-          message: '创建分组成功!',
-          type: 'success',
-        });
-        emit('close');
-        getUserGroup();
-      })
-      .catch((e) => console.error(e));
-  }, 500);
-  const debounceChange = debounce((modifyUserGroupParams) => {
-    modifyUserGroup(modifyUserGroupParams)
-      .then(() => {
-        ElMessage({
-          message: '更新分组成功!',
-          type: 'success',
-        });
-        emit('close');
-        getUserGroup();
-      })
-      .catch((e) => console.error(e));
-  }, 500);
-  const submitForm = (formEl: FormInstance | undefined) => {
+};
+const changeForm = (formEl: FormInstance | undefined) => {
+  ElMessageBox.confirm('更新之后,引用该分组的“推送对象”将同步更新', '请确认是否更新', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  }).then(() => {
     if (!formEl) return;
     formEl.validate((valid) => {
       if (!valid) return;
-      const params = ref<addUserGroupParams>();
+      const params = ref<modifyUserGroupParams>();
       params.value = {
+        userGroupId: props.formData.userGroupId,
         name: ruleForm.name,
         description: ruleForm.description,
-        userIdList: ruleForm.userList.map((user) => user.id),
+        userIdList: ruleForm.userList.map((user) => user.userId),
         total: total.value,
       };
-      debounceEmit(params.value);
-    });
-  };
-  const changeForm = (formEl: FormInstance | undefined) => {
-    ElMessageBox.confirm('更新之后,引用该分组的“推送对象”将同步更新', '请确认是否更新', {
-      confirmButtonText: '确定',
-      cancelButtonText: '取消',
-      type: 'warning',
-    }).then(() => {
-      if (!formEl) return;
-      formEl.validate((valid) => {
-        if (!valid) return;
-        const params = ref<modifyUserGroupParams>();
-        params.value = {
-          userGroupId: props.formData.userGroupId,
-          name: ruleForm.name,
-          description: ruleForm.description,
-          userIdList: ruleForm.userList.map((user) => user.id),
-          total: total.value,
-        };
-        debounceChange(params.value);
-      });
+      debounceChange(params.value);
     });
-  };
-  const resetForm = (formEl: FormInstance | undefined) => {
-    if (!formEl) return;
-    formEl.resetFields();
-  };
-  const userList = ref<SelectedFilterPersonInfo[]>();
-  const recoverForm = (formEl: FormInstance | undefined) => {
-    if (!formEl) return;
-    ruleForm.name = props.formData.name;
-    ruleForm.description = props.formData.description ? props.formData.description : '';
-    // userList.value = props.formData.userList.map((user) => ({
-    //   id: `u${user.userId}`,
-    //   userId: user.userId,
-    //   name: `${user.loginName}-${user.nickname}`,
-    // }));
-    userList.value = props.formData.userList.map((user) => ({
-      id: user.userId,
-      nickname: user.nickname,
-      staffNo: user.loginName,
+  });
+};
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+};
+const userList = ref<UserList[]>();
+const recoverForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  ruleForm.name = props.formData.name;
+  ruleForm.description = props.formData.description ? props.formData.description : '';
+  userList.value = props.formData.userList.map((user) => ({
+    id: `u${user.userId}`,
+    userId: user.userId,
+    name: `${user.loginName}-${user.nickname}`,
+  }));
+  selectedUser.value = userList.value;
+  ruleForm.userList = userList.value;
+  total.value = props.formData.userList.length;
+};
+const props = defineProps<{
+  drawerTitle: string;
+  formData: FormData;
+}>();
+watch(
+  () => ruleForm.userList,
+  (newUserList) => {
+    total.value = newUserList.length;
+    const ids = newUserList.map((user) => user.id);
+    selectedUser.value = selectedUser.value.filter((user) => ids.includes(user.id));
+  },
+  { immediate: true },
+);
+watch(
+  () => props.formData,
+  (newForm) => {
+    ruleForm.name = newForm.name;
+    ruleForm.description = newForm.description ? newForm.description : '';
+    if (props.drawerTitle === '查看人员分组') {
+      ruleForm.operator = newForm.operator;
+    }
+    userList.value = newForm.userList.map((user) => ({
+      id: `u${user.userId}`,
+      userId: user.userId,
+      name: `${user.loginName}-${user.nickname}`,
     }));
     selectedUser.value = userList.value;
     ruleForm.userList = userList.value;
-    total.value = props.formData.userList.length;
-  };
-  const props = defineProps<{
-    drawerTitle: string;
-    formData: FormData;
-  }>();
-  watch(
-    () => ruleForm.userList,
-    (newUserList) => {
-      total.value = newUserList.length;
-      const ids = newUserList.map((user) => user.id);
-      selectedUser.value = selectedUser.value.filter((user) => ids.includes(user.id));
-    },
-    { immediate: true },
-  );
-  watch(
-    () => props.formData,
-    (newForm) => {
-      ruleForm.name = newForm.name;
-      ruleForm.description = newForm.description ? newForm.description : '';
-      if (props.drawerTitle === '查看人员分组') {
-        ruleForm.operator = newForm.operator;
-      }
-      // userList.value = newForm.userList.map((user) => ({
-      //   id: `u${user.userId}`,
-      //   userId: user.userId,
-      //   name: `${user.loginName}-${user.nickname}`,
-      // }));
-      userList.value = props.formData.userList.map((user) => ({
-        id: user.userId,
-        nickname: user.nickname,
-        staffNo: user.loginName,
-      }));
-      selectedUser.value = userList.value;
-      ruleForm.userList = userList.value;
-      total.value = newForm.userList.length;
-    },
-  );
+    total.value = newForm.userList.length;
+  },
+);
 </script>
 
 <style lang="scss" scoped>
-  .el-form {
+.el-form {
+  display: flex;
+  flex-direction: column;
+  margin-top: 24px;
+  gap: 20px;
+  ::v-deep .el-select__selection {
+    min-height: 25px;
+    max-height: 60px;
+    overflow-y: auto;
+  }
+  p {
+    margin-top: 8px;
+    font-weight: 400;
+    font-size: 14px;
+    color: rgba(0, 0, 0, 0.85);
+    line-height: 22px;
+  }
+  span {
+    font-weight: 400;
+    font-size: 14px;
+    color: #1890ff;
+    line-height: 22px;
+  }
+  .buttons {
     display: flex;
-    flex-direction: column;
-    margin-top: 24px;
-    gap: 20px;
-    ::v-deep .el-select__selection {
-      min-height: 25px;
-      max-height: 60px;
-      overflow-y: auto;
-    }
-    p {
-      margin-top: 8px;
-      font-weight: 400;
-      font-size: 14px;
-      color: rgba(0, 0, 0, 0.85);
-      line-height: 22px;
-    }
-    span {
-      font-weight: 400;
-      font-size: 14px;
-      color: #1890ff;
-      line-height: 22px;
-    }
-    .buttons {
-      display: flex;
-      gap: 8px;
-      position: absolute;
-      bottom: 35px;
-      right: 79px;
-      .el-button {
-        width: 65px;
-        height: 32px;
-        padding: 5px 16px 5px 16px;
-        border-radius: 2px;
-      }
+    gap: 8px;
+    position: absolute;
+    bottom: 35px;
+    right: 79px;
+    .el-button {
+      width: 65px;
+      height: 32px;
+      padding: 5px 16px 5px 16px;
+      border-radius: 2px;
     }
   }
-</style>
+}
+</style>

+ 138 - 138
src/views/message/persongroup/components/SelectTree.vue

@@ -59,155 +59,155 @@
 </template>
 
 <script lang="ts" setup>
-  import { onMounted, ref, watch } from 'vue';
-  import { Search } from '@element-plus/icons-vue';
-  import { ElTree } from 'element-plus';
-  import { treeSelected, TreeNode, FormattedNode } from '../type';
-  import { countLeafNodes, formatTree } from '@/views/message/persongroup/utils/index';
-  import { queryUserTree } from '@/api/message/person-group';
-  import { cloneDeep } from 'lodash-es';
-  import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
-  const loading = ref(true);
-  const queryStr = ref<string>('');
-  const defaultProps = {
-    children: 'children',
-    label: 'name',
-  };
-  const treeData = ref<TreeNode[]>();
-  const nodeData = ref<FormattedNode[]>();
-  const filterNode = (query: string, nodeData: FormattedNode, node: any) => {
-    if (!query) return true;
-    nodeData.filter = nodeData.name!.includes(query);
-    if (!nodeData.filter && node.level > 1) {
-      nodeData.filter = node.parent.data.filter;
-    }
-    return nodeData.filter!;
-  };
+import { onMounted, ref, watch } from 'vue';
+import { Search } from '@element-plus/icons-vue';
+import { ElTree } from 'element-plus';
+import { treeSelected, TreeNode, FormattedNode } from '../type';
+import { countLeafNodes, formatTree } from '../hook/index';
+import { queryUserTree } from '../api/index';
+import { cloneDeep } from 'lodash-es';
+import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
+const loading = ref(true);
+const queryStr = ref<string>('');
+const defaultProps = {
+  children: 'children',
+  label: 'name',
+};
+const treeData = ref<TreeNode[]>();
+const nodeData = ref<FormattedNode[]>();
+const filterNode = (query: string, nodeData: FormattedNode, node: any) => {
+  if (!query) return true;
+  nodeData.filter = nodeData.name!.includes(query);
+  if (!nodeData.filter && node.level > 1) {
+    nodeData.filter = node.parent.data.filter;
+  }
+  return nodeData.filter!;
+};
 
-  const treeRef = ref<InstanceType<typeof ElTree>>();
-  const total = ref<number>(0);
-  const selected = ref<number>(0);
-  const selectedPeople = ref<treeSelected[]>([]);
-  const handleTagClose = (id) => {
-    const index = selectedPeople.value.findIndex((item) => item.id === id);
-    if (index !== -1) {
-      selectedPeople.value.splice(index, 1);
-      selected.value = selectedPeople.value.length;
-      treeRef.value!.setChecked(id, false, true);
-    }
-  };
-  const emit = defineEmits(['cancel', 'submit']);
-  const handleCancle = () => {
-    emit('cancel');
-  };
-  const handleSubmit = () => {
-    emit('submit', selectedPeople.value);
-  };
-  const handleCheckChange = (node, checked) => {
-    if (!node.children || (node.children.length === 0 && node.userId)) {
-      if (checked) {
-        const exists = selectedPeople.value.some((item) => item.id === node.id);
-        if (!exists) {
-          selectedPeople.value.push({
-            id: node.id,
-            name: node.name,
-            userId: node.userId,
-          });
-        }
-      } else {
-        const index = selectedPeople.value.findIndex((item) => item.id === node.id);
-        if (index !== -1) {
-          selectedPeople.value.splice(index, 1);
-        }
+const treeRef = ref<InstanceType<typeof ElTree>>();
+const total = ref<number>(0);
+const selected = ref<number>(0);
+const selectedPeople = ref<treeSelected[]>([]);
+const handleTagClose = (id) => {
+  const index = selectedPeople.value.findIndex((item) => item.id === id);
+  if (index !== -1) {
+    selectedPeople.value.splice(index, 1);
+    selected.value = selectedPeople.value.length;
+    treeRef.value!.setChecked(id, false, true);
+  }
+};
+const emit = defineEmits(['cancel', 'submit']);
+const handleCancle = () => {
+  emit('cancel');
+};
+const handleSubmit = () => {
+  emit('submit', selectedPeople.value);
+};
+const handleCheckChange = (node, checked) => {
+  if (!node.children || (node.children.length === 0 && node.userId)) {
+    if (checked) {
+      const exists = selectedPeople.value.some((item) => item.id === node.id);
+      if (!exists) {
+        selectedPeople.value.push({
+          id: node.id,
+          name: node.name,
+          userId: node.userId,
+        });
+      }
+    } else {
+      const index = selectedPeople.value.findIndex((item) => item.id === node.id);
+      if (index !== -1) {
+        selectedPeople.value.splice(index, 1);
       }
-      selected.value = selectedPeople.value.length;
-    }
-  };
-  const handleNodeClick = (node, checked) => {
-    if (node.children.length === 0 && node.userId) {
-      treeRef.value!.setChecked(node.id, !checked.checked, true);
     }
-    // handleCheckChange(node, checked.checked);
-    // treeRef.value!.setChecked(node.id, !checked.checked, true);
-  };
-  const props = defineProps<{
-    selectedUser: treeSelected[];
-  }>();
-  onMounted(() => {
-    selectedPeople.value = cloneDeep(props.selectedUser);
     selected.value = selectedPeople.value.length;
-    queryUserTree().then((res) => {
-      treeData.value = res;
-      nodeData.value = formatTree(treeData.value!);
-      total.value = countLeafNodes(nodeData.value);
-      const selectedIds: TreeKey[] = selectedPeople.value.map((item) => item.id as string);
-      treeRef.value!.setCheckedKeys(selectedIds);
-      loading.value = false;
-    });
-  });
-  // watch(
-  //   () => props.selectedUser,
-  //   (newSelected) => {
-  //     selectedPeople.value = cloneDeep(newSelected);
-  //     selected.value = selectedPeople.value.length;
-  //   },
-  //   { immediate: true },
-  // );
-  watch(queryStr, (query) => {
-    treeRef.value!.filter(query);
+  }
+};
+const handleNodeClick = (node, checked) => {
+  if (node.children.length === 0 && node.userId) {
+    treeRef.value!.setChecked(node.id, !checked.checked, true);
+  }
+  // handleCheckChange(node, checked.checked);
+  // treeRef.value!.setChecked(node.id, !checked.checked, true);
+};
+const props = defineProps<{
+  selectedUser: treeSelected[];
+}>();
+onMounted(() => {
+  selectedPeople.value = cloneDeep(props.selectedUser);
+  selected.value = selectedPeople.value.length;
+  queryUserTree().then((res) => {
+    treeData.value = res;
+    nodeData.value = formatTree(treeData.value!);
+    total.value = countLeafNodes(nodeData.value);
+    const selectedIds: TreeKey[] = selectedPeople.value.map((item) => item.id as string);
+    treeRef.value!.setCheckedKeys(selectedIds);
+    loading.value = false;
   });
+});
+// watch(
+//   () => props.selectedUser,
+//   (newSelected) => {
+//     selectedPeople.value = cloneDeep(newSelected);
+//     selected.value = selectedPeople.value.length;
+//   },
+//   { immediate: true },
+// );
+watch(queryStr, (query) => {
+  treeRef.value!.filter(query);
+});
 </script>
 
 <style lang="scss" scoped>
-  .select-tree {
+.select-tree {
+  display: flex;
+  width: 100%;
+  height: 98%;
+  .left {
     display: flex;
-    width: 100%;
-    height: 98%;
-    .left {
+    flex-direction: column;
+    width: 50%;
+    height: 100%;
+    border-right: 1px solid rgba(0, 0, 0, 0.06);
+    .el-tree {
+      width: 100%;
+      margin-top: 20px;
+      font-weight: 500;
+      font-size: 14px;
+      color: #303133;
+      line-height: 22px;
+      overflow-y: auto;
+      max-height: calc(100% - 80px);
+    }
+  }
+  .right {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    height: 100%;
+    position: relative;
+    .head {
       display: flex;
-      flex-direction: column;
-      width: 50%;
-      height: 100%;
-      border-right: 1px solid rgba(0, 0, 0, 0.06);
-      .el-tree {
-        width: 100%;
-        margin-top: 20px;
-        font-weight: 500;
-        font-size: 14px;
-        color: #303133;
-        line-height: 22px;
-        overflow-y: auto;
-        max-height: calc(100% - 80px);
-      }
+      align-items: center;
+      font-weight: 400;
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 22px;
     }
-    .right {
+    .selected {
       display: flex;
-      flex-direction: column;
-      flex: 1;
-      height: 100%;
-      position: relative;
-      .head {
-        display: flex;
-        align-items: center;
-        font-weight: 400;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 22px;
-      }
-      .selected {
-        display: flex;
-        flex-wrap: wrap;
-        gap: 8px;
-        overflow-y: auto;
-        max-height: calc(100% - 120px);
-      }
-      .footer {
-        display: flex;
-        gap: 6px;
-        position: absolute;
-        right: 24px;
-        bottom: 20px;
-      }
+      flex-wrap: wrap;
+      gap: 8px;
+      overflow-y: auto;
+      max-height: calc(100% - 120px);
+    }
+    .footer {
+      display: flex;
+      gap: 6px;
+      position: absolute;
+      right: 24px;
+      bottom: 20px;
     }
   }
-</style>
+}
+</style>

src/views/message/persongroup/utils/index.ts → src/views/message/persongroup/hook/index.ts


+ 0 - 98
src/views/message/persongroup/hook/usePersonGroupFilterList.ts

@@ -1,98 +0,0 @@
-import {
-  QueryPersonFilterParams,
-  QueryPersonFilterListReturn,
-  SelectedFilterPersonInfo,
-  FilterPersonInfo,
-  queryPersonFilterList,
-} from '@/api/message/person-group';
-import { ref } from 'vue';
-
-export const usePersonGroupFilterList = () => {
-  const FILTER_TYPES = [
-    { type: 'nickname', label: '姓名' },
-    { type: 'staffNo', label: '工号' },
-    { type: 'deptName', label: '部门' },
-  ];
-
-  // 复用输入框类型及标签
-  const personFilterType = ref({ type: 'nickname', label: '姓名' });
-  // 输入框绑定数据
-  const personFilterValue = ref<string>();
-  // 查询参数
-  const personFilterParams = ref<QueryPersonFilterParams>({
-    pageNumber: 1,
-    pageSize: 10,
-  });
-  // 查询事件
-  const getPersonFilterList = async () => {
-    personFilterParams.value = {
-      pageNumber: 1,
-      pageSize: 10,
-    };
-    personFilterParams.value[personFilterType.value.type] = personFilterValue.value;
-    const res = await queryPersonFilterList(personFilterParams.value);
-    personFilterList.value = res;
-    // 如果有返回且搜索到则添加选中标记
-    if (personFilterList.value && personFilterList.value.availableUserDTOS)
-      personFilterList.value.availableUserDTOS = checkPersonList(
-        personFilterList.value.availableUserDTOS,
-      );
-  };
-  // 查询翻页事件
-  const getNextPersonFilterList = async () => {
-    personFilterParams.value.pageNumber++;
-    const res = await queryPersonFilterList(personFilterParams.value);
-    res.availableUserDTOS = checkPersonList(res.availableUserDTOS);
-    personFilterList.value!.total = res.total;
-    personFilterList.value!.availableUserDTOS.push(...res.availableUserDTOS);
-  };
-  // 查询结果
-  const personFilterList = ref<QueryPersonFilterListReturn>();
-  // 已选择人员
-  const selectedPersonList = ref<SelectedFilterPersonInfo[]>([]);
-  // 查询结果添加选中标记
-  const checkPersonList = (list: FilterPersonInfo[]) => {
-    return list.map((item) => {
-      return {
-        ...item,
-        checked: selectedPersonList.value.some((person) => person.id === item.id),
-      };
-    });
-  };
-
-  // 查询结果刷新选中标记
-  const refreshPersonFilterCheckedStatus = (personId: number) => {
-    const person = personFilterList.value?.availableUserDTOS.find((item) => item.id === personId);
-    if (person) person.checked = selectedPersonList.value.some((person) => person.id === personId);
-  };
-
-  // 添加已选择人员
-  const handleAddSelectedPerson = (person: FilterPersonInfo) => {
-    selectedPersonList.value.push(person);
-    // refreshPersonFilterCheckedStatus(person.id);
-  };
-
-  // 移除已选择人员
-  const handleRemoveSelectedPerson = (personId: number) => {
-    // selectedPersonList.value = selectedPersonList.value.filter((item) => item.id !== personId);
-    selectedPersonList.value.splice(
-      selectedPersonList.value.findIndex((item) => item.id === personId),
-      1,
-    );
-    refreshPersonFilterCheckedStatus(personId);
-  };
-  return {
-    FILTER_TYPES,
-    personFilterType,
-    personFilterValue,
-    personFilterParams,
-    personFilterList,
-    selectedPersonList,
-    getPersonFilterList,
-    getNextPersonFilterList,
-    handleAddSelectedPerson,
-    handleRemoveSelectedPerson,
-  };
-};
-
-export default usePersonGroupFilterList;

+ 27 - 27
src/views/message/persongroup/store/index.ts

@@ -1,34 +1,34 @@
-import { ref } from 'vue';
-import { defineStore } from 'pinia';
+import { ref } from 'vue'
+import { defineStore } from "pinia";
 import { userData } from '../type';
-import { queryUserGroupListParams, queryUserGroupList } from '@/api/message/person-group';
+import { queryUserGroupListParams, queryUserGroupList } from '../api/index'
 import { useRequest } from 'vue-hooks-plus';
 export const userGroupList = defineStore('user-group', () => {
-  const total = ref<number>(0);
-  const page = ref<number>(1);
-  const pagesize = ref<number>(10);
-  const queryStr = ref<string>('');
-  const conditionSearch = () => {
-    const params: queryUserGroupListParams = {
-      pageNumber: page.value,
-      pageSize: pagesize.value,
-    };
-    if (queryStr.value) {
-      params.queryStr = queryStr.value;
+    const total = ref<number>(0)
+    const page = ref<number>(1);
+    const pagesize = ref<number>(10);
+    const queryStr = ref<string>('')
+    const conditionSearch = () => {
+        const params: queryUserGroupListParams = {
+            pageNumber: page.value,
+            pageSize: pagesize.value,
+        };
+        if (queryStr.value) {
+            params.queryStr = queryStr.value
+        }
+        return queryUserGroupList(params).then((res) => {
+            return res;
+        });
     }
-    return queryUserGroupList(params).then((res) => {
-      return res;
+    const userListData = ref<userData[]>([])
+    const { run: getUserGroup } = useRequest(conditionSearch, {
+        manual: true,
+        onSuccess: (res) => {
+            userListData.value = res.groupVOList;
+            total.value = res.total;
+        },
     });
-  };
-  const userListData = ref<userData[]>([]);
-  const { run: getUserGroup } = useRequest(conditionSearch, {
-    manual: true,
-    onSuccess: (res) => {
-      userListData.value = res.groupVOList;
-      total.value = res.total;
-    },
-  });
-  return { total, page, pagesize, queryStr, userListData, getUserGroup };
+    return { total, page, pagesize, queryStr, userListData, getUserGroup }
 });
 
-export default userGroupList;
+export default userGroupList;

+ 48 - 48
src/views/message/persongroup/type.ts

@@ -1,63 +1,63 @@
 export interface userData {
-  //分组描述
-  description?: string;
-  //ID
-  id?: number;
-  //用户组名称
-  name?: string;
-  //操作时间
-  operationTime?: string;
-  //操作人姓名
-  operatorName?: string;
-  //人数
-  total?: number;
+    //分组描述
+    description?: string;
+    //ID
+    id?: number;
+    //用户组名称
+    name?: string;
+    //操作时间
+    operationTime?: string;
+    //操作人姓名
+    operatorName?: string;
+    //人数
+    total?: number;
 }
 export interface treeSelected {
-  //ID
-  id?: string;
-  //名称
-  name?: string;
-  //userID
-  userId?: number;
+    //ID
+    id?: string;
+    //名称
+    name?: string;
+    //userID
+    userId?: number;
 }
 interface UserVO {
-  userId: number;
-  userNickname: string | null;
-  userNumber: string | null;
-  userLoginName: string | null;
+    userId: number;
+    userNickname: string | null;
+    userNumber: string | null;
+    userLoginName: string | null;
 }
 export interface TreeNode {
-  deptId: number;
-  deptName: string;
-  treePath: string | null;
-  grade: string | null;
-  parent: number;
-  parentName: string | null;
-  orderNum: number | null;
-  children: TreeNode[] | null;
-  userVOList: UserVO[] | null;
+    deptId: number;
+    deptName: string;
+    treePath: string | null;
+    grade: string | null;
+    parent: number;
+    parentName: string | null;
+    orderNum: number | null;
+    children: TreeNode[] | null;
+    userVOList: UserVO[] | null;
 }
 export interface FormattedNode {
-  id: string;
-  name: string | null;
-  userId: number | null;
-  children: FormattedNode[];
-  filter?: boolean;
+    id: string;
+    name: string | null;
+    userId: number | null;
+    children: FormattedNode[];
+    filter?: boolean;
 }
 export interface FromUserList {
-  userId: number;
-  loginName: string;
-  nickname: string;
+    userId: number;
+    loginName: string;
+    nickname: string;
 }
 export interface FormData {
-  description?: string;
-  name: string;
-  operator: string;
-  total: number;
-  userGroupId: number;
-  userList: FromUserList[];
+    description?: string;
+    name: string;
+    operator: string;
+    total: number;
+    userGroupId: number;
+    userList: FromUserList[];
 }
 export interface GroupData extends FormData {
-  isExpand: boolean;
-  isHidden: boolean;
-}
+    isExpand: boolean;
+    isHidden: boolean;
+}

+ 20 - 23
src/views/message/reportmessage/CustomReport.vue

@@ -1,13 +1,11 @@
 <template>
-  <div v-for="(item, index) in prop.form.customPushConfigList">
-    <div v-if="item.isDeleted != 1" class="reportCard">
+  <div  v-for="(item, index) in prop.form.customPushConfigList" >
+    <div v-if="item.isDeleted != 1" class="reportCard"> 
       <a v-if="!disableType.contentDisable">
         <el-icon
           class="cardIcon"
           color="rgb(216,216,216)"
-          v-if="
-            prop.form.customPushConfigList.filter((custom) => custom.isDeleted === 0).length > 1
-          "
+          v-if="prop.form.customPushConfigList.filter(custom => custom.isDeleted === 0).length > 1"
           @click="deleteReportCard(index)"
         >
           <CircleCloseFilled />
@@ -22,7 +20,7 @@
           <el-col :span="22">
             <el-date-picker
               v-model="item.daterange"
-              style="width: 327.5px"
+              style="width: 327.5px;"
               type="daterange"
               range-separator="至"
               start-placeholder="开始日期"
@@ -54,7 +52,7 @@
           </el-col>
         </el-form-item>
 
-        <el-col class="text-center" :span="2" style="padding-bottom: 10px">
+        <el-col class="text-center" :span="2" style="padding-bottom: 10px;">
           <span class="text-gray-500">—</span>
         </el-col>
 
@@ -91,7 +89,7 @@
         v-if="item.recipientType === '2'"
         label="选择分组:"
         required
-        style="margin-top: 10px"
+        style=" margin-top: 10px;"
         :prop="`customPushConfigList[` + index + `].userGroupList`"
         :rules="{ required: true, message: '请选择分组', trigger: 'change' }"
       >
@@ -121,13 +119,13 @@
         label="选择人员:"
         required
         placeholder="请选择人员"
-        style="width: 526px; margin-top: 10px"
+        style="width: 526px; margin-top: 10px;"
         :prop="`customPushConfigList[` + index + `].customUserList`"
-        :rules="{ required: true, message: '请选择推送人员', trigger: 'blur' }"
+        :rules="{ required: true, message: '请选择推送人员', trigger: 'change' }"
       >
         <el-col :span="18">
-          <CustomPersonSelection
-            style="padding-bottom: 0"
+          <CustomSelectTree
+            style="padding-bottom: 0;"
             :form="form"
             :disableType="disableType"
             :index="index"
@@ -136,6 +134,7 @@
           />
         </el-col>
       </el-form-item>
+
     </div>
   </div>
   <el-button
@@ -152,8 +151,8 @@
   import { ref, reactive, onMounted } from 'vue';
   import { computeCustom, createCustomReport } from './class.ts';
   import { CircleCloseFilled } from '@element-plus/icons-vue';
-  import { searchGroup } from '@/api/message/report-message';
-  import CustomPersonSelection from './components/CustomPersonSelection.vue';
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import CustomSelectTree from '../CustomSelectTree.vue';
   import { Plus } from '@element-plus/icons-vue';
 
   const prop = defineProps(['form', 'disableType', 'ruleFormRef']);
@@ -172,7 +171,7 @@
   };
 
   const deleteReportCard = (index) => {
-    prop.form.customPushConfigList[index].isDeleted = 1;
+    prop.form.customPushConfigList[index].isDeleted = 1
     // prop.form.customPushConfigList.splice(index, 1);
   };
 
@@ -185,14 +184,12 @@
       .then((res) => {
         options.value = res.groupVOList;
       })
-      .catch((e) => {
-        console.log(e);
-      });
+      .catch((error) => {});
   });
 </script>
 
 <style scoped>
-  .reportCard {
+.reportCard {
     margin-left: 87px;
     margin-bottom: 16px;
     padding: 12px 0px 0px 12px;
@@ -225,14 +222,14 @@
     /* margin-bottom: 8px; */
     margin-bottom: 0px;
     padding-bottom: 10px;
-  }
+}
 
-  .reportCard > .el-form-item:last-child {
-    /* background:#ff0000; */
+  .reportCard > .el-form-item:last-child{
+  /* background:#ff0000; */
     padding-bottom: 16px;
   }
 
-  ::v-deep .el-select__selection {
+ ::v-deep .el-select__selection{
     min-height: 25px;
   }
 </style>

+ 80 - 83
src/views/message/reportmessage/MonthReport.vue

@@ -1,41 +1,42 @@
 <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 
+        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" style="padding-bottom: 10px">
+      <el-col class="text-center" :span="2" style="padding-bottom: 10px;">
         <span class="text-gray-500">—</span>
       </el-col>
 
-      <el-form-item
-        prop="pushTimeList[0]"
+      <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"
+        >
+          <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-col>
       </el-form-item>
     </el-form-item>
 
@@ -47,93 +48,89 @@
       </el-radio-group>
     </el-form-item>
 
-    <el-form-item
+    <el-form-item 
       v-if="form.recipientType === 2"
       label="选择分组:"
       required
-      style="margin-top: 10px"
+      style="margin-top: 10px;"
       prop="userGroupList"
-    >
-      <el-col :span="10">
-        <el-select
-          v-model="form.userGroupList"
-          multiple
-          placeholder="请选择分组"
-          style="width: 326px"
-          :disabled="disableType.contentDisable"
-        >
-          <el-option
-            v-for="item in options"
-            :key="item.userGroupId"
-            :label="item.name"
-            :value="item.userGroupId"
-          />
-        </el-select>
-      </el-col>
+      >
+        <el-col :span="10">
+          <el-select
+            v-model="form.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 326px"
+            :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
+    <el-form-item 
       v-if="form.recipientType === 3"
       label="选择人员:"
       required
       prop="customUserList.value"
-      style="width: 526px; margin-top: 10px"
-      :rules="{ required: true, message: '请选择推送人员', trigger: 'blur' }"
-    >
-      <el-col :span="18">
-        <DefaultPersonSelection :form="form" :disableType="disableType" />
-      </el-col>
+      style="width: 526px; margin-top: 10px;"
+      :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/message/report-message';
-  import DefaultPersonSelection from './components/DefaultPersonSelection.vue';
+  import { searchGroup } from '@/api/sendMessage/sendMessage';
+  import SelectTree from '../SelectTree.vue';
 
-  defineProps(['form', 'disableType']);
-  const options = ref();
+  defineProps(['form', 'disableType'])
+  const options =  ref()
 
   const dayArray = Array.from({ length: 31 }, (_, index) => ({
     id: index + 1,
     value: `${index + 1}`,
-    label: `每月${index + 1} 日`,
+    label: `每月${index + 1} 日`
   }));
 
-  onMounted(() => {
-    searchGroup()
-      .then((res) => {
-        options.value = res.groupVOList;
-      })
-      .catch((e) => {
-        console.log(e);
-      });
-  });
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
 </script>
 
 <style scoped>
-  .reportCard {
-    margin-left: 87px;
-    padding: 12px 0px 0px 12px;
-    margin-bottom: 16px;
-    background-color: #fafafa;
-    width: 530px;
-    box-sizing: border-box;
-  }
-
-  .el-form-item--default {
+.reportCard {
+  margin-left: 87px;
+  padding: 12px 0px 0px 12px;
+  margin-bottom: 16px;
+  background-color: #fafafa;
+  width: 530px;
+  box-sizing: border-box;
+}
+ 
+.el-form-item--default {
     /* margin-bottom: 8px; */
     margin-bottom: 0px;
     padding-bottom: 10px;
-  }
+}
 
-  .reportCard > .el-form-item:last-child {
-    /* background:#ff0000; */
+.reportCard > .el-form-item:last-child{
+  /* background:#ff0000; */
     padding-bottom: 16px;
-  }
+  }  
 
-  ::v-deep .el-select__selection {
+ ::v-deep .el-select__selection{
     min-height: 25px;
   }
 </style>

+ 1 - 0
src/views/message/reportmessage/ReportMessage.vue

@@ -20,6 +20,7 @@
   import { typeName } from '@/views/message/constant';
   import { storeToRefs } from 'pinia';
   import useFormList from './store/useFormList';
+  import { computed } from 'vue';
   import { useGlobSetting } from '@/hooks/setting';
   const formStore = useFormList();
   const { type } = storeToRefs(formStore);

+ 8 - 8
src/views/message/reportmessage/ReportOperation.vue

@@ -31,7 +31,7 @@
             :rules="{ required: true, message: '请选择人员', trigger: ['change'] }"
           >
             <el-col :span="18">
-              <DesignatedPersonSelection :form="form" :disableType="disableType" />
+              <DesignatedUserList :form="form" :disableType="disableType" />
             </el-col>
           </el-form-item>
 
@@ -170,13 +170,13 @@
   import YearReport from './YearReport.vue';
   import CustomReport from './CustomReport.vue';
   import { reportMessage, toReportMessage, reportMessageToFinal } from './class.ts';
-  import { addMassage, searchMassage, editMassage } from '@/api/message/report-message';
+  import { addMassage, searchMassage, editMassage } from '@/api/sendMessage/sendMessage';
   import { ElMessage } from 'element-plus';
   import { storeToRefs } from 'pinia';
   import { useUserStore } from '@/store/modules/user';
   import { useFormList } from './store/useFormList';
   import { useRoute, useRouter } from 'vue-router';
-  import DesignatedPersonSelection from './components/DesignatedPersonSelection.vue';
+  import DesignatedUserList from '@/views/message/designatedUserSelectTree.vue';
   import type { FormProps } from 'element-plus';
   import { debounce } from 'lodash-es';
 
@@ -190,7 +190,7 @@
 
   const weekVisible = ref(false); // 控制Tooltip显示
   const monthVisible = ref(false); // 控制Tooltip显示
-  // const seasonVisible = ref(false); // 控制Tooltip显示
+  const seasonVisible = ref(false); // 控制Tooltip显示
   const yearVisible = ref(false); // 控制Tooltip显示
   const customVisible = ref(false); // 控制Tooltip显示
 
@@ -271,10 +271,10 @@
     });
   };
 
-  // const resetForm = (formEl: FormInstance | undefined) => {
-  //   if (!formEl) return;
-  //   formEl.resetFields();
-  // };
+  const resetForm = (formEl: FormInstance | undefined) => {
+    if (!formEl) return;
+    formEl.resetFields();
+  };
 
   const clickBack = () => {
     type.value = reportType.value;

+ 32 - 40
src/views/message/reportmessage/WeekReport.vue

@@ -21,7 +21,7 @@
         </el-col>
       </el-form-item>
 
-      <el-col class="text-center" :span="2" style="padding-bottom: 10px">
+      <el-col class="text-center" :span="2"  style="padding-bottom: 10px;">
         <span class="text-gray-500">—</span>
       </el-col>
 
@@ -47,19 +47,13 @@
         <el-radio :value="3">自定义</el-radio>
       </el-radio-group>
     </el-form-item>
-    <el-form-item
-      v-if="form.recipientType === 2"
-      label="选择分组:"
-      required
-      prop="userGroupList"
-      style="margin-top: 10px"
-    >
+    <el-form-item v-if="form.recipientType === 2" label="选择分组:" required prop="userGroupList" style=" margin-top: 10px;">
       <el-col :span="10">
         <el-select
           v-model="form.userGroupList"
           multiple
           placeholder="请选择分组"
-          style="width: 326px"
+          style="width: 326px;"
           :disabled="disableType.contentDisable"
         >
           <el-option
@@ -76,57 +70,55 @@
       label="选择人员:"
       required
       prop="customUserList.value"
-      style="width: 526px; margin-top: 10px"
-      :rules="{ required: true, message: '请选择推送人员', trigger: 'blur' }"
+      style="width: 526px; margin-top: 10px;"
+      :rules="{ required: true, message: '请选择推送人员', trigger: ['change'] }"
     >
       <el-col :span="18">
-        <DefaultPersonSelection :form="form" :disableType="disableType" />
+        <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/message/report-message';
-  import DefaultPersonSelection from './components/DefaultPersonSelection.vue';
+import { ref, onMounted } from 'vue';
+import { searchGroup } from '@/api/sendMessage/sendMessage';
+import SelectTree from '../SelectTree.vue';
 
-  defineProps(['form', 'disableType']);
-  const options = ref();
+const prop = defineProps(['form', 'disableType']);
+const options = ref();
 
-  onMounted(() => {
-    searchGroup()
-      .then((res) => {
-        options.value = res.groupVOList;
-      })
-      .catch((e) => {
-        console.log(e);
-      });
-  });
+onMounted(() => {
+  searchGroup()
+    .then((res) => {
+      options.value = res.groupVOList;
+    })
+    .catch((error) => {});
+});
 </script>
 
 <style scoped>
-  .reportCard {
-    margin-left: 87px;
-    padding: 12px 0px 0px 12px;
-    margin-bottom: 16px;
-    background-color: #fafafa;
-    width: 530px;
-    box-sizing: border-box;
-  }
-
-  .el-form-item--default {
+.reportCard {
+  margin-left: 87px;
+  padding: 12px 0px 0px 12px;
+  margin-bottom: 16px;
+  background-color: #fafafa;
+  width: 530px;
+  box-sizing: border-box;
+}
+ 
+.el-form-item--default {
     /* margin-bottom: 8px; */
     margin-bottom: 0px;
     padding-bottom: 10px;
-  }
+}
 
-  .reportCard > .el-form-item:last-child {
-    /* background:#ff0000; */
+.reportCard > .el-form-item:last-child{
+  /* background:#ff0000; */
     padding-bottom: 16px;
   }
 
-  ::v-deep .el-select__selection {
+ ::v-deep .el-select__selection{
     min-height: 25px;
   }
 </style>

+ 108 - 118
src/views/message/reportmessage/YearReport.vue

@@ -1,172 +1,162 @@
 <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: 146.5px; height: 32px"
-            :disabled="disableType.contentDisable"
-          />
-        </el-col>
-      </el-form-item>
+      <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: 146.5px; height: 32px;"
+             :disabled="disableType.contentDisable"
+            />
+          </el-col>
+        </el-form-item>
 
-      <el-col class="text-center" :span="2" style="padding-bottom: 10px">
-        <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: 146.5px; height: 32px"
-            :disabled="disableType.contentDisable"
-          />
+        <el-col class="text-center" :span="2" style="padding-bottom: 10px;"   >
+          <span class="text-gray-500">—</span>
         </el-col>
-      </el-form-item>
+
+        <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: 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="prop.form.recipientType" :disabled="disableType.contentDisable">
+      <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
+    <el-form-item 
       v-if="prop.form.recipientType === 2"
       label="选择分组:"
       required
-      style="margin-top: 10px"
+      style="margin-top: 10px;"
       prop="userGroupList"
-    >
-      <el-col :span="10">
-        <el-select
-          v-model="prop.form.userGroupList"
-          multiple
-          placeholder="请选择分组"
-          style="width: 326px"
-          :disabled="disableType.contentDisable"
-        >
-          <el-option
-            v-for="item in options"
-            :key="item.userGroupId"
-            :label="item.name"
-            :value="item.userGroupId"
-          />
-        </el-select>
-      </el-col>
+      >
+        <el-col :span="10">
+          <el-select
+            v-model="prop.form.userGroupList"
+            multiple
+            placeholder="请选择分组"
+            style="width: 326px;"
+            :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
+    <el-form-item 
       v-if="form.recipientType === 3"
       label="选择人员:"
       required
       prop="customUserList.value"
-      style="width: 526px; margin-top: 10px"
-      :rules="{ required: true, message: '请选择推送人员', trigger: 'blur' }"
-    >
-      <el-col :span="18">
-        <DefaultPersonSelection :form="form" :disableType="disableType" />
-      </el-col>
+      style="width: 526px; margin-top: 10px;"
+      :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/message/report-message';
-  import DefaultPersonSelection from './components/DefaultPersonSelection.vue';
+  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 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]);
+    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])
       }
     }
-  };
+  }
+
 
   // 默认每年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 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} 日`,
-    })),
+        id: dayIndex + 1,
+        value: `${dayIndex + 1}`,
+        label: `${dayIndex + 1} 日`  
+      }))
+    
   }));
 
-  onMounted(() => {
-    searchGroup()
-      .then((res) => {
-        options.value = res.groupVOList;
-      })
-      .catch((e) => {
-        console.log(e);
-      });
-  });
+  onMounted(()=>{
+    searchGroup().then(res => {
+      options.value = res.groupVOList
+    }).catch(error => {});
+  })
 </script>
 
 <style scoped>
-  .reportCard {
-    margin-left: 87px;
-    padding: 12px 0px 0px 12px;
-    margin-bottom: 16px;
-    background-color: #fafafa;
-    width: 530px;
-    box-sizing: border-box;
-  }
-
-  .el-form-item--default {
+.reportCard {
+  margin-left: 87px;
+  padding: 12px 0px 0px 12px;
+  margin-bottom: 16px;
+  background-color: #fafafa;
+  width: 530px;
+  box-sizing: border-box;
+}
+ 
+.el-form-item--default {
     /* margin-bottom: 8px; */
     margin-bottom: 0px;
     padding-bottom: 10px;
-  }
+}
 
-  .reportCard > .el-form-item:last-child {
-    /* background:#ff0000; */
+.reportCard > .el-form-item:last-child{
+  /* background:#ff0000; */
     padding-bottom: 16px;
-  }
+  }  
 
-  ::v-deep .el-select__selection {
+ ::v-deep .el-select__selection{
     min-height: 25px;
   }
 </style>

+ 38 - 0
src/views/message/reportmessage/api/index.ts

@@ -0,0 +1,38 @@
+import { http } from '@/utils/http/axios';
+export function queryReportConfigList(type: number) {
+    return http.request({
+        url: '/reportMessage/queryReportConfigList',
+        method: 'get',
+        params: { type },
+    });
+}
+export function deleteReportConfig(type: number, statisticType: number) {
+    return http.request({
+        url: `/reportMessage/deleteReportConfig?type=${type}&statisticType=${statisticType}`,
+        method: 'post',
+    });
+}
+export interface queryPushRecordsParams {
+    pageNum: number,
+    pageSize: number,
+    statisticType?: number,
+    type?: number,
+}
+export function queryPushRecords(params: queryPushRecordsParams) {
+    return http.request({
+        url: '/reportMessage/queryPushRecords',
+        method: 'post',
+        params,
+    });
+}
+export interface updateStatusParams {
+    type: number,
+    statisticType: number,
+    status: number
+}
+export function updateStatus(params: updateStatusParams) {
+    return http.request({
+        url: `/reportMessage/updateStatus?statisticType=${params.statisticType}&status=${params.status}&type=${params.type}`,
+        method: 'post',
+    });
+}

+ 0 - 87
src/views/message/reportmessage/components/CustomPersonSelection.vue

@@ -1,87 +0,0 @@
-<template>
-  <div>
-    <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.staffNo + '-' + user.nickname"
-        :value="user"
-      />
-    </el-select>
-    <el-dialog
-      v-model="dialogVisible"
-      title="添加人员"
-      align-center
-      :close-on-click-modal="false"
-      style="height: 583px"
-      :width="731"
-      :destroy-on-close="true"
-      :append-to-body="true"
-      class="workShopDialog"
-    >
-      <!-- <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-      <PersonFilterSelection
-        @cancel="handleCancle"
-        @submit="handleSubmit"
-        :init-selected="selectedUser"
-      />
-    </el-dialog>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, onMounted, watch } from 'vue';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-  // import SelectTree from '@/views/message/persongroup/components/SelectTree.vue';
-  import PersonFilterSelection from '@/views/message/components/PersonFilterSelection.vue';
-  // interface UserList {
-  //   id: string;
-  //   name: string;
-  //   userId: number;
-  // }
-  const dialogVisible = ref<boolean>(false);
-  const selectedUser = ref<SelectedFilterPersonInfo[]>([]);
-
-  const prop = defineProps(['form', 'disableType', 'index', 'ruleFormRef']);
-
-  const handleCancle = () => {
-    dialogVisible.value = false;
-  };
-  const handleSubmit = (selectedData: SelectedFilterPersonInfo[]) => {
-    selectedUser.value = selectedData;
-    prop.form.customPushConfigList[prop.index].customUserList.length = 0;
-    prop.form.customPushConfigList[prop.index].customUserList.push(...selectedUser.value);
-    prop.ruleFormRef.validateField(`customPushConfigList[` + prop.index + `].customUserList`);
-    dialogVisible.value = false;
-  };
-  watch(
-    () => prop.form.customPushConfigList[prop.index].customUserList,
-    (newSelected) => {
-      selectedUser.value = newSelected;
-    },
-    { deep: true, immediate: true },
-  );
-  onMounted(() => {
-    if (prop.form.customPushConfigList[prop.index].customUserList.length > 0) {
-      selectedUser.value = prop.form.customPushConfigList[prop.index].customUserList;
-    }
-  });
-</script>
-
-<style lang="scss" scoped>
-  ::v-deep .el-dialog__body {
-    height: 527px;
-  }
-  ::v-deep .el-select__selection {
-    min-height: 25px;
-    max-height: 60px;
-    overflow-y: auto;
-  }
-</style>

+ 0 - 86
src/views/message/reportmessage/components/DefaultPersonSelection.vue

@@ -1,86 +0,0 @@
-<template>
-  <div>
-    <el-select
-      v-model="prop.form.customUserList.value"
-      value-key="id"
-      multiple
-      placeholder="请选择人员"
-      @click="dialogVisible = !disableType.contentDisable"
-      :disabled="disableType.contentDisable"
-    >
-      <el-option
-        v-for="user in selectedUser"
-        :key="user.id"
-        :label="user.staffNo + '-' + user.nickname"
-        :value="user"
-      />
-    </el-select>
-    <el-dialog
-      v-model="dialogVisible"
-      title="添加人员"
-      align-center
-      :close-on-click-modal="false"
-      style="height: 583px"
-      :width="731"
-      :destroy-on-close="true"
-      :append-to-body="true"
-      class="workShopDialog"
-    >
-      <!-- <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-      <PersonFilterSelection
-        @cancel="handleCancle"
-        @submit="handleSubmit"
-        :init-selected="selectedUser"
-      />
-    </el-dialog>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, onMounted, watch } from 'vue';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-  // import SelectTree from '@/views/message/persongroup/components/SelectTree.vue';
-  import PersonFilterSelection from '@/views/message/components/PersonFilterSelection.vue';
-  // interface UserList {
-  //   id: string;
-  //   name: string;
-  //   userId: number;
-  // }
-  const dialogVisible = ref<boolean>(false);
-  const selectedUser = ref<SelectedFilterPersonInfo[]>([]);
-
-  const prop = defineProps(['form', 'disableType']);
-
-  const handleCancle = () => {
-    dialogVisible.value = false;
-  };
-  const handleSubmit = (selectedData: SelectedFilterPersonInfo[]) => {
-    selectedUser.value = selectedData;
-    prop.form.customUserList.value = selectedUser.value;
-    dialogVisible.value = false;
-  };
-  watch(
-    () => prop.form.customUserList.value,
-    (newSelected) => {
-      selectedUser.value = newSelected;
-    },
-    { deep: true, immediate: true },
-  );
-  onMounted(() => {
-    if (prop.form.customUserList.value.length > 0) {
-      console.log(prop.form.customUserList.value);
-      selectedUser.value = prop.form.customUserList.value;
-    }
-  });
-</script>
-
-<style lang="scss" scoped>
-  ::v-deep .el-dialog__body {
-    height: 527px;
-  }
-  ::v-deep .el-select__selection {
-    min-height: 25px;
-    max-height: 60px;
-    overflow-y: auto;
-  }
-</style>

+ 0 - 87
src/views/message/reportmessage/components/DesignatedPersonSelection.vue

@@ -1,87 +0,0 @@
-<template>
-  <div>
-    <el-select
-      v-model="prop.form.designatedUserList.value"
-      value-key="id"
-      multiple
-      placeholder="请选择人员"
-      @click="dialogVisible = !disableType.contentDisable"
-      :disabled="disableType.contentDisable"
-    >
-      <el-option
-        v-for="user in selectedUser"
-        :key="user.id"
-        :label="user.staffNo + '-' + user.nickname"
-        :value="user"
-      />
-    </el-select>
-    <el-dialog
-      v-model="dialogVisible"
-      title="添加人员"
-      align-center
-      :close-on-click-modal="false"
-      style="height: 583px"
-      :width="731"
-      :destroy-on-close="true"
-      :append-to-body="true"
-      class="workShopDialog"
-    >
-      <!-- <SelectTree @cancel="handleCancle" @submit="handleSubmit" :selectedUser="selectedUser" /> -->
-      <PersonFilterSelection
-        @cancel="handleCancle"
-        @submit="handleSubmit"
-        :init-selected="selectedUser"
-      />
-    </el-dialog>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, onBeforeUpdate, watch } from 'vue';
-  import { SelectedFilterPersonInfo } from '@/api/message/person-group';
-  // import SelectTree from '@/views/message/persongroup/components/SelectTree.vue';
-  import PersonFilterSelection from '@/views/message/components/PersonFilterSelection.vue';
-  // interface UserList {
-  //   id: string;
-  //   name: string;
-  //   userId: number;
-  // }
-  const dialogVisible = ref<boolean>(false);
-  const selectedUser = ref<SelectedFilterPersonInfo[]>([]);
-
-  const prop = defineProps(['form', 'disableType']);
-
-  const handleCancle = () => {
-    dialogVisible.value = false;
-  };
-  const handleSubmit = (selectedData: SelectedFilterPersonInfo[]) => {
-    selectedUser.value = selectedData;
-    prop.form.designatedUserList.value = selectedUser.value;
-    dialogVisible.value = false;
-  };
-
-  watch(
-    () => prop.form.designatedUserList.value,
-    (newSelected) => {
-      selectedUser.value = newSelected;
-    },
-    { deep: true, immediate: true },
-  );
-
-  onBeforeUpdate(() => {
-    if (prop.form.designatedUserList?.value?.length > 0) {
-      selectedUser.value = prop.form.designatedUserList.value;
-    }
-  });
-</script>
-
-<style lang="scss" scoped>
-  ::v-deep .el-dialog__body {
-    height: 527px;
-  }
-  ::v-deep .el-select__selection {
-    min-height: 25px;
-    max-height: 60px;
-    overflow-y: auto;
-  }
-</style>

+ 109 - 109
src/views/message/reportmessage/components/Form.vue

@@ -36,115 +36,115 @@
     </el-dialog>
   </div>
 </template>
-
-<script lang="ts" setup>
-  import { h, ref, reactive, watch, onUnmounted } from 'vue';
-  import { BasicTable, TableActionIcons, BasicColumn } from '@/components/Table';
-  import { reportDataCol } from '../overviewColumns';
-  import { Plus } from '@element-plus/icons-vue';
-  import logIcon from '@/assets/images/reportmessage/log.png';
-  import viewIcon from '@/assets/images/reportmessage/view.png';
-  import editIcon from '@/assets/images/reportmessage/edit.png';
-  import deleteIcon from '@/assets/images/reportmessage/delete.png';
-  import { ElMessage, ElMessageBox } from 'element-plus';
-  import LogForm from './LogForm.vue';
-  import { storeToRefs } from 'pinia';
-  import useFormList from '../store/useFormList';
-  const formStore = useFormList();
-  const { getForm } = formStore;
-  import { deleteReportConfig } from '@/api/message/report-message';
-  const { type, formList } = storeToRefs(formStore);
-  const logFormVisible = ref(false);
-  const actionColumn: BasicColumn = reactive({
-    width: 224,
-    title: '操作',
-    prop: 'action',
-    key: 'action',
-    fixed: 'right',
-    render(record) {
-      return h(TableActionIcons as any, {
-        space: 20,
-        color: '#629bf9',
-        style: 'img',
-        size: 16,
-        actionIcons: [
-          {
-            label: '推送记录',
-            icon: logIcon,
-            onClick: handleLog.bind(null, record.row),
-          },
-          {
-            label: '查看',
-            icon: viewIcon,
-            onClick: handleView.bind(null, record.row),
-          },
-          {
-            label: '编辑',
-            icon: editIcon,
-            onClick: handleEdit.bind(null, record.row),
-          },
-          {
-            label: '删除',
-            icon: deleteIcon,
-            onClick: handleDelete.bind(null, record.row),
-          },
-        ],
+  
+  <script lang="ts" setup>
+import { h, ref, reactive, watch, onUnmounted } from 'vue';
+import { BasicTable, TableActionIcons, BasicColumn } from '@/components/Table';
+import { reportDataCol } from '../overviewColumns';
+import { Plus } from '@element-plus/icons-vue';
+import logIcon from '@/assets/images/reportmessage/log.png';
+import viewIcon from '@/assets/images/reportmessage/view.png';
+import editIcon from '@/assets/images/reportmessage/edit.png';
+import deleteIcon from '@/assets/images/reportmessage/delete.png';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import LogForm from './LogForm.vue';
+import { storeToRefs } from 'pinia';
+import useFormList from '../store/useFormList';
+const formStore = useFormList();
+const { getForm } = formStore;
+import { deleteReportConfig } from '../api/index';
+const { type, formList } = storeToRefs(formStore);
+const logFormVisible = ref(false);
+const actionColumn: BasicColumn = reactive({
+  width: 224,
+  title: '操作',
+  prop: 'action',
+  key: 'action',
+  fixed: 'right',
+  render(record) {
+    return h(TableActionIcons as any, {
+      space: 20,
+      color: '#629bf9',
+      style: 'img',
+      size: 16,
+      actionIcons: [
+        {
+          label: '推送记录',
+          icon: logIcon,
+          onClick: handleLog.bind(null, record.row),
+        },
+        {
+          label: '查看',
+          icon: viewIcon,
+          onClick: handleView.bind(null, record.row),
+        },
+        {
+          label: '编辑',
+          icon: editIcon,
+          onClick: handleEdit.bind(null, record.row),
+        },
+        {
+          label: '删除',
+          icon: deleteIcon,
+          onClick: handleDelete.bind(null, record.row),
+        },
+      ],
+    });
+  },
+});
+import { useRouter } from 'vue-router';
+const router = useRouter();
+const CreateReport = (type) => {
+  router.push(`/message/reportoperation?type=${type}&operationType=1`);
+};
+const statisticType = ref<number>(0);
+const handleLog = (record: Recordable) => {
+  logFormVisible.value = true;
+  statisticType.value = record.statisticType;
+};
+const handleView = (record: Recordable) => {
+  router.push(
+    `/message/reportoperation?type=${type.value}&statisticType=${record.statisticType}&operationType=2`,
+  );
+};
+const handleEdit = (record: Recordable) => {
+  router.push(
+    `/message/reportoperation?type=${type.value}&statisticType=${record.statisticType}&operationType=3`,
+  );
+};
+const handleDelete = (record: Recordable) => {
+  ElMessageBox.confirm('删除之后,这条数据无法恢复', '请确认是否删除', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+    .then(() => {
+      deleteReportConfig(type.value, record.statisticType).then(() => {
+        ElMessage.success('删除成功');
+        getForm(type.value);
       });
-    },
-  });
-  import { useRouter } from 'vue-router';
-  const router = useRouter();
-  const CreateReport = (type) => {
-    router.push(`/message/reportoperation?type=${type}&operationType=1`);
-  };
-  const statisticType = ref<number>(0);
-  const handleLog = (record: Recordable) => {
-    logFormVisible.value = true;
-    statisticType.value = record.statisticType;
-  };
-  const handleView = (record: Recordable) => {
-    router.push(
-      `/message/reportoperation?type=${type.value}&statisticType=${record.statisticType}&operationType=2`,
-    );
-  };
-  const handleEdit = (record: Recordable) => {
-    router.push(
-      `/message/reportoperation?type=${type.value}&statisticType=${record.statisticType}&operationType=3`,
-    );
-  };
-  const handleDelete = (record: Recordable) => {
-    ElMessageBox.confirm('删除之后,这条数据无法恢复', '请确认是否删除', {
-      confirmButtonText: '确定',
-      cancelButtonText: '取消',
-      type: 'warning',
     })
-      .then(() => {
-        deleteReportConfig(type.value, record.statisticType).then(() => {
-          ElMessage.success('删除成功');
-          getForm(type.value);
-        });
-      })
-      .catch(() => {});
-  };
-  onUnmounted(() => {
-    type.value = 1;
-    formList.value = [];
-  });
-  watch(
-    type,
-    (newType) => {
-      getForm(newType);
-    },
-    { immediate: true },
-  );
+    .catch(() => {});
+};
+onUnmounted(() => {
+  type.value = 1;
+  formList.value = [];
+});
+watch(
+  type,
+  (newType) => {
+    getForm(newType);
+  },
+  { immediate: true },
+);
 </script>
-
-<style lang="scss" scoped>
-  .report-list {
-    position: relative;
-    width: 100%;
-  }
-  ::v-deep .el-dialog__body {
-    height: 600px;
-  }
-</style>
+  
+  <style lang="scss" scoped>
+.report-list {
+  position: relative;
+  width: 100%;
+}
+::v-deep .el-dialog__body{
+  height: 600px;
+}
+</style>

+ 45 - 45
src/views/message/reportmessage/components/LogForm.vue

@@ -32,53 +32,53 @@
 </template>
 
 <script lang="ts" setup>
-  import { ref, onMounted } from 'vue';
-  import { BasicTable } from '@/components/Table';
-  import { logColumns } from '../overviewColumns';
-  import { logData } from '../type';
-  import { queryPushRecords, queryPushRecordsParams } from '@/api/message/report-message';
-  import { storeToRefs } from 'pinia';
-  import useFormList from '../store/useFormList';
-  const formStore = useFormList();
-  const { type } = storeToRefs(formStore);
-  const props = defineProps<{
-    statisticType: number;
-  }>();
-  const logList = ref<logData[]>();
-  const total = ref<number>(0);
-  const pageSize = ref<number>(10);
-  const pageNum = ref<number>(1);
-  const getLoglist = (pageNum, pageSize) => {
-    const params: queryPushRecordsParams = {
-      pageNum: pageNum,
-      pageSize: pageSize,
-      statisticType: props.statisticType,
-      type: type.value,
-    };
-    queryPushRecords(params).then((res) => {
-      logList.value = res.reportPushRecords;
-      total.value = res.total;
-    });
+import { ref, onMounted } from 'vue';
+import { BasicTable } from '@/components/Table';
+import { logColumns } from '../overviewColumns';
+import { logData } from '../type';
+import { queryPushRecords, queryPushRecordsParams } from '../api/index';
+import { storeToRefs } from 'pinia';
+import useFormList from '../store/useFormList';
+const formStore = useFormList();
+const { type } = storeToRefs(formStore);
+const props = defineProps<{
+  statisticType: number;
+}>();
+const logList = ref<logData[]>();
+const total = ref<number>(0);
+const pageSize = ref<number>(10);
+const pageNum = ref<number>(1);
+const getLoglist = (pageNum, pageSize) => {
+  const params: queryPushRecordsParams = {
+    pageNum: pageNum,
+    pageSize: pageSize,
+    statisticType: props.statisticType,
+    type: type.value,
   };
-  const handlePageNumChange = (num) => {
-    pageNum.value = num;
-    getLoglist(pageNum.value, pageSize.value);
-  };
-  const handlePageSizeChange = (size) => {
-    pageNum.value = 1;
-    pageSize.value = size;
-    getLoglist(pageNum.value, pageSize.value);
-  };
-  onMounted(() => {
-    getLoglist(pageNum.value, pageSize.value);
+  queryPushRecords(params).then((res) => {
+    logList.value = res.reportPushRecords;
+    total.value = res.total;
   });
+};
+const handlePageNumChange = (num) => {
+  pageNum.value = num;
+  getLoglist(pageNum.value, pageSize.value);
+};
+const handlePageSizeChange = (size) => {
+  pageNum.value = 1;
+  pageSize.value = size;
+  getLoglist(pageNum.value, pageSize.value);
+};
+onMounted(() => {
+  getLoglist(pageNum.value, pageSize.value);
+});
 </script>
 
 <style lang="scss" scoped>
-  .log-form {
-    height: 100%;
-  }
-  ::v-deep .el-table--fit {
-    height: 528px !important;
-  }
-</style>
+.log-form {
+  height: 100%;
+}
+::v-deep .el-table--fit {
+  height: 528px !important;
+}
+</style>

+ 26 - 18
src/views/message/reportmessage/overviewColumns.ts

@@ -1,35 +1,39 @@
 import { h } from 'vue';
 import type { BasicColumn } from '@/components/Table';
 import { ElSwitch } from 'element-plus';
-import { pushChannelName, recipientTypeName, statusName, statisticTypeName } from '../constant';
+import { pushChannelName, recipientTypeName, statusName,statisticTypeName } from '../constant'
 import { storeToRefs } from 'pinia';
 import useFormList from './store/useFormList';
 const formStore = useFormList();
 const { type } = storeToRefs(formStore);
 const { getForm } = formStore;
-import { updateStatus, updateStatusParams } from '@/api/message/report-message';
+import { updateStatus, updateStatusParams } from './api/index'
 export const reportDataCol: BasicColumn[] = [
   {
     label: '报表周期',
     prop: 'statisticType',
     render(record) {
-      const typeName = statisticTypeName.find((item) => item.value === record.row.statisticType);
-      return h('span', {}, typeName ? typeName.label : '');
-    },
+      const typeName = statisticTypeName.find(item => item.value === record.row.statisticType);
+      return h(
+        'span',
+        {},
+        typeName ? typeName.label : ''
+      )
+    }
   },
   {
     label: '推送渠道',
     prop: 'pushChannel',
     render(record) {
       const labels = record.row.pushChannel
-        .map((channel) => {
-          const typeName = pushChannelName.find((item) => item.value === channel);
+        .map(channel => {
+          const typeName = pushChannelName.find(item => item.value === channel);
           return typeName ? typeName.label : '';
         })
-        .filter((label) => label !== '')
+        .filter(label => label !== '')
         .join(', ');
       return h('span', {}, labels);
-    },
+    }
   },
   {
     label: '推送对象',
@@ -39,9 +43,9 @@ export const reportDataCol: BasicColumn[] = [
       if (length > 1) {
         return h('span', {}, '多类对象');
       }
-      const label = recipientTypeName.find((item) => item.value === record.row.recipientType[0]);
+      const label = recipientTypeName.find(item => item.value === record.row.recipientType[0])
       return h('span', {}, label ? label.label : '');
-    },
+    }
   },
   {
     label: '是否启用',
@@ -55,8 +59,8 @@ export const reportDataCol: BasicColumn[] = [
             const params: updateStatusParams = {
               type: type.value,
               statisticType: record.row.statisticType,
-              status: record.row.status === 1 ? 0 : 1,
-            };
+              status: record.row.status === 1 ? 0 : 1
+            }
             updateStatus(params).then(() => {
               getForm(type.value);
             });
@@ -71,7 +75,7 @@ export const reportDataCol: BasicColumn[] = [
   {
     label: '操作时间',
     prop: 'updatedAt',
-  },
+  }
 ];
 export const logColumns: BasicColumn[] = [
   {
@@ -87,9 +91,13 @@ export const logColumns: BasicColumn[] = [
     label: '推送状态',
     prop: 'status',
     render(record) {
-      const name = statusName.find((item) => item.value === record.row.status);
+      const name = statusName.find(item => item.value === record.row.status);
       const style = record.row.status === 1 ? { color: '#FAAD14' } : {};
-      return h('span', { style }, name ? name.label : '');
-    },
+      return h(
+        'span',
+        { style },
+        name ? name.label : ''
+      )
+    }
   },
-];
+];

+ 12 - 12
src/views/message/reportmessage/store/useFormList.ts

@@ -1,16 +1,16 @@
-import { ref } from 'vue';
-import { defineStore } from 'pinia';
+import { ref } from 'vue'
+import { defineStore } from "pinia";
 import { reportData } from '../type';
-import { queryReportConfigList } from '@/api/message/report-message';
+import { queryReportConfigList } from '../api/index'
 export const useFormList = defineStore('form-list', () => {
-  const type = ref<number>(1);
-  const formList = ref<reportData[]>([]);
-  const getForm = (type: number) => {
-    queryReportConfigList(type).then((res) => {
-      formList.value = res;
-    });
-  };
-  return { type, formList, getForm };
+    const type = ref<number>(1)
+    const formList = ref<reportData[]>([])
+    const getForm = (type: number) => {
+        queryReportConfigList(type).then((res) => {
+            formList.value = res
+        })
+    }
+    return { type, formList, getForm }
 });
 
-export default useFormList;
+export default useFormList;

+ 336 - 336
src/views/message/sysnotion-config/SysnotionConfig.vue

@@ -154,379 +154,378 @@
 </template>
 
 <script lang="ts" setup>
-  import { useRoute, useRouter } from 'vue-router';
-  import { ref, reactive, onMounted } from 'vue';
-  import { storeToRefs } from 'pinia';
-  import { debounce } from 'lodash-es';
-  import { ElMessage } from 'element-plus';
-  import { useUserStore } from '@/store/modules/user';
-  import { pushChannelName } from '../constant';
-  import type { FormProps } from 'element-plus';
-  import PushObject from '../components/PushObject.vue';
-  import type { FormInstance } from 'element-plus';
-  import {
-    queryReportConfigListParams,
-    queryReportConfigList,
-    confirmReportConfig,
-    viewSystemMessage,
-  } from '@/api/message/sysnotion-config';
-  import { ObjectFrom } from './type';
-  const title = ref<string>('本系统进行了重大升级,请查看详细内容');
-  const content = ref<string>(
-    '尊敬的用户:\n    我们计划于2024年9月5日进行平台系统升级,以提升服务性能和用户体验,升级期间,平台将暂时不可用,预计停机时间为4小时,从上午2:00至6:00。请您提前做好相关安排,以避免不便,感谢您的理解与支持。如有疑问,请联系客服支持团队。\n敬请留意。\n天眼团队',
-  );
-  const isDisabled = ref<boolean>(false);
-  const ruleFormRef = ref<FormInstance>();
-  const childFromRef = ref();
-  const validate = ref<boolean>();
-  const useUser = useUserStore();
-  const { info } = storeToRefs(useUser);
-  const labelPosition = ref<FormProps['labelPosition']>('left');
-  interface RuleForm {
-    title: string;
-    content: string;
-    channel: number[];
-    object: ObjectFrom;
-    operator: string;
-  }
-  const ruleForm = reactive<RuleForm>({
-    title: '',
-    content: '',
-    channel: [],
-    object: {},
-    operator: info.value.nickname,
-  });
-  const activeName = ref('platform');
-  const debounceEmit = debounce((params) => {
-    queryReportConfigList(params)
-      .then((res) => {
-        confirmReportConfig(res).then(() => {
-          ElMessage({
-            message: '下发成功!',
-            type: 'success',
-          });
-          router.back();
+import { useRoute, useRouter } from 'vue-router';
+import { ref, reactive, onMounted } from 'vue';
+import { storeToRefs } from 'pinia';
+import { debounce } from 'lodash-es';
+import { ElMessage } from 'element-plus';
+import { useUserStore } from '@/store/modules/user';
+import { pushChannelName } from '../constant';
+import type { FormProps } from 'element-plus';
+import PushObject from '../components/PushObject.vue';
+import type { FormInstance } from 'element-plus';
+import {
+  queryReportConfigListParams,
+  queryReportConfigList,
+  confirmReportConfig,
+  viewSystemMessage,
+} from './api/index';
+import { ObjectFrom } from './type';
+const title = ref<string>('本系统进行了重大升级,请查看详细内容');
+const content = ref<string>(
+  '尊敬的用户:\n    我们计划于2024年9月5日进行平台系统升级,以提升服务性能和用户体验,升级期间,平台将暂时不可用,预计停机时间为4小时,从上午2:00至6:00。请您提前做好相关安排,以避免不便,感谢您的理解与支持。如有疑问,请联系客服支持团队。\n敬请留意。\n天眼团队',
+);
+const isDisabled = ref<boolean>(false);
+const ruleFormRef = ref<FormInstance>();
+const childFromRef = ref();
+const validate = ref<boolean>();
+const useUser = useUserStore();
+const { info } = storeToRefs(useUser);
+const labelPosition = ref<FormProps['labelPosition']>('left');
+interface RuleForm {
+  title: string;
+  content: string;
+  channel: number[];
+  object: ObjectFrom;
+  operator: string;
+}
+const ruleForm = reactive<RuleForm>({
+  title: '',
+  content: '',
+  channel: [],
+  object: {},
+  operator: info.value.nickname,
+});
+const activeName = ref('platform');
+const debounceEmit = debounce((params) => {
+  queryReportConfigList(params)
+    .then((res) => {
+      confirmReportConfig(res).then(() => {
+        ElMessage({
+          message: '下发成功!',
+          type: 'success',
         });
-      })
-      .catch((e) => console.error(e));
-  }, 500);
-  const submitForm = () => {
-    const childValue = childFromRef.value!.getChildValue();
-    childFromRef.value!.submitForm().then((res) => {
-      validate.value = res;
-    });
-    ruleFormRef.value!.validate((valid) => {
-      if (validate.value && valid) {
-        const params: queryReportConfigListParams = {
-          content: ruleForm.content,
-          title: ruleForm.title,
-          pushChannel: ruleForm.channel.map((item) => item),
-          recipientType: childValue.recipientType,
-          userGroupList: childValue.userGroupList,
-          customUserList: childValue.customUserList,
-        };
-        debounceEmit(params);
-      } else {
-        console.log('下发失败');
-      }
-    });
-  };
-  const refresh = () => {
-    if (!ruleFormRef.value) return;
-    ruleFormRef.value.resetFields();
-    childFromRef.value.refreshForm();
-  };
-  const router = useRouter();
-  const rollback = () => {
-    router.back();
-  };
-  const route = useRoute();
-  const sysId = route.query.id;
-  onMounted(() => {
-    if (sysId) {
-      isDisabled.value = true;
-      viewSystemMessage(Number(sysId)).then((res) => {
-        ruleForm.title = res.title;
-        ruleForm.content = res.content ? res.content : ' ';
-        ruleForm.channel = res.pushChannel;
-        ruleForm.object.recipientType = res.recipientType;
-        if (res.recipientType === 2) {
-          ruleForm.object.userGroupList = res.userGroupList;
-        }
-        if (res.recipientType === 3) {
-          ruleForm.object.customUserList = res.customUserList;
-        }
+        router.back();
       });
+    })
+    .catch((e) => console.error(e));
+}, 500);
+const submitForm = () => {
+  const childValue = childFromRef.value!.getChildValue();
+  childFromRef.value!.submitForm().then((res) => {
+    validate.value = res;
+  });
+  ruleFormRef.value!.validate((valid) => {
+    if (validate.value && valid) {
+      const params: queryReportConfigListParams = {
+        content: ruleForm.content,
+        title: ruleForm.title,
+        pushChannel: ruleForm.channel.map((item) => item),
+        recipientType: childValue.recipientType,
+        userGroupList: childValue.userGroupList,
+        customUserList: childValue.customUserList,
+      };
+      debounceEmit(params);
+    } else {
+      console.log('下发失败');
     }
   });
+};
+const refresh = () => {
+  if (!ruleFormRef.value) return;
+  ruleFormRef.value.resetFields();
+  childFromRef.value.refreshForm();
+};
+const router = useRouter();
+const rollback = () => {
+  router.back();
+};
+const route = useRoute();
+const sysId = route.query.id;
+onMounted(() => {
+  if (sysId) {
+    isDisabled.value = true;
+    viewSystemMessage(Number(sysId)).then((res) => {
+      ruleForm.title = res.title;
+      ruleForm.content = res.content ? res.content : ' ';
+      ruleForm.channel = res.pushChannel;
+      ruleForm.object.recipientType = res.recipientType;
+      if (res.recipientType === 2) {
+        ruleForm.object.userGroupList = res.userGroupList;
+      }
+      if (res.recipientType === 3) {
+        ruleForm.object.customUserList = res.customUserList;
+      }
+    });
+  }
+});
 </script>
 
 <style lang="scss" scoped>
-  .sysnotion-config {
-    position: relative;
-    height: calc(100vh - 64px - 18px);
-    background-color: rgba(255, 255, 255, 1);
-    box-sizing: border-box !important;
-    .tophead {
+.sysnotion-config {
+  position: relative;
+  height: calc(100vh - 64px - 18px);
+  background-color: rgba(255, 255, 255, 1);
+  box-sizing: border-box !important;
+  .tophead {
+    display: flex;
+    gap: 20px;
+    width: 100%;
+    height: 50px;
+    padding: 16px 0 14px 21px;
+    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+    div {
       display: flex;
-      gap: 20px;
-      width: 100%;
-      height: 50px;
-      padding: 16px 0 14px 21px;
-      border-bottom: 1px solid rgba(0, 0, 0, 0.06);
-      div {
-        display: flex;
-        align-items: center;
-        font-weight: 400;
-        font-size: 14px;
-        color: #303133;
-        line-height: 22px;
-        cursor: pointer;
-        img {
-          margin-right: 4px;
-        }
+      align-items: center;
+      font-weight: 400;
+      font-size: 14px;
+      color: #303133;
+      line-height: 22px;
+      cursor: pointer;
+      img {
+        margin-right: 4px;
       }
     }
-    .content {
+  }
+  .content {
+    display: flex;
+    width: 100%;
+    height: calc(100vh - 64px - 18px - 50px);
+    padding: 0 30px 0 0;
+    .left {
       display: flex;
-      width: 100%;
-      height: calc(100vh - 64px - 18px - 50px);
-      padding: 0 30px 0 0;
-      .left {
+      flex-direction: column;
+      flex: 1;
+      position: relative;
+      padding: 21px;
+      border-right: 1px solid rgba(0, 0, 0, 0.06);
+      overflow-y: auto;
+      .el-form-outer {
         display: flex;
         flex-direction: column;
+        gap: 32px;
+      }
+      .transprant {
+        :deep(.el-form-item__label::before) {
+          content: '**';
+          opacity: 0;
+        }
+      }
+      .btns {
+        margin-top: 35px;
         flex: 1;
+        width: 100%;
         position: relative;
-        padding: 21px;
-        border-right: 1px solid rgba(0, 0, 0, 0.06);
-        overflow-y: auto;
-        .el-form-outer {
-          display: flex;
-          flex-direction: column;
-          gap: 32px;
-        }
-        .transprant {
-          :deep(.el-form-item__label::before) {
-            content: '**';
-            opacity: 0;
-          }
-        }
-        .btns {
-          margin-top: 35px;
-          flex: 1;
-          width: 100%;
-          position: relative;
+      }
+    }
+    .right {
+      width: 380px;
+      height: 100%;
+      padding: 20px 9px 0 20px;
+      .top-head {
+        display: flex;
+        gap: 7px;
+        align-items: center;
+        width: 100%;
+        height: 22px;
+        font-weight: 600;
+        font-size: 14px;
+        color: rgba(0, 0, 0, 0.85);
+        line-height: 22px;
+        img {
+          cursor: pointer;
         }
       }
-      .right {
-        width: 380px;
-        height: 100%;
-        padding: 20px 9px 0 20px;
-        .top-head {
-          display: flex;
-          gap: 7px;
-          align-items: center;
-          width: 100%;
-          height: 22px;
-          font-weight: 600;
+      .tabs {
+        margin-top: 14px;
+        overflow-y: auto;
+        :deep(.el-tabs__header) {
+          margin: 0 0 22px;
+        }
+        :deep(.is-top) {
+          font-weight: 550;
           font-size: 14px;
-          color: rgba(0, 0, 0, 0.85);
           line-height: 22px;
-          img {
-            cursor: pointer;
-          }
         }
-        .tabs {
-          margin-top: 14px;
-          overflow-y: auto;
-          :deep(.el-tabs__header) {
-            margin: 0 0 22px;
-          }
-          :deep(.is-top) {
-            font-weight: 550;
-            font-size: 14px;
-            line-height: 22px;
-          }
-          :deep(.el-tabs__nav-wrap::after) {
-            height: 0px;
-          }
-          .platform {
-            display: flex;
-            flex-direction: column;
-            gap: 24px;
-            .tabs-content {
+        :deep(.el-tabs__nav-wrap::after) {
+          height: 0px;
+        }
+        .platform {
+          display: flex;
+          flex-direction: column;
+          gap: 24px;
+          .tabs-content {
+            width: 100%;
+            height: auto;
+            max-height: calc(100vh - 450px);
+            .title {
+              display: flex;
+              align-items: center;
+              margin-bottom: 12px;
+              gap: 18px;
               width: 100%;
-              height: auto;
-              max-height: calc(100vh - 450px);
-              .title {
+              height: 31px;
+              .vertical {
+                width: 4px;
+                height: 12px;
+                background: #1777ff;
+                border-radius: 3px;
+              }
+              span {
+                font-weight: 400;
+                font-size: 14px;
+                color: #303133;
+                line-height: 20px;
+              }
+            }
+            .card {
+              width: 100%;
+              height: 124px;
+              padding: 10px 14px 0 12px;
+              background: #ffffff;
+              border-radius: 4px;
+              border: 1px solid rgba(0, 0, 0, 0.06);
+              .card-title {
                 display: flex;
-                align-items: center;
-                margin-bottom: 12px;
-                gap: 18px;
-                width: 100%;
-                height: 31px;
-                .vertical {
-                  width: 4px;
-                  height: 12px;
-                  background: #1777ff;
-                  border-radius: 3px;
-                }
-                span {
-                  font-weight: 400;
+                justify-content: space-between;
+                font-weight: 600;
+                font-size: 15px;
+                color: #646566;
+                line-height: 20px;
+                a {
                   font-size: 14px;
-                  color: #303133;
-                  line-height: 20px;
-                }
-              }
-              .card {
-                width: 100%;
-                height: 124px;
-                padding: 10px 14px 0 12px;
-                background: #ffffff;
-                border-radius: 4px;
-                border: 1px solid rgba(0, 0, 0, 0.06);
-                .card-title {
                   display: flex;
-                  justify-content: space-between;
-                  font-weight: 600;
-                  font-size: 15px;
-                  color: #646566;
-                  line-height: 20px;
-                  a {
-                    font-size: 14px;
-                    display: flex;
-                    gap: 8px;
-                    cursor: default;
-                  }
-                }
-                .card-content {
-                  margin-top: 15px;
-                  font-weight: 400;
-                  line-height: 20px;
+                  gap: 8px;
+                  cursor: default;
                 }
               }
-              .info {
-                width: 100%;
-                max-height: calc(100vh - 450px - 32px);
-                background: #ffffff;
-                border-radius: 4px;
-                border: 1px solid rgba(0, 0, 0, 0.06);
-                .info-title {
-                  display: flex;
-                  justify-content: center;
-                  align-items: center;
-                  width: 100%;
-                  height: 41px;
-                  font-weight: 600;
-                  font-size: 14px;
-                  color: rgba(0, 0, 0, 0.85);
-                  line-height: 22px;
-                  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
-                }
-                .info-content {
-                  width: 100%;
-                  max-height: calc(100vh - 450px - 32px - 55px);
-                  overflow-y: auto;
-                  padding: 12px 7px 12px 12px;
-                  font-weight: 400;
-                  font-size: 14px;
-                  color: #646566;
-                  line-height: 22px;
-                  word-wrap: break-word;
-                  white-space: pre-wrap;
-                }
+              .card-content {
+                margin-top: 15px;
+                font-weight: 400;
+                line-height: 20px;
               }
             }
-          }
-          .lanxin {
-            display: flex;
-            flex-direction: column;
-            gap: 24px;
-            .tabs-content {
+            .info {
               width: 100%;
-              height: auto;
-              max-height: calc(100vh - 400px);
-              .title {
+              max-height: calc(100vh - 450px - 32px);
+              background: #ffffff;
+              border-radius: 4px;
+              border: 1px solid rgba(0, 0, 0, 0.06);
+              .info-title {
                 display: flex;
+                justify-content: center;
                 align-items: center;
-                margin-bottom: 12px;
-                gap: 18px;
                 width: 100%;
-                height: 31px;
-                .vertical {
-                  width: 4px;
-                  height: 12px;
-                  background: #1777ff;
-                  border-radius: 3px;
-                }
-                span {
-                  font-weight: 400;
-                  font-size: 14px;
-                  color: #303133;
-                  line-height: 20px;
-                }
+                height: 41px;
+                font-weight: 600;
+                font-size: 14px;
+                color: rgba(0, 0, 0, 0.85);
+                line-height: 22px;
+                border-bottom: 1px solid rgba(0, 0, 0, 0.06);
               }
-              .card {
+              .info-content {
                 width: 100%;
-                height: 79px;
-                padding: 10px 14px 0 12px;
-                background: #ffffff;
-                border-radius: 4px;
-                border: 1px solid rgba(0, 0, 0, 0.06);
-                position: relative;
-                .card-title {
+                max-height: calc(100vh - 450px - 32px - 55px);
+                overflow-y: auto;
+                padding: 12px 7px 12px 12px;
+                font-weight: 400;
+                font-size: 14px;
+                color: #646566;
+                line-height: 22px;
+                word-wrap: break-word;
+                white-space: pre-wrap;
+              }
+            }
+          }
+        }
+        .lanxin {
+          display: flex;
+          flex-direction: column;
+          gap: 24px;
+          .tabs-content {
+            width: 100%;
+            height: auto;
+            max-height: calc(100vh - 400px);
+            .title {
+              display: flex;
+              align-items: center;
+              margin-bottom: 12px;
+              gap: 18px;
+              width: 100%;
+              height: 31px;
+              .vertical {
+                width: 4px;
+                height: 12px;
+                background: #1777ff;
+                border-radius: 3px;
+              }
+              span {
+                font-weight: 400;
+                font-size: 14px;
+                color: #303133;
+                line-height: 20px;
+              }
+            }
+            .card {
+              width: 100%;
+              height: 79px;
+              padding: 10px 14px 0 12px;
+              background: #ffffff;
+              border-radius: 4px;
+              border: 1px solid rgba(0, 0, 0, 0.06);
+              position: relative;
+              .card-title {
+                display: flex;
+                justify-content: space-between;
+                font-weight: 600;
+                font-size: 15px;
+                color: #646566;
+                line-height: 20px;
+                a {
                   display: flex;
-                  justify-content: space-between;
-                  font-weight: 600;
-                  font-size: 15px;
-                  color: #646566;
-                  line-height: 20px;
-                  a {
-                    display: flex;
-                    gap: 8px;
-                  }
-                }
-                .card-content {
-                  margin-top: 15px;
-                  font-weight: 400;
-                  line-height: 20px;
-                }
-                img {
-                  position: absolute;
-                  top: 10px;
-                  right: 17px;
+                  gap: 8px;
                 }
               }
-              .info {
+              .card-content {
+                margin-top: 15px;
+                font-weight: 400;
+                line-height: 20px;
+              }
+              img {
+                position: absolute;
+                top: 10px;
+                right: 17px;
+              }
+            }
+            .info {
+              width: 100%;
+              max-height: calc(100vh - 400px - 50px);
+              background: #ffffff;
+              border-radius: 4px;
+              border: 1px solid rgba(0, 0, 0, 0.06);
+              .info-title {
+                display: flex;
+                justify-content: center;
+                align-items: center;
                 width: 100%;
-                max-height: calc(100vh - 400px - 50px);
-                background: #ffffff;
-                border-radius: 4px;
-                border: 1px solid rgba(0, 0, 0, 0.06);
-                .info-title {
-                  display: flex;
-                  justify-content: center;
-                  align-items: center;
-                  width: 100%;
-                  height: 41px;
-                  font-weight: 600;
-                  font-size: 14px;
-                  color: rgba(0, 0, 0, 0.85);
-                  line-height: 22px;
-                  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
-                }
-                .info-content {
-                  width: 100%;
-                  max-height: calc(100vh - 400px - 32px - 41px);
-                  overflow-y: auto;
-                  padding: 12px 7px 12px 12px;
-                  font-weight: 400;
-                  font-size: 14px;
-                  color: #646566;
-                  line-height: 22px;
-                  word-wrap: break-word;
-                  white-space: pre-wrap;
-                }
+                height: 41px;
+                font-weight: 600;
+                font-size: 14px;
+                color: rgba(0, 0, 0, 0.85);
+                line-height: 22px;
+                border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+              }
+              .info-content {
+                width: 100%;
+                max-height: calc(100vh - 400px - 32px - 41px);
+                overflow-y: auto;
+                padding: 12px 7px 12px 12px;
+                font-weight: 400;
+                font-size: 14px;
+                color: #646566;
+                line-height: 22px;
+                word-wrap: break-word;
+                white-space: pre-wrap;
               }
             }
           }
@@ -534,4 +533,5 @@
       }
     }
   }
-</style>
+}
+</style>

src/api/message/sysnotion-config.ts → src/views/message/sysnotion-config/api/index.ts


+ 59 - 0
src/views/message/systemNotifications/api/index.ts

@@ -0,0 +1,59 @@
+import { http } from '@/utils/http/axios';
+import { queryParams } from '../type'
+// 获取系统通知数据列表
+export function getSystemMessageList(params: queryParams) {
+    return http.request({
+        url: '/systemMessage/getSystemMessageList',
+        method: 'get',
+        params
+    });
+}
+// 删除系统消息通知
+export function deleteSystemMessage(id: number) {
+    return http.request({
+        url: `/systemMessage/deleteSystemMessage?id=${id}`,
+        method: 'post',
+    });
+}
+
+// 获取问题处理通知
+export function queryIssueProcessMessage() {
+    return http.request({
+        url: '/issueProcessMessage/queryIssueProcessMessage',
+        method: 'post',
+    });
+}
+
+// 修改推送文案
+export function modifyContent(content: string, id: number) {
+    return http.request({
+        url: `/issueProcessMessage/modifyContent?content=${content}&id=${id}`,
+        method: 'post',
+    });
+}
+
+// 获取车间列表
+export function getList() {
+    return http.request({
+        url: '/scene/getList',
+        method: 'get',
+    });
+}
+
+// 下发车间
+export function modifyWorkshopList(workshopList: number[]) {
+    return http.request({
+        url: '/issueProcessMessage/modifyWorkshopList',
+        method: 'post',
+        params: { workshopList }
+    });
+}
+
+// 查询车间姓名
+export function queryWorkshopNamebyIds(workshopList: number[]) {
+    return http.request({
+        url: '/issueProcessMessage/queryWorkshopNamebyIds',
+        method: 'post',
+        params: { workshopList }
+    });
+}

+ 164 - 164
src/views/message/systemNotifications/components/WorkShopTree.vue

@@ -59,184 +59,184 @@
 </template>
 
 <script lang="ts" setup>
-  import { onMounted, ref, watch, computed } from 'vue';
-  import { Search } from '@element-plus/icons-vue';
-  import { ElTree } from 'element-plus';
-  import { countLeafNodes } from '@/views/message/persongroup/utils/index';
-  import { getList } from '@/api/message/system-notifications';
-  import useScene from '@/views/system-config/scene-manage/use-scene';
-  import { storeToRefs } from 'pinia';
-  import { cloneDeep } from 'lodash-es';
-  import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
-  const sceneInfos = useScene();
-  const { tableData } = storeToRefs(sceneInfos);
-  const loading = ref(true);
-  const queryStr = ref<string>('');
-  const defaultProps = { label: 'name' };
-  const nodeData = computed(() => {
-    const newList: any[] = [];
-    if (tableData.value && tableData.value.length) {
-      for (let i = 0; i < tableData.value.length; i++) {
-        const data = tableData.value[i];
-        if (data.children && data.children.length) {
-          const treeItem = {
-            id: data.id,
-            code: data.id,
-            name: data.name,
-            children: data
-              .labelList!.map((item) => {
-                return {
-                  id: item.id,
-                  code: item.code,
-                  name: item.name,
-                  children: data
-                    .children!.filter((children) => children.sceneLabelId === item.id)
-                    .map((children) => {
-                      return {
-                        id: children.id,
-                        code: children.code,
-                        name: children.name,
-                        isShop: true,
-                      };
-                    }),
-                };
-              })
-              .filter((label) => label.children.length),
-          };
-          newList.push(treeItem);
-        }
+import { onMounted, ref, watch, computed } from 'vue';
+import { Search } from '@element-plus/icons-vue';
+import { ElTree } from 'element-plus';
+import { countLeafNodes } from '@/views/message/persongroup/hook/index';
+import { getList } from '../api/index';
+import useScene from '@/views/system-config/scene-manage/use-scene';
+import { storeToRefs } from 'pinia';
+import { cloneDeep } from 'lodash-es';
+import { TreeKey } from 'element-plus/es/components/tree/src/tree.type';
+const sceneInfos = useScene();
+const { tableData } = storeToRefs(sceneInfos);
+const loading = ref(true);
+const queryStr = ref<string>('');
+const defaultProps = { label: 'name' };
+const nodeData = computed(() => {
+  const newList: any[] = [];
+  if (tableData.value && tableData.value.length) {
+    for (let i = 0; i < tableData.value.length; i++) {
+      const data = tableData.value[i];
+      if (data.children && data.children.length) {
+        const treeItem = {
+          id: data.id,
+          code: data.id,
+          name: data.name,
+          children: data
+            .labelList!.map((item) => {
+              return {
+                id: item.id,
+                code: item.code,
+                name: item.name,
+                children: data
+                  .children!.filter((children) => children.sceneLabelId === item.id)
+                  .map((children) => {
+                    return {
+                      id: children.id,
+                      code: children.code,
+                      name: children.name,
+                      isShop: true,
+                    };
+                  }),
+              };
+            })
+            .filter((label) => label.children.length),
+        };
+        newList.push(treeItem);
       }
     }
-    return newList;
-  });
-  const filterNode = (query, nodeData, node) => {
-    if (!query) return true;
-    nodeData.filter = nodeData.name!.includes(query);
-    if (!nodeData.filter && node.level > 1) {
-      nodeData.filter = node.parent.data.filter;
-    }
-    return nodeData.filter!;
-  };
-  const treeRef = ref<InstanceType<typeof ElTree>>();
-  const total = ref<number>(0);
-  const selected = ref<number>(0);
-  interface treeSelected {
-    code: number | string;
-    name: string;
-    id: number;
   }
-  const selectedPeople = ref<treeSelected[]>([]);
-  const handleTagClose = (code) => {
-    const index = selectedPeople.value.findIndex((item) => item.code === code);
-    if (index !== -1) {
-      selectedPeople.value.splice(index, 1);
-      selected.value = selectedPeople.value.length;
-      treeRef.value!.setChecked(code, false, true);
-    }
-  };
-  const emit = defineEmits(['cancel', 'submit']);
-  const handleCancle = () => {
-    emit('cancel');
-  };
-  const handleSubmit = () => {
-    emit('submit', selectedPeople.value);
-  };
-  const handleCheckChange = (node, checked) => {
-    if (!node.children) {
-      if (checked) {
-        const exists = selectedPeople.value.some((item) => item.code === node.code);
-        if (!exists) {
-          selectedPeople.value.push({
-            id: node.id,
-            code: node.code,
-            name: node.name,
-          });
-        }
-      } else {
-        const index = selectedPeople.value.findIndex((item) => item.code === node.code);
-        if (index !== -1) {
-          selectedPeople.value.splice(index, 1);
-        }
+  return newList;
+});
+const filterNode = (query, nodeData, node) => {
+  if (!query) return true;
+  nodeData.filter = nodeData.name!.includes(query);
+  if (!nodeData.filter && node.level > 1) {
+    nodeData.filter = node.parent.data.filter;
+  }
+  return nodeData.filter!;
+};
+const treeRef = ref<InstanceType<typeof ElTree>>();
+const total = ref<number>(0);
+const selected = ref<number>(0);
+interface treeSelected {
+  code: number | string;
+  name: string;
+  id: number;
+}
+const selectedPeople = ref<treeSelected[]>([]);
+const handleTagClose = (code) => {
+  const index = selectedPeople.value.findIndex((item) => item.code === code);
+  if (index !== -1) {
+    selectedPeople.value.splice(index, 1);
+    selected.value = selectedPeople.value.length;
+    treeRef.value!.setChecked(code, false, true);
+  }
+};
+const emit = defineEmits(['cancel', 'submit']);
+const handleCancle = () => {
+  emit('cancel');
+};
+const handleSubmit = () => {
+  emit('submit', selectedPeople.value);
+};
+const handleCheckChange = (node, checked) => {
+  if (!node.children) {
+    if (checked) {
+      const exists = selectedPeople.value.some((item) => item.code === node.code);
+      if (!exists) {
+        selectedPeople.value.push({
+          id: node.id,
+          code: node.code,
+          name: node.name,
+        });
+      }
+    } else {
+      const index = selectedPeople.value.findIndex((item) => item.code === node.code);
+      if (index !== -1) {
+        selectedPeople.value.splice(index, 1);
       }
-      selected.value = selectedPeople.value.length;
-    }
-  };
-  const handleNodeClick = (node, checked) => {
-    if (!node.children) {
-      treeRef.value!.setChecked(node.code, !checked.checked, true);
-    }
-  };
-  const props = defineProps<{
-    selectedUser: treeSelected[];
-  }>();
-  onMounted(() => {
-    if (props.selectedUser) {
-      selectedPeople.value = cloneDeep(props.selectedUser);
     }
     selected.value = selectedPeople.value.length;
-    getList().then((res) => {
-      tableData.value = res;
-      total.value = countLeafNodes(nodeData.value);
-      const selectedIds: TreeKey[] = selectedPeople.value.map((item) => item.code);
-      treeRef.value!.setCheckedKeys(selectedIds);
-      loading.value = false;
-    });
-  });
-  watch(queryStr, (query) => {
-    treeRef.value!.filter(query);
+  }
+};
+const handleNodeClick = (node, checked) => {
+  if (!node.children) {
+    treeRef.value!.setChecked(node.code, !checked.checked, true);
+  }
+};
+const props = defineProps<{
+  selectedUser: treeSelected[];
+}>();
+onMounted(() => {
+  if (props.selectedUser) {
+    selectedPeople.value = cloneDeep(props.selectedUser);
+  }
+  selected.value = selectedPeople.value.length;
+  getList().then((res) => {
+    tableData.value = res;
+    total.value = countLeafNodes(nodeData.value);
+    const selectedIds: TreeKey[] = selectedPeople.value.map((item) => item.code);
+    treeRef.value!.setCheckedKeys(selectedIds);
+    loading.value = false;
   });
+});
+watch(queryStr, (query) => {
+  treeRef.value!.filter(query);
+});
 </script>
 
 <style lang="scss" scoped>
-  .select-tree {
+.select-tree {
+  display: flex;
+  width: 100%;
+  height: 100%;
+  .left {
+    display: flex;
+    flex-direction: column;
+    width: 50%;
+    height: 100%;
+    border-right: 1px solid rgba(0, 0, 0, 0.06);
+    .el-tree {
+      width: 100%;
+      margin-top: 20px;
+      font-weight: 500;
+      font-size: 14px;
+      color: #303133;
+      line-height: 22px;
+      overflow-y: auto;
+      max-height: calc(100% - 80px);
+    }
+  }
+  .right {
     display: flex;
-    width: 100%;
+    flex-direction: column;
+    flex: 1;
     height: 100%;
-    .left {
+    position: relative;
+    .head {
       display: flex;
-      flex-direction: column;
-      width: 50%;
-      height: 100%;
-      border-right: 1px solid rgba(0, 0, 0, 0.06);
-      .el-tree {
-        width: 100%;
-        margin-top: 20px;
-        font-weight: 500;
-        font-size: 14px;
-        color: #303133;
-        line-height: 22px;
-        overflow-y: auto;
-        max-height: calc(100% - 80px);
-      }
+      align-items: center;
+      font-weight: 400;
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 22px;
     }
-    .right {
+    .selected {
       display: flex;
-      flex-direction: column;
-      flex: 1;
-      height: 100%;
-      position: relative;
-      .head {
-        display: flex;
-        align-items: center;
-        font-weight: 400;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 22px;
-      }
-      .selected {
-        display: flex;
-        flex-wrap: wrap;
-        gap: 8px;
-        overflow-y: auto;
-        max-height: calc(100% - 120px);
-      }
-      .footer {
-        display: flex;
-        gap: 6px;
-        position: absolute;
-        right: 24px;
-        bottom: 20px;
-      }
+      flex-wrap: wrap;
+      gap: 8px;
+      overflow-y: auto;
+      max-height: calc(100% - 120px);
+    }
+    .footer {
+      display: flex;
+      gap: 6px;
+      position: absolute;
+      right: 24px;
+      bottom: 20px;
     }
   }
-</style>
+}
+</style>

+ 152 - 152
src/views/message/systemNotifications/components/problemHandleTable.vue

@@ -101,7 +101,7 @@
     >
       <el-input
         v-model="content"
-        style="width: 370px"
+        style="width: 370px;"
         :autosize="{ minRows: 4, maxRows: 5 }"
         maxlength="100"
         show-word-limit
@@ -118,174 +118,174 @@
   </div>
 </template>
 <script lang="ts" setup>
-  import { ref, onMounted, nextTick } from 'vue';
-  import { problemPhase, issueStateMapping } from '../type';
-  import {
-    queryIssueProcessMessage,
-    modifyContent,
-    modifyWorkshopList,
-    queryWorkshopNamebyIds,
-  } from '@/api/message/system-notifications';
-  import WorkShopTree from './WorkShopTree.vue';
-  import { ElMessage } from 'element-plus';
-  const problemTableData = ref<problemPhase[]>([]);
-  const workDialog = ref<boolean>(false);
-  const showDialog = ref<boolean>(false);
-  const content = ref<string>('');
-  const listLeft = ref();
-  const isExpandShow = ref<boolean>(false);
-  const isExpand = ref<boolean>(true);
-  const toExpand = () => {
-    isExpand.value = !isExpand.value;
-    if (isExpand.value) {
-      listLeft.value.style.maxHeight = '24px';
-    } else {
-      listLeft.value.style.maxHeight = 'none';
-    }
-  };
-  const editId = ref<number>(0);
-  const handleWorkShopEdit = () => {
-    workDialog.value = true;
-  };
-  const handleProbleEdit = (id: number, _content: string) => {
-    showDialog.value = true;
-    editId.value = id;
-    content.value = _content;
-  };
-
-  const submitDialog = () => {
-    modifyContent(content.value, editId.value)
-      .then(() => {
-        ElMessage({
-          message: '修改成功',
-          type: 'success',
-          plain: true,
-        });
-        closeDialog();
-        queryIssueData();
-      })
-      .catch((error) => {
-        console.error(error);
-      });
-  };
-
-  const closeDialog = () => {
-    showDialog.value = false;
-  };
-  interface UserList {
-    code: number | string;
-    name: string;
-    id: number;
+import { ref, onMounted, nextTick } from 'vue';
+import { problemPhase, issueStateMapping } from '../type';
+import {
+  queryIssueProcessMessage,
+  modifyContent,
+  modifyWorkshopList,
+  queryWorkshopNamebyIds,
+} from '../api/index';
+import WorkShopTree from './WorkShopTree.vue';
+import { ElMessage } from 'element-plus';
+const problemTableData = ref<problemPhase[]>([]);
+const workDialog = ref<boolean>(false);
+const showDialog = ref<boolean>(false);
+const content = ref<string>('');
+const listLeft = ref();
+const isExpandShow = ref<boolean>(false);
+const isExpand = ref<boolean>(true);
+const toExpand = () => {
+  isExpand.value = !isExpand.value;
+  if (isExpand.value) {
+    listLeft.value.style.maxHeight = '24px';
+  } else {
+    listLeft.value.style.maxHeight = 'none';
   }
-  const selectedUser = ref<UserList[]>([]);
-  const queryIssueData = () => {
-    queryIssueProcessMessage().then((res) => {
-      let params;
-      if (res[0].workshopList) {
-        params = JSON.parse(res[0].workshopList);
-      } else {
-        params = [];
-      }
-      queryWorkshopNamebyIds(params).then((res) => {
-        selectedUser.value = res;
-        nextTick(() => {
-          const height = listLeft.value.scrollHeight;
-          isExpandShow.value = height > 24 ? false : true;
-        });
-      });
-      problemTableData.value = res;
-    });
-  };
-  const handleCancle = () => {
-    workDialog.value = false;
-  };
-  const handleSubmit = (selectedData: UserList[]) => {
-    const params = selectedData.map((item) => item.id);
-    modifyWorkshopList(params).then(() => {
+};
+const editId = ref<number>(0);
+const handleWorkShopEdit = () => {
+  workDialog.value = true;
+};
+const handleProbleEdit = (id: number, _content: string) => {
+  showDialog.value = true;
+  editId.value = id;
+  content.value = _content;
+};
+
+const submitDialog = () => {
+  modifyContent(content.value, editId.value)
+    .then(() => {
       ElMessage({
-        message: '添加成功',
+        message: '修改成功',
         type: 'success',
         plain: true,
       });
-      workDialog.value = false;
+      closeDialog();
       queryIssueData();
+    })
+    .catch((error) => {
+      console.error(error);
     });
-  };
-  onMounted(() => {
+};
+
+const closeDialog = () => {
+  showDialog.value = false;
+};
+interface UserList {
+  code: number | string;
+  name: string;
+  id: number;
+}
+const selectedUser = ref<UserList[]>([]);
+const queryIssueData = () => {
+  queryIssueProcessMessage().then((res) => {
+    let params;
+    if (res[0].workshopList) {
+      params = JSON.parse(res[0].workshopList);
+    } else {
+      params = [];
+    }
+    queryWorkshopNamebyIds(params).then((res) => {
+      selectedUser.value = res;
+      nextTick(() => {
+        const height = listLeft.value.scrollHeight;
+        isExpandShow.value = height > 24 ? false : true;
+      });
+    });
+    problemTableData.value = res;
+  });
+};
+const handleCancle = () => {
+  workDialog.value = false;
+};
+const handleSubmit = (selectedData: UserList[]) => {
+  const params = selectedData.map((item) => item.id);
+  modifyWorkshopList(params).then(() => {
+    ElMessage({
+      message: '添加成功',
+      type: 'success',
+      plain: true,
+    });
+    workDialog.value = false;
     queryIssueData();
   });
+};
+onMounted(() => {
+  queryIssueData();
+});
 </script>
 <style lang="scss" scoped>
-  .pushWorkShopBar {
-    margin: 24px 0 0 0;
+.pushWorkShopBar {
+  margin: 24px 0 0 0;
+  display: flex;
+  img {
+    cursor: pointer;
+  }
+  :nth-of-type(1) {
+    margin-right: 12px;
+    margin-bottom: 16px;
+  }
+  .pushiWorkShopSpan {
+    width: 56px;
+    height: 20px;
+    font-weight: 600;
+    font-size: 14px;
+    color: #303133;
+    line-height: 20px;
+  }
+  .descriptionSpan {
+    width: 300px;
+    height: 14px;
+    font-weight: 400;
+    font-size: 12px;
+    color: #999999;
+    line-height: 20px;
+  }
+}
+.workshopList {
+  display: flex;
+  .left {
     display: flex;
-    img {
-      cursor: pointer;
-    }
-    :nth-of-type(1) {
-      margin-right: 12px;
-      margin-bottom: 16px;
-    }
-    .pushiWorkShopSpan {
-      width: 56px;
-      height: 20px;
-      font-weight: 600;
-      font-size: 14px;
-      color: #303133;
-      line-height: 20px;
-    }
-    .descriptionSpan {
-      width: 300px;
-      height: 14px;
+    flex-wrap: wrap;
+    width: 95%;
+    max-height: 24px;
+    overflow-y: hidden;
+    gap: 20px;
+  }
+  .right {
+    flex: 1;
+    cursor: pointer;
+    span {
       font-weight: 400;
       font-size: 12px;
-      color: #999999;
-      line-height: 20px;
-    }
-  }
-  .workshopList {
-    display: flex;
-    .left {
-      display: flex;
-      flex-wrap: wrap;
-      width: 95%;
-      max-height: 24px;
-      overflow-y: hidden;
-      gap: 20px;
+      color: #303133;
+      line-height: 17px;
     }
-    .right {
-      flex: 1;
-      cursor: pointer;
-      span {
-        font-weight: 400;
-        font-size: 12px;
-        color: #303133;
-        line-height: 17px;
-      }
-      img {
-        margin-left: 4px;
-      }
+    img {
+      margin-left: 4px;
     }
   }
-  .emptyDiv {
-    margin-top: 78px;
-    margin: auto;
-    width: 396px;
-    .emptyImg {
-      height: 257px;
-    }
-    .emptySpan {
-      font-family: PingFangSC, PingFang SC;
-      font-weight: 400;
-      font-size: 18px;
-      color: rgba(0, 0, 0, 0.45);
-      text-align: left;
-      font-style: normal;
-    }
+}
+.emptyDiv {
+  margin-top: 78px;
+  margin: auto;
+  width: 396px;
+  .emptyImg {
+    height: 257px;
   }
-  .operation {
-    display: flex;
-    justify-content: center;
-    width: 100%;
+  .emptySpan {
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 400;
+    font-size: 18px;
+    color: rgba(0, 0, 0, 0.45);
+    text-align: left;
+    font-style: normal;
   }
+}
+.operation {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+}
 </style>

+ 104 - 104
src/views/message/systemNotifications/components/systemNotificationTable.vue

@@ -94,123 +94,123 @@
   </el-dialog>
 </template>
 <script lang="ts" setup>
-  import { ref, onMounted } from 'vue';
-  import { useRouter } from 'vue-router';
-  import { pushChannelMapping, recipientTypeMapping } from '../type';
-  import SearchBar from './SearchBar.vue';
-  import { storeToRefs } from 'pinia';
-  import useSysNotion from '../store/index';
-  import { deleteSystemMessage } from '@/api/message/system-notifications';
-  import { ElMessage } from 'element-plus';
-  const sysNotion = useSysNotion();
-  const { total, page, pagesize, sysNotionData } = storeToRefs(sysNotion);
-  const { getSysNotion } = sysNotion;
-  const deleteDialog = ref(false);
-  const router = useRouter();
-
-  const createNotification = () => {
-    router.push('/message/sysnotion-config');
-  };
-
-  const handleView = (id: number) => {
-    router.push(`/message/sysnotion-config?id=${id}`);
-  };
-  const deleteId = ref<number>(0);
-  const handleDelete = (id: number) => {
-    deleteDialog.value = true;
-    deleteId.value = id;
-  };
-
-  const confirmDelete = () => {
-    deleteSystemMessage(deleteId.value).then(() => {
-      ElMessage({
-        message: '删除成功',
-        type: 'success',
-        plain: true,
-      });
-      deleteDialog.value = false;
-      getSysNotion();
+import { ref, onMounted } from 'vue';
+import { useRouter } from 'vue-router';
+import { pushChannelMapping, recipientTypeMapping, pushStatusMapping } from '../type';
+import SearchBar from './SearchBar.vue';
+import { storeToRefs } from 'pinia';
+import useSysNotion from '../store/index';
+import { deleteSystemMessage } from '../api/index';
+import { ElMessage } from 'element-plus';
+const sysNotion = useSysNotion();
+const { total, page, pagesize, sysNotionData } = storeToRefs(sysNotion);
+const { getSysNotion } = sysNotion;
+const deleteDialog = ref(false);
+const router = useRouter();
+
+const createNotification = () => {
+  router.push('/message/sysnotion-config');
+};
+
+const handleView = (id: number) => {
+  router.push(`/message/sysnotion-config?id=${id}`);
+};
+const deleteId = ref<number>(0);
+const handleDelete = (id: number) => {
+  deleteDialog.value = true;
+  deleteId.value = id;
+};
+
+const confirmDelete = () => {
+  deleteSystemMessage(deleteId.value).then(() => {
+    ElMessage({
+      message: '删除成功',
+      type: 'success',
+      plain: true,
     });
-  };
-
-  const handleSizeChange = (newPageSize: number) => {
-    pagesize.value = newPageSize;
+    deleteDialog.value = false;
     getSysNotion();
-  };
+  });
+};
 
-  const handleCurrentChange = (newCurrentPage: number) => {
-    page.value = newCurrentPage;
-    getSysNotion();
-  };
+const handleSizeChange = (newPageSize: number) => {
+  pagesize.value = newPageSize;
+  getSysNotion();
+};
 
-  onMounted(() => {
-    getSysNotion();
-  });
+const handleCurrentChange = (newCurrentPage: number) => {
+  page.value = newCurrentPage;
+  getSysNotion();
+};
+
+onMounted(() => {
+  getSysNotion();
+});
 </script>
 <style lang="scss" scoped>
-  .pagination {
-    position: absolute;
-    bottom: 35px;
-    right: 67px;
-  }
-
-  .deleteDialog {
-    .deleteDialogHeader {
-      display: flex;
-      .deleteTip {
-        height: 24px;
-        width: 24px;
-      }
-      .titleSpan {
-        height: 24px;
-        font-size: 16px;
-        color: rgba(0, 0, 0, 0.88);
-        line-height: 24px;
-        text-align: center;
-        margin-left: 12px;
-      }
+.pagination {
+  position: absolute;
+  bottom: 35px;
+  right: 67px;
+}
+
+.deleteDialog {
+  .deleteDialogHeader {
+    display: flex;
+    .deleteTip {
+      height: 24px;
+      width: 24px;
     }
-    .dialogBottom {
-      display: flex;
-      justify-content: flex-end;
-      margin-top: 12px;
+    .titleSpan {
+      height: 24px;
+      font-size: 16px;
+      color: rgba(0, 0, 0, 0.88);
+      line-height: 24px;
+      text-align: center;
+      margin-left: 12px;
     }
   }
-
-  .operation {
+  .dialogBottom {
     display: flex;
-    justify-content: center;
-    /* :first-child {
-      margin-right: 20px;
-    } */
-    :nth-child(2) {
-      margin-left: 20px;
-    }
+    justify-content: flex-end;
+    margin-top: 12px;
   }
+}
 
-  .emptyDiv {
-    margin-top: 78px;
-    margin: auto;
-    width: 396px;
-    .emptyImg {
-      height: 257px;
-    }
-    .emptySpan {
-      font-family: PingFangSC, PingFang SC;
-      font-weight: 400;
-      font-size: 18px;
-      color: rgba(0, 0, 0, 0.45);
-      text-align: left;
-      font-style: normal;
-    }
+.operation {
+  display: flex;
+  justify-content: center;
+  /* :first-child {
+      margin-right: 20px;
+    } */
+  :nth-child(2) {
+    margin-left: 20px;
   }
-
-  :deep(.el-dialog) {
-    border-radius: 8px;
+}
+
+.emptyDiv {
+  margin-top: 78px;
+  margin: auto;
+  width: 396px;
+  .emptyImg {
+    height: 257px;
   }
-  .pushstatus {
-    display: flex;
-    justify-content: center;
-    width: 100%;
+  .emptySpan {
+    font-family: PingFangSC, PingFang SC;
+    font-weight: 400;
+    font-size: 18px;
+    color: rgba(0, 0, 0, 0.45);
+    text-align: left;
+    font-style: normal;
   }
+}
+
+:deep(.el-dialog) {
+  border-radius: 8px;
+}
+.pushstatus {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+}
 </style>

+ 29 - 29
src/views/message/systemNotifications/store/index.ts

@@ -1,33 +1,33 @@
-import { ref } from 'vue';
-import { defineStore } from 'pinia';
-import { systemTableData } from '../type';
-import { getSystemMessageList, queryParams } from '@/api/message/system-notifications';
+import { ref } from 'vue'
+import { defineStore } from "pinia";
+import { systemTableData, queryParams } from '../type'
+import { getSystemMessageList } from '../api/index'
 import { useRequest } from 'vue-hooks-plus';
 export const useSysNotion = defineStore('sys-notion', () => {
-  const total = ref<number>(0);
-  const page = ref<number>(1);
-  const pagesize = ref<number>(10);
-  const content = ref<string>('');
-  const sysNotionData = ref<systemTableData[]>([]);
-  const conditionSearch = () => {
-    const params: queryParams = {
-      pageNumber: page.value,
-      pageSize: pagesize.value,
-    };
-    if (content.value) {
-      params.content = content.value;
+    const total = ref<number>(0)
+    const page = ref<number>(1);
+    const pagesize = ref<number>(10);
+    const content = ref<string>('');
+    const sysNotionData = ref<systemTableData[]>([]);
+    const conditionSearch = () => {
+        const params: queryParams = {
+            pageNumber: page.value,
+            pageSize: pagesize.value,
+        };
+        if (content.value) {
+            params.content = content.value
+        }
+        return getSystemMessageList(params).then((res) => {
+            return res;
+        });
     }
-    return getSystemMessageList(params).then((res) => {
-      return res;
+    const { run: getSysNotion } = useRequest(conditionSearch, {
+        manual: true,
+        onSuccess: (res) => {
+            sysNotionData.value = res.records;
+            total.value = res.totalRow;
+        },
     });
-  };
-  const { run: getSysNotion } = useRequest(conditionSearch, {
-    manual: true,
-    onSuccess: (res) => {
-      sysNotionData.value = res.records;
-      total.value = res.totalRow;
-    },
-  });
-  return { total, page, pagesize, content, sysNotionData, getSysNotion };
-});
-export default useSysNotion;
+    return { total, page, pagesize, content, sysNotionData, getSysNotion }
+})
+export default useSysNotion;

+ 91 - 82
src/views/message/systemNotifications/type.ts

@@ -1,119 +1,128 @@
 export interface systemTableData {
-  id: number;
-  // 消息标题
-  title: string;
-  // 推送渠道
-  pushChannel: number[];
-  // 推送对象
-  recipientType: number;
-  // 推送状态
-  status: number;
-  // 推送时间
-  pushAt: string;
+    id: number,
+    // 消息标题
+    title: string,
+    // 推送渠道
+    pushChannel: number[],
+    // 推送对象
+    recipientType: number,
+    // 推送状态
+    status: number,
+    // 推送时间
+    pushAt: string
+}
+export interface queryParams {
+    content?: string;
+    pageNumber: number;
+    pageSize: number;
 }
 
 export enum pushChannelEnum {
-  platform = 2,
-  lanxin = 1,
+    platform = 2,
+    lanxin = 1,
 }
 
 export const pushChannelMapping = {
-  [pushChannelEnum.platform]: '平台',
-  [pushChannelEnum.lanxin]: '蓝信',
+    [pushChannelEnum.platform]: '平台',
+    [pushChannelEnum.lanxin]: '蓝信',
 };
 
+
 export enum recipientTypeEnum {
-  all = 1,
-  byGroup = 2,
-  custom = 3,
+    all = 1,
+    byGroup = 2,
+    custom = 3
 }
 
 export const recipientTypeMapping = {
-  [recipientTypeEnum.all]: '全员',
-  [recipientTypeEnum.byGroup]: '分组',
-  [recipientTypeEnum.custom]: '自定义',
+    [recipientTypeEnum.all]: '全员',
+    [recipientTypeEnum.byGroup]: '分组',
+    [recipientTypeEnum.custom]: '自定义',
 };
 
 export enum pushStatus {
-  completed = 1,
-  prepareToPush = 0,
+    completed = 1,
+    prepareToPush = 0
 }
 
 export const pushStatusMapping = {
-  [pushStatus.completed]: '推送完成',
-  [pushStatus.prepareToPush]: '等待推送',
+    [pushStatus.completed]: '推送完成',
+    [pushStatus.prepareToPush]: '等待推送',
 };
 
+
 export interface systemInfoRes {
-  records: systemMessage[];
-  pageNumber: number;
-  pageSize: number;
-  totalPage: number;
-  totalRow: number;
+    records: systemMessage[],
+    pageNumber: number,
+    pageSize: number,
+    totalPage: number,
+    totalRow: number
 }
 
+
 export interface systemMessage {
-  id: number;
-  // 消息标题
-  messagType: string;
-  // 推送渠道
-  pushChannel: string;
-  // 推送对象
-  recipientType: recipientTypeEnum;
-  // 推送状态
-  pushStatus: pushStatus;
-  // 推送时间
-  pushTime: string;
+    id: number,
+    // 消息标题
+    messagType: string,
+    // 推送渠道
+    pushChannel: string,
+    // 推送对象
+    recipientType: recipientTypeEnum,
+    // 推送状态
+    pushStatus: pushStatus,
+    // 推送时间
+    pushTime: string
 }
 
+
 export interface problemInfoRes {
-  records: problemPhase[];
-  pageNumber: number;
-  pageSize: number;
-  totalPage: number;
-  totalRow: number;
+    records: problemPhase[],
+    pageNumber: number,
+    pageSize: number,
+    totalPage: number,
+    totalRow: number
 }
 
 export interface problemPhase {
-  id: number;
-  //推送内容
-  content: string;
-  //车间id
-  workshopList: number[];
-  //问题状态
-  issuePhase: string;
-  //问题状态
-  issueState: number;
-  //接收对象
-  recipient: string;
-  //创建时间
-  createdAt: string;
-  //更新时间
-  updatedAt: string;
-  //是否删除
-  isDeleted: number;
+    id: number,
+    //推送内容
+    content: string;
+    //车间id
+    workshopList: number[];
+    //问题状态
+    issuePhase: string;
+    //问题状态
+    issueState: number;
+    //接收对象
+    recipient: string;
+    //创建时间
+    createdAt: string;
+    //更新时间
+    updatedAt: string;
+    //是否删除
+    isDeleted: number;
 }
 
 enum issueStateEnum {
-  tobeSubmitted = 0,
-  tobeReviewed = 1,
-  tobeIssued = 2,
-  revoked = 3,
-  pending = 4,
-  review = 5,
-  process = 6,
-  reviewSuccess = 7,
-  closed = 8,
+    tobeSubmitted = 0,
+    tobeReviewed = 1,
+    tobeIssued = 2,
+    revoked = 3,
+    pending = 4,
+    review = 5,
+    process = 6,
+    reviewSuccess = 7,
+    closed = 8
 }
 
 export const issueStateMapping = {
-  [issueStateEnum.tobeSubmitted]: '待提交',
-  [issueStateEnum.tobeReviewed]: '待审核',
-  [issueStateEnum.tobeIssued]: '待下发',
-  [issueStateEnum.revoked]: '已撤消',
-  [issueStateEnum.pending]: '待处理',
-  [issueStateEnum.review]: '待复核',
-  [issueStateEnum.process]: '复核未通过',
-  [issueStateEnum.reviewSuccess]: '复核通过',
-  [issueStateEnum.closed]: '已关闭',
-};
+    [issueStateEnum.tobeSubmitted]: '待提交',
+    [issueStateEnum.tobeReviewed]: '待审核',
+    [issueStateEnum.tobeIssued]: '待下发',
+    [issueStateEnum.revoked]: '已撤消',
+    [issueStateEnum.pending]: '待处理',
+    [issueStateEnum.review]: '待复核',
+    [issueStateEnum.process]: '复核未通过',
+    [issueStateEnum.reviewSuccess]: '复核通过',
+    [issueStateEnum.closed]: '已关闭'
+};