马宇豪
2023-06-14 e2f129ee192ae3469848beeceac262b13ba8eacb
新增页面和配置,对接口
已修改21个文件
已添加5个文件
已删除1个文件
4528 ■■■■ 文件已修改
src/api/list.js 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/review.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/send.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/user.js 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/style/themeColor.less 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/menu/index.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/util/request.js 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/util/storage.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/History.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/Report.vue 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/callRecord.vue 370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/components/msgEditMod.vue 531 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/components/sameLevelMod.vue 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/components/userMod.vue 200 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/history.vue 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/list.vue 455 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/massSend.vue 305 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/menuManage.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/msgRecord.vue 161 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/msgReview.vue 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/notice.vue 493 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/release.vue 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/sameLevel.vue 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Admin/userManage.vue 97 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Home.vue 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/list.js
对比新文件
@@ -0,0 +1,59 @@
//将拦截器整体导入
import request from '@/util/request'//导入已经写好的拦截器
// 我收到的
export function getMsgRecord(data){
    return request({
        url: '/published/warninfo/receive/Page',
        method: 'post',
        data: data
    })
}
// 叫应
export function responseMsg(id){
    return request({
        url: '/published/warninfo/responseById?id=' + id,
        method: 'get'
    })
}
export function readById(id){
    return request({
        url: '/published/warninfo/readById?id=' + id,
        method: 'get'
    })
}
// 我发出的
export function getPublishRecord(data){
    return request({
        url: '/published/warninfo/publish/Page',
        method: 'post',
        data: data
    })
}
// 历史信息
export function getHistoryRecord(data){
    return request({
        url: '/published/warninfo/history/publish',
        method: 'post',
        data: data
    })
}
// 历史叫应信息
export function getResponseRecord(data){
    return request({
        url: '/published/warninfo/history/response',
        method: 'post',
        data: data
    })
}
src/api/login.js
@@ -21,4 +21,12 @@
        url:'/sys/menu/get/u',
        method:'get',
    })
}
// 获取区划列表
export function getDistrictInfo(){
    return request({
        url:'/sys/districtInfo/all',
        method:'get',
    })
}
src/api/review.js
对比新文件
@@ -0,0 +1,44 @@
//将拦截器整体导入
import request from '@/util/request'//导入已经写好的拦截器
// 审核记录
export function getReviewRecord(data){
    return request({
        url: '/warning/info/review/Page',
        method: 'post',
        data: data
    })
}
// 信息详情
export function getReviewDetail(id){
    return request({
        url: '/warning/info/review/findById?id=' + id,
        method: 'get'
    })
}
// 工作人员查看详情
export function getReviewDetailByWorker(id){
    return request({
        url: '/warning/info/findById?id=' + id,
        method: 'get'
    })
}
// 提交审核
export function postReview(data){
    return request({
        url: '/warning/info/review/submit',
        method: 'post',
        data: data
    })
}
src/api/send.js
对比新文件
@@ -0,0 +1,49 @@
//将拦截器整体导入
import request from '@/util/request'//导入已经写好的拦截器
// 信息编辑
export function msgSend(data){
    return request({
        url: '/warning/info/add',
        method: 'post',
        data: data
    })
}
// 群发信息
export function massSend(data){
    return request({
        url: '/mesmanager/mes/send',
        method: 'post',
        data: data
    })
}
export function getMassRecord(data){
    return request({
        url: '/mesmanager/mes/page',
        method: 'post',
        data: data
    })
}
// 发布信息
export function publishMsg(id){
    return request({
        url: '/warning/info/publishById?id=' + id,
        method: 'get'
    })
}
// 删除信息
export function deleteMsg(id){
    return request({
        url: '/warning/info/deleteById?id=' + id,
        method: 'get'
    })
}
src/api/user.js
@@ -18,6 +18,14 @@
    })
}
export function updateUser(data){
    return request({
        url: '/account/user/update/info',
        method: 'post',
        data: data,
    })
}
export function delUser(id){
    return request({
        url: '/account/user/deleteUser?userId=' + id,
@@ -42,28 +50,57 @@
    })
}
export function getRecipientById(data){
export function getRecipientById(id){
    return request({
        url:'/mesmanager/recipient/findById',
        method:'post',
        data:data,
        url:'/mesmanager/recipient/findById?id=' + id,
        method:'get'
    })
}
export function getPeerRecipient(){
    return request({
        url:'/mesmanager/recipient/listPeerRecipient',
        method:'get'
    })
}
export function getAreaWithUserIfo(){
    return request({
        url:'/sys/districtInfo/allWithUserIfo',
        method:'get'
    })
}
export function addRecipient(data){
    return request({
        url:'/mesmanager/recipient/page',
        url:'/mesmanager/recipient/add',
        method:'post',
        data:data,
    })
}
export function updateRecipient(data){
    return request({
        url:'/mesmanager/recipient/update',
        method:'post',
        data:data,
    })
}
export function delRecipient(id){
    return request({
        url:'/mesmanager/recipient/delete?id=' + id,
        method: 'get'
    })
}
// 获取同级领导
export function getLeaders(){
    return request({
        url: '/account/user/list/auditors',
        method: 'get'
    })
}
src/assets/style/themeColor.less
@@ -3,4 +3,5 @@
@success: #52c41a;
@warning: #faad14;
@danger: #f5222d;
@blackText: rgba(0,0,0,.65);
@blackText: rgba(0,0,0,.65);
@blackBorder: #d9d9d9;
src/layout/menu/index.js
@@ -36,7 +36,7 @@
        Children: [{
                MenuID: "21",
                MenuTitle: "信息编辑",
                MenuPath: "/torelease",
                MenuPath: "/notice",
            },
            {
                MenuID: "22",
src/router/index.js
@@ -53,8 +53,8 @@
        component: () => import('@/views/Admin/Audit'),
      },
      {
        path: '/torelease',
        name: 'torelease',
        path: '/notice',
        name: 'notice',
        meta: { title: '信息编辑' },
        component: () => import('@/views/Admin/notice'),
      },
@@ -74,7 +74,7 @@
        path: '/history',
        name: 'history',
        meta: { title: '历史信息' },
        component: () => import('@/views/Admin/History'),
        component: () => import('@/views/Admin/history'),
      },
      {
        path: '/callRecord',
src/util/request.js
@@ -35,8 +35,13 @@
http.interceptors.response.use(
    (response) => {
        // 对响应数据做点什么
        if (response.data.code && response.data.code === 'A0213') {
            message.error('用户uid不存在');
        if (response.data.code && response.data.code === 401) {
            message.error('用户不存在');
            loginOut()
                .then(() => {
                    Session.clear();
                    window.location.href = '/';
                });
            // useLoginApi()
            //     .signOut()
            //     .then(() => {
src/util/storage.js
@@ -7,6 +7,13 @@
 * @method remove 移除永久缓存
 * @method clear 移除全部永久缓存
 */
export function getUserInfo() {
    const userInfo = Cookies.get('userInfo')
    if(userInfo){
        return JSON.parse(userInfo)
    }
}
export const Local = {
    // 设置永久缓存
    set(key, val) {
src/views/Admin/History.vue
文件已删除
src/views/Admin/Report.vue
@@ -1,175 +1,283 @@
<template>
  <div class="inner">
      <a-radio-group v-model="category">
          <a-radio-button value="default">
              全部
          </a-radio-button>
          <a-radio-button value="1">
              已审核
          </a-radio-button>
          <a-radio-button value="2">
              未审核
          </a-radio-button>
      </a-radio-group>
      <div style="float:right">
          时间区间筛选:<a-range-picker :placeholder="['开始时间', '结束时间']"/>
      </div>
      <br/><br/>
      <!-- 表格实体部分-->
      <a-table :columns="columns" :data-source="data" bordered>
          <span slot="level" slot-scope="text">
              <a-tag :color="text === '黄色' ? 'yellow' :text === '橙色'? 'orange':text === '红色'?'red':'blue'">
                  {{ text }}
              </a-tag>
          </span>
          <template slot="attachment" slot-scope="text">
              <span v-if="text==='无'">无</span>
              <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
          </template >
          <template slot="operation" slot-scope="text, record, index">
              <div class="editable-row-operations">
                <a-button v-if="record.audit==='已审核'" type="primary" @click="showModal(record.id)" >
                    确认发布</a-button>&nbsp;&nbsp;
                  <router-link :to="{path:'/details',query: {id: record.id}}">信息详情</router-link>
                &nbsp;&nbsp;<a style="color:red">删除</a>
              </div>
          </template>
      </a-table>
      <!-- 对话框 -->
      <a-modal title="信息发布"
      okText="确认发布"
      cancelText="取消"
      :visible="visible" :confirm-loading="confirmLoading" @ok="handleOk" @cancel="handleCancel">
      <p>确认发布 “[{{show_id}}]2023年5月23日,全疆黄色高温预警信息”?</p>
      </a-modal>
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="search.searchParams.reviewStatus" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button :value="2">
            审核通过
          </a-radio-button>
          <a-radio-button :value="1">
            未审核
          </a-radio-button>
          <a-radio-button :value="3">
            审核驳回
          </a-radio-button>
        </a-radio-group>
      </a-col>
      <a-col :span="16">
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="timeChange"
                @ok="onOk"
                style="width: 100%"
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
    </a-row>
    <div class="table-cont">
      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination" :rowKey="record=>record.id">
        <template #index="text,record,index">
          {{ index+1 }}
        </template>
        <template #disasterType="text">
          {{ getRiskName(text) }}
        </template>
        <template #attachment="text">
          <span v-if="text==='无'">无</span>
          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
        </template >
        <template #reviewStatus="reviewStatus">
          <a-tag
              :color="reviewStatus === 1 ? 'blue' : reviewStatus === 2 ? 'green' : 'red'"
          >
            {{ reviewStatus==1?'未审核':reviewStatus==2?'已审核':reviewStatus==3?'审核驳回':'' }}
          </a-tag>
        </template>
        <template #operation="text, record, index">
          <a-button type="primary" v-if="record.reviewStatus == 2" @click="confirmPost(record.id)">确认发布</a-button>
          <a-button type="link" v-if="record.reviewStatus == 2 || record.reviewStatus == 3" @click="openMod('view',record)">查看信息详情</a-button>
          <a-button class="del" type="link" @click="delData(record.id)">删除</a-button>
        </template>
      </a-table>
    </div>
    <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
  </div>
</template>
<script>
    const columns = [{
            title: '编号',
            dataIndex: 'id',
            width: '8%',
        },
        {
            title: '提交审核时间',
            dataIndex: 'time',
            width: '13%',
            scopedSlots: {
                customRender: 'time'
            }, //设置定制化表格数据
        },
        {
            title: '发布单位',
            dataIndex: 'department',
            width: '12%',
        },
        {
            title: '类别',
            dataIndex: 'category',
            width: '6%',
        },
        {
            title: '级别',
            dataIndex: 'level',
            scopedSlots: {
                customRender: 'level'
            }, //设置定制化表格数据
            width: '6%',
        },
        {
            title: '信息标题',
            dataIndex: 'title',
            width: '16%',
        },
        {
            title: '附件',
            dataIndex: 'attachment',
            width: '6%',
            scopedSlots: {
                customRender: 'attachment'
            },
        },
        {
            title: '审核情况',
            dataIndex: 'audit',
            width: '10%',
            scopedSlots: {
                customRender: 'audit'
            }, //设置定制化表格数据
        },
        {
            title: '操作',
            dataIndex: 'operation',
            scopedSlots: {
                customRender: 'operation'
            },
        },
    ];
    const data = [{
            key: 1,
            id:1001,
            readed:false,
            time: '2023年5月3日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '黄色',
            title: '全疆高温红色预警',
            attachment: '1',
            audit: '已审核'
        },
        {
                key: 2,
                id:1002,
                readed:false,
                time: '2023年5月3日 15:30',
                department: '自治区预警中心',
                category: '气象',
                level: '黄色',
                title: '全疆高温红色预警',
                attachment: '1',
                audit: '未审核'
            },{
                key: 3,
                id:1003,
                readed:false,
                time: '2023年5月3日 15:30',
                department: '自治区预警中心',
                category: '气象',
                level: '黄色',
                title: '全疆高温红色预警',
                attachment: '1',
                audit: '已审核'
            }]
    export default {
        data() {
            return {
                category: 'default',
                data,
                columns,
                visible: false,
                confirmLoading: false,
                show_id:''
            }
        },
        methods: {
            showModal(id) {
                this.visible = true;
                this.show_id=id
            },
            //确认发布
            handleOk(e) {
                this.ModalText = '正在发布,请稍候...';
                this.confirmLoading = true;
                setTimeout(() => {
                    this.visible = false;
                    this.confirmLoading = false;
                }, 2000);
            },
            handleCancel(e) {
                this.visible = false;
            },
        }
        }
</script>
<script>
import {getReviewDetail, getReviewRecord} from "@/api/review";
import msgEditMod from '@/views/Admin/components/msgEditMod'
import {delRecipient} from "@/api/user";
import {deleteMsg, publishMsg} from "@/api/send";
export default {
  name: 'msgReview',
  components: { msgEditMod },
  data () {
    return {
      search:{
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          reviewStatus: null,
          startTime: '',
          endTime: ''
        }
      },
      timeRange: [],
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      pagination: {
        current: 1,
        defaultCurrent: 1,
        defaultPageSize: 10,
        total: 0,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
        showTotal: total => `共 ${total} 条`
      },
      columns: [
        {
          title: '序号',
          key: 'index',
          scopedSlots: {
            customRender: 'index'
          },
        },
        {
          title: '提交审核时间',
          key: 'gmtReviewSubmit',
          dataIndex: 'gmtReviewSubmit',
        },
        {
          title: '发布单位',
          key: 'publishingUnit',
          dataIndex: 'publishingUnit',
        },
        {
          title: '灾种',
          dataIndex: 'disasterType',
          key: 'disasterType',
          scopedSlots: {
            customRender: 'disasterType'
          }, //设置定制化表格数据
        },
        {
          title: '信息标题',
          key: 'title',
          dataIndex: 'title',
        },
        {
          title: '附件',
          key: 'attachment',
          dataIndex: 'attachment',
          scopedSlots: {
            customRender: 'attachment'
          },
        },
        {
          title: '审核情况',
          dataIndex: 'reviewStatus',
          scopedSlots: {
            customRender: 'reviewStatus'
          }, //设置定制化表格数据
        },
        {
          title: '操作',
          dataIndex: 'operation',
          scopedSlots: {
            customRender: 'operation'
          },
        },
      ],
      data: []
    }
  },
  created() {
    const t = this
    t.getData()
  },
  methods:{
    async getData(){
      const t = this
      const res = await getReviewRecord(this.search)
      if(res.data.code == 100){
        t.data = res.data.data
        t.pagination.total = res.data.total
      }else{
        this.$message.error(res.data.msg)
      }
    },
    resetSearch(){
      const t = this
      t.search = {
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          reviewStatus: null,
          startTime: '',
          endTime: ''
        }
      }
      t.timeRange = []
      t.getData()
    },
    timeChange(value, dateString) {
      const t = this
      if(dateString){
        t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
        t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
      }
    },
    confirmPost(id){
      const t = this
      this.$confirm({
        title: '提示',
        content: h => <div>是否发布该条信息?</div>,
        cancelText: '取消',
        okText: '确认',
        centered: true,
        async onOk() {
          let res = await publishMsg(id)
          if(res.data.code == 100){
            t.$message.success('信息发布成功');
            t.getData()
          }else{
            t.$message.warning(res.data.msg);
          }
        },
        onCancel() {
          console.log('Cancel');
        },
      });
    },
    delData(id){
      const t = this
      this.$confirm({
        title: '提示',
        content: h => <div>是否删除该条信息?</div>,
        cancelText: '取消',
        okText: '确认',
        centered: true,
        async onOk() {
          let res = await deleteMsg(id)
          if(res.data.code == 100){
            t.$message.success('信息删除成功');
            t.getData()
          }else{
            t.$message.warning(res.data.msg);
          }
        },
        onCancel() {
          console.log('Cancel');
        },
      });
    },
    openMod(type,data){
      const t = this
      getReviewDetail(data.id).then(res=>{
        if(res.data.code == 100){
          t.$refs.msgEdit.openMod(type,res.data.data)
        }else{
          this.$message.error(res.data.msg)
        }
      })
    },
    onPageChange(page, pageSize) {
      const t= this
      t.pagination.current = page
      t.search.pageIndex = page
      t.getData()
    },
    onOk(value) {
      console.log('onOk: ', value);
    },
    getRiskName(disasterType){
      return this.riskOptions.find(i => i.value === disasterType)?.name;
    }
  }
}
</script>
<style lang="less" scoped>
.del{
  color: @danger;
}
</style>
src/views/Admin/callRecord.vue
@@ -1,200 +1,254 @@
<template>
  <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="search.searchParams.emergType" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button :value="1">
            紧临
          </a-radio-button>
          <a-radio-button :value="2">
            常规
          </a-radio-button>
        </a-radio-group>
      </a-col>
      <a-col :span="16">
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="timeChange"
                @ok="timeOk"
                style="width: 100%"
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
    </a-row>
    <!-- 表格实体部分-->
    <div class="table-cont">
      <a-table :columns="columns" :data-source="tableData" :pagination="pagination" :rowKey="record=>record.id" bordered>
        <template #level="level">
          <a-tag
              :key="level"
              :color="level === 1 ? 'pink' : level === 2 ? 'blue' : 'green'"
          >
            {{ level==1?'省级':level==2?'地(市、州)级':level==3?'区县级':'村(乡、镇)级' }}
      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
        <template #index="text,record,index">
          {{ index + 1 }}
        </template>
        <template #warningLevel="text">
          <a-tag :color="text === 3 ? 'yellow' :text === 2? 'orange':text === 1?'red':'blue'">
            {{ getLevelName(text) }}
          </a-tag>
        </template>
        <template #actions="actions,row">
          <a-button type="link" @click="viewData()">查看</a-button>
        <template #unittype="unittype">
          <a-tag
              :color="unittype === 1 ? 'purple' : unittype === 2 ? 'blue' : unittype === 3 ? 'cyan' : 'green'"
          >
            {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':unittype==4?'村(乡、镇)级':'管理员' }}
          </a-tag>
        </template >
        <template #operation="text, record, index">
<!--          <a-button type="primary">叫应列表</a-button>-->
          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
        </template>
      </a-table>
      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
    </div>
    <a-modal
        title="信息详情"
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        cancelText="取消" okText="确认"
        width="50%"
    >
      <a-row class="tit">
        <a-col :span="4" style="text-align: right;padding-right: 8px">标题</a-col>
        <a-col :span="14">信息详情标题</a-col>
      </a-row>
      <a-form-model :model="form" :label-col="labelCol" :wrapper-col="wrapperCol" :colon="false">
        <a-form-model-item label="类别">
          <a-input readonly v-model="form.type"/>
        </a-form-model-item>
        <a-form-model-item label="级别">
          <a-tag color="yellow">黄色</a-tag>
        </a-form-model-item>
        <a-form-model-item label="发布单位">
          <a-input readonly v-model="form.dep"/>
        </a-form-model-item>
        <a-form-model-item label="短信内容">
          <a-input readonly type="textarea" v-model="form.content"/>
        </a-form-model-item>
        <a-form-model-item label="附件内容">
          <a><b><a-icon type="paper-clip"/>附件</b></a>
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </div>
</template>
<script>
import {getUser} from '@/api/user'
import {getHistoryRecord, getMsgRecord, getPublishRecord, getResponseRecord} from "@/api/list";
import msgEditMod from "@/views/Admin/components/msgEditMod";
import {getReviewDetailByWorker} from "@/api/review";
const columns = [{
  title: '序号',
  dataIndex: 'index',
  width: '8%',
  scopedSlots: {
    customRender: 'index'
  }
},
  {
    title: '叫应时间',
    dataIndex: 'responseTime',
    width: '15%',
    scopedSlots: {
      customRender: 'responseTime'
    } //设置定制化表格数据
  },
  {
    title: '预警级别',
    dataIndex: 'warningLevel',
    scopedSlots: {
      customRender: 'warningLevel'
    }, //设置定制化表格数据
    width: '8%',
  },
  {
    title: '发布单位',
    dataIndex: 'publishingUnit',
    width: '20%',
  },
  {
    title: '接收人单位',
    dataIndex: 'receiveUnit',
    width: '20%',
    scopedSlots: {
      customRender: 'receiveUnit'
    }
  },
  {
    title: '接收人',
    dataIndex: 'recipienterName',
    width: '20%',
    scopedSlots: {
      customRender: 'recipienterName'
    }
  },
  {
    title: '级别',
    dataIndex: 'unittype',
    width: '12%',
    scopedSlots: {
      customRender: 'unittype'
    },
  },
  {
    title: '操作',
    dataIndex: 'operation',
    scopedSlots: {
      customRender: 'operation'
    },
  },
];
export default {
  name: 'callRecord',
  components: {},
  data () {
  name: 'release',
  components: { msgEditMod },
  data() {
    return {
      visible: false,
      form: {},
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      columns:[
        {
          title: '叫应时间',
          dataIndex: 'callTime',
          key: 'callTime'
        },
        {
          title: '预警信息',
          dataIndex: 'warnings',
          key: 'warnings'
        },
        {
          title: '接收人单位',
          dataIndex: 'depName',
          key: 'depName'
        },
        {
          title: '接收人',
          dataIndex: 'name',
          key: 'name'
        },
        {
          title: '级别',
          dataIndex: 'level',
          key: 'level',
          scopedSlots: { customRender: 'level' }
        },
        {
          title: '操作',
          dataIndex: 'actions',
          key: 'actions',
          scopedSlots: { customRender: 'actions' }
      search:{
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          emergType: null,
          startTime: '',
          endTime: ''
        }
      ],
      tableData: [
        {
          id: 1,
          callTime: '2023-06-02',
          warnings: '666666',
          name: '黄公子',
          level: 1
        },
        {
          id: 2,
          callTime: '2023-06-02',
          warnings: '666666',
          name: '黄公子',
          level: 2
        },
        {
          id: 3,
          callTime: '2023-06-02',
          warnings: '666666',
          name: '黄公子',
          level: 4
        },
      ],
      },
      timeRange: [],
      category: 'default',
      data:[],
      columns,
      visible: false,
      confirmLoading: false,
      pagination: {
        current: 1,
        defaultCurrent: 1,
        defaultPageSize: 10,
        total: 11,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize)
        total: 0,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
        showTotal: total => `共 ${total} 条`
      },
      areaData: [
        {
          value: 1,
          label: '江苏省',
          children: [
            {
              value: 11,
              label: '苏州市',
              children: [
                {
                  value: 111,
                  label: '工业园区',
                },
              ],
            },
          ],
        },
        {
          value: 2,
          label: '新疆维吾尔自治区',
          children: [
            {
              value: 21,
              label: '乌鲁木齐市',
              children: [
                {
                  value: 211,
                  label: '国泰新华',
                },
              ],
            },
          ],
        },
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      levelOptions: [
        {name: '红色预警',value: 1},
        {name: '橙色预警',value: 2},
        {name: '黄色预警',value: 3},
        {name: '蓝色预警',value: 4}
      ]
    }
  },
  created() {
    const t = this
    t.getData()
  },
  methods:{
    async getUserList(){
  methods: {
    async getData(){
      const t = this
      const res = await getUser(t.search)
      const res = await getResponseRecord(this.search)
      if(res.data.code == 100){
        t.data = res.data.data
        t.pagination.total = res.data.total
      }else{
        this.$message.error(res.data.msg)
      }
    },
    viewData(){
    openMod(type,data){
      const t = this
      t.visible = true
      getReviewDetailByWorker(data.warnInfoId).then(res=>{
        if(res.data.code == 100){
          if(res.data.data){
            t.$refs.msgEdit.openMod(type,res.data.data)
          }else{
            t.$message.error('查询信息详情失败')
          }
        }else{
          this.$message.error(res.data.msg)
        }
      })
    },
    onPageChange(page, pageSize) {
      const t= this
      t.pagination.current = page
      t.search.pageIndex = page
      t.getData()
    },
    timeChange(value, dateString) {
      const t = this
      if(dateString){
        t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
        t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
      }
    },
    timeOk(value) {
      console.log('onOk: ', value);
    },
    resetSearch(){
      const t = this
      t.search = {
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          emergType: null,
          startTime: '',
          endTime: ''
        }
      }
      t.timeRange = []
      t.getData()
    },
    //弹出层
    showModal() {
      this.visible = true;
    },
    handleOk(e) {
      this.visible = false
    },
    handleCancel(e) {
      this.visible = false;
    },
    getLevelName(warningLevel){
      return this.levelOptions.find(i => i.value === warningLevel)?.name;
    }
  }
}
</script>
<style lang="less" scoped>
  .tit{
    font-size: 18px;
    font-weight: bolder;
    color: @blackText;
    margin-bottom: 24px;
  }
</style>
</script>
src/views/Admin/components/msgEditMod.vue
对比新文件
@@ -0,0 +1,531 @@
<template>
  <a-modal
      :title="title"
      :visible="visible"
      centered
      width="50%"
      @cancel="handleCancel"
      :afterClose="clearMod"
      :footer="null"
  >
    <a-form-model ref="ruleForm" :model="form" :rules="rules" :wrapper-col="wrapperCol" class="form-cont">
      <div class="left">
        <a-form-model-item prop="title">
          <a-input v-model="form.title" placeholder="请输入标题" style="height: 50px; font-size: 20px;" :readOnly="disable"/>
        </a-form-model-item>
        <!--      <a-row>-->
        <!--        <a-col :span="12" style="display: flex;align-items: center">-->
        <!--          <span style="display: block;margin-bottom: 24px">相关灾种</span>-->
        <!--        </a-col>-->
        <!--        <a-col :span="12" style="display: flex;align-items: center;justify-content: right">-->
        <!--          <span style="display: block;margin-bottom: 24px">预警级别:</span>-->
        <!--        </a-col>-->
        <!--      </a-row>-->
        <a-row>
          <a-col :span="12">
            <a-form-model-item prop="emergType">
              <a-radio-group v-model="form.emergType" button-style="solid" :disabled="disable">
                <a-radio-button :value="2">
                  常规
                </a-radio-button>
                <a-radio-button :value="1">
                  紧临
                </a-radio-button>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
          <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
            <a-form-model-item prop="disasterType" style="margin-right: 12px">
              <a-select placeholder="请选择相关灾种" v-model="form.disasterType" style="min-width: 160px" allowClear @change="handleRisk" :disabled="disable">
                <a-select-option v-for="item in riskOptions" :key="item.value" :value="item.value">
                  {{ item.name }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
            <a-form-model-item prop="warningLevel">
              <a-select placeholder="请选择预警级别" v-model="form.warningLevel" style="min-width: 160px" allowClear @change="handleLevel" :disabled="disable">
                <a-select-option v-for="item in levelOptions" :key="item.value" :value="item.value">
                  {{ item.name }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-form-model-item prop="content">
          <a-textarea v-model="form.content" placeholder="请输入短信通知内容部分" :auto-size="{ minRows: 3, maxRows: 5 }" :readOnly="disable"/>
        </a-form-model-item>
        <a-row>
          <a-col :span="12">
            <a-button>上传附件</a-button>
          </a-col>
          <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
            <b style="margin-bottom: 24px">超时设置:</b>
            <a-form-model-item prop="timeout">
              <a-input v-model="form.timeout" style="width:200px;" placeholder="输入时间" suffix="分钟" :readOnly="disable"/>
            </a-form-model-item>
          </a-col>
        </a-row>
        <span><b>发布单位:</b>{{form.publishingUnit}}</span>
        <br/><br/>
        <!-- 子单位-->
        <a-row :gutter="24">
          <a-col :span="12">
            <div style="display:flex;justify-content: space-between;align-items: center;">
              <b>选择接收单位:</b>
              <a-checkbox :checked="checkAll" @change="checkChange" :disabled="disable">
                全选
              </a-checkbox>
            </div>
            <a-form-model-item prop="receiver">
              <a-tree-select
                  show-search
                  tree-checkable
                  treeCheckStrictly
                  style="width: 100%"
                  v-model="form.receiver"
                  :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                  placeholder="选择工作通知接收单位"
                  allow-clear
                  multiple
                  @change="depChanges"
                  @search="onSearch"
                  @select="onSelect"
                  :tree-data="areaUsers"
                  :replaceFields="replaceFields"
                  :disabled="disable"
              >
              </a-tree-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <b style="margin-bottom: 6px">平级接收人选择:</b>
            <a-form-model-item prop="recipient">
              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle" :disabled="disable">
                <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                  {{ item.recipientName }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24" style="display: flex;justify-content: right" v-if="title=='信息审核'">
          <a-col :span="20" style="display: flex;justify-content: right">
            <a-button type="primary" style="min-width: 140px;margin-right: 12px" @click="confirmSend(2)">
              审批通过
            </a-button>
            <a-button type="danger" style="min-width: 140px;" @click="confirmSend(3)">
              驳回
            </a-button>
          </a-col>
        </a-row>
        <a-row :gutter="24" style="display: flex;justify-content: right;align-items: center" v-if="title=='信息转发'">
          <a-col :span="12">
            <b style="margin-bottom: 6px">选择审批领导:</b>
            <a-form-model-item prop="reviewId">
              <a-select show-search v-model="form.reviewId" placeholder="请选择审批领导">
                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.name}}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="12" style="display: flex;justify-content: right">
            <a-button type="primary" style="min-width: 140px;margin-right: 12px" @click="confirmSend(4)">
              确认转发
            </a-button>
          </a-col>
        </a-row>
      </div>
      <div class="right">
        <h2>短信预览</h2>
        <div class="mobile">
          <div class="mesg">
            <P>【{{form.title}}】{{form.content}}。发布单位:{{form.publishingUnit}}</P>
          </div>
        </div>
      </div>
    </a-form-model>
  </a-modal>
</template>
<script>
import {getAreaWithUserIfo, getPeerRecipient, getLeaders} from '@/api/user'
import {getUserInfo} from "@/util/storage";
import Cookies from "js-cookie";
import {massSend, msgSend} from "@/api/send";
import {postReview} from "@/api/review";
export default {
  name: "msgEditMod",
  data() {
    return {
      title: '信息审核',
      disable: true,
      visible: false,
      confirmLoading: false,
      leaders: [],
      userInfo: {},
      wrapperCol: { span: 24 },
      filteredOptions:[],
      form: {
        id: null,
        title: '',
        emergType: null,
        disasterType: undefined,
        warningLevel: undefined,
        content: '',
        publishingUnit: '',
        districtId: null,
        attachments: [],
        timeout: null,
        reviewId: null,
        receiver: [],
        recipient: [],
        acceptingUnitIds: [],
        peerRecipientIds: []
      },
      checkAll: false,
      areaUsers: [],
      replaceFields: {
        children:'children',
        title:'name',
        key:'id',
        value: 'id'
      },
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      levelOptions: [
        {name: '红色预警',value: 1},
        {name: '橙色预警',value: 2},
        {name: '黄色预警',value: 3},
        {name: '蓝色预警',value: 4}
      ],
      rules: {
        emergType: [{ required: true, message: '请选择紧急类型', trigger: 'change'}],
        disasterType: [{ required: true, message: '请选择灾种', trigger: 'change'}],
        warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change'}],
        title: [{ required: true, message: '请输入信息标题', trigger: 'blur'}],
        content: [{ required: true, message: '请输入信息内容', trigger: 'blur'}],
        timeout: [{ required: true, message: '请输入超时时间', trigger: 'blur'}],
        receiver: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
        reviewId: [{ required: true, message: '请选择审批人', trigger: 'change'}],
        recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
        // acceptingUnitIds: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
        // peerRecipientIds: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
      }
    };
  },
  components: {},
  created() {
    const t = this
    t.userInfo = getUserInfo()
    t.form.districtId = t.userInfo.districtId
    t.form.publishingUnit = t.userInfo.company
    t.getSameLevel()
    t.getAreaUsers()
  },
  computed: {},
  methods: {
    openMod(type,data){
      const t = this
      for(let i in data){
        if(t.isValidKey(i,t.form)){
          t.form[i] = data[i]
        }
      }
      const arr = data.acceptingUnitIds.map((i)=>{return {
        value: i.districtId
      }})
      t.form.receiver = JSON.parse(JSON.stringify(arr)).filter(
          (item, index) => JSON.parse(JSON.stringify(arr)).findIndex(obj => obj.value === item.value) === index
      )
      t.form.recipient = data.peerRecipientIds.map(i=>i.recipienterId)
      t.form.acceptingUnitIds = []
      t.form.peerRecipientIds = []
      if(type == 'review') {
        t.title = '信息审核'
        t.disable = false
      }else if(type == 'view'){
        t.title = '信息详情'
        t.disable = true
      }else{
        t.title = '信息转发'
        t.getLeaders()
        t.disable = false
      }
      t.visible = true
    },
    isValidKey(key, object){
      return key in object;
    },
    // 获取同级接收人
    async getSameLevel(){
      let t = this
      let res = await getPeerRecipient()
      if(res.data.code == 100){
        if(res.data.data){
          t.filteredOptions = res.data.data
        }else{
          this.$message.warning('暂无数据');
        }
      }else{
        this.$message.warning(res.data.msg);
      }
    },
    // 获取接收单位
    async getAreaUsers(){
      let t = this
      let res = await getAreaWithUserIfo()
      if(res.data.code == 100){
        if(res.data.data){
          const treeD = []
          t.userTitTree(res.data.data)
          treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
          t.areaUsers = treeD
          t.unittype = this.findNodeById(this.areaUsers,t.userInfo.districtId)?.type
        }else{
          this.$message.warning('暂无数据');
        }
      }else{
        this.$message.warning(res.data.msg);
      }
    },
    // 获取领导
    async getLeaders(){
      let t = this
      let res = await getLeaders()
      if(res.data.code == 100){
        if(res.data.data){
          t.leaders = res.data.data
        }else{
          this.$message.warning('暂无数据');
        }
      }else{
        this.$message.warning(res.data.msg);
      }
    },
    //选择子部门部分
    depChanges(value,label,extra) {
      const t = this
      if(t.form.receiver.length == 0){
        t.checkAll = false
      }
    },
    checkChange(e) {
      const t = this
      this.checkAll = !this.checkAll
      if(t.checkAll == true){
        t.form.receiver = t.traverseTree(t.areaUsers[0])
      }else{
        t.form.receiver = []
      }
    },
    confirmSend(status){
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          this.form.acceptingUnitIds = []
          this.form.peerRecipientIds = []
          const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
          const newAList = [].concat(...aList)
          for(let i of newAList){
            const {realName,...data} = i
            const {id:recipienterId,name: recipienterName,phone: recipienterPhone,company: receiveUnit,...rest} = data
            const obj = { recipienterId, recipienterName, recipienterPhone, receiveUnit,...rest}
            this.form.acceptingUnitIds.push(obj)
          }
          const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
          for(let i of bList){
            const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
            const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
            this.form.peerRecipientIds.push(obj)
          }
          if(status == 2 || status == 3){
            const {receiver,recipient,reviewId,...data} = this.form
            data.reviewStatus = status
            postReview(data).then( res =>{
              if(res.data.code == 100){
                this.$message.success('审核已提交')
                this.$emit('refresh')
                this.visible = false
              }else{
                this.$message.error(res.data.msg)
              }
              this.$refs.ruleForm.clearValidate()
              this.$refs.ruleForm.resetFields()
            })
          }else{
            const {receiver,recipient,id,...data} = this.form
            msgSend(data).then( res =>{
              if(res.data.code == 100){
                this.$message.success('信息已提交审核')
              }else{
                this.$message.error(res.data.msg)
              }
              this.$emit('refresh')
              this.visible = false
              this.$refs.ruleForm.clearValidate()
              this.$refs.ruleForm.resetFields()
            })
          }
        }else{
          console.log('error submit!!');
          return false;
        }
      })
    },
    handleCancel(e) {
      const t = this
      t.visible = false;
    },
    clearMod(){
      this.$refs.ruleForm.clearValidate()
      this.$refs.ruleForm.resetFields()
    },
// 根据id查对象
    findNodeById(data,value) {
      for (const node of data) {
        if (node.id === value) {
          return node;
        }
        if (node.children) {
          const foundNode = this.findNodeById(node.children, value);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },
    // 将树状数据所有id和name放入对象数组
    traverseTree(treeData) {
      let result = [];
      function traverse(node) {
        result.push({ label: node.name, value: node.id });
        if (node.children && node.children.length > 0) {
          for (let child of node.children) {
            traverse(child);
          }
        }
      }
      traverse(treeData);
      return result;
    },
    // 将树状数据name字段放入users的姓名电话
    userTitTree(treeData) {
      for(const node of treeData){
        if(node.users){
          node.users = node.users.map((i)=>{
            return{
              ...i,
              unittype: node.type,
              districtId: node.id
            }
          })
          node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
        }
        if(node.children){
          this.userTitTree(node.children)
        }
      }
      return treeData
    },
    onSearch() {
      console.log(...arguments);
    },
    onSelect() {
      console.log(...arguments);
    },
    //选择平级部门部分
    handle(selectedItems) {
      this.selectedItems = selectedItems;
    },
    handleRisk(selectedItems) {
      // this.selectedItems = selectedItems;
    },
    handleLevel(selectedItems) {
      // this.selectedItems = selectedItems;
    },
    onChange(){
      console.log(this.value)
    },
    handleChange(value) {
      console.log(`selected ${value}`);
    },
    handleBlur() {
      console.log('blur');
    },
    handleFocus() {
      console.log('focus');
    },
    filterOption(input, option) {
      return (
          option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
      );
    },
  },
}
</script>
<style lang="less" scoped>
.form-cont{
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  .left {
    width: 58%;
  }
  .right {
    width: 39%;
    border-left: 1px silver solid;
    padding-left: 18px;
    .mobile {
      position: relative;
      background: black;
      border: 1px solid black;
      width: 280px;
      min-height: 500px;
      border-radius: 25px;
      margin-left: 20px;
      .mesg {
        width: 260px;
        margin: 25px auto;
        min-height: 450px;
        background: white;
        padding-top: 10px;
        p {
          padding: 15px;
          background-color: #f5f5f5;
          border-radius: 10px;
          font-size: 16px;
          margin: 15px 10px;
        }
      }
    }
  }
}
</style>
src/views/Admin/components/sameLevelMod.vue
@@ -12,17 +12,17 @@
      :afterClose="clearMod"
  >
    <a-form-model ref="ruleForm" :rules="rules" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol" :colon="false">
      <a-form-model-item label="姓名或称呼" prop="name">
        <a-input v-model="form.name"/>
      <a-form-model-item label="姓名或称呼" prop="recipientName">
        <a-input v-model="form.recipientName"/>
      </a-form-model-item>
      <a-form-model-item label="单位名称(备注)" prop="depName">
        <a-input v-model="form.depName"/>
      <a-form-model-item label="单位名称(备注)" prop="company">
        <a-input v-model="form.company"/>
      </a-form-model-item>
      <a-form-model-item label="手机号码" prop="phone">
        <a-input v-model="form.phone"/>
      </a-form-model-item>
      <a-form-model-item label="选择级别" prop="level">
        <a-select v-model="form.level" placeholder="监管级别">
      <a-form-model-item label="单位层级">
        <a-select v-model="form.unittype" placeholder="单位层级" disabled>
          <a-select-option :value="1">
            省级
          </a-select-option>
@@ -37,13 +37,16 @@
          </a-select-option>
        </a-select>
      </a-form-model-item>
      <a-form-model-item label="所属地区" prop="area">
      <a-form-model-item label="所属地区" prop="districtId">
        <a-tree-select
            v-model="form.area"
            v-model="form.districtId"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="areaData"
            placeholder="行政区划"
            :replaceFields="replaceFields"
            @change="changeArea"
            disabled
        >
        </a-tree-select>
      </a-form-model-item>
@@ -52,9 +55,12 @@
</template>
<script>
import { addUser } from '@/api/user'
import {addRecipient, addUser, updateRecipient, updateUser} from "@/api/user";
export default {
  name: 'userMod',
  props: [],
  data () {
    return {
      title: '新增用户',
@@ -63,20 +69,25 @@
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      areaData: [],
      replaceFields: {
        children:'children',
        title:'name',
        key:'id',
        value: 'id'
      },
      unitName: '',
      form: {
        name: '',
        depName: '',
        id: null,
        recipientName: '',
        company: '',
        phone: '',
        level: null,
        area: null
        unittype: null,
        districtId: null
      },
      rules: {
        name: [{ required: true, message: '请输入姓名', trigger: 'blur'}],
        phone: [{ required: true, message: '请输入手机号', trigger: 'blur'}],
        depName: [{ required: true, message: '请输入单位名称', trigger: 'blur'}],
        level: [{ required: true, message: '请选择监管级别', trigger: 'change'}],
        area: [{ required: true, message: '请选择行政区划', trigger: 'change'}]
        recipientName: [{ required: true, message: '请输入姓名或称呼', trigger: 'blur'}],
        company: [{ required: true, message: '请输入单位名称(备注)', trigger: 'blur'}],
        phone: [{ required: true, message: '请输入手机号', trigger: 'blur'}]
      }
    }
  },
@@ -89,27 +100,58 @@
      if(type == 'add'){
        t.title = '新增用户'
        t.form = {
          name: '',
          depName: '',
          id: null,
          recipientName: '',
          company: '',
          phone: '',
          level: null,
          area: null
          unittype: null,
          districtId: null
        }
      }else{
        t.title = '编辑用户'
        t.form = data
        for(let i in data){
          if(t.isValidKey(i,t.form)){
            t.form[i] = data[i]
          }
        }
      }
      t.visible = true
    },
    isValidKey(key, object){
      return key in object;
    },
    clearMod(){
      this.$refs.ruleForm.clearValidate()
      this.$refs.ruleForm.resetFields()
    },
    onSubmit() {
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          alert('submit!');
          if(this.title == '新增用户'){
            const { id,...data } = this.form
            console.log(data,'data')
            addRecipient(data).then((res)=>{
              if(res.data.code == 100){
                this.$message.success('新增平级接收人成功')
                this.$emit('refresh')
              }else{
                this.$message.error(res.data.msg)
              }
            })
          }else{
            const data = this.form
            updateRecipient(data).then((res)=>{
              if(res.data.code == 100){
                this.$message.success('修改用户成功')
                this.$emit('refresh')
              }else{
                this.$message.error(res.data.msg)
              }
            })
          }
          this.visible = false
        } else {
          return false;
@@ -117,16 +159,40 @@
      });
    },
    handleOk(e) {
    changeArea(value, label, extra){
      const t = this
      t.confirmLoading = true;
      t.form.districtId = value
      const code = t.findCodeById(t.areaData,value).code
      if(code.length == 2){
        t.form.company = '自治区自然灾害预警中心'
        // t.form.province = t.findNodeByCode(t.areaData,code).name
        // t.form.city = ''
        // t.form.area = ''
        // t.form.town = ''
      } else if(code.length == 9){
        // t.form.province = t.findNodeByCode(t.areaData,code.substr(0,2)).name
        // t.form.city = t.findNodeByCode(t.areaData,code.substr(0,4)).name
        // t.form.area = t.findNodeByCode(t.areaData,code.substr(0,6)).name
        // t.form.town = t.findNodeByCode(t.areaData,code).name
        t.form.company = label[0]
      } else{
        // if(code.length == 4){
        //   t.form.city = t.findNodeByCode(t.areaData,code).name
        //   t.form.area = ''
        // }
        // if(code.length == 6){
        //   t.form.city = t.findNodeByCode(t.areaData,code.substr(0,4)).name
        //   t.form.area = t.findNodeByCode(t.areaData,code).name
        // }
        // t.form.province = t.findNodeByCode(t.areaData,code.substr(0,2)).name
        // t.form.town = ''
        t.form.company = label[0] + '自然灾害综合预警监测中心'
      }
    },
    handleCancel(e) {
      const t = this
      t.visible = false;
    },
    onChange(value) {
      console.log(value);
    }
  }
}
src/views/Admin/components/userMod.vue
@@ -33,15 +33,15 @@
          <a-radio-button :value="0">女</a-radio-button>
        </a-radio-group>
      </a-form-model-item>
      <a-form-model-item label="选择级别" prop="unittype">
        <a-select v-model="form.unittype" placeholder="监管级别">
          <a-select-option :value="1">
      <a-form-model-item label="单位层级" prop="unittype">
        <a-select v-model="form.unittype" placeholder="单位层级" @change="changeLevel">
          <a-select-option :disabled="unittype !== 1&&unittype !== null"  :value="1">
            省级
          </a-select-option>
          <a-select-option :value="2">
          <a-select-option :disabled="unittype !== 1&&unittype !== null && unittype !== 2" :value="2">
            地(市、州)级
          </a-select-option>
          <a-select-option :value="3">
          <a-select-option :disabled="unittype == 4 ? true : false" :value="3">
            区县级
          </a-select-option>
          <a-select-option :value="4">
@@ -49,21 +49,23 @@
          </a-select-option>
        </a-select>
      </a-form-model-item>
      <a-form-model-item label="所属地区" prop="area">
<!--        <a-cascader v-model="form.area" :options="areaData" expandTrigger="hover" changeOnSelect placeholder="请选择" @change="onChange"/>-->
      <a-form-model-item label="所属地区" prop="districtId">
        <!--        <a-cascader v-model="form.area" :options="areaData" expandTrigger="hover" changeOnSelect placeholder="请选择" @change="onChange"/>-->
        <a-tree-select
            v-model="form.area"
            v-model="form.districtId"
            style="width: 100%"
            :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
            :tree-data="areaData"
            placeholder="行政区划"
            :replaceFields="replaceFields"
            @change="changeArea"
        >
        </a-tree-select>
      </a-form-model-item>
      <a-form-model-item label="所属单位">
        <a-input v-model="unitName"/>
        <a-input v-model="form.company" readOnly/>
      </a-form-model-item>
      <a-form-model-item label="角色" prop="role">
      <a-form-model-item label="角色" prop="roleId">
        <a-select v-model="form.roleId" placeholder="角色">
          <a-select-option :value="2">
            领导
@@ -78,19 +80,59 @@
</template>
<script>
import { addUser } from '@/api/user'
import {addUser, updateUser} from '@/api/user'
import {verifyPasswordPowerful, verifyPhone} from "@/util/validate";
export default {
  name: 'userMod',
  props: ['unitType'],
  data () {
    let validatePwd = (rule, value, callback)=>{
      if(value === ''){
        callback(new Error('请输入密码'))
      }else{
        if(!verifyPasswordPowerful(value)){
          callback(new Error('密码须包含字母、数字、特殊字符(不包括下划线),长度在6-16之间'))
        }else{
          callback()
        }
      }
    }
    let validatePhone = (rule, value, callback)=>{
      if(value === ''){
        callback(new Error('请输入手机号'))
      }else{
        if(!verifyPhone(value)){
          callback(new Error('手机号格式有误'))
        }else{
          callback()
        }
      }
    }
    let validatePwd2 = (rule, value, callback)=>{
      if(value === ''){
        callback(new Error('请再次输入密码'))
      }else if(value !== this.form.pwd){
        callback(new Error('两次输入密码不同'))
      }else{
        callback()
      }
    }
    return {
      title: '新增用户',
      visible: false,
      unittype: this.unitType,
      confirmLoading: false,
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      areaData: [],
      unitName: '',
      replaceFields: {
        children:'children',
        title:'name',
        key:'id',
        value: 'id'
      },
      form: {
        id: null,
        realName: '',
        phone: '',
        name: '',
@@ -98,18 +140,19 @@
        dupPwd: '',
        sex: null,
        unittype: null,
        area: null,
        roleId: null
        districtId: null,
        roleId: null,
        company: ''
      },
      rules: {
        realName: [{ required: true, message: '请输入姓名', trigger: 'blur'}],
        phone: [{ required: true, message: '请输入手机号', trigger: 'blur'}],
        phone: [{ required: true, validator: validatePhone, trigger: 'blur'}],
        name: [{ required: true, message: '请输入用户名', trigger: 'blur'}],
        pwd: [{ required: true, message: '请输入密码', trigger: 'blur'}],
        dupPwd: [{ required: true, message: '请再次输入密码', trigger: 'blur'}],
        dupPwd: [{ required: true, validator: validatePwd2, trigger: 'blur'}],
        sex: [{ required: true, message: '请选择性别', trigger: 'change'}],
        unittype: [{ required: true, message: '请选择监管级别', trigger: 'change'}],
        area: [{ required: true, message: '请选择行政区划', trigger: 'change'}],
        unittype: [{ required: true, message: '请选择单位层级', trigger: 'change'}],
        districtId: [{ required: true, message: '请选择行政区划', trigger: 'change'}],
        roleId: [{ required: true, message: '请选择角色', trigger: 'change'}]
      }
    }
@@ -123,38 +166,135 @@
      if(type == 'add'){
        t.title = '新增用户'
        t.form = {
          id: null,
          realName: '',
          phone: '',
          name: '',
          pwd: '',
          dupPwd: '',
          sex: undefined,
          unittype: undefined,
          area: undefined,
          roleId: null
          sex: null,
          unittype: null,
          districtId: null,
          roleId: null,
          company: ''
        }
      }else{
        t.title = '编辑用户'
        data.roleId = data.role.roleId
        const { realName,phone,name,sex,unittype,roleId } = data
        t.form = { realName,phone,name,sex,unittype,roleId }
        for(let i in data){
          if(t.isValidKey(i,t.form)){
            t.form[i] = data[i]
          }
        }
      }
      t.visible = true
    },
    isValidKey(key, object){
      return key in object;
    },
    // 根据id查对象
    findNodeById(data,value) {
      for (const node of data) {
        if (node.id === value) {
          return node;
        }
        if (node.children) {
          const foundNode = this.findNodeById(node.children, value);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },
    // 根据code查对象
    findNodeByCode(data,code) {
      for (const node of data) {
        if (node.code === code) {
          return node;
        }
        if (node.children) {
          const foundNode = this.findNodeByCode(node.children,code);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },
    changeLevel(value, option){
      console.log(value)
    },
    changeArea(value, label, extra){
      const t = this
      t.form.districtId = value
      const code = t.findNodeById(t.areaData,value).code
      if(code.length == 2){
        t.form.company = '自治区自然灾害预警中心'
        // t.form.province = t.findNodeByCode(t.areaData,code).name
        // t.form.city = ''
        // t.form.area = ''
        // t.form.town = ''
      } else if(code.length == 9){
        // t.form.province = t.findNodeByCode(t.areaData,code.substr(0,2)).name
        // t.form.city = t.findNodeByCode(t.areaData,code.substr(0,4)).name
        // t.form.area = t.findNodeByCode(t.areaData,code.substr(0,6)).name
        // t.form.town = t.findNodeByCode(t.areaData,code).name
        t.form.company = label[0]
      } else{
        // if(code.length == 4){
        //   t.form.city = t.findNodeByCode(t.areaData,code).name
        //   t.form.area = ''
        // }
        // if(code.length == 6){
        //   t.form.city = t.findNodeByCode(t.areaData,code.substr(0,4)).name
        //   t.form.area = t.findNodeByCode(t.areaData,code).name
        // }
        // t.form.province = t.findNodeByCode(t.areaData,code.substr(0,2)).name
        // t.form.town = ''
        t.form.company = label[0] + '自然灾害综合预警监测中心'
      }
    },
    clearMod(){
      this.$refs.ruleForm.clearValidate()
      this.$refs.ruleForm.resetFields()
    },
    onSubmit() {
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          if(this.title == '新增用户')
             addUser(this.form).then((res)=>{
               if(res.data.code == 100){
                 console.log(res,'res')
               }
             })
          if(this.form.unittype !==  this.findNodeById(this.areaData,this.form.districtId).type){
            this.$message.error('单位层级和所属地区不匹配,请重新选择')
            return
          }
          if(this.title == '新增用户'){
            const { id,...data } = this.form
            addUser(data).then((res)=>{
              if(res.data.code == 100){
                this.$message.success('新增用户成功')
                this.$emit('refresh')
              }else{
                this.$message.error(res.data.msg)
              }
            })
          }else{
            const {pwd,dupPwd,...data} = this.form
            updateUser(data).then((res)=>{
              if(res.data.code == 100){
                this.$message.success('修改用户成功')
                this.$emit('refresh')
              }else{
                this.$message.error(res.data.msg)
              }
            })
          }
          this.visible = false
        } else {
          console.log('error submit!!');
          return false;
src/views/Admin/history.vue
对比新文件
@@ -0,0 +1,278 @@
<template>
  <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="search.searchParams.emergType" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button :value="1">
            紧临
          </a-radio-button>
          <a-radio-button :value="2">
            常规
          </a-radio-button>
        </a-radio-group>
      </a-col>
      <a-col :span="16">
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="timeChange"
                @ok="timeOk"
                style="width: 100%"
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
    </a-row>
    <!-- 表格实体部分-->
    <div class="table-cont">
      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
        <template #index="text,record,index">
          {{ index + 1 }}
        </template>
        <template #publishingTime="text">
          {{ text }}
        </template>
        <template #publishingUnit="text">
          {{ text }}
        </template>
        <template #disasterType="text">
          {{ getRiskName(text) }}
        </template>
        <template #warningLevel="text">
          <a-tag :color="text === 3 ? 'yellow' :text === 2? 'orange':text === 1?'red':'blue'">
            {{ getLevelName(text) }}
          </a-tag>
        </template>
        <template #attachment="text">
          <a><b><a-icon type="paper-clip" /></b></a>
        </template >
        <template #responseSituation="text">
          <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
            {{text == 1 ? '待叫应' : text == 2 ?'已叫应':text == 3 ?'超时未叫应' : ''}}
          </a-tag>
        </template>
        <template #operation="text, record, index">
          <a-button type="primary">叫应列表</a-button>
          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
        </template>
      </a-table>
      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
    </div>
    <!-- 对话框 -->
    <a-modal title="查看叫应详情"
             okText="确认"
             cancelText="关闭"
             :visible="visible" :confirm-loading="confirmLoading" @ok="handleOk" @cancel="handleOk">
    </a-modal>
  </div>
</template>
<script>
import {getHistoryRecord, getMsgRecord, getPublishRecord} from "@/api/list";
import msgEditMod from "@/views/Admin/components/msgEditMod";
import {getReviewDetailByWorker} from "@/api/review";
const columns = [{
  title: '序号',
  dataIndex: 'index',
  width: '8%',
  scopedSlots: {
    customRender: 'index'
  }
},
  {
    title: '发布时间',
    dataIndex: 'publishingTime',
    width: '15%',
    scopedSlots: {
      customRender: 'publishingTime'
    } //设置定制化表格数据
  },
  {
    title: '发布单位',
    dataIndex: 'publishingUnit',
    width: '12%',
  },
  {
    title: '灾种',
    dataIndex: 'disasterType',
    width: '8%',
    scopedSlots: {
      customRender: 'disasterType'
    }
  },
  {
    title: '预警级别',
    dataIndex: 'warningLevel',
    scopedSlots: {
      customRender: 'warningLevel'
    }, //设置定制化表格数据
    width: '8%',
  },
  {
    title: '信息标题',
    dataIndex: 'title',
    width: '16%',
  },
  {
    title: '附件',
    dataIndex: 'attachment',
    width: '6%',
    scopedSlots: {
      customRender: 'attachment'
    },
  },
  {
    title: '叫应情况',
    dataIndex: 'responseSituation',
    width: '10%',
    scopedSlots: {
      customRender: 'responseSituation'
    }, //设置定制化表格数据
  },
  {
    title: '操作',
    dataIndex: 'operation',
    scopedSlots: {
      customRender: 'operation'
    },
  },
];
export default {
  name: 'release',
  components: { msgEditMod },
  data() {
    return {
      search:{
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          emergType: null,
          startTime: '',
          endTime: ''
        }
      },
      timeRange: [],
      category: 'default',
      data:[],
      columns,
      visible: false,
      confirmLoading: false,
      pagination: {
        current: 1,
        defaultCurrent: 1,
        defaultPageSize: 10,
        total: 0,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
        showTotal: total => `共 ${total} 条`
      },
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      levelOptions: [
        {name: '红色预警',value: 1},
        {name: '橙色预警',value: 2},
        {name: '黄色预警',value: 3},
        {name: '蓝色预警',value: 4}
      ]
    }
  },
  created() {
    const t = this
    t.getData()
  },
  methods: {
    async getData(){
      const t = this
      const res = await getHistoryRecord(this.search)
      if(res.data.code == 100){
        t.data = res.data.data
        t.pagination.total = res.data.total
      }else{
        this.$message.error(res.data.msg)
      }
    },
    openMod(type,data){
      const t = this
      getReviewDetailByWorker(data.id).then(res=>{
        if(res.data.code == 100){
          if(res.data.data){
            t.$refs.msgEdit.openMod(type,res.data.data)
          }else{
            t.$message.error('查询信息详情失败')
          }
        }else{
          this.$message.error(res.data.msg)
        }
      })
    },
    onPageChange(page, pageSize) {
      const t= this
      t.pagination.current = page
      t.search.pageIndex = page
      t.getData()
    },
    timeChange(value, dateString) {
      const t = this
      if(dateString){
        t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
        t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
      }
    },
    timeOk(value) {
      console.log('onOk: ', value);
    },
    resetSearch(){
      const t = this
      t.search = {
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          emergType: null,
          startTime: '',
          endTime: ''
        }
      }
      t.timeRange = []
      t.getData()
    },
    //弹出层
    showModal() {
      this.visible = true;
    },
    handleOk(e) {
      this.visible = false;
    },
    getRiskName(disasterType){
      return this.riskOptions.find(i => i.value === disasterType)?.name;
    },
    getLevelName(warningLevel){
      return this.levelOptions.find(i => i.value === warningLevel)?.name;
    }
  }
}
</script>
src/views/Admin/list.vue
@@ -2,17 +2,17 @@
    <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="category">
          <a-radio-button value="default">
        <a-radio-group v-model="search.searchParams.responseStatus" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button value="1">
          <a-radio-button :value="1">
            待叫应
          </a-radio-button>
          <a-radio-button value="2">
          <a-radio-button :value="2">
            已叫应
          </a-radio-button>
          <a-radio-button value="3">
          <a-radio-button :value="3">
            超时未叫应
          </a-radio-button>
        </a-radio-group>
@@ -21,6 +21,7 @@
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="timeChange"
@@ -29,233 +30,297 @@
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary">查询</a-button>
            <a-button style="margin-left: 12px">重置</a-button>
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
    </a-row>
        <!-- 表格实体部分-->
    <div class="table-cont">
      <a-table :columns="columns" :data-source="data" bordered>
        <template #time="text,record">
          <a v-if="!record.readed" style="color:red">[未读]</a>{{text}}
      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
        <template #index="text,record,index">
          {{index + 1}}
        </template>
        <template #level="text">
          <a-tag :color="text === '黄色' ? 'yellow' :text === '橙色'? 'orange':text === '红色'?'red':'blue'">
            {{ text }}
        <template #publishingTime="text,record">
          <span v-if="record.readStatus==0" style="color:red">[未读]</span>{{text}}
        </template>
        <template #disasterType="text">
            {{ getRiskName(text) }}
        </template>
        <template #warningLevel="text">
          <a-tag :color="text === 3 ? 'yellow' :text === 2? 'orange':text === 1?'red':'blue'">
            {{ getLevelName(text) }}
          </a-tag>
        </template>
        <template #attachment="text">
          <span v-if="text==='无'">无</span>
          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
          <a><b><a-icon type="paper-clip" /> {{text}}</b></a>
        </template >
        <template #receipt="text">
          <span v-if="text=='待叫应'"
            style='background-color:blue;padding:5px;color:#fff;border-radius: 5px;'>{{text}}</span>
          <span v-else-if="text=='已叫应'"
            style='background-color:limegreen;padding:5px;color:#2a2a2a;border-radius: 5px;'>{{text}}</span>
          <span v-else style='background-color:red;padding:5px;color:#fff;border-radius: 5px;'>{{text}}
          </span>
        <template #responseStatus="text">
          <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
            {{text == 1 ? '待叫应' : text == 2 ?'已叫应':text == 3 ?'超时未叫应' : ''}}
          </a-tag>
        </template>
<!--        <template #operation="text, record, index">-->
<!--          <div class="editable-row-operations">-->
<!--            <div v-if="record.responseStatus==='待叫应'">-->
<!--              <a @click="showModal" style="color:orangered"><a-icon type="notification" />-->
<!--                确认已收到</a>&nbsp;&nbsp;-->
<!--            </div>-->
<!--            <br />-->
<!--            <a-button type="primary">转发</a-button>&nbsp;&nbsp;-->
<!--            <a-button type="link" @click="viewDetails(item)">查看详情</a-button>-->
<!--          </div>-->
<!--        </template>-->
        <template #operation="text, record, index">
          <div class="editable-row-operations">
            <div v-if="record.receipt==='待叫应'">
              <a @click="showModal" style="color:orangered"><a-icon type="notification" />
                确认已收到</a>&nbsp;&nbsp;
            </div>
            <br />
            <router-link :to="{path:'/torelease'}">转发</router-link>&nbsp;&nbsp;
            <router-link :to="{path:'/details',query: {id: record.id}}">查看详情</router-link>
          </div>
          <a-button type="primary" v-if="record.responseStatus == 1" style="margin-right: 12px" @click="confirmResponce(record.id)">确认已收到</a-button>
          <a-button type="primary" @click="openMod('repost',record)">转发</a-button>
          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
        </template>
      </a-table>
    </div>
    <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
        <!-- 对话框 -->
        <a-modal title="回执"
        okText="确认已安排部署"
        cancelText="取消"
        :visible="visible" :confirm-loading="confirmLoading" @ok="handleOk"
            @cancel="handleCancel">
            <p>{{ ModalText }}</p>
        </a-modal>
<!--        <a-modal title="回执" -->
<!--        okText="确认已安排部署"-->
<!--        cancelText="取消"-->
<!--        :visible="visible" :confirm-loading="confirmLoading" @ok="handleOk"-->
<!--            @cancel="handleCancel">-->
<!--            <p>{{ ModalText }}</p>-->
<!--        </a-modal>-->
    </div>
</template>
<script>
    const columns = [{
            title: '序号',
            dataIndex: 'key',
            width: '5%',
        },
        {
            title: '发布时间',
            dataIndex: 'time',
            width: '15%',
            scopedSlots: {
                customRender: 'time'
            }, //设置定制化表格数据
        },
        {
            title: '发布单位',
            dataIndex: 'department',
            width: '12%',
        },
        {
            title: '类别',
            dataIndex: 'category',
            width: '8%',
        },
        {
            title: '级别',
            dataIndex: 'level',
            scopedSlots: {
                customRender: 'level'
            }, //设置定制化表格数据
            width: '8%',
        },
        {
            title: '信息标题',
            dataIndex: 'title',
            width: '16%',
        },
        {
            title: '附件',
            dataIndex: 'attachment',
            width: '6%',
            scopedSlots: {
                customRender: 'attachment'
            },
        },
        {
            title: '叫应状态',
            dataIndex: 'receipt',
            width: '10%',
            scopedSlots: {
                customRender: 'receipt'
            }, //设置定制化表格数据
        },
        {
            title: '操作',
            dataIndex: 'operation',
            scopedSlots: {
                customRender: 'operation'
            },
        },
    ];
import {getMsgRecord, readById, responseMsg} from "@/api/list";
import msgEditMod from "@/views/Admin/components/msgEditMod";
import {publishMsg} from "@/api/send";
import {getReviewDetail, getReviewDetailByWorker} from "@/api/review";
    const data = [{
            key: 1,
            id:1001,
            readed:false,
            time: '2023年5月3日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '黄色',
            title: '全疆高温红色预警',
            attachment: '1',
            receipt: '待叫应'
        },
        {
            key: 2,
            readed:true,
            id:1002,
            time: '2023年5月2日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '橙色',
            title: '全疆高温红色预警',
            attachment: '1',
            receipt: '已叫应'
        },
        {
            key: 3,
            readed:true,
            id:1003,
            time: '2023年5月1日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '橙色',
            title: '全疆高温红色预警',
            attachment: '1',
            receipt: '已叫应'
        },
        {
            key: 4,
            readed:true,
            id:1004,
            time: '2023年5月1日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '橙色',
            title: '全疆高温红色预警',
            attachment: '2',
            receipt: '超时未叫应'
        },
        {
            key: 5,
            readed:true,
            id:1005,
            time: '2023年4月21日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '橙色',
            title: '全疆高温红色预警',
            attachment: '无',
            receipt: '已叫应'
        },
        {
            key: 6,
            readed:true,
            id:1006,
            time: '2023年4月21日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '橙色',
            title: '全疆高温红色预警',
            attachment: '1',
            receipt: '已叫应'
        },
        {
            key: 7,
            readed:true,
            id:1007,
            time: '2023年1月21日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '红色',
            title: '全疆低温红色预警',
            attachment: '1',
            receipt: '已叫应'
        },
    ];
    export default {
  export default {
    name: 'list',
    components: { msgEditMod },
        data() {
            this.cacheData = data.map(item => ({
                ...item
            }));
            return {
                data,
                columns,
        search:{
          pageIndex: 1,
          pageSize: 10,
          searchParams:{
            responseStatus: null,
            startTime: '',
            endTime: ''
          }
        },
        timeRange: [],
        columns:[
          {
            title: '序号',
            dataIndex: 'index',
            width: '5%',
            scopedSlots: {
              customRender: 'index'
            },
          },
          {
            title: '发布时间',
            dataIndex: 'publishingTime',
            width: '15%',
            scopedSlots: {
              customRender: 'publishingTime'
            }, //设置定制化表格数据
          },
          {
            title: '发布单位',
            dataIndex: 'publishingUnit',
            width: '12%',
          },
          {
            title: '灾种',
            dataIndex: 'disasterType',
            width: '8%',
            scopedSlots: {
              customRender: 'disasterType'
            }
          },
          {
            title: '预警级别',
            dataIndex: 'warningLevel',
            scopedSlots: {
              customRender: 'warningLevel'
            }, //设置定制化表格数据
            width: '8%',
          },
          {
            title: '信息标题',
            dataIndex: 'title',
            width: '16%',
          },
          {
            title: '附件',
            dataIndex: 'attachment',
            width: '6%',
            scopedSlots: {
              customRender: 'attachment'
            },
          },
          {
            title: '叫应状态',
            dataIndex: 'responseStatus',
            width: '10%',
            scopedSlots: {
              customRender: 'responseStatus'
            }, //设置定制化表格数据
          },
          {
            title: '操作',
            dataIndex: 'operation',
            scopedSlots: {
              customRender: 'operation'
            },
          },
        ],
                data: [],
        pagination: {
          current: 1,
          defaultCurrent: 1,
          defaultPageSize: 10,
          total: 0,
          onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
          showTotal: total => `共 ${total} 条`
        },
        total: null,
        details: {},
                editingKey: '',
                category: 'default',
                ModalText: '确认已经安排部署?',
                visible: false,
                confirmLoading: false,
        riskOptions: [
          {name: '地震',value: 1},
          {name: '洪涝',value: 2},
          {name: '气象',value: 3},
          {name: '泥石流',value: 4},
          {name: '水旱',value: 5},
          {name: '森林草原火灾',value: 6}
        ],
        levelOptions: [
          {name: '红色预警',value: 1},
          {name: '橙色预警',value: 2},
          {name: '黄色预警',value: 3},
          {name: '蓝色预警',value: 4}
        ]
            };
        },
        methods: {
    created() {
      const t = this
      t.getData()
    },
    methods: {
      async getData(){
        const t = this
        const res = await getMsgRecord(this.search)
        if(res.data.code == 100){
          t.data = res.data.data
          t.pagination.total = res.data.total
        }else{
          this.$message.error(res.data.msg)
        }
      },
      onPageChange(page, pageSize) {
        const t= this
        t.pagination.current = page
        t.search.pageIndex = page
        t.getData()
      },
      timeChange(value, dateString) {
        const t = this
        if(dateString){
          t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
          t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
        }
      },
      resetSearch(){
        const t = this
        t.search = {
          pageIndex: 1,
          pageSize: 10,
          searchParams:{
            responseStatus: null,
            startTime: '',
            endTime: ''
          }
        }
        t.timeRange = []
        t.getData()
      },
      confirmResponce(id){
        const t = this
        this.$confirm({
          title: '回执',
          content: h => <div>确认已安排部署?</div>,
          cancelText: '取消',
          okText: '确认',
          centered: true,
          async onOk() {
            let res = await responseMsg(id)
            if(res.data.code == 100){
              t.$message.success('信息叫应成功');
              t.getData()
            }else{
              t.$message.warning(res.data.msg);
            }
          },
          onCancel() {
            console.log('Cancel');
          },
        });
      },
      openMod(type,data){
        const t = this
        getReviewDetailByWorker(data.warnInfoId).then(res=>{
          if(res.data.code == 100){
            if(res.data.data){
              t.read(data.id)
              t.$refs.msgEdit.openMod(type,res.data.data)
            }else{
              t.$message.error('查询信息详情失败')
            }
          }else{
            this.$message.error(res.data.msg)
          }
        })
      },
      async read(id){
        const t = this
        const res = await readById(id)
        if(res.data.code == 100){
          console.log('已读')
        }else{
          t.$message.error('设置已读出错')
        }
      },
      getRiskName(disasterType){
        return this.riskOptions.find(i => i.value === disasterType)?.name;
      },
      getLevelName(warningLevel){
        return this.levelOptions.find(i => i.value === warningLevel)?.name;
      },
            handleChange(value) {
                console.log(`Selected: ${value}`);
            },
            popupScroll() {
                console.log('popupScroll');
            },
            timeChange(date, dateString) {
                console.log(date, dateString);
            },
      timeOk(value) {
        console.log('timeOk: ', value);
      },
src/views/Admin/massSend.vue
@@ -1,11 +1,11 @@
<template>
    <div class="inner">
        <h2>预警信息发布</h2>
    <a-form-model :model="form" :wrapper-col="wrapperCol">
    <a-form-model ref="ruleForm" :model="form" :rules="rules" :wrapper-col="wrapperCol">
        <div class="left">
      <a-form-model-item prop="title">
              <a-input v-model="form.title" placeholder="请输入标题" style="height: 50px; font-size: 20px;" />
      </a-form-model-item>
<!--      <a-form-model-item prop="title">-->
<!--              <a-input v-model="form.title" placeholder="请输入标题" style="height: 50px; font-size: 20px;" />-->
<!--      </a-form-model-item>-->
<!--      <a-row>-->
<!--        <a-col :span="12" style="display: flex;align-items: center">-->
<!--          <span style="display: block;margin-bottom: 24px">相关灾种</span>-->
@@ -19,27 +19,27 @@
      <a-row>
        <a-col :span="12">
          <a-form-model-item prop="type">
            <a-radio-group v-model="form.type" default-value="a" button-style="solid">
              <a-radio-button value="a">
          <a-form-model-item prop="emergType">
            <a-radio-group v-model="form.emergType" button-style="solid">
              <a-radio-button :value="2">
                常规
              </a-radio-button>
              <a-radio-button value="b">
              <a-radio-button :value="1">
                紧临
              </a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
          <a-form-model-item prop="riskType" style="margin-right: 20px">
            <a-select placeholder="请选择相关灾种" v-model="form.riskType" style="width: 240px" allowClear @change="handleRisk">
          <a-form-model-item prop="disasterType" style="margin-right: 20px">
            <a-select placeholder="请选择相关灾种" v-model="form.disasterType" style="width: 240px" allowClear @change="handleRisk">
              <a-select-option v-for="item in riskOptions" :key="item.value" :value="item.value">
                {{ item.name }}
              </a-select-option>
            </a-select>
          </a-form-model-item>
          <a-form-model-item prop="level">
            <a-select placeholder="请选择预警级别" v-model="form.level" style="width: 240px" allowClear @change="handleLevel">
          <a-form-model-item prop="warningLevel">
            <a-select placeholder="请选择预警级别" v-model="form.warningLevel" style="width: 240px" allowClear @change="handleLevel">
              <a-select-option v-for="item in levelOptions" :key="item.value" :value="item.value">
                {{ item.name }}
              </a-select-option>
@@ -47,63 +47,59 @@
          </a-form-model-item>
        </a-col>
      </a-row>
      <a-form-model-item prop="message">
              <a-textarea v-model="form.message" placeholder="请输入短信通知内容部分" :auto-size="{ minRows: 3, maxRows: 5 }" />
      <a-form-model-item prop="content">
              <a-textarea v-model="form.content" placeholder="请输入短信通知内容部分" :auto-size="{ minRows: 3, maxRows: 5 }" />
      </a-form-model-item>
      <a-row>
        <a-col :span="12">
          <a-button>上传附件</a-button>
        </a-col>
        <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
          <b style="margin-bottom: 24px">超时设置:</b>
          <a-form-model-item prop="overTime">
            <a-input v-model="form.overTime" style="width:200px;" placeholder="输入时间" suffix="分钟"/>
          </a-form-model-item>
        </a-col>
      </a-row>
            <span><b>发布单位:</b>{{department}}</span>
<!--      <a-row>-->
<!--        <a-col :span="12">-->
<!--          <a-button>上传附件</a-button>-->
<!--        </a-col>-->
<!--        <a-col :span="12" style="display: flex;align-items: center;justify-content: right">-->
<!--          <b style="margin-bottom: 24px">超时设置:</b>-->
<!--          <a-form-model-item prop="overTime">-->
<!--            <a-input v-model="form.overTime" style="width:200px;" placeholder="输入时间" suffix="分钟"/>-->
<!--          </a-form-model-item>-->
<!--        </a-col>-->
<!--      </a-row>-->
            <span><b>发布单位:</b>{{form.publishingUnit}}</span>
            <br/><br/>
            <!-- 子单位-->
      <a-row :gutter="24">
        <a-col :span="12">
                <b style="margin-bottom: 6px">选择接收单位:</b>
          <a-form-model-item prop="svalue">
          <div style="display:flex;justify-content: space-between;align-items: center;">
                <b>选择接收单位:</b>
          <a-checkbox :checked="checkAll" @change="checkChange">
            全选
          </a-checkbox>
          </div>
          <a-form-model-item prop="receiver">
            <a-tree-select
                show-search
                tree-checkable
                treeCheckStrictly
                style="width: 100%"
                v-model="form.svalue"
                v-model="form.receiver"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                placeholder="选择工作通知接收单位"
                allow-clear
                multiple
                tree-default-expand-all
                @change="onChanges"
                @search="onSearch"
                @select="onSelect"
                :tree-data="areaUsers"
                :replaceFields="replaceFields"
              >
              <a-tree-select-node key="0" value="all" title="全选">
              </a-tree-select-node>
                <a-tree-select-node key="0-1" value="乌鲁木齐" title="乌鲁木齐(张XX 13268813610)">
                  <a-tree-select-node key="0-1-1" value="米东区" title="米东区(张XX 13268813610)">
                    <a-tree-select-node key="0-1-1-1" value="XX村1" title="XX村(李有田 13268813610)" />
                  </a-tree-select-node>
                  <a-tree-select-node key="0-1-2" value="天山区" title="天山区">
                    <a-tree-select-node key="0-1-2-1" value="XX村2">
                      <b slot="title" style="color: #08c">XX村</b>
                    </a-tree-select-node>
                  </a-tree-select-node>
                </a-tree-select-node>
            </a-tree-select>
          </a-form-model-item>
        </a-col>
        <a-col :span="12">
          <b style="margin-bottom: 6px">平级接收人选择:</b>
          <a-form-model-item prop="sameDep">
            <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.sameDep" @change="handle">
              <a-select-option v-for="item in filteredOptions" :key="item" :value="item">
                {{ item }}
          <div>
            <b>平级接收人选择:</b>
          </div>
          <a-form-model-item prop="recipient">
            <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle">
              <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                {{ item.recipientName }}
              </a-select-option>
            </a-select>
          </a-form-model-item>
@@ -126,7 +122,7 @@
<!--                </a-select>-->
<!--      </div>-->
      <div style="display: flex;justify-content: right">
        <a-button type="primary" style="width: 250px;">
        <a-button type="primary" style="width: 250px;" @click="confirmSend()">
          确认发送
        </a-button>
      </div>
@@ -136,7 +132,7 @@
            <h2>短信预览</h2>
            <div class="mobile">
                <div class="mesg">
                    <P>【{{form.title}}】{{form.message}}。发布单位:{{department}}</P>
                    <P>{{form.content}}发布单位:{{form.publishingUnit}}</P>
                </div>
            </div>
@@ -146,26 +142,36 @@
</template>
<script>
    const OPTIONS = ['自治区消防(李XX)', '自治区公安厅(王XX)', '自治区自然资源厅(刘XX)'];
import { getPeerRecipient, getAreaWithUserIfo } from '@/api/user'
import { massSend } from "@/api/send";
import {getUserInfo} from "@/util/storage";
    export default {
        name: "release",
        name: "massSend",
        data() {
            return {
                message: '',
                signname: '自然灾害风险预警提示',
        userInfo: {},
                department: '自治区自然灾害综合监测预警中心',
        filteredOptions:[],
        wrapperCol: { span: 24 },
        form: {
          title: '',
          riskType: 1,
          level: 1,
          type: 'a',
          svalue: undefined,
          sameDep: [],
          message: '',
          overTime: ''
          id: null,
          emergType: null,
          disasterType: undefined,
          warningLevel: undefined,
          content: '',
          publishingUnit: '',
          receiver: [],
          recipient: [],
          verticalRecipient: [],
          horizontalRecipient: []
        },
        checkAll: false,
        areaUsers: [],
        replaceFields: {
          children:'children',
          title:'name',
          key:'id',
          value: 'id'
        },
        riskOptions: [
          {name: '地震',value: 1},
@@ -179,32 +185,129 @@
          {name: '红色预警',value: 1},
          {name: '橙色预警',value: 2},
          {name: '黄色预警',value: 3},
          {name: '蓝色预警',value: 4},
          {name: '其他短信通知',value: 5}
        ]
          {name: '蓝色预警',value: 4}
        ],
        rules: {
          emergType: [{ required: true, message: '请选择紧急类型', trigger: 'change'}],
          disasterType: [{ required: true, message: '请选择灾种', trigger: 'change'}],
          warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change'}],
          content: [{ required: true, message: '请输入信息内容', trigger: 'blur'}],
          receiver: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
          recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
          // verticalRecipient: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
          // horizontalRecipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
        }
            };
        },
        components: {},
        computed: {
            filteredOptions() {
                return OPTIONS.filter(o => !this.form.sameDep.includes(o));
            },
    created() {
      const t = this
      t.userInfo = getUserInfo()
      t.form.publishingUnit = t.userInfo.company
      t.getSameLevel()
      t.getAreaUsers()
    },
    computed: {
        },
        methods: {
      // 获取同级接收人
      async getSameLevel(){
        let t = this
        let res = await getPeerRecipient()
        if(res.data.code == 100){
          if(res.data.data){
            t.filteredOptions = res.data.data
          }else{
            this.$message.warning('暂无数据');
          }
        }else{
          this.$message.warning(res.data.msg);
        }
      },
      // 获取接收单位
      async getAreaUsers(){
        let t = this
        let res = await getAreaWithUserIfo()
        if(res.data.code == 100){
          if(res.data.data){
            const treeD = []
            t.userTitTree(res.data.data)
            treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
            t.areaUsers = treeD
          }else{
            this.$message.warning('暂无数据');
          }
        }else{
          this.$message.warning(res.data.msg);
        }
      },
            //选择子部门部分
            onChanges(value) {
            if(value.find(i=>i.value == 'all')){
              console.log('全选了')
            }else{
              this.svalue = value;
            onChanges(value,label,extra) {
        const t = this
        if(t.form.receiver.length == 0){
          t.checkAll = false
        }
        // for(let i of value){
        //   t.form.verticalRecipient = [...t.form.verticalRecipient,...t.findNodeById(t.areaUsers,i.value).users]
        // }
      },
      checkChange(e) {
        const t = this
        this.checkAll = !this.checkAll
        if(t.checkAll == true){
          t.form.receiver = t.traverseTree(t.areaUsers[0])
        }else{
          t.form.receiver = []
        }
      },
      confirmSend(){
        this.$refs.ruleForm.validate(valid => {
          if (valid) {
            this.form.verticalRecipient = []
            this.form.horizontalRecipient = []
            const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
            const newAList = [].concat(...aList)
            for(let i of newAList){
              const {realName,...data} = i
              const {company: recipientUnit,...rest} = data
              const obj = {recipientUnit,recipientType:1,...rest}
              this.form.verticalRecipient.push(obj)
            }
            console.log(this.svalue);
                },
            const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
            for(let i of bList){
              const {recipientName: name, company: recipientUnit,...rest} = i
              const obj = {name,recipientUnit,recipientType:2,...rest}
              this.form.horizontalRecipient.push(obj)
            }
            const {receiver,recipient,...data} = this.form
            massSend(data).then( res =>{
              if(res.data.code == 100){
                this.$message.success('信息群发成功')
                this.$refs.ruleForm.clearValidate()
                this.$refs.ruleForm.resetFields()
              }else{
                this.$message.error(res.data.msg)
                this.$refs.ruleForm.clearValidate()
                this.$refs.ruleForm.resetFields()
              }
            })
          }else{
            console.log('error submit!!');
            return false;
          }
        })
      },
      onSearch() {
        console.log(...arguments);
        // console.log(...arguments);
      },
      onSelect() {
        console.log(...arguments);
        // console.log(...arguments);
      },
            //选择平级部门部分
      handleRisk(selectedItems) {
@@ -233,6 +336,50 @@
                    option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
                );
            },
      // 根据id查对象
      findNodeById(data,value) {
        for (const node of data) {
          if (node.id === value) {
            return node;
          }
          if (node.children) {
            const foundNode = this.findNodeById(node.children, value);
            if (foundNode) {
              return foundNode;
            }
          }
        }
        return null;
      },
      // 将树状数据所有id和name放入对象数组
      traverseTree(treeData) {
        let result = [];
        function traverse(node) {
          result.push({ label: node.name, value: node.id });
          if (node.children && node.children.length > 0) {
            for (let child of node.children) {
              traverse(child);
            }
          }
        }
        traverse(treeData);
        return result;
      },
      // 将树状数据新增title字段放入users的姓名电话
      userTitTree(treeData) {
        for(const node of treeData){
          if(node.users){
            node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
          }
          if(node.children){
            this.userTitTree(node.children)
          }
        }
        return treeData
      }
        },
    }
</script>
src/views/Admin/menuManage.vue
@@ -38,8 +38,8 @@
        </template>
      </a-table>
    </div>
    <user-mod ref="userMod" @refrech="getUserList"></user-mod>
    <pwd-mod ref="pwdMod" @refrech="getUserList"></pwd-mod>
    <user-mod ref="userMod" @refresh="getUserList"></user-mod>
    <pwd-mod ref="pwdMod" @refresh="getUserList"></pwd-mod>
  </div>
</template>
src/views/Admin/msgRecord.vue
@@ -3,16 +3,17 @@
    <a-row type="flex" :gutter="12" style="margin-bottom: 20px">
      <a-col :span="6">
        <a-range-picker
            v-model="timeRange"
            format="YYYY-MM-DD"
            :placeholder="['开始时间', '结束时间']"
            @change="onChange"
            @change="timeChange"
            @ok="onOk"
            style="width: 100%"
        />
      </a-col>
      <a-col :span="4">
        <a-button type="primary">查询</a-button>
        <a-button style="margin-left: 12px">重置</a-button>
        <a-button type="primary" @click="getData">查询</a-button>
        <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
      </a-col>
    </a-row>
    <div class="table-cont">
@@ -20,7 +21,7 @@
        <a-card hoverable class="msg-item" v-for="item in msg" :key="item.id">
          <template #title>
            <div class="tit">
              发送时间:<span>{{item.time}}</span>
              发送时间:<span>{{item.gmtCreate}}</span>
            </div>
            <a-divider type="vertical" />
            <div class="tit">
@@ -32,66 +33,135 @@
          </p>
          <template #actions>
            <div>
              接收号码:<span>{{item.phone.join(',')}}</span>
              接收号码:<span>{{item.recipients.map(i=>i.name + '(' + i.phone + ')').join('、')}}</span>
            </div>
            <div>
              <a-button type="primary" @click="viewDetails">查看详情</a-button>
              <a-button type="primary" @click="viewDetails(item)">查看详情</a-button>
            </div>
          </template>
        </a-card>
      </div>
    </div>
    <a-modal v-model="visible" width="50%" title="短信详情" @ok="handleOk" cancelText="取消" okText="确认">
      短信详情
    <a-pagination v-model="search.pageIndex" :total="total" :show-total="total => `共 ${total} 条数据`" show-less-items/>
    <a-modal v-model="visible" width="40%" title="短信详情" @ok="handleOk" cancelText="取消" okText="确认" centered>
      <div class="detail-mod">
        <a-row :gutter="24"><a-col :span="4" style="text-align: right">{{ details.emergType == 1?'紧急':details.emergType == 2?'常规':'' }}</a-col></a-row>
        <a-row :gutter="24"><a-col :span="4" style="text-align: right">发送时间</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{details.gmtCreate}}</a-col></a-row>
        <a-row :gutter="24"><a-col :span="4" style="text-align: right">灾种类型</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{ getRiskName(details.disasterType)}}</a-col></a-row>
        <a-row :gutter="24"><a-col :span="4" style="text-align: right">预警级别</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{ getLevelName(details.warningLevel)}}</a-col></a-row>
        <a-row :gutter="24"><a-col :span="4" style="text-align: right">信息内容</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{details.content}}</a-col></a-row>
        <a-row :gutter="24">
          <a-col :span="4" style="text-align: right">接收人</a-col>
          <a-col :span="20" style="border: 1px solid #d9d9d9;padding: 0 !important;">
            <div v-for="(item,index) in details.recipients" :key="index" class="table">
            <div style="width: 20%">
              {{item.name}}
            </div>
            <div style="width: 20%">
              {{item.phone}}
            </div>
            <div style="width: 60%">
              {{item.recipientUnit}}
            </div>
            </div>
          </a-col>
        </a-row>
      </div>
    </a-modal>
  </div>
</template>
<script>
import {getUser} from '@/api/user'
import {getMassRecord} from "@/api/send";
export default {
  name: 'msgRecord',
  components: {},
  data () {
    return {
      msg: [
        {
          time: '2023-05-30',
          id: '1201',
          content: '第一条短信',
          phone: ['15261806176','15261806176','15261806176','15261806176','15261806176','15261806176','15261806176','15261806176','15261806176']
        },
        {
          time: '2023-05-30',
          id: '1202',
          content: '第二条短信',
          phone: ['15261806176','15261806176','15261806176','15261806176','15261806176']
        },
        {
          time: '2023-05-30',
          id: '1203',
          content: '第三条短信',
          phone: ['15261806176','15261806176','15261806176','15261806176','15261806176']
      search:{
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          startTime: '',
          endTime: ''
        }
      },
      timeRange: [],
      total: 0,
      msg: [],
      visible: false,
      details: {},
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      visible: false
      levelOptions: [
        {name: '红色预警',value: 1},
        {name: '橙色预警',value: 2},
        {name: '黄色预警',value: 3},
        {name: '蓝色预警',value: 4}
      ]
    }
  },
  created() {
    const t = this
    t.getData()
  },
  methods:{
    onChange(value, dateString) {
      console.log('Selected Time: ', value);
      console.log('Formatted Selected Time: ', dateString);
    async getData(){
      const t = this
      const res = await getMassRecord(this.search)
      if(res.data.code == 200){
        t.msg = res.data.data
        t.pagination.total = res.data.total
      }else{
        this.$message.error(res.data.msg)
      }
    },
    resetSearch(){
      const t = this
      t.search = {
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          startTime: '',
          endTime: ''
        }
      }
      t.timeRange = []
      t.getData()
    },
    timeChange(value, dateString) {
      const t = this
      if(dateString){
        t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
        t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
      }
    },
    onOk(value) {
      console.log('onOk: ', value);
    },
    viewDetails(){
    viewDetails(item){
      const t = this
      t.details = item
      t.visible = true
    },
    getRiskName(disasterType){
      return this.riskOptions.find(i => i.value === disasterType)?.name;
    },
    getLevelName(warningLevel){
      return this.levelOptions.find(i => i.value === warningLevel)?.name;
    },
    handleOk(e) {
      console.log(e);
      this.visible = false;
@@ -109,9 +179,9 @@
    width: 100%;
    margin-bottom: 24px;
    /deep/ .ant-card-head-title{
      display: flex;
      align-items: center;
    /deep/.ant-card-head-title{
      display: flex !important;
      align-items: center !important;
      .tit{
        width: 50%;
      }
@@ -138,5 +208,28 @@
    }
  }
}
.detail-mod{
  font-size: 16px;
  .ant-row{
    margin-bottom: 24px;
    .table{
      display: flex;
      align-items: center;
      border-bottom: 1px solid @blackBorder;
      &:last-of-type{
        border-bottom: none;
      }
      &>div{
        border-right: 1px solid @blackBorder;
        padding: 5px 10px;
        &:last-of-type{
          border-right: none;
        }
      }
    }
  }
}
</style>
src/views/Admin/msgReview.vue
@@ -2,14 +2,14 @@
  <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="category">
          <a-radio-button :value="0">
        <a-radio-group v-model="search.searchParams.reviewStatus" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button :value="1">
          <a-radio-button :value="2">
            审核通过
          </a-radio-button>
          <a-radio-button :value="2">
          <a-radio-button :value="1">
            未审核
          </a-radio-button>
          <a-radio-button :value="3">
@@ -21,108 +21,123 @@
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="timeChange"
                @ok="timeOk"
                @ok="onOk"
                style="width: 100%"
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary">查询</a-button>
            <a-button style="margin-left: 12px">重置</a-button>
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
    </a-row>
    <div class="table-cont">
      <a-table :columns="columns" :data-source="data" bordered>
        <template #level="level">
          <a-tag :color="level === '黄色' ? 'yellow' :level === '橙色'? 'orange':level === '红色'?'red':'blue'">
            {{ level }}
          </a-tag>
      <a-table :columns="columns" :data-source="data" bordered :rowKey="record=>record.id">
        <template #index="text,record,index">
          {{ index+1 }}
        </template>
        <template #disasterType="text">
          {{ getRiskName(text) }}
        </template>
        <template #attachment="text">
          <span v-if="text==='无'">无</span>
          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
        </template >
        <template #status="status">
        <template #reviewStatus="reviewStatus">
          <a-tag
              :color="status === 1 ? 'green' : status === 2 ? 'blue' : 'red'"
              :color="reviewStatus === 1 ? 'blue' : reviewStatus === 2 ? 'green' : 'red'"
          >
            {{ status==1?'审核通过':status==2?'未审核':'审核驳回' }}
            {{ reviewStatus==1?'未审核':reviewStatus==2?'已审核':reviewStatus==3?'审核驳回':'' }}
          </a-tag>
        </template>
        <template #operation="text, record, index">
          <a-button type="link" v-if="record.status == 1 || record.status == 3">查看信息详情</a-button>
          <a-button type="primary" v-if="record.status == 2">查看并审核</a-button>
          <a-button type="link" v-if="record.reviewStatus == 2 || record.reviewStatus == 3" @click="openMod('view',record)">查看信息详情</a-button>
          <a-button type="primary" v-if="record.reviewStatus == 1" @click="openMod('review',record)">查看并审核</a-button>
        </template>
      </a-table>
    </div>
    <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
  </div>
</template>
<script>
import {getReviewDetail, getReviewRecord} from "@/api/review";
import msgEditMod from '@/views/Admin/components/msgEditMod'
export default {
  name: 'msgReview',
  components: {},
  components: { msgEditMod },
  data () {
    return {
      category: 0,
      search:{
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          reviewStatus: null,
          startTime: '',
          endTime: ''
        }
      },
      timeRange: [],
      riskOptions: [
        {name: '地震',value: 1},
        {name: '洪涝',value: 2},
        {name: '气象',value: 3},
        {name: '泥石流',value: 4},
        {name: '水旱',value: 5},
        {name: '森林草原火灾',value: 6}
      ],
      columns: [
        {
          title: '序号',
          dataIndex: 'key',
          width: '5%',
          key: 'index',
          scopedSlots: {
            customRender: 'index'
          },
        },
        {
          title: '提交审核时间',
          dataIndex: 'time',
          width: '15%',
          scopedSlots: {
            customRender: 'time'
          }, //设置定制化表格数据
          key: 'gmtReviewSubmit',
          dataIndex: 'gmtReviewSubmit',
        },
        {
          title: '发布单位',
          dataIndex: 'department',
          width: '12%',
          key: 'publishingUnit',
          dataIndex: 'publishingUnit',
        },
        {
          title: '类别',
          dataIndex: 'category',
          width: '8%',
        },
        {
          title: '级别',
          dataIndex: 'level',
          title: '灾种',
          dataIndex: 'disasterType',
          key: 'disasterType',
          scopedSlots: {
            customRender: 'level'
            customRender: 'disasterType'
          }, //设置定制化表格数据
          width: '8%',
        },
        {
          title: '信息标题',
          key: 'title',
          dataIndex: 'title',
          width: '16%',
        },
        {
          title: '附件',
          key: 'attachment',
          dataIndex: 'attachment',
          width: '6%',
          scopedSlots: {
            customRender: 'attachment'
          },
        },
        {
          title: '审核情况',
          dataIndex: 'status',
          width: '10%',
          dataIndex: 'reviewStatus',
          scopedSlots: {
            customRender: 'status'
            customRender: 'reviewStatus'
          }, //设置定制化表格数据
        },
        {
@@ -133,53 +148,66 @@
          },
        },
      ],
      data: [
        {
          key: 1,
          id:1001,
          time: '2023-05-02 15:30',
          department: '自治区预警中心',
          category: '气象',
          level: '黄色',
          title: '全疆高温红色预警',
          attachment: '1',
          status: 1
        },
        {
          key: 2,
          id:1002,
          time: '2023-05-02 15:30',
          department: '自治区预警中心',
          category: '气象',
          level: '橙色',
          title: '全疆高温红色预警',
          attachment: '1',
          status: 2
        },
        {
          key: 3,
          id:1003,
          time: '2023-05-02 15:30',
          department: '自治区预警中心',
          category: '气象',
          level: '橙色',
          title: '全疆高温红色预警',
          attachment: '1',
          status: 3
        }
      ]
      data: []
    }
  },
  created() {
    const t = this
    t.getData()
  },
  methods:{
    timeChange(date, dateString) {
      console.log(date, dateString);
    async getData(){
      const t = this
      const res = await getReviewRecord(this.search)
      if(res.data.code == 100){
        t.data = res.data.data
        t.pagination.total = res.data.total
      }else{
        this.$message.error(res.data.msg)
      }
    },
    timeOk(value) {
      console.log('timeOk: ', value);
    resetSearch(){
      const t = this
      t.search = {
        pageIndex: 1,
        pageSize: 10,
        searchParams:{
          reviewStatus: null,
          startTime: '',
          endTime: ''
        }
      }
      t.timeRange = []
      t.getData()
    },
    timeChange(value, dateString) {
      const t = this
      if(dateString){
        t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
        t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
      }
    },
    openMod(type,data){
      const t = this
      getReviewDetail(data.id).then(res=>{
        if(res.data.code == 100){
          t.$refs.msgEdit.openMod(type,res.data.data)
        }else{
          this.$message.error(res.data.msg)
        }
      })
    },
    onOk(value) {
      console.log('onOk: ', value);
    },
    getRiskName(disasterType){
      return this.riskOptions.find(i => i.value === disasterType)?.name;
    }
  }
}
</script>
src/views/Admin/notice.vue
@@ -1,146 +1,384 @@
<template>
    <div class="inner">
        <h2>预警信息发布</h2>
        <div class="left">
            <a-input placeholder="请输入标题" style="height: 50px; font-size: 20px;" />
            <br /><br />
            <a-radio-group v-model="value" @change="onChange">
                <a-radio :value="1">
                    蓝色
                </a-radio>
                <a-radio :value="2">
                    黄色
                </a-radio>
                <a-radio :value="3">
                    橙色
                </a-radio>
                <a-radio :value="4">
                    红色
                </a-radio>
            </a-radio-group>
            <br /><br />
            <a-radio-group default-value="a" button-style="solid">
                <a-radio-button value="a">
                    常规
                </a-radio-button>
                <a-radio-button value="b">
                    紧临
                </a-radio-button>
            </a-radio-group>
            <div class="ftright">
                平级接收人选择:
                <a-select mode="multiple" placeholder="选择平级接收单位" :value="selectedItems" style="width: 180px"
                    @change="handle">
                    <a-select-option v-for="item in filteredOptions" :key="item" :value="item">
                        {{ item }}
                    </a-select-option>
                </a-select>
            </div>
    <h2>预警信息发布</h2>
    <a-form-model ref="ruleForm" :model="form" :rules="rules" :wrapper-col="wrapperCol">
      <div class="left">
        <a-form-model-item prop="title">
          <a-input v-model="form.title" placeholder="请输入标题" style="height: 50px; font-size: 20px;" />
        </a-form-model-item>
        <!--      <a-row>-->
        <!--        <a-col :span="12" style="display: flex;align-items: center">-->
        <!--          <span style="display: block;margin-bottom: 24px">相关灾种</span>-->
            <br /><br />
            <a-textarea v-model="message" placeholder="请输入短信通知内容部分" :auto-size="{ minRows: 3, maxRows: 5 }" />
            <br /><br />
            <a-button>上传附件</a-button>  <div style="float: right;width:50%;text-align: right;">超时设置: <a-input style="width:100px;" placeholder="输入时间" /> 分钟</div>
            <br /><br />
            <span><b>发布单位:</b>{{department}}</span>
            <br/><br/>
            <!-- 子单位-->
            <div style="margin-bottom: 10px">选择接收单位:</div>
            <a-tree-select
                show-search
          tree-checkable
          treeCheckStrictly
                style="width: 100%"
          v-model="svalue"
                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                placeholder="选择工作通知接收单位"
                allow-clear
                multiple
                tree-default-expand-all
                @change="onChanges"
                @search="onSearch"
                @select="onSelect"
              >
        <a-tree-select-node key="0" value="all" title="全选">
        </a-tree-select-node>
                <a-tree-select-node key="0-1" value="乌鲁木齐" title="乌鲁木齐(张XX 13268813610)">
                  <a-tree-select-node key="0-1-1" value="米东区" title="米东区(张XX 13268813610)">
                    <a-tree-select-node key="0-1-1-1" value="XX村1" title="XX村(李有田 13268813610)" />
                  </a-tree-select-node>
                  <a-tree-select-node key="0-1-2" value="天山区" title="天山区">
                    <a-tree-select-node key="0-1-2-1" value="XX村2">
                      <b slot="title" style="color: #08c">XX村</b>
                    </a-tree-select-node>
                  </a-tree-select-node>
                </a-tree-select-node>
              </a-tree-select>
              <br/><br/>
            <div style="float: right;"><b>选择审批领导:</b> <a-select show-search placeholder="请选择审批领导"
                    option-filter-prop="children" style="width: 200px" :filter-option="filterOption"
                    @focus="handleFocus" @blur="handleBlur" @change="handleChange">
                    <a-select-option value="jack">
                        裴小威
                    </a-select-option>
                    <a-select-option value="lucy">
                        赵东升
                    </a-select-option>
                    <a-select-option value="tom">
                        王卫萍
                    </a-select-option>
                </a-select></div>
            <br /><br />
            <a-button type="primary" class="ftright">
                确认并提交审核
            </a-button>
        </div>
        <!--        </a-col>-->
        <!--        <a-col :span="12" style="display: flex;align-items: center;justify-content: right">-->
        <!--          <span style="display: block;margin-bottom: 24px">预警级别:</span>-->
        <div class="right">
            <h2>短信预览</h2>
            <div class="mobile">
                <div class="mesg">
                    <P>【{{signname}}】{{message}}。发布单位:{{department}}</P>
                </div>
        <!--        </a-col>-->
        <!--      </a-row>-->
            </div>
        </div>
        <a-row>
          <a-col :span="12">
            <a-form-model-item prop="emergType">
              <a-radio-group v-model="form.emergType" button-style="solid">
                <a-radio-button :value="2">
                  常规
                </a-radio-button>
                <a-radio-button :value="1">
                  紧临
                </a-radio-button>
              </a-radio-group>
            </a-form-model-item>
          </a-col>
          <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
            <a-form-model-item prop="disasterType" style="margin-right: 20px">
              <a-select placeholder="请选择相关灾种" v-model="form.disasterType" style="width: 240px" allowClear @change="handleRisk">
                <a-select-option v-for="item in riskOptions" :key="item.value" :value="item.value">
                  {{ item.name }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
            <a-form-model-item prop="warningLevel">
              <a-select placeholder="请选择预警级别" v-model="form.warningLevel" style="width: 240px" allowClear @change="handleLevel">
                <a-select-option v-for="item in levelOptions" :key="item.value" :value="item.value">
                  {{ item.name }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-form-model-item prop="content">
          <a-textarea v-model="form.content" placeholder="请输入短信通知内容部分" :auto-size="{ minRows: 3, maxRows: 5 }" />
        </a-form-model-item>
        <a-row>
          <a-col :span="12">
            <a-button>上传附件</a-button>
          </a-col>
          <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
            <b style="margin-bottom: 24px">超时设置:</b>
            <a-form-model-item prop="timeout">
              <a-input v-model="form.timeout" style="width:200px;" placeholder="输入时间" suffix="分钟"/>
            </a-form-model-item>
          </a-col>
        </a-row>
        <span><b>发布单位:</b>{{form.publishingUnit}}</span>
        <br/><br/>
        <!-- 子单位-->
        <a-row :gutter="24">
          <a-col :span="12">
            <div style="display:flex;justify-content: space-between;align-items: center;">
              <b>选择接收单位:</b>
              <a-checkbox :checked="checkAll" @change="checkChange">
                全选
              </a-checkbox>
            </div>
            <a-form-model-item prop="receiver">
              <a-tree-select
                  show-search
                  tree-checkable
                  treeCheckStrictly
                  style="width: 100%"
                  v-model="form.receiver"
                  :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
                  placeholder="选择工作通知接收单位"
                  allow-clear
                  multiple
                  @change="depChanges"
                  @search="onSearch"
                  @select="onSelect"
                  :tree-data="areaUsers"
                  :replaceFields="replaceFields"
              >
              </a-tree-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="12">
            <b style="margin-bottom: 6px">平级接收人选择:</b>
            <a-form-model-item prop="recipient">
              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle">
                <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                  {{ item.recipientName }}
                </a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
        </a-row>
        <a-row :gutter="24" style="display: flex;align-items: center">
          <a-col :span="12">
            <b style="margin-bottom: 6px">选择审批领导:</b>
            <a-form-model-item prop="reviewId">
              <a-select show-search v-model="form.reviewId" placeholder="请选择审批领导" style="width: 300px">
                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.name}}</a-select-option>
              </a-select>
            </a-form-model-item>
          </a-col>
          <a-col :span="12" style="text-align: right">
            <a-button type="primary" style="width: 250px;" @click="confirmSend()">
              确认并提交审核
            </a-button>
          </a-col>
        </a-row>
      </div>
      <div class="right">
        <h2>短信预览</h2>
        <div class="mobile">
          <div class="mesg">
            <P>【{{form.title}}】{{form.content}}。发布单位:{{form.publishingUnit}}</P>
          </div>
        </div>
      </div>
    </a-form-model>
    </div>
</template>
<script>
    const OPTIONS = ['自治区消防(李XX)', '自治区公安厅(王XX)', '自治区自然资源厅(刘XX)'];
import {getAreaWithUserIfo, getPeerRecipient, getLeaders} from '@/api/user'
  import {getUserInfo} from "@/util/storage";
  import Cookies from "js-cookie";
import {massSend, msgSend} from "@/api/send";
    export default {
        name: "release",
        name: "notice",
        data() {
            return {
                value: 1,
                message: '',
                signname: '自然灾害风险预警提示',
                department: '自治区自然灾害综合监测预警中心',
                selectedItems: [],
                svalue:undefined,
        userInfo: {},
        wrapperCol: { span: 24 },
        filteredOptions:[],
        form: {
          id: null,
          title: '',
          emergType: null,
          disasterType: undefined,
          warningLevel: undefined,
          content: '',
          publishingUnit: '',
          districtId: null,
          attachments: [],
          timeout: null,
          reviewId: null,
          receiver: [],
          recipient: [],
          acceptingUnitIds: [],
          peerRecipientIds: []
        },
        leaders: [],
        checkAll: false,
        areaUsers: [],
        replaceFields: {
          children:'children',
          title:'name',
          key:'id',
          value: 'id'
        },
        riskOptions: [
          {name: '地震',value: 1},
          {name: '洪涝',value: 2},
          {name: '气象',value: 3},
          {name: '泥石流',value: 4},
          {name: '水旱',value: 5},
          {name: '森林草原火灾',value: 6}
        ],
        levelOptions: [
          {name: '红色预警',value: 1},
          {name: '橙色预警',value: 2},
          {name: '黄色预警',value: 3},
          {name: '蓝色预警',value: 4}
        ],
        rules: {
          emergType: [{ required: true, message: '请选择紧急类型', trigger: 'change'}],
          disasterType: [{ required: true, message: '请选择灾种', trigger: 'change'}],
          warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change'}],
          title: [{ required: true, message: '请输入信息标题', trigger: 'blur'}],
          content: [{ required: true, message: '请输入信息内容', trigger: 'blur'}],
          timeout: [{ required: true, message: '请输入超时时间', trigger: 'blur'}],
          receiver: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
          reviewId: [{ required: true, message: '请选择审批人', trigger: 'change'}],
          recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
          // acceptingUnitIds: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
          // peerRecipientIds: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
        }
            };
        },
        components: {},
        computed: {
            filteredOptions() {
                return OPTIONS.filter(o => !this.selectedItems.includes(o));
            },
        },
    created() {
      const t = this
      t.userInfo = getUserInfo()
      t.form.districtId = t.userInfo.districtId
      t.form.publishingUnit = t.userInfo.company
      t.getSameLevel()
      t.getAreaUsers()
      t.getLeaders()
    },
    computed: {},
        methods: {
      // 获取同级接收人
      async getSameLevel(){
        let t = this
        let res = await getPeerRecipient()
        if(res.data.code == 100){
          if(res.data.data){
            t.filteredOptions = res.data.data
          }else{
            this.$message.warning('暂无数据');
          }
        }else{
          this.$message.warning(res.data.msg);
        }
      },
      // 获取接收单位
      async getAreaUsers(){
        let t = this
        let res = await getAreaWithUserIfo()
        if(res.data.code == 100){
          if(res.data.data){
            const treeD = []
            t.userTitTree(res.data.data)
            const obj = t.findNodeById(res.data.data,t.userInfo.districtId)
            treeD.push(t.removeNodesWithoutUsers(obj))
            t.areaUsers = treeD
            t.unittype = this.findNodeById(this.areaUsers,t.userInfo.districtId)?.type
          }else{
            this.$message.warning('暂无数据');
          }
        }else{
          this.$message.warning(res.data.msg);
        }
      },
      // 获取领导
      async getLeaders(){
        let t = this
        let res = await getLeaders()
        if(res.data.code == 100){
          if(res.data.data){
            t.leaders = res.data.data
          }else{
            this.$message.warning('暂无数据');
          }
        }else{
          this.$message.warning(res.data.msg);
        }
      },
            //选择子部门部分
            onChanges(value) {
            if(value.find(i=>i.value == 'all')){
              console.log('全选了')
            }else{
              this.svalue = value;
      depChanges(value,label,extra) {
        const t = this
        if(t.form.receiver.length == 0){
          t.checkAll = false
        }
      },
      checkChange(e) {
        const t = this
        this.checkAll = !this.checkAll
        if(t.checkAll == true){
          t.form.receiver = t.traverseTree(t.areaUsers[0])
        }else{
          t.form.receiver = []
        }
      },
      confirmSend(){
        this.$refs.ruleForm.validate(valid => {
          if (valid) {
            this.form.acceptingUnitIds = []
            this.form.peerRecipientIds = []
            const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
            console.log(aList,'a')
            const newAList = [].concat(...aList)
            console.log(newAList,'b')
            for(let i of newAList){
              const {realName,...data} = i
              const {id:recipienterId,name: recipienterName,phone: recipienterPhone,company: receiveUnit,...rest} = data
              const obj = { recipienterId, recipienterName, recipienterPhone, receiveUnit,...rest}
              this.form.acceptingUnitIds.push(obj)
            }
            console.log(this.svalue);
                },
            const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
            for(let i of bList){
              const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
              const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
              this.form.peerRecipientIds.push(obj)
            }
            const {receiver,recipient,id,...data} = this.form
            msgSend(data).then( res =>{
              if(res.data.code == 100){
                this.$message.success('信息已提交审核')
              }else{
                this.$message.error(res.data.msg)
              }
              this.$refs.ruleForm.clearValidate()
              this.$refs.ruleForm.resetFields()
            })
          }else{
            console.log('error submit!!');
            return false;
          }
        })
      },
// 根据id查对象
      findNodeById(data,value) {
        for (const node of data) {
          if (node.id === value) {
            return node;
          }
          if (node.children) {
            const foundNode = this.findNodeById(node.children, value);
            if (foundNode) {
              return foundNode;
            }
          }
        }
        return null;
      },
      // 将树状数据所有id和name放入对象数组
      traverseTree(treeData) {
        let result = [];
        function traverse(node) {
          result.push({ label: node.name, value: node.id });
          if (node.children && node.children.length > 0) {
            for (let child of node.children) {
              traverse(child);
            }
          }
        }
        traverse(treeData);
        return result;
      },
      // 将树状数据name字段放入users的姓名电话
      userTitTree(treeData) {
        for(const node of treeData){
          if(node.users){
            node.users = node.users.map((i)=>{
              return{
                ...i,
                unittype: node.type,
                districtId: node.id
              }
            })
            node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
          }
          if(node.children){
            this.userTitTree(node.children)
          }
        }
        return treeData
      },
      // 将users为null的节点删除
      removeNodesWithoutUsers(node) {
          if (node.users === null) {
            return null; // 返回 null 表示删除节点
          }
          if (node.children && node.children.length > 0) {
            node.children = node.children.map(child => this.removeNodesWithoutUsers(child)).filter(Boolean);
          }
          return node;
      },
      onSearch() {
        console.log(...arguments);
      },
@@ -151,6 +389,13 @@
            handle(selectedItems) {
                this.selectedItems = selectedItems;
            },
      handleRisk(selectedItems) {
        // this.selectedItems = selectedItems;
      },
      handleLevel(selectedItems) {
        // this.selectedItems = selectedItems;
      },
            onChange(){
                console.log(this.value)
            },
src/views/Admin/release.vue
@@ -2,14 +2,14 @@
  <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="8">
        <a-radio-group v-model="category">
          <a-radio-button value="default">
        <a-radio-group v-model="search.searchParams.emergType" @change="getData">
          <a-radio-button :value="null">
            全部
          </a-radio-button>
          <a-radio-button value="1">
          <a-radio-button :value="1">
            紧临
          </a-radio-button>
          <a-radio-button value="2">
          <a-radio-button :value="2">
            常规
          </a-radio-button>
        </a-radio-group>
@@ -18,16 +18,17 @@
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="8">
            <a-range-picker
                v-model="timeRange"
                format="YYYY-MM-DD"
                :placeholder="['开始时间', '结束时间']"
                @change="onChange"
                @ok="onOk"
                @change="timeChange"
                @ok="timeOk"
                style="width: 100%"
            />
          </a-col>
          <a-col :span="4">
            <a-button type="primary">查询</a-button>
            <a-button style="margin-left: 12px">重置</a-button>
            <a-button type="primary" @click="getData">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
      </a-col>
@@ -35,24 +36,38 @@
      <!-- 表格实体部分-->
    <div class="table-cont">
      <a-table :columns="columns" :data-source="data" bordered>
        <template #level="text">
          <a-tag :color="text === '黄色' ? 'yellow' :text === '橙色'? 'orange':text === '红色'?'red':'blue'">
            {{ text }}
      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
        <template #index="text,record,index">
          {{ index + 1 }}
        </template>
        <template #publishingTime="text">
          {{ text }}
        </template>
        <template #publishingUnit="text">
          {{ text }}
        </template>
        <template #disasterType="text">
          {{ getRiskName(text) }}
        </template>
        <template #warningLevel="text">
          <a-tag :color="text === 3 ? 'yellow' :text === 2? 'orange':text === 1?'red':'blue'">
            {{ getLevelName(text) }}
          </a-tag>
        </template>
        <template #attachment="text">
          <span v-if="text==='无'">无</span>
          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
          <a><b><a-icon type="paper-clip"/></b></a>
        </template >
        <template #responseSituation="text">
          <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
            {{text == 1 ? '待叫应' : text == 2 ?'已叫应':text == 3 ?'超时未叫应' : ''}}
          </a-tag>
        </template>
        <template #operation="text, record, index">
          <div class="editable-row-operations">
          <a @click="showModal" style="color:orangered">
            叫应列表</a>&nbsp;&nbsp;
            <router-link :to="{path:'/details',query: {id: record.id}}">信息详情</router-link>
          </div>
          <a-button type="primary">叫应列表</a-button>
          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
        </template>
      </a-table>
      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
    </div>
      <!-- 对话框 -->
      <a-modal title="查看叫应详情" 
@@ -63,37 +78,46 @@
  </div>
</template>
<script>
    const columns = [{
import {getMsgRecord, getPublishRecord} from "@/api/list";
import msgEditMod from "@/views/Admin/components/msgEditMod";
import {getReviewDetailByWorker} from "@/api/review";
  const columns = [{
            title: '序号',
            dataIndex: 'key',
            dataIndex: 'index',
            width: '8%',
      scopedSlots: {
        customRender: 'index'
      }
        },
        {
            title: '发布时间',
            dataIndex: 'time',
            dataIndex: 'publishingTime',
            width: '15%',
            scopedSlots: {
                customRender: 'time'
            }, //设置定制化表格数据
                customRender: 'publishingTime'
            } //设置定制化表格数据
        },
        {
            title: '发布单位',
            dataIndex: 'department',
            dataIndex: 'publishingUnit',
            width: '12%',
        },
        {
            title: '类别',
            dataIndex: 'category',
            width: '8%',
        },
        {
            title: '级别',
            dataIndex: 'level',
            scopedSlots: {
                customRender: 'level'
            }, //设置定制化表格数据
            width: '8%',
        },
    {
      title: '灾种',
      dataIndex: 'disasterType',
      width: '8%',
      scopedSlots: {
        customRender: 'disasterType'
      }
    },
    {
      title: '预警级别',
      dataIndex: 'warningLevel',
      scopedSlots: {
        customRender: 'warningLevel'
      }, //设置定制化表格数据
      width: '8%',
    },
        {
            title: '信息标题',
            dataIndex: 'title',
@@ -109,10 +133,10 @@
        },
        {
            title: '叫应情况',
            dataIndex: 'receipt',
            dataIndex: 'responseSituation',
            width: '10%',
            scopedSlots: {
                customRender: 'receipt'
                customRender: 'responseSituation'
            }, //设置定制化表格数据
        },
        {
@@ -123,58 +147,113 @@
            },
        },
    ];
    const data = [{
            key: 1,
            id:1001,
            readed:false,
            time: '2023年5月3日 15:30',
            department: '自治区预警中心',
            category: '气象',
            level: '黄色',
            title: '全疆高温红色预警',
            attachment: '1',
            receipt: '部分叫应'
        },
        {
                key: 2,
                id:1002,
                readed:false,
                time: '2023年5月3日 15:30',
                department: '自治区预警中心',
                category: '气象',
                level: '黄色',
                title: '全疆高温红色预警',
                attachment: '1',
                receipt: '全部叫应'
            },{
                key: 3,
                id:1003,
                readed:false,
                time: '2023年5月3日 15:30',
                department: '自治区预警中心',
                category: '气象',
                level: '黄色',
                title: '全疆高温红色预警',
                attachment: '1',
                receipt: '均未叫应'
            }]
    export default {
    name: 'release',
    components: { msgEditMod },
        data() {
            return {
        search:{
          pageIndex: 1,
          pageSize: 10,
          searchParams:{
            emergType: null,
            startTime: '',
            endTime: ''
          }
        },
        timeRange: [],
                category: 'default',
                data,
                data:[],
                columns,
                visible: false,
                confirmLoading: false,
        pagination: {
          current: 1,
          defaultCurrent: 1,
          defaultPageSize: 10,
          total: 0,
          onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
          showTotal: total => `共 ${total} 条`
        },
        riskOptions: [
          {name: '地震',value: 1},
          {name: '洪涝',value: 2},
          {name: '气象',value: 3},
          {name: '泥石流',value: 4},
          {name: '水旱',value: 5},
          {name: '森林草原火灾',value: 6}
        ],
        levelOptions: [
          {name: '红色预警',value: 1},
          {name: '橙色预警',value: 2},
          {name: '黄色预警',value: 3},
          {name: '蓝色预警',value: 4}
        ]
            }
        },
    created() {
      const t = this
      t.getData()
    },
        methods: {
      onChange(value, dateString) {
        console.log('Selected Time: ', value);
        console.log('Formatted Selected Time: ', dateString);
      async getData(){
        const t = this
        const res = await getPublishRecord(this.search)
        if(res.data.code == 100){
          t.data = res.data.data
          t.pagination.total = res.data.total
        }else{
          this.$message.error(res.data.msg)
        }
      },
      onOk(value) {
      openMod(type,data){
        const t = this
        getReviewDetailByWorker(data.id).then(res=>{
          if(res.data.code == 100){
            if(res.data.data){
              t.$refs.msgEdit.openMod(type,res.data.data)
            }else{
              t.$message.error('查询信息详情失败')
            }
          }else{
            this.$message.error(res.data.msg)
          }
        })
      },
      onPageChange(page, pageSize) {
        const t= this
        t.pagination.current = page
        t.search.pageIndex = page
        t.getData()
      },
      timeChange(value, dateString) {
        const t = this
        if(dateString){
          t.search.searchParams.startTime = value[0].format('YYYY-MM-DD 00:00:00')
          t.search.searchParams.endTime = value[1].format('YYYY-MM-DD 23:59:59')
        }
      },
      timeOk(value) {
        console.log('onOk: ', value);
      },
      resetSearch(){
        const t = this
        t.search = {
          pageIndex: 1,
          pageSize: 10,
          searchParams:{
            emergType: null,
            startTime: '',
            endTime: ''
          }
        }
        t.timeRange = []
        t.getData()
      },
            //弹出层
@@ -185,6 +264,13 @@
            handleOk(e) {
                this.visible = false;
            },
      getRiskName(disasterType){
        return this.riskOptions.find(i => i.value === disasterType)?.name;
      },
      getLevelName(warningLevel){
        return this.levelOptions.find(i => i.value === warningLevel)?.name;
      }
        }
        }
src/views/Admin/sameLevel.vue
@@ -2,15 +2,15 @@
  <div class="inner">
    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
      <a-col :span="4">
        <a-button type="primary" @click="editData('add',{})">新增用户</a-button>
        <a-button v-if="unittype && unittype !== null" type="primary" @click="editData('add',{})">新增用户</a-button>
      </a-col>
      <a-col :span="20">
      <a-col :span="20" v-if="unittype == null || !unittype">
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="4">
            <a-cascader :options="areaData" v-model="areaVal" placeholder="行政规划" expandTrigger="hover" changeOnSelect @change="onChange" style="width: 100%"/>
            <a-cascader :options="areaData" v-model="areaVal" placeholder="行政规划" expandTrigger="hover" :fieldNames="fieldNames" changeOnSelect @change="onChange" style="width: 100%"/>
          </a-col>
          <a-col :span="4">
            <a-button type="primary">查询</a-button>
            <a-button type="primary" @click="getUserList">查询</a-button>
            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
          </a-col>
        </a-row>
@@ -22,7 +22,7 @@
          <a-tag
              :color="unittype === 1 ? 'purple' : unittype === 2 ? 'blue' : unittype === 3 ? 'cyan' : 'green'"
          >
            {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':'村(乡、镇)级' }}
            {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':unittype==4?'村(乡、镇)级':'管理员' }}
          </a-tag>
        </template>
        <template #area="text,row">
@@ -33,17 +33,19 @@
        </template>
        <template #action="action,row">
          <a-button type="link" @click="editData('edit',row)">编辑</a-button>
          <a-button type="link" class="delBtn">删除</a-button>
          <a-button type="link" class="delBtn" @click="delData(row)">删除</a-button>
        </template>
      </a-table>
    </div>
    <same-level-mod ref="sameLevelMod" @refrech=""></same-level-mod>
    <same-level-mod ref="sameLevelMod" @refresh="getUserList"></same-level-mod>
  </div>
</template>
<script>
import {getRecipient} from '@/api/user'
import {delRecipient, delUser, getRecipient, getUser} from '@/api/user'
import sameLevelMod from "@/views/Admin/components/sameLevelMod"
import {getUserInfo} from "@/util/storage";
import {getDistrictInfo} from "@/api/login";
export default {
  name: 'sameLevel',
  components: {
@@ -52,6 +54,8 @@
  data () {
    return {
      areaVal: [],
      unittype: null,
      districtId: null,
      search:{
        pageIndex: 1,
        pageSize: 10,
@@ -102,57 +106,54 @@
        defaultCurrent: 1,
        defaultPageSize: 10,
        total: 0,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize)
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
        showTotal: total => `共 ${total} 条`
      },
      areaData: [
        {
          value: 1,
          label: '江苏省',
          children: [
            {
              value: 11,
              label: '苏州市',
              children: [
                {
                  value: 111,
                  label: '工业园区',
                },
              ],
            },
          ],
        },
        {
          value: 2,
          label: '新疆维吾尔自治区',
          children: [
            {
              value: 21,
              label: '乌鲁木齐市',
              children: [
                {
                  value: 211,
                  label: '国泰新华',
                },
              ],
            },
          ],
        },
      ]
      areaData: [],
      fieldNames:{
        label: 'name',
        value: 'id',
        children: 'children'
      }
    }
  },
  created() {
    const t = this
    t.getSameLevel()
    console.log(getUserInfo(),'id')
    t.unittype = getUserInfo().unittype
    t.districtId = getUserInfo().districtId
    t.getUserList()
    t.getDistrictInfo()
  },
  methods:{
    async getSameLevel(){
    async getUserList(){
      const t = this
      const res = await getRecipient(t.search)
      if(res.data.code == 100){
        t.tableData = res.data.data
        t.pagination.total = res.data.total
      if(t.search.searchParams.province == '' && t.search.searchParams.city == '' && t.search.searchParams.area == '' ){
        const {searchParams,...data} = t.search
        const res = await getRecipient(data)
        if(res.data.code == 100){
          t.tableData = res.data.data
          t.pagination.total = res.data.total
        }else{
          t.$message.warning(res.data.msg);
        }
      }else{
        t.$message.warning(res.data.msg);
        const res = await getRecipient(t.search)
        if(res.data.code == 100){
          t.tableData = res.data.data
          t.pagination.total = res.data.total
        }else{
          t.$message.warning(res.data.msg);
        }
      }
    },
    async getDistrictInfo(){
      let res = await getDistrictInfo()
      if(res.data.code == 100){
        this.areaData = res.data.data
      } else {
        this.$message.warning(res.data.msg);
      }
    },
@@ -176,31 +177,76 @@
      const t = this
      t.$refs.sameLevelMod.openDialog(type,data)
      t.$refs.sameLevelMod.areaData = t.areaData
      t.$refs.sameLevelMod.form.unittype = t.unittype
      t.$refs.sameLevelMod.form.districtId = t.districtId
    },
    async delData(row){
      const t = this
      this.$confirm({
        title: '提示',
        content: h => <div>是否删除该条用户信息?</div>,
        cancelText: '取消',
        okText: '确认',
        centered: true,
        async onOk() {
          let res = await delRecipient(row.id)
          if(res.data.code == 100){
            t.$message.success('删除用户信息成功');
            t.getUserList()
          }else{
            t.$message.warning(res.data.msg);
          }
        },
        onCancel() {
          console.log('Cancel');
        },
      });
    },
    // 根据id查对象
    findCodeById(data,value) {
      for (const node of data) {
        if (node.id === value) {
          return node;
        }
        if (node.children) {
          const foundNode = this.findCodeById(node.children, value);
          if (foundNode) {
            return foundNode;
          }
        }
      }
      return null;
    },
    onPageChange(page, pageSize) {
      const t= this
      t.pagination.current = page
      t.search.pageIndex = page
      t.getUserList()
    },
    onChange(value) {
      const t = this
      // t.search.searchParams.districtId = value[value.length - 1]
    },
    findAreaById(data,value) {
      for (const node of data) {
        if (node.value === value) {
          return node.label;
        }
        if (node.children) {
          const foundLabel = this.findAreaById(node.children, value);
          if (foundLabel) {
            return foundLabel;
          }
        }
      t.search.searchParams = {
        province: '',
        city: '',
        area: '',
        town: ''
      }
      return null;
    }
      if(value[0]){
        t.search.searchParams.province = t.findCodeById(t.areaData,value[0]).name
      }
      if(value[1]){
        t.search.searchParams.city = t.findCodeById(t.areaData,value[1]).name
      }
      if(value[2]){
        t.search.searchParams.area = t.findCodeById(t.areaData,value[2]).name
      }
      if(value[3]){
        t.search.searchParams.town = t.findCodeById(t.areaData,value[3]).name
      }
    },
  }
}
</script>
src/views/Admin/userManage.vue
@@ -7,7 +7,7 @@
      <a-col :span="20">
        <a-row type="flex" justify="end" :gutter="12">
          <a-col :span="4">
            <a-cascader :options="areaData" v-model="areaVal" placeholder="行政规划" expandTrigger="hover" changeOnSelect @change="onChange" style="width: 100%"/>
            <a-cascader :options="areaData" v-model="areaVal" placeholder="行政规划" expandTrigger="hover" :fieldNames="fieldNames" changeOnSelect @change="onChange" style="width: 100%"/>
          </a-col>
          <a-col :span="4">
            <a-select v-model="search.searchParams.unittype" placeholder="监管层级" style="width: 100%">
@@ -44,7 +44,7 @@
          <a-tag
              :color="unittype === 1 ? 'purple' : unittype === 2 ? 'blue' : unittype === 3 ? 'cyan' : 'green'"
          >
            {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':'村(乡、镇)级' }}
            {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':unittype==4?'村(乡、镇)级':'管理员' }}
          </a-tag>
        </template>
        <template #area="text,row">
@@ -62,8 +62,14 @@
          <a-button type="link" @click="editPwd(row)">重置密码</a-button>
        </template>
      </a-table>
<!--      <a-pagination-->
<!--          :total="85"-->
<!--          :show-total="total => `Total ${total} items`"-->
<!--          :page-size="20"-->
<!--          :default-current="1"-->
<!--      />-->
    </div>
    <user-mod ref="userMod" @refresh="getUserList"></user-mod>
    <user-mod ref="userMod" :unitType="unittype" @refresh="getUserList"></user-mod>
    <pwd-mod ref="pwdMod" @refresh="getUserList"></pwd-mod>
  </div>
</template>
@@ -72,8 +78,9 @@
import {getUser,delUser} from '@/api/user'
import userMod from "@/views/Admin/components/userMod"
import pwdMod from "@/views/Admin/components/pwdMod";
import {loginOut} from "@/api/login";
import {Session} from "@/util/storage";
import {getDistrictInfo, loginOut} from "@/api/login";
import {getUserInfo, Session} from "@/util/storage";
import Cookies from "js-cookie";
export default {
  name: 'user',
  components: {
@@ -83,6 +90,7 @@
  data () {
    return {
      areaVal: [],
      unittype: null,
      search:{
        pageIndex: 1,
        pageSize: 10,
@@ -149,57 +157,53 @@
        defaultCurrent: 1,
        defaultPageSize: 10,
        total: 0,
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize)
        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
        showTotal: total => `共 ${total} 条`
      },
      areaData: [
        {
          value: 1,
          label: '江苏省',
          children: [
            {
              value: 11,
              label: '苏州市',
              children: [
                {
                  value: 111,
                  label: '工业园区',
                },
              ],
            },
          ],
        },
        {
          value: 2,
          label: '新疆维吾尔自治区',
          children: [
            {
              value: 21,
              label: '乌鲁木齐市',
              children: [
                {
                  value: 211,
                  label: '国泰新华',
                },
              ],
            },
          ],
        },
      ]
      areaData: [],
      fieldNames:{
        label: 'name',
        value: 'id',
        children: 'children'
      }
    }
  },
  created() {
    const t = this
    t.unittype = getUserInfo().unittype
    console.log(t.unittype,'unit')
    t.getUserList()
    t.getDistrictInfo()
  },
  methods:{
    async getUserList(){
      const t = this
      const res = await getUser(t.search)
      if(res.data.code == 100){
        t.tableData = res.data.data
        t.pagination.total = res.data.total
      if(t.search.searchParams.realName == '' && t.search.searchParams.districtId == null && t.search.searchParams.unittype == null){
        const {searchParams,...data} = t.search
        const res = await getUser(data)
        if(res.data.code == 100){
          t.tableData = res.data.data
          t.pagination.total = res.data.total
        }else{
          t.$message.warning(res.data.msg);
        }
      }else{
        t.$message.warning(res.data.msg);
        const res = await getUser(t.search)
        if(res.data.code == 100){
          t.tableData = res.data.data
          t.pagination.total = res.data.total
        }else{
          t.$message.warning(res.data.msg);
        }
      }
    },
    async getDistrictInfo(){
      let res = await getDistrictInfo()
      if(res.data.code == 100){
        this.areaData = res.data.data
      } else {
        this.$message.warning(res.data.msg);
      }
    },
@@ -257,10 +261,13 @@
    onPageChange(page, pageSize) {
      const t= this
      t.pagination.current = page
      t.search.pageIndex = page
      t.getUserList()
    },
    onChange(value) {
      const t = this
      t.search.searchParams.districtId = value[value.length - 1]
      console.log(value,'val')
    },
    findAreaById(data,value) {
      for (const node of data) {
src/views/Home.vue
@@ -50,9 +50,9 @@
    import menuSider from "@/layout/menuSider";
    import TabsHeader from '@/components/TabsHeader';
  import pwdMod from "@/views/Admin/components/pwdMod";
  import { loginOut } from "@/api/login";
  import { Session } from '@/util/storage';
  import Cookies from 'js-cookie';
  import { loginOut, getDistrictInfo } from "@/api/login";
  import { Session, getUserInfo} from '@/util/storage';
  import Cookies from "js-cookie";
    export default {
        name: "Home",
        data() {
@@ -70,7 +70,8 @@
      pwdMod
        },
        created() {
      this.userInfo = JSON.parse(Cookies.get('userInfo'))
      this.userInfo = getUserInfo()
      // this.getDistrictInfo()
            const route = this.$route
            if (this.pageList.findIndex(item => item.path === route.path) === -1) {
                this.pageList.push(this.createPage(route))
@@ -138,6 +139,18 @@
          class: 'test',
        });
            },
      // async getDistrictInfo(){
      //   let res = await getDistrictInfo()
      //   if(res.data.code == 100){
      //     console.log(res.data.data)
      //     Cookies.set('district', res.data.data);
      //     console.log(Cookies.get('district'),666)
      //   } else {
      //     this.$message.warning(res.data.msg);
      //   }
      // },
            changePage(key) {
                this.activePage = key
                const page = this.pageList.find(item => item.path === key)