Newer
Older
DH_Apicture / src / views / pictureOnMap / page / PublicOpinionAnalysis / index.vue
@zhangqy zhangqy on 29 Nov 23 KB first commit
<template>
  <!-- 舆情分析 -->
  <div class="PublicOpinionAnalysis">
    <!-- 左侧 -->
    <div class="moduleBox moduleBoxLeft">
      <!-- 今日新增舆情 -->
      <div class="YqToday">
        <div class="rqTitle">今日新增舆情</div>
        <div class="rqNumContent">
          <div class="yqNumber">
            <div class="Onnumber flex flex-align-center flex-justcontent-center">
              <div class="OnnumberText" v-for="item in AllData.oneData.newsNumbers">
                <div class="OnnumberTextA">{{ item }}</div>
              </div>
            </div>
            <div class="Upnumber flex flex-align-center flex-justcontent-center">
              同比昨日:
              <span class="red" v-if="AllData.oneData.newsPercentage >= 0">
                <img :src="numOp" />
                {{ Math.abs(AllData.oneData.newsPercentage) }}%
              </span>
              <span class="green" v-else>
                <img :src="numUp" />
                {{ Math.abs(AllData.oneData.newsPercentage) }}%
              </span>
            </div>
          </div>
        </div>
      </div>
      <!-- 七日舆情统计 -->
      <div class="YqSeven">
        <div class="rqTitle flex">
          七日舆情统计
          <span>(总数:{{ AllData.sevenData.allNewsNumber }})</span>
        </div>
        <div class="rqContent" style="overflow: auto">
          <div class="listBox" v-for="item in AllData.sevenData.datalist" @click="selectSeven(item)" style="cursor: pointer">
            <div class="Yqtjabove flex">
              <div class="icon"></div>
              <div class="typepattern">
                {{ item.showName }}
              </div>
              <div class="leve4 flex flex-align-center flex-justcontent-center">{{ item.number || '0' }}条</div>
              <div :class="item.weekchain >= 0 ? 'red1' : 'green1'">
                <el-icon v-if="item.weekchain >= 0"><Top /></el-icon>
                <el-icon v-else><Bottom /></el-icon>
                {{ Math.abs(item.weekchain) || '0' }}%
              </div>
            </div>
            <div class="Yqtjbelow flex" v-if="item.proportion != '100'">
              <div class="zb" :style="{ width: `${item.proportion || '0'}%` }"></div>
              <div class="Arrows"></div>
              <div class="Wz">{{ item.proportion || '0' }}%</div>
            </div>
            <div class="Yqtjbelow flex" v-if="item.proportion == '100'">
              <div class="zb" :style="{ width: `${item.proportion || '0'}%` }">
                <div class="WzA" v-if="item.proportion == '100'">{{ item.proportion }}%</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 近30天舆情 -->
      <div class="YqThirty">
        <div class="rqTitle">
          近30天舆情增量 <span>(总数:{{ AllData.thirtyData.alldataNumber }})</span>
        </div>
        <div class="rqContent">
          <twoLine :echartData="lineData" :key="YqThirtyKey" />
        </div>
      </div>
    </div>
    <!-- 右侧 -->
    <div class="moduleBox moduleBoxRight">
      <!-- 本年舆情 -->
      <div class="YqToday">
        <div class="rqTitle">本年舆情</div>
        <div class="rqNumContent">
          <div class="yqNumber">
            <div class="Onnumber flex flex-align-center flex-justcontent-center">
              <div class="OnnumberText" v-for="item in AllData.yearData.yearNumbers">
                <div class="OnnumberTextA">{{ item }}</div>
              </div>
            </div>
            <div class="Upnumber flex flex-align-center flex-justcontent-center">
              同比上年:

              <span class="red" v-if="AllData.yearData.newsPercentage >= 0">
                <img :src="numOp" />
                {{ Math.abs(AllData.yearData.newsPercentage) }}%
              </span>
              <span class="green" v-else>
                <img :src="numUp" />
                {{ Math.abs(AllData.yearData.newsPercentage) }}%
              </span>
            </div>
          </div>
        </div>
      </div>
      <!-- 待处理舆情 -->
      <div class="DclYq">
        <div class="rqTitle">
          待处理舆情跟踪<span>(总数:{{ AllData.pendingData.length }})</span>
        </div>
        <div class="rqContent">
          <div class="sevenPublic">
            <div class="hader">
              <div class="tableHeaderList tableList1">舆情名称</div>
              <div class="tableHeaderList tableList2">舆情类型</div>
              <div class="tableHeaderList tableList3">跟踪情况</div>
            </div>

            <div class="ListBox">
              <div class="tableBodyList flex" v-for="(item, index) in AllData.pendingData" :key="index">
                <div class="tableBodyList_span1" :title="item.title">
                  {{ item.title }}
                </div>
                <div class="tableBodyList_span2">
                  {{ getChineseFun(AllData.typeList, 'wordCode', item.keywordsSecondary, 'showName') }}
                </div>
                <div class="tableBodyList_span3">待反馈</div>
              </div>

              <div v-if="AllData.pendingData.length == ''" class="flex flex-align-center flex-justcontent-center">暂无数据</div>
            </div>
          </div>
        </div>
      </div>
      <!-- 舆情来源 -->
      <div class="YqLy">
        <div class="rqTitle">
          舆情来源分布<span>(总数:{{ AllData.YqlyData.allnewsnumber }})</span>
        </div>
        <div class="rqContent">
          <ChartRy2 :echartData="ryData" :key="ryRefresh" @newsType="newsType" />
        </div>
      </div>
    </div>
    <!-- 中间 -->
    <div class="BoxContent">
      <!-- 近一年舆情统计 -->
      <div class="YqOneYear">
        <div class="rqTitleA flex">
          近一年舆情统计<span>(总数:{{ AllData.yearChart.allnumber }})</span>
        </div>
        <div class="YqOneYearContent">
          <ChartBar :key="refreshOneY" :echartData="echartData" />
        </div>
      </div>
      <!-- 舆情跟踪管理 -->
      <div class="YqTrack">
        <div class="rqTitleA">
          舆情跟踪管理<span>(总数:{{ total }})</span>
          <div class="TabList flex flex-align-center flex-justcontent-center">
            <div style="width: 35%">
              <div class="tabData flex">
                <div
                  class="eachClick"
                  :class="tabActive == item.value ? 'active' : ''"
                  v-for="item in rightTabArr"
                  :key="item.value"
                  @click="rightTabClick('day', item)"
                >
                  {{ item.label }}
                </div>
              </div>
            </div>
            <div style="width: 31%">
              <div class="tabData flex">
                <div
                  class="eachClick"
                  :class="tabActive2 == item.value ? 'active' : ''"
                  v-for="item in rightTabArr2"
                  :key="item.value"
                  @click="rightTabClick('active', item)"
                >
                  {{ item.label }}
                </div>
              </div>
            </div>
            <div style="width: 31%">
              <el-form class="drainageResponseBox">
                <el-select
                  v-model="AllData.queryParams.mainwords"
                  size="small"
                  @change="Kschange"
                  style="width: 95%"
                  placeholder="请选择类型"
                >
                  <el-option
                    v-for="(item, index) in AllData.typeList"
                    :key="index"
                    :label="item.showName"
                    :value="item.wordCode"
                  ></el-option>
                </el-select>
              </el-form>
            </div>
            <div @click="resetTable" style="cursor: pointer" title="重置">
              <el-icon class="aaa"><RefreshLeft /></el-icon>
            </div>
          </div>
        </div>
        <div class="YqTracContent">
          <el-table :data="tableData" height="100%" class="dispatchTable" stripe>
            <el-table-column prop="title" label="标题">
              <template #default="scope">
                <div class="tableLiName" :title="scope.row.title" @click="newsOpen(scope.row)">{{ scope.row.title }}</div>
              </template>
            </el-table-column>
            <el-table-column prop="publishTime" label="日期" />
            <el-table-column prop="keywordsSecondary" label="类型">
              <template #default="scope">
                {{ getChineseFun(AllData.typeList, 'wordCode', scope.row.keywordsSecondary, 'showName') }}
              </template>
            </el-table-column>
            <el-table-column prop="fromWhere" label="来源" />
            <el-table-column prop="publisher" label="发布单位" show-overflow-tooltip />
            <el-table-column label="操作" width="170" align="center">
              <template #default="scope">
                <el-button type="primary" link @click="rowIgnore(scope.row)" v-if="scope.row.isIgnore == 0">忽略</el-button>
                <el-button type="primary" link @click="rowFollow(scope.row)" v-if="scope.row.isCare == 0">加关注</el-button>
                <el-button class="greening" link disabled v-if="scope.row.isCare == 1">已关注</el-button>
                <el-button type="primary" link @click="rowUpdate(scope.row)" v-if="scope.row.isFeedback == 0">分派</el-button>
                <el-button type="primary" link disabled v-if="scope.row.isFeedback == 1">待反馈</el-button>
                <el-button class="greening" link disabled v-if="scope.row.isFeedback == 2">已反馈</el-button>
              </template>
            </el-table-column>
          </el-table>
          <!-- 分页 -->
          <pagination
            v-show="total > 0"
            :total="total"
            v-model:page="AllData.queryParams.pageNum"
            v-model:limit="AllData.queryParams.pageSize"
            @pagination="getYqGzData"
          />
        </div>
      </div>
    </div>
    <!-- 分派对话框 -->
    <el-dialog
      title="舆情分派"
      v-model="openFp"
      width="800px"
      class="publicDialog"
      :show-close="false"
      :close-on-click-modal="false"
    >
      <div class="publicDBox">
        <div class="info">
          <div class="boxName">舆情基本情况</div>
          <div class="list">
            <div class="box">
              <div class="title">新闻所属分类</div>
              <div class="flex10">{{ AllData.popData.keywordsMain }}</div>
            </div>
            <div class="box">
              <div class="title">网站地址</div>
              <div class="flex10">
                <a :href="AllData.popData.url" target="_blank">{{ AllData.popData.url }}</a>
              </div>
            </div>
          </div>
          <div class="list">
            <div class="box">
              <div class="title">网站来源</div>
              <div class="flex10">{{ AllData.popData.fromWhere }}</div>
            </div>
            <div class="box">
              <div class="title">网站名称</div>
              <div class="flex10">{{ AllData.popData.publisher }}</div>
            </div>
          </div>
          <div class="list">
            <div class="box">
              <div class="title">采集时间</div>
              <div class="flex10">{{ AllData.popData.publishTime }}</div>
            </div>
            <div class="box">
              <div class="title">所属分类</div>
              <div class="flex10">{{ AllData.popData.keywordsSecondary }}</div>
            </div>
          </div>
        </div>
        <div class="info">
          <div class="boxName">问题督促处理</div>
          <el-form ref="ruleForm" :model="AllData.queryParams2" :rules="AllData.rules" label-width="150px">
            <el-form-item label="责任单位:" prop="xesponsibilityunit" style="width: 100%">
              <el-tree-select
                style="width: 100%"
                v-model="AllData.queryParams2.xesponsibilityunit"
                :data="deptList"
                placeholder="请选择责任单位"
                node-key="deptId"
                filterable
                :render-after-expand="false"
                clearable
                collapse-tags-tooltip
                :multiple="false"
                :props="{
                  value: 'deptId',
                  label: 'deptName',
                  children: 'children',
                }"
                @node-click="handleNodeClick"
              />
            </el-form-item>

            <el-form-item label="处理人:" prop="feedbackuser" style="width: 100%">
              <el-select placeholder="请选择处理人" v-model="AllData.queryParams2.feedbackuser" style="width: 100%">
                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId"></el-option>
              </el-select>
            </el-form-item>
            <!-- 
            <el-form-item label="处理方式:" prop="infoxmationHandType" style="width: 100%">
              <el-select placeholder="请选择处理方式" v-model="AllData.queryParams2.infoxmationHandType">
                <el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId"></el-option>
              </el-select>
            </el-form-item> -->

            <el-form-item label="最迟反馈时间:" prop="lastFeedbackTime" style="width: 100%">
              <el-date-picker
                style="width: 100%"
                v-model="AllData.queryParams2.lastFeedbackTime"
                :default-time="defaultTime"
                type="datetime"
                placeholder="请选择最迟反馈时间"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
              />
            </el-form-item>
          </el-form>
        </div>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">下发</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<script setup name="PublicOpinionAnalysis">
import bus from '@/bus';
import {
  querySevenDayNews,
  queryThirtyDayNews,
  queryTodayAddNews,
  queryYearsNews,
  queryYearsNewsCharts,
  informationWuhanPaishuiPage,
  queryAllnewsClass,
  queryAllnewsUpdate,
  informationWuhanPaishuiList,
  queryAllnewsNewsFreeback,
  queryClassType,
  listDept,
  listUser,
} from '@/api/DP_api/sentiment';
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
import twoLine from './components/twoLine.vue';
import ChartRy2 from './components/ChartRy.vue';
import ChartBar from './components/ChartBar.vue';
import numUp from '@/assets/images/pictureOnMap/numUp_icon.png'; //上升
import numOp from '@/assets/images/pictureOnMap/numDn_icon.png'; //下降
import { getChineseFun } from '@/utils/util.js';
const { proxy } = getCurrentInstance();
const total = ref(0);
const openFp = ref(false);
const tableData = ref([]);
const YqThirtyKey = ref('1');
const refreshOneY = ref('1');
const ryRefresh = ref('1');
const AllData = reactive({
  oneData: {},
  sevenData: {},
  thirtyData: {},
  yearChart: {},
  yearData: {},
  YqlyData: {},
  pendingData: {},
  popData: {},
  typeList: [],
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    isIgnore: '0',
    fromWhere: '',
    mainwords: '',
    startTime: '',
    endTime: '',
    isCare: '',
    isFeedback: '',
  },
  queryParams2: {
    xesponsibilityunit: '',
    feedbackuser: '',
    infoxmationHandType: '',
    lastFeedbackTime: '',
  },
  rules: {
    xesponsibilityunit: [{ required: true, message: '请选择预警开始时间', trigger: 'blur' }],
    feedbackuser: [{ required: true, message: '请选择预警结束时间', trigger: 'blur' }],
    lastFeedbackTime: [{ required: true, message: '请选择最迟反馈时间', trigger: 'blur' }],
  },
});
const ryData = ref({});
const echartData = ref({});
const lineData = ref({
  tabX: [],
  series: [
    {
      name: '网页',
      tabY: [],
    },
    {
      name: '质讯',
      tabY: [],
    },
    {
      name: '微信',
      tabY: [],
    },
  ],
});
// 今日新增舆情
const getJrYq = item => {
  queryTodayAddNews().then(res => {
    AllData.oneData = res.data;
  });
};
//   七日舆情统计
const getSevenYq = item => {
  querySevenDayNews().then(res => {
    AllData.sevenData = res.data;
  });
};
// 本年舆情
const getThisYearYq = item => {
  queryYearsNews().then(res => {
    AllData.yearData = res.data;
  });
};
// 近30天舆情增量
const getthirtyYq = item => {
  queryThirtyDayNews().then(res => {
    YqThirtyKey.value++;
    AllData.thirtyData = res.data;
    lineData.value.tabX = AllData.thirtyData.timelist;
    lineData.value.series[0].tabY = AllData.thirtyData.wangyelist;
    lineData.value.series[1].tabY = AllData.thirtyData.zixunlist;
    lineData.value.series[2].tabY = AllData.thirtyData.weixinlist;
  });
};
// 舆情来源点击事件
async function newsType(data) {
  AllData.queryParams.fromWhere = data;
  getYqGzData();
}
// 七日舆情统计点击事件
function selectSeven(data) {
  AllData.queryParams.mainwords = data.wordCode;
  getYqGzData();
}
// 舆情来源分布
function getData() {
  let YQnumber = [];
  let YQfromwhere = [];
  queryAllnewsClass().then(res => {
    AllData.YqlyData = res.data;
    AllData.YqlyData.datalist.forEach(item => {
      YQnumber.push(item.number);
      YQfromwhere.push(item.fromwhere);
    });
  });
  setTimeout(() => {
    ryRefresh.value++;
    let obj = {
      xData: YQfromwhere,
      data: YQnumber,
      num: [],
      Maximum: '',
    };
    let max = JSON.parse(JSON.stringify(obj.data));
    let one = max.sort((a, b) => b - a)[0];
    obj.Maximum = one;
    max.forEach(i => {
      obj.num.push(one);
    });
    ryData.value = obj;
  }, 1000);
}
// 近一年舆情统计
function getOneYearData() {
  queryYearsNewsCharts().then(res => {
    AllData.yearChart = res.data;
    console.log(AllData.yearChart, ' AllData.yearChart AllData.yearChart AllData.yearChart');
  });
  setTimeout(() => {
    refreshOneY.value++;
    let obj = {
      xAxis: AllData.yearChart.timelist,
      seriesData: AllData.yearChart.datalist,
      num: [],
      Maximum: '',
    };
    let max = JSON.parse(JSON.stringify(obj.seriesData));
    let one = max.sort((a, b) => b - a)[0];
    obj.Maximum = one;
    max.forEach(i => {
      obj.num.push(one);
    });
    echartData.value = obj;
  }, 1000);
}
// 待处理舆情
function getDclYqData() {
  informationWuhanPaishuiList({ isFeedback: 1 }).then(res => {
    AllData.pendingData = res.data;
  });
}
// 下拉框
function getdropdown() {
  queryClassType().then(res => {
    AllData.typeList = res.data;
  });
}
//下拉框事件
function Kschange(val) {
  getYqGzData();
}

// 重置
function resetTable() {
  AllData.queryParams.pageNum = 1;
  AllData.queryParams.pageSize = 10;
  AllData.queryParams.isIgnore = '0';
  AllData.queryParams.fromWhere = '';
  AllData.queryParams.mainwords = '';
  AllData.queryParams.startTime = '';
  AllData.queryParams.endTime = '';
  AllData.queryParams.isCare = '';
  AllData.queryParams.isFeedback = '';
  // AllData.queryParams = {};
  tabActive.value = '';
  tabActive2.value = '';
  getYqGzData();
}

//舆情跟踪管理
async function getYqGzData() {
  informationWuhanPaishuiPage(AllData.queryParams).then(res => {
    tableData.value = res.data;
    total.value = res.total;
  });
}
function newsOpen(data) {
  window.open(data.url);
}
const tabActive = ref('');
const tabActive2 = ref('');
const rightTabArr = ref([
  {
    label: '最近7日',
    value: '1',
  },
  {
    label: '最近30天',
    value: '2',
  },
]);
const rightTabArr2 = ref([
  {
    label: '已关注',
    value: '1',
  },
  {
    label: '已反馈',
    value: '2',
  },
]);
const rightTabClick = (type, tab) => {
  if (type == 'day') {
    tabActive.value = tab.value;
    if (tabActive.value == 1) {
      AllData.queryParams.endTime = proxy.moment(new Date().getTime()).format('YYYY-MM-DD HH:mm:ss');
      AllData.queryParams.startTime = proxy.moment().add(-7, 'd').format('YYYY-MM-DD HH:mm:ss');
    }
    if (tabActive.value == 2) {
      AllData.queryParams.endTime = proxy.moment(new Date().getTime()).format('YYYY-MM-DD HH:mm:ss');
      AllData.queryParams.startTime = proxy.moment().add(-30, 'd').format('YYYY-MM-DD HH:mm:ss');
    }
  } else if (type == 'active') {
    tabActive2.value = tab.value;
    if (tabActive2.value == 1) {
      AllData.queryParams.isCare = 1;
      AllData.queryParams.isFeedback = null;
    }
    if (tabActive2.value == 2) {
      AllData.queryParams.isCare = null;
      AllData.queryParams.isFeedback = 2;
    }
  }
  getYqGzData();
};
// 忽略点击事件
function rowIgnore(val) {
  let params = {
    id: val.id,
    isIgnore: 1,
  };
  proxy.$modal
    .confirm('确认要忽略本舆情新闻吗?忽略后的舆情新闻将不在系统进行展示,但仍然可以通过后台管理进行导出和查看。')
    .then(function () {
      return queryAllnewsUpdate(params);
    })
    .then(() => {
      proxy.$modal.msgSuccess('已忽略~');
      getYqGzData();
    })
    .catch(() => {});
}
// 加关注点击事件
function rowFollow(val) {
  let params = {
    id: val.id,
    isCare: 1,
  };
  queryAllnewsUpdate(params).then(res => {
    if (res.code == 200) {
      proxy.$modal.msgSuccess('已关注!');
      getYqGzData();
    }
  });
}
// 分派点击事件
function rowUpdate(data) {
  openFp.value = true;
  AllData.popData = data;
  getSelect();
}
const deptList = ref([]);
const getSelect = () => {
  listDept().then(res => {
    if (res.code === 200) {
      if (res.data?.length > 0) {
        deptList.value = proxy.handleTree(res.data, 'deptId');
        console.log('新的接收人11', deptList.value);
      }
    }
  });
};
/** 节点单击事件 */
function handleNodeClick(data) {
  console.log(data.deptId, ' data.id');
  getListUser(data.deptId);
  AllData.queryParams2.feedbackuser = '';
}
//获取所有人员
const userList = ref([]);
function getListUser(val) {
  listUser({ deptId: val }).then(res => {
    userList.value = res.data;
  });
}
// 下发 点击
function submitForm() {
  proxy.$refs['ruleForm'].validate(valid => {
    AllData.queryParams2.isCare = 1;
    AllData.queryParams2.id = AllData.popData.id;
    console.log(AllData.queryParams2, '11111');
    if (valid) {
      proxy.$modal
        .confirm(
          '确认要派发处理本舆情新闻吗?派发后系统将自动通过语音呼叫提醒到处理人员,并且本条新闻将自动进行关注,确认操作吗?'
        )
        .then(function () {})
        .then(() => {
          proxy.$modal.msgSuccess('下发成功');
          openFp.value = false;
          AllData.queryParams2 = {};
          userList.value = [];
          getYqGzData();
        })
        .catch(() => {});
    }
  });
}
// 取消
function cancel() {
  proxy.resetForm('ruleForm');
  userList.value = [];
  openFp.value = false;
}

onMounted(() => {
  setTimeout(() => bus.emit('YQ_head', false), 100);
  getYqGzData();
  getdropdown();
  getJrYq();
  getSevenYq();
  getthirtyYq();
  getData();
  getThisYearYq();
  getOneYearData();
  getDclYqData();
});
</script>
<style lang="scss" scoped>
@import '@/assets/styles/PublicOpinionAnalysis.scss';
</style>