This commit is contained in:
lcw
2025-11-22 21:59:58 +08:00
parent ea3022c3f6
commit 93c49dff27
661 changed files with 195357 additions and 2160 deletions

View File

@ -34,8 +34,9 @@
</h3>
</template>
<div class="grid-container">
<div v-for="(item,index) in listQuery.ossList" class="grid-item" :key="index">
<el-image :src="setAddress(item.id)" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :preview-src-list="srcList"
<el-image :src="setAddress(item.fjZp)" :zoom-rate="1.2" :max-scale="7" :min-scale="0.2" :preview-src-list="srcList"
show-progress :initial-index="4" fit="cover">
<template #error>
<div class="image-slot">
@ -102,6 +103,8 @@ const listQuery = ref({})
const srcList = ref([])
const getDataById = (id) => {
qcckGet({}, '/mosty-gsxt/tbGsxtBk/selectVoById/' + id).then(res => {
console.log(res);
listQuery.value=res
srcList.value=res.ossList.map(v=>setAddress(v.id))
})

View File

@ -2,7 +2,7 @@
<div>
<div class="titleBox">
<PageTitle title="重点车辆管理">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
</template>
@ -23,7 +23,7 @@
</div>
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle"><CirclePlus /></el-icon>
<span style="vertical-align: middle">新增</span>

View File

@ -2,7 +2,7 @@
<div>
<div class="titleBox">
<PageTitle title="重点群体管理">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请
</el-button>
@ -25,8 +25,8 @@
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary">导入</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<!-- <el-button size="small" type="primary">导入</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', null)">
<el-icon style="vertical-align: middle">
<CirclePlus />

View File

@ -2,7 +2,7 @@
<div>
<div class="titleBox">
<PageTitle title="重点群体管理">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请
</el-button>
@ -26,8 +26,8 @@
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary" >导入</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<!-- <el-button size="small" type="primary" >导入</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', null)">
<el-icon style="vertical-align: middle">
<CirclePlus />

View File

@ -2,7 +2,7 @@
<div>
<div class="titleBox">
<PageTitle title="重点群体审核">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请
</el-button>
@ -24,7 +24,7 @@
</div>
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', null)">
<el-icon style="vertical-align: middle">
<CirclePlus />
@ -39,12 +39,12 @@
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
@chooseData="chooseData"
>
@ -60,13 +60,13 @@
<li class="one_text_detail">创建时间{{ row.xtCjsj }}</li>
</ul>
</div>
</template>
<template #bqList="{ row }">
<ul >
<ul >
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </li>
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </li>
</ul>
</ul>
</template>

View File

@ -100,7 +100,10 @@ import VisitRecord from '../model/visitRecord.vue'
import CaseInfo from '../model/caseInfo.vue'
import ActualPerformance from '../model/actualPerformance.vue'
import CzModel from '../model/czModel.vue'
import { ref, onUnmounted ,getCurrentInstance} from "vue";
import { useRouter, useRoute } from 'vue-router'
import { ref, onUnmounted, getCurrentInstance } from "vue";
const router = useRouter()
const route = useRoute()
const { proxy } = getCurrentInstance();
const emit = defineEmits(["updateDate"]);
const chooseMarksVisible = ref(false);
@ -218,8 +221,15 @@ const submit = async () => {
// 关闭
const close = () => {
if (route.query.id) {
const query = { ...route.query };
delete query.id;
router.replace({ query });
}
dialogForm.value = false;
loading.value = false;
emit('updateDate')
};
defineExpose({ init });

View File

@ -2,16 +2,16 @@
<div>
<div class="titleBox">
<PageTitle title="重点人管理">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
</template>
<div class="flex just-center">
<el-button size="small" type="primary" v-for="it in D_GS_BK_SQLX" :key="it.dm"
@click="handleApplication(it)">{{it.zdmc }}</el-button>
@click="handleApplication(it)">{{ it.zdmc }}</el-button>
</div>
</el-popover>
<el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
</el-popover> -->
<!-- <el-popover placement="bottom" :visible="visiblefp" :width="400" trigger="click">
<template #reference>
<el-button size="small" type="primary" @click="(visiblefp = !visiblefp), (visible = false)">指定分配</el-button>
</template>
@ -22,10 +22,10 @@
<el-button type="primary" @click="handlefp" size="small">分配</el-button>
</div>
</div>
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary" >导入</el-button>
</el-popover> -->
<!-- <el-button size="small" type="primary" @click="handleZxs">转线索</el-button> -->
<!-- <el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
<!-- <el-button size="small" type="primary">导入</el-button> -->
<el-button type="primary" size="small" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle">
<CirclePlus />
@ -81,8 +81,10 @@
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="handleremove(row.id)">移除</el-link>
<el-link size="small" type="success" v-if="row.zdrZt == '01'||row.zdrZt == '03'" @click="handleSend(row.id)">送审</el-link>
<el-link size="small" type="primary" v-if="row.zdrZt == '01'||row.zdrZt == '03'" @click="addEdit('edit', row)">编辑</el-link>
<el-link size="small" type="success" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
@click="handleSend(row.id)">送审</el-link>
<el-link size="small" type="primary" v-if="row.zdrZt == '01' || row.zdrZt == '03'"
@click="addEdit('edit', row)">编辑</el-link>
<el-link size="small" type="primary" @click="addEdit('detail', row)">详情</el-link>
<el-link size="small" type="danger" @click="deleteRow(row.id)">删除</el-link>
</template>
@ -114,6 +116,9 @@ import Search from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick } from "vue";
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const { proxy } = getCurrentInstance();
const { D_GS_ZDQT_ZT, D_GS_ZDR_RYJB, D_BZ_XB, D_BZ_MZ, D_BZ_XZQHDM, D_GS_ZDR_BK_ZT, D_GS_ZDR_CZZT, D_GS_BQ_ZL, D_GS_BQ_LB, D_GS_BQ_LX, D_GS_ZDR_YJDJ, D_GS_BK_SSJZ, D_GS_BK_SQLX, D_BZ_SF, D_GS_XS_LY, D_BZ_SSZT, D_GS_XS_LX, D_GS_XS_QTLX } =
proxy.$dict("D_GS_ZDQT_ZT", "D_GS_ZDR_RYJB", "D_BZ_XB", "D_BZ_MZ", "D_BZ_XZQHDM", "D_GS_ZDR_BK_ZT", "D_GS_ZDR_CZZT", "D_GS_BQ_ZL", "D_GS_BQ_LB", "D_GS_BQ_LX", "D_GS_ZDR_YJDJ", "D_GS_BK_SSJZ", "D_GS_BK_SQLX", "D_BZ_SF", "D_GS_XS_LY", "D_BZ_SSZT", "D_GS_XS_LX", "D_GS_XS_QTLX");
@ -191,8 +196,14 @@ const pageData = reactive({
});
onMounted(() => {
getList();
tabHeightFn();
tabHeightFn();
if (route.query.id) {
addEdit('x', {
id: route.query.id
})
}else{
getList();
}
});
// 搜索
@ -215,7 +226,8 @@ const changeSize = (val) => {
const getList = () => {
pageData.tableConfiger.loading = true;
// 人员类型D_ZDRY_RYLX(01 重点 02 普通〉
let data = { rylx: '01', ...pageData.pageConfiger, ...queryFrom.value };
// rylx: '01',
let data = {...pageData.pageConfiger, ...queryFrom.value };
qcckGet(data, "/mosty-gsxt/tbGsxtZdry/selectPage").then((res) => {
pageData.tableData = res.records || [];
pageData.total = res.total;

View File

@ -69,7 +69,7 @@ const rules = reactive({
ryJg: [{ required: true, message: "请选择籍贯", trigger: "change" }],
zdrRyjb: [{ required: true, message: "请选择人员级别", trigger: "change" }],
zdrYjdj: [{ required: true, message: "请选择预警等级", trigger: "change" }],
rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
// rylx: [{ required: true, message: "请选择人员类型", trigger: "change" }]
});
const listQuery = ref({ ryLxdh: [""] }); //表单
const chooseMarksVisible = ref(false); // 控制标签选择弹窗显示
@ -90,19 +90,19 @@ const formData = ref([
{ label: "出生日期", prop: "ryCsrq", type: "date" },
{ label: "户籍地区划", prop: "hjdQh", type: "select", options: D_BZ_XZQHDM },
{ label: "户籍地详址", prop: "hjdXz", type: "input" },
{ label: "户籍地派出所", prop: "hjdPcsdm", type: "department" },
{ label: "户籍地派出所", prop: "hjdPcsdm",depMc:"hjdPcsmc" ,type: "department" },
{ label: "现住地区划", prop: "xzdQh", type: "select", options: D_BZ_XZQHDM },
{ label: "现住地详址", prop: "xzdXz", type: "input" },
{ label: "现住地派出所", prop: "xzdPcsdm", type: "department" },
{ label: "现住地派出所", prop: "xzdPcsdm",depMc:"xzdPcsmc" ,type: "department" },
{ label: "管辖单位", prop: "gxSsbmdm", depMc: 'gxSsbmmc', type: "department" },
{ label: "诉求单位", prop: "sqSsbmdm", depMc: 'sqSsbmmc', type: "department" },
{ label: "责任单位", prop: "zrSsbmdm", depMc: 'zrSsbmmc', type: "department" },
{ label: "所属警种", prop: "zdrSsjz", type: "select", options: D_GS_BK_SSJZ },
{ label: "涉及警种", prop: "zdrSjjz", type: "select", options: D_GS_BK_SSJZ, multiple: true },
{ label: "婚姻状态", prop: "hyzk", type: "select", options: D_BZ_HYZK },
{ label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
{ label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
{ label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
// { label: "处置状态", prop: "zdrCzzt", type: "select", options: D_GS_ZDR_CZZT },
// { label: "布控状态", prop: "zdrBkZt", type: "select", options: D_BZ_RCBKZT },
// { label: "人员类型", prop: "rylx", type: "select", options: D_ZDRY_RYLX },
{ label: "入库开始时间", prop: "zdrRkkssj", type: "datetime" },
{ label: "入库结束时间", prop: "zdrRkjssj", type: "datetime" },
{ label: "Mac地址", prop: "macDz", type: "input" },

View File

@ -2,7 +2,7 @@
<div>
<div class="titleBox">
<PageTitle title="重点人审批">
<el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<!-- <el-popover placement="bottom" :visible="visible" :width="400" trigger="click">
<template #reference>
<el-button type="primary" @click="(visible = !visible), (visiblefp = false)" size="small">布控申请</el-button>
</template>
@ -23,7 +23,7 @@
</div>
</el-popover>
<el-button size="small" type="primary" @click="handleZxs">转线索</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button>
<el-button size="small" type="primary" @click="handleMove">移交管控</el-button> -->
</PageTitle>
</div>
<!-- 搜索 -->
@ -56,7 +56,7 @@
</template>
<template #bqList="{ row }">
<ul >
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </li>
<li class="one_text_detail marks mb4" :key="index" v-for="(item, index) in row.bqList">{{ item.bqMc }}({{ item.bqFz || 0 }} ) </li>
</ul>
</template>

View File

@ -138,13 +138,11 @@ const init = (row) => {
listQuery.value = res
})
};
watch(() => approvalEcho.value, (val) => {
if (val) {
approvalEcho.value.getWorkflow(listQuery.value.gzlid)
}
}, { deep: true })
// 关闭
const close = () => {
dialogForm.value = false;

View File

@ -1,16 +1,17 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">警务工作{{ title }}</span>
<span class="title">{{ titleData }}{{ title }}</span>
<div>
<el-button @click="submitForm()" type="primary">保存</el-button>
<el-button @click="close">关闭</el-button>
</div>
</div>
<div style="display: flex;width: 100%;" v-loading="loading">
<div style="display: flex;width: 100%;" v-loading="loading">
<div class="form_cnt">
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #gapdive>
<div style="width: 100%;height: 10px;" class="mb20">
<el-divider content-position="left">基础信息</el-divider>
</div>
@ -30,15 +31,15 @@
</template>
</FormMessage>
<el-divider content-position="left"><span class="mr20">活跃人员</span> </el-divider>
<Personnel :dict="props.dict" ref="personnel" :perList="listQuery.ryList"/>
<Personnel :dict="props.dict" ref="personnel" :perList="listQuery.ryList" />
<el-divider content-position="left"><span class="mr20">车辆信息</span> </el-divider>
<VehicleCar :dict="props.dict" ref="vehicleCar" :clList="listQuery.clList"/>
<VehicleCar :dict="props.dict" ref="vehicleCar" :clList="listQuery.clList" />
<el-divider content-position="left"><span class="mr20">关联群体</span> </el-divider>
<Group :dict="props.dict" ref="group" :qtList="listQuery.qtList" />
</div>
<div class="person" v-if="showPj">
<!-- <div class="person" v-if="showPj&&listQuery.qbjb!='00'">
<AddForm ref="addForm" :dict="props.dict" :msgeDat="msgeDat" />
</div>
</div> -->
</div>
</div>
</template>
@ -50,14 +51,18 @@ import VehicleCar from '../components/vehicleCar/index.vue'
import Group from '../components/group/index.vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qbcjAdd, qbcjUpdate, qbcjSelectByid } from "@/api/Intelligence.js";
import { ref, defineExpose, onMounted, defineEmits, watch } from "vue";
import { ref, defineExpose, onMounted, defineEmits, watch } from "vue";
import AddForm from '@/views/backOfficeSystem/MakeAcomment/components/a/addForm.vue'
import {useRoute,useRouter} from 'vue-router'
const emit = defineEmits(["getList"]);
const props = defineProps({
dict: Object
dict: Object,
titleData: {
type: String,
default: ""
}
});
const loading=ref(false)
const loading = ref(false)
const dialogForm = ref(false); //弹窗
const formData = ref();
watch(() => dialogForm.value, (val) => {
@ -66,8 +71,8 @@ watch(() => dialogForm.value, (val) => {
{ prop: "gapdive", type: "slot", width: '100%' },
{ label: "情报标题", prop: "qbmc", type: "input", width: '45%' },
{ label: "情报类型", prop: "qblx", type: "select", options: props.dict.D_GS_XS_LX, width: '45%' },
{ label: "情报级", prop: "qbmj", type: "select", options: props.dict.D_BZ_BMJB, width: '45%' },
{ label: "情报来源", prop: "qbly", type: "select", options: props.dict.D_GS_XS_LY, width: '45%' },
{ label: "情报级", prop: "qbmj", type: "select", options: props.dict.D_BZ_BMJB, width: '45%' },
// { label: "情报来源", prop: "qbly", type: "select", options: props.dict.D_GS_XS_LY, width: '45%' },
{ label: "情报上报时间", prop: "sxsbsj", type: "datetime", width: '45%' },
{ label: "指向时间", prop: "zxkssj", type: "datetime", width: '45%' },
{ label: "指向地址", prop: "zxdz", type: "input", width: '45%' },
@ -118,12 +123,16 @@ const submitForm = () => {
loading.value = true
elform.value.submit(valid => {
if (valid) {
const promes = {
...listQuery.value,
fjdz: fjdz.value.length > 0 ? fjdz.value.join(',') : '',
ryList: personnel.value.listData() || [],
clList: vehicleCar.value.listData() || [],
qtList:group.value.listData() || [],
qtList: group.value.listData() || [],
cjLx: 0
}
if (title.value == '新增') {
qbcjAdd(promes).then((res) => {
@ -143,8 +152,15 @@ const submitForm = () => {
}
})
}
const route = useRoute()
const router = useRouter()
// 关闭
const close = () => {
if (route.query.id) {
const query = { ...route.query };
delete query.id;
router.replace({ query });
}
fjdz.value = []
listQuery.value = {};
dialogForm.value = false;

View File

@ -1,7 +1,7 @@
<template>
<div>
<div class="titleBox">
<PageTitle title="警务工作管理">
<PageTitle :title="titleData">
<el-button type="primary" @click="addEdit('add')">
<el-icon style="vertical-align: middle">
<CirclePlus />
@ -14,6 +14,18 @@
</el-icon>
<span style="vertical-align: middle">导出</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="batchMark(ids)" v-if="qxkz.deptLevel == '01'">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle" >批量打标</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="handleSumbit(ids)" v-if="qxkz.deptLevel != '01'">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">批量上报</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)">
<el-icon style="vertical-align: middle">
<CirclePlus />
@ -35,63 +47,34 @@
<template #qblx="{ row }">
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
</template>
<template #qbly="{ row }">
<DictTag :tag="false" :value="row.qbly" :options="D_GS_XS_LY" />
<template #cjlx="{ row }">
<DictTag :tag="false" :value="row.cjLx" :options="D_BZ_CJLX" />
</template>
<!-- <template #czzt="{row}">
<DictTag :tag="false" :value="row.czzt" :options="D_GS_XS_CZZT" />
</template> -->
<template #shzt="{ row }">
<!-- 采纳将这条信息推送到情报管理,退回 -->
<DictTag :tag="false" :value="row.shzt" :options="D_BZ_XSSHZT" @clickTag="clickTag(row.shzt)" />
<template #czzt="{ row }">
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<!-- 01 提交 02 上报 03 采纳 04 退回 05 打标签v-if="qxkz.deptLevel == '01'" -->
<el-link size="small" type="primary" v-if="row.czzt == '02'&&qxkz.deptLevel == '01'" @click="cnMsg(row)">采纳</el-link>
<el-link size="small" type="primary" v-if="row.czzt == '03'&&qxkz.deptLevel == '01'" @click="opneMsg(row)">打标签</el-link>
<el-link size="small" type="primary" @click="rollbackNewspapers(row)"
v-if="row.czzt == '02' && row.qbjb == '00'" >回退</el-link>
<el-link size="small" type="primary" @click="checkProcess(row)">查看流程</el-link>
<el-link size="small" type="primary" @click="appearNewspapers(row)"
v-if="row.czzt == '01' || row.czzt == '04' && row.qbjb == '00'&&qxkz.deptLevel != '01'">上报</el-link>
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<el-link size="small" type="primary" @click="addEdit('edit', row)">修改</el-link>
<!-- <el-link size="small" type="primary" @click="addEdit('edit', row)">下发指令</el-link> -->
<el-popconfirm title="是否进行发布?" @confirm="confirm(row)">
<template #reference>
<el-link size="small" type="primary">发布</el-link>
</template>
</el-popconfirm>
<el-popover placement="left" :visible="row.visible" :width="400" trigger="click">
<template #reference>
<el-link size="small" type="primary" @click.stop="handleSh(row)">转线索</el-link>
</template>
<div class="flex mb10 align-center">
<div class="w70 label-pop">状态 :</div>
<div style="flex:1">
<el-radio-group v-model="chooseRow.shzt" @change="rules.bhyy = false">
<el-radio v-for="obj in D_BZ_XSSHZT" :key="obj.value" :label="obj.value">{{ obj.zdmc }}</el-radio>
</el-radio-group>
</div>
</div>
<div class="flex" v-if="chooseRow.shzt == '01'">
<div class="w70 label-pop">驳回原因 :</div>
<div style="flex:1">
<MOSTY.Other filterable style="width: 100%;" v-model="chooseRow.bhyy" type="textarea" rows="3" clearable
placeholder="请输入审核原因" />
<div class="f12" style="color: red;" v-if="rules.bhyy">请输入驳回原因</div>
</div>
</div>
<div class="mt10 flex just-center">
<el-button size="small" @click.stop="cancel(row)">取消</el-button>
<el-button size="small" type="primary" @click.stop="handleSumbit(row)">确定</el-button>
</div>
</el-popover>
<el-link size="small" type="danger" @click="delDictItem(row.id)">删除</el-link>
</template>
</MyTable>
</MyTable>checkProcess
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- 新增 -->
<AddForm ref="detailDiloag" @getList="getList" :dict="{
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{
D_BZ_SF,
D_GS_XS_LY,
D_BZ_SSZT,
@ -105,7 +88,11 @@
D_BZ_XZQHDM
}" />
</div>
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY ,D_GS_XS_LX}" :dataModel="pageData.tableData"/>
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
:dataModel="pageData.tableData" />
<MakeTag v-model="chooseRow" :dataList="dataList" :dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
@getList="getList" />
<CheckProcess v-model="checkProcessModel" :dataList="dataList" :dict="{ D_BZ_QBCZZT}"/>
</template>
@ -116,43 +103,46 @@ import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import { qbcjSelectPage, qbcjDeletes } from "@/api/Intelligence.js";
import { reactive, ref, onMounted, getCurrentInstance, nextTick, watch } from "vue";
import { useRouter, useRoute } from 'vue-router'
import { qbcjSelectQbsbPage, qbcjDeletes, qbcjCzzt,qbcjPlsb } from "@/api/Intelligence.js";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import MakeTag from '../components/maketag.vue'
import ExportFile from './components/exportFile.vue'
import CheckProcess from '../components/checkProcess.vue'
import { ElMessageBox } from 'element-plus'
import { getItem } from '@//utils/storage.js'
const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX,
D_GS_XS_QTLX, D_BZ_XSSHZT, D_GS_ZDQT_LB,
D_BZ_BMJB, D_BZ_CLPP, D_BZ_CLYS, D_BZ_CLLX, D_BZ_XZQHDM, D_GS_XS_CZZT } =
proxy.$dict("D_BZ_BMJB", "D_GS_XS_CZZT", "D_GS_XS_LY",
const { D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_BZ_BQJB,
D_GS_XS_QTLX, D_GS_ZDQT_LB,
D_BZ_BMJB, D_BZ_CLPP, D_BZ_CLYS, D_BZ_CLLX, D_BZ_XZQHDM, D_BZ_QBCZZT, D_BZ_CJLX } =
proxy.$dict("D_BZ_BMJB", "D_GS_XS_LY",
"D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX",
"D_BZ_XSSHZT", "D_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_GS_XS_CZZT"); //获取字典数据
"D_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB"); //获取字典数据
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const chooseRow = ref({})
const rules = reactive({
bhyy: false,
shzt: false,
})
const ids = ref([])
const tableList = ref([]);
const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value=val
}
const isShow = ref(false)
const searchConfiger = ref([
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
{ label: "姓名", prop: 'sjryxm', placeholder: "请输入姓名", showType: "input" },
{ label: "身份证号", prop: 'sjrysfzh', placeholder: "请输入身份证号", showType: "input" },
{ label: "姓名", prop: 'xssbr', placeholder: "请输入姓名", showType: "input" },
{ label: "身份证号", prop: 'sfzh', placeholder: "请输入身份证号", showType: "input" },
{ label: "群体名称", prop: 'qtmc', placeholder: "请输入群体名称", showType: "input" },
{ label: "指向地点", prop: 'zxdz', placeholder: "请输入指向地点", showType: "input" },
{ label: "指向时间", prop: 'zxkssj', placeholder: "请选择开始时间", showType: "datetimerange" },
{ label: "录入时间", prop: 'lrkssj', placeholder: "请选择开始时间", showType: "datetimerange" },
{ label: "情报类型", prop: 'qblx', placeholder: "请选择情报类型", showType: "select", options: D_GS_XS_LX },
{ label: "情报来源", prop: 'qbly', placeholder: "请选择情报来源", showType: "select", options: D_GS_XS_LY },
{ label: "情报处置状态", prop: 'czzt', placeholder: "请选择处置状态", showType: "select", options: D_GS_XS_CZZT },
{ label: "来源单位", prop: 'gxdwdm', placeholder: "请选择来源单位", showType: "department" },
{ label: "情报来源", prop: 'cjLx', placeholder: "请选择情报来源", showType: "select", options: D_BZ_CJLX },
{ label: "情报处置状态", prop: 'czzt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_QBCZZT },
{ label: "来源单位", prop: 'ssbmdm', placeholder: "请选择来源单位", showType: "department" },
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
]);
const pageData = reactive({
@ -174,52 +164,99 @@ const pageData = reactive({
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报类型", prop: "qblx", showSolt: true },
{ label: "情报来源", prop: "qbly", showSolt: true },
{ label: "情报来源", prop: "cjlx", showSolt: true },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "指向地点", prop: "zxdz" },
{ label: "消息状态", prop: "czzt", showSolt: true },
{ label: "情报内容", prop: "qbnr" },
]
});
const queryFrom = ref({});
// 上报
const appearNewspapers = (item) => {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
qbcjCzzt({ id: item.id, czzt: '02', qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
onMounted(() => {
getList()
tabHeightFn()
});
const handleSh = (val) => {
chooseRow.value = { id: val.id, shzt: '01' }
val.visible = !val.visible;
}).catch(() => { });
}
const cancel = (row) => {
row.visible = false;
rules.bhyy = false;
chooseRow.value = {}
}
const handleSumbit = (row) => {
rules.bhyy = !chooseRow.value.bhyy ? true : false;
if (chooseRow.value.shzt == '01' && rules.bhyy) return false;
let data = { ...chooseRow.value }
qcckPost(data, '/mosty-gsxt/qbcj/updateByXssh').then(res => {
row.visible = false;
proxy.$message({ type: "success", message: "审核成功" });
getList();
// 回退
const rollbackNewspapers = (item) => {
ElMessageBox.prompt('请输入回退原因', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(({ value }) => {
qbcjCzzt({ id: item.id, czzt: '04', qbjb: '00', czthyy: value }).then(res => {
proxy.$message({ type: "success", message: "回退成功" });
getList();
})
})
.catch(() => {
})
}
const chooseRow = ref(false)
const dataList = ref()
const opneMsg = (item) => {
chooseRow.value = true
dataList.value = [item]
}
const cnMsg = (item) => {
proxy.$confirm("确定要采纳", "警告", { type: "warning" }).then(() => {
qbcjCzzt({ id: item.id, czzt: '03', qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "采纳成功" });
getList();
})
}).catch(() => { });
}
// 批量打标
const batchMark = () => {
const listDb= tableList.value.filter(item => item.czzt != '03')
if (listDb.length == 0) {
chooseRow.value = true
dataList.value = tableList.value
} else {
proxy.$message({
message: '还有情报未审批',
type: 'warning',
showClose: true,
})
}
}
const handleSumbit = () => {
const listDb = tableList.value.filter(item => item.czzt != '01' && item.czzt != '04')
if (listDb.length == 0) {
proxy.$confirm("确定要上报", "警告", { type: "warning" }).then(() => {
qbcjPlsb({ ids: ids.value, qbjb: '00' }).then(res => {
proxy.$message({ type: "success", message: "上报成功" });
getList();
})
}).catch(() => { });
} else {
proxy.$message({
message: '请选择正确数据',
type: 'warning',
showClose: true,
})
}
}
// 搜索
const onSearch = (val) => {
const { lrkssj, zxkssj } = val
console.log(lrkssj, zxkssj);
const promes = {
...pageData.pageConfiger,
...pageData.pageConfiger,
...val,
lrkssj: lrkssj ? lrkssj[0] : '',
lrjssj: lrkssj ? lrkssj[1] : '',
zxkssj: zxkssj ? zxkssj[0] : '',
@ -244,7 +281,7 @@ const changeSize = (val) => {
const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
qbcjSelectPage(data).then(res => {
qbcjSelectQbsbPage(data).then(res => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
@ -257,22 +294,20 @@ const delDictItem = (id) => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
}).catch(() => {
})
}).catch(() => { });
}
// 导出数据
const tableColumn = reactive([
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报类型", prop: "qblx", showSolt: true,zd:'D_GS_XS_LX' },
{ label: "情报来源", prop: "qbly", showSolt: true,zd:'D_GS_XS_LY' },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "指向地点", prop: "zxdz" },
{ label: "情报内容", prop: "qbnr",showOverflowTooltip: true },
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报类型", prop: "qblx", showSolt: true, zd: 'D_GS_XS_LX' },
{ label: "情报来源", prop: "cjLx", showSolt: true, zd: 'D_BZ_CJLX' },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "指向地点", prop: "zxdz" },
{ label: "情报内容", prop: "qbnr", showOverflowTooltip: true },
])
// 详情
const addEdit = (type, row) => {
isShow.value = true;
@ -280,14 +315,6 @@ const addEdit = (type, row) => {
detailDiloag.value.init(type, row);
}, 500)
};
//发布
const confirm = (item) => {
qcckPost({ id: item.id, sffb: 1 }, '/mosty-gsxt/qbcj/qbfb').then(res => {
proxy.$message({ type: "success", message: "发布成功" });
getList();
})
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
@ -295,10 +322,42 @@ const tabHeightFn = () => {
tabHeightFn();
};
};
const route = useRoute()
const titleData = ref()
const qxkz = reactive({
deptBizType: '',
deptLevel: '',
});
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList()
});
const getRouter = () => {
titleData.value = route.meta.title
}
const exportFileModel = ref(false)
const dologCancel = () => {
exportFileModel.value = true;
}
// 流程
const checkProcessModel=ref()
const checkProcess = (item) => {
checkProcessModel.value = true
dataList.value = item
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">社会信息员工工作考核{{ title }} </span>
<span class="title">工作考核{{ title }} </span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" >保存</el-button>
<el-button size="small" @click="close">关闭</el-button>

View File

@ -1,7 +1,7 @@
<template>
<div>
<div class="titleBox">
<PageTitle title="社会信息员工工作考核">
<PageTitle title="工作考核">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle"><CirclePlus /></el-icon>
<span style="vertical-align: middle">新增</span>

View File

@ -0,0 +1,213 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ titleData }}{{ title }}</span>
<div>
<!-- <el-button @click="submitForm()" type="primary">保存</el-button> -->
<el-button @click="close">关闭</el-button>
</div>
</div>
<div style="display: flex;width: 100%;" v-loading="loading">
<div class="form_cnt">
<FormMessage :disabled="disabled" v-model="listQuery" :formList="formData" ref="elform" :rules="rules">
<template #gapdive>
<div style="width: 100%;height: 10px;" class="mb20">
<el-divider content-position="left">基础信息</el-divider>
</div>
</template>
<template #gapline>
<div style="width: 100%;height: 10px;" class="mb20">
<el-divider content-position="left">情报内容</el-divider>
</div>
</template>
<template #scfj>
<div style="width: 100%;padding-left: 50px;">
<div>上传附件:<span class="f12">可附电子表格Word文档图像音视频文件</span> </div>
<div>
<MOSTY.Upload :showBtn="true" :isAll="true" :isImg="true" disabled :limit="10" v-model="fjdz" />
</div>
</div>
</template>
</FormMessage>
<el-divider content-position="left"><span class="mr20">活跃人员</span> </el-divider>
<Personnel :dict="props.dict" ref="personnel" :perList="listQuery.ryList" />
<el-divider content-position="left"><span class="mr20">车辆信息</span> </el-divider>
<VehicleCar :dict="props.dict" ref="vehicleCar" :clList="listQuery.clList" />
<el-divider content-position="left"><span class="mr20">关联群体</span> </el-divider>
<Group :dict="props.dict" ref="group" :qtList="listQuery.qtList" />
</div>
<div class="person" v-if="showPj&&listQuery.qbjb!='00'">
<AddForm ref="addForm" :dict="props.dict" :msgeDat="msgeDat" />
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import Personnel from '../components/personnel/index.vue'
import VehicleCar from '../components/vehicleCar/index.vue'
import Group from '../components/group/index.vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qbcjAdd, qbcjUpdate, qbcjSelectByid } from "@/api/Intelligence.js";
import { ref, defineExpose, onMounted, defineEmits, watch } from "vue";
import AddForm from '@/views/backOfficeSystem/MakeAcomment/components/a/addForm.vue'
import {useRoute,useRouter} from 'vue-router'
const emit = defineEmits(["getList"]);
const props = defineProps({
dict: Object,
titleData: {
type: String,
default: ""
}
});
const loading = ref(false)
const dialogForm = ref(false); //弹窗
const formData = ref();
watch(() => dialogForm.value, (val) => {
if (val) {
formData.value = [
{ prop: "gapdive", type: "slot", width: '100%' },
{ label: "情报标题", prop: "qbmc", type: "input", width: '45%' },
{ label: "情报类型", prop: "qblx", type: "select", options: props.dict.D_GS_XS_LX, width: '45%' },
{ label: "情报等级", prop: "qbmj", type: "select", options: props.dict.D_BZ_BMJB, width: '45%' },
// { label: "情报来源", prop: "qbly", type: "select", options: props.dict.D_GS_XS_LY, width: '45%' },
{ label: "情报上报时间", prop: "sxsbsj", type: "datetime", width: '45%' },
{ label: "指向时间", prop: "zxkssj", type: "datetime", width: '45%' },
{ label: "指向地址", prop: "zxdz", type: "input", width: '45%' },
{ label: "附件上传", prop: "fjdz", type: "upload", width: '100%' },
{ label: "情报内容", prop: "qbnr", type: "textarea", width: '100%' },
]
}
}, { deep: true })
const fjdz = ref()
const listQuery = ref({}); //表单
const elform = ref();
onMounted(() => {
})
const addForm = ref()
const msgeDat = ref()
const title = ref("")
const showPj = ref(false)
const disabled = ref(false)
// 初始化数据
const init = (type, row) => {
title.value = type == "add" ? "新增" : type == "info" ? "详情" : "编辑"
disabled.value = type == 'info' ? true : false
fjdz.value = []
dialogForm.value = true;
if (type == 'info' || type == 'edit') {
showPj.value = true
msgeDat.value = row
// 初始化表单数据,并根据详情页设置禁用状态
if (row) getDataById(row.id);
} else {
showPj.value = false
}
};
// 根据id查询详情
const getDataById = (id) => {
qbcjSelectByid({ id }).then((res) => {
fjdz.value = res.ossList || [];
listQuery.value = res;
});
};
// 获取人员信息
const personnel = ref(null)
const vehicleCar = ref(null)
const group = ref(null)
// 新增
const submitForm = () => {
loading.value = true
elform.value.submit(valid => {
if (valid) {
const promes = {
...listQuery.value,
fjdz: fjdz.value.length > 0 ? fjdz.value.join(',') : '',
ryList: personnel.value.listData() || [],
clList: vehicleCar.value.listData() || [],
qtList: group.value.listData() || [],
cjLx: 0
}
if (title.value == '新增') {
qbcjAdd(promes).then((res) => {
emit("getList")
close()
}).finally(() => {
loading.value = false
})
} else if (title.value == '编辑') {
qbcjUpdate(promes).then((res) => {
emit("getList")
close()
}).finally(() => {
loading.value = false
})
}
}
})
}
const route = useRoute()
const router = useRouter()
// 关闭
const close = () => {
if (route.query.id) {
const query = { ...route.query };
delete query.id;
router.replace({ query });
}
fjdz.value = []
listQuery.value = {};
dialogForm.value = false;
loading.value = false;
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
.boxlist {
width: 99%;
height: 225px;
margin-top: 10px;
overflow: hidden;
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
.form_cnt {
// width: 75%;
flex: 1;
}
.person {
padding-left: 20px;
width: 25%;
// height: 100vh;
}
</style>

View File

@ -0,0 +1,8 @@
<!-- 批量导入 -->
<template>
</template>
<script setup>
</script>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,159 @@
<!--文件导出 -->
<template>
<el-dialog v-model="modelValue" :title="title" :width="width" top="5vh" @close="close" append-to-body>
<div style="height: 70vh;">
<MyTable ref="tableData" :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn"
:tableHeight="pageForm.tableHeight" :key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger"
:controlsWidth="pageForm.controlsWidth">
<template #[item.prop]="{ row }" v-for="(item, index) in soltData">
<template v-if="item.zd">
<DictTag :tag="false" :value="row[item.prop]" :options="props.dict[item.zd]" />
</template>
<template v-else>
<slot :name="item.prop" :row="row"></slot>
</template>
</template>
</MyTable>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="exportCurrentTable">导出 </el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import * as XLSX from 'xlsx'
import { onMounted, reactive, watch, ref } from 'vue'
import MyTable from "@/components/aboutTable/MyTable.vue";
import { template } from 'lodash';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
width: {
type: String,
default: '50%'
}, tableColumn: {
type: Array,
default: () => []
}, dict: {
type: Object,
default: () => ({})
},
title: {
type: String,
default: '导出数据'
}, dataModel: {
type: Array,
default: () => ([])
}
})
onMounted(() => {
{ { props.dict } }
})
watch(() => props.modelValue, (newVal, oldVal) => {
if(newVal){
pageForm.tableData = props.dataModel
}
})
const emit = defineEmits(['update:modelValue'])
const pageForm = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
controlsWidth: 220,
tableColumn: [
],
});
const soltData = ref([])
// 当对话框显示时处理表格列配置
watch(() => props.modelValue, (newVal) => {
if (newVal) {
pageForm.tableColumn = props.tableColumn.map(item => ({
...item,
showSolt: item.showSolt || false,
showOverflowTooltip: item.showOverflowTooltip || false,
prop: item.prop || item.key,
label: item.title || item.label || item.name,
zd: item.zd
}))
soltData.value = props.tableColumn.filter(item => item.showSolt)
}
}, { deep: true })
const close = () => {
emit('update:modelValue', false)
}
const tableData = ref(null)
// 导出当前表格的数据
const exportCurrentTable = () => {
try {
// 创建工作簿
const wb = XLSX.utils.book_new();
// 检查表格列配置是否存在
if (pageForm.tableColumn && pageForm.tableColumn.length > 0) {
// 准备导出数据使用表格列配置中的label作为表头
const exportData = pageForm.tableData.map(row => {
const formattedRow = {};
// 遍历表格列配置
pageForm.tableColumn.forEach(col => {
// 使用列的label作为Excel的表头对应的值为行中该属性的值
if (col.prop && row.hasOwnProperty(col.prop)) {
// 处理带字典的列
let cellValue = row[col.prop];
if (col.zd && props.dict[col.zd] && cellValue !== undefined) {
// 查找字典中的对应文本值
const dictItem = props.dict[col.zd].find(d => d.value === cellValue);
if (dictItem) {
cellValue = dictItem.zdmc || dictItem.label || cellValue;
}
}
formattedRow[col.label || col.prop] = cellValue;
}
});
return formattedRow;
});
// 使用格式化后的数据创建工作表
const ws = XLSX.utils.json_to_sheet(exportData);
// 添加工作表到工作簿
XLSX.utils.book_append_sheet(wb, ws, props.title);
// 导出文件
XLSX.writeFile(wb, props.title + '.xlsx');
} else {
// 如果没有表格列配置,使用原始数据
const exportData = pageForm.tableData.map(row => {
const exportRow = { ...row };
// 处理带字典的列
soltData.value.forEach(item => {
if (item.zd && props.dict[item.zd] && exportRow[item.prop] !== undefined) {
// 查找字典中的对应文本值
const dictItem = props.dict[item.zd].find(d => d.value === exportRow[item.prop]);
if (dictItem) {
exportRow[item.prop] = dictItem.zdmc || dictItem.label || exportRow[item.prop];
}
}
});
return exportRow;
});
const ws = XLSX.utils.json_to_sheet(exportData);
XLSX.utils.book_append_sheet(wb, ws, props.title);
XLSX.writeFile(wb, props.title + '.xlsx');
}
} catch (error) {
console.error('导出文件失败:', error);
}
}
</script>

View File

@ -0,0 +1,81 @@
<template>
<el-dialog v-model="modelValue" :destroy-on-close="true" title="新增群体" @close="close" :close-on-click-modal="false">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform">
</FormMessage>
<template #footer>
<div class="flex just-center">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { ref, watch } from 'vue';
import { getUUid } from '@/utils/tools'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dict: {
type: Object,
default: () => ({})
},
dialogValue: {
type: Object,
default: () => ({})
}
})
watch(() => props.dialogValue, (val) => {
if (val) {
listQuery.value = { ...props.dialogValue }
}
})
const elform = ref()
const emit = defineEmits(['update:modelValue', 'changePersonnel'])
const listQuery = ref({})
const formData = ref()
watch(() => props.dict, () => {
formData.value=[
{ label: "群体名称", prop: "qtmc", type: "input", width: "45%" },
{
label: "群体类别",
prop: "qtlb",
type: "select",
options: props.dict.D_GS_ZDQT_LB, width: "45%"
},
{ label: "预警规模", prop: "yjgm", type: "input", width: "45%" },
{ label: "活跃人数", prop: "hyrs", type: "number", width: "45%" },
{ label: "备注", prop: "bz", type: "textarea", width: "100%" },
]
},{deep:true,immediate:true})
const submitForm = () => {
if (listQuery.value.id) {
emit('changePersonnel', listQuery.value)
} else {
const promes = {
id: getUUid(),
...listQuery.value
}
emit('changePersonnel', promes)
}
close()
}
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.marks {
width: 100%;
min-height: 32px;
border: 1px solid #e9e9e9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div>
<div class="controls">
<el-button type="primary" @click="addEdit()">
<el-icon class="icon">
<CirclePlus />
</el-icon>
<span class="icon" >新增</span>
</el-button>
</div>
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<!-- 操作 -->
<template #qtlb="{ row}">
<DictTag :tag="false" :value="row.qtlb" :options="props.dict.D_GS_ZDQT_LB" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="addEdit(row)">修改</el-link>
<el-link size="small" type="danger" @click="del(row)">删除</el-link>
</template>
</MyTable>
</div>
<AddPersonnel :dialogValue="dialogValue" v-model="showDialog" :dict="props.dict" @changePersonnel="changePersonnel" />
</template>
<script setup>
import { reactive ,ref,watch} from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import AddPersonnel from "./addPersonnel.vue";
const props = defineProps({
dict: {
type: Object,
default: () => ({})
},
qtList: {
type: Array,
default: () => []
}
});
watch(() => props.qtList, val => {
pageForm.value.tableData=val
},{deep:true})
const showDialog = ref(false)
const pageForm = ref({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
controlsWidth: 220,
tableColumn: [
{ label: "群体名称", prop: "qtmc",showOverflowTooltip:true },
{ label: "群体类别", prop: "qtlb",showOverflowTooltip:true ,showSolt: true},
{ label: "预警规模", prop: "yjgm",showOverflowTooltip:true },
{ label: "活跃人数", prop: "hyrs",showOverflowTooltip:true },
{ label: "备注", prop: "bz" ,showOverflowTooltip:true},
]
});
watch(() => props.perList, (val) => {
pageForm.value.tableData=val
},{deep:true})
const changePersonnel = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.id == val.id)
if (index != -1) {
pageForm.value.tableData[index] = val
} else {
pageForm.value.tableData.push(val)
}
}
const dialogValue=ref()
const addEdit = (val) => {
showDialog.value = true
dialogValue.value=val
}
const listData = () => {
return pageForm.value.tableData
}
const del = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.id == val.id)
if (index != -1) {
pageForm.value.tableData.splice(index, 1)
ElMessage.success('删除成功')
}
}
defineExpose({ listData });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.controls {
display: flex;
justify-content: end;
margin-bottom: 10px;
padding: 0 20px;
.icon {
vertical-align: middle
}
}
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
.form_cnt {
// width: 75%;
flex: 1;
}
.person {
padding-left: 20px;
width: 25%;
// height: 100vh;
}
</style>

View File

@ -0,0 +1,54 @@
<!-- 使用示例在父组件中集成文件导入组件 -->
<script setup>
// 导入刚才创建的文件导入组件
import ToChannel from './components/toChannel.vue'
// 响应式数据
const importDialogVisible = ref(false)
// 表格列配置(用于导入预览和模板生成)
const tableColumns = ref([
{ label: '姓名', prop: 'xm' },
{ label: '身份证号', prop: 'sfzh' },
{ label: '手机号', prop: 'sjhm' },
{ label: '地址', prop: 'dz' },
{ label: '群体类别', prop: 'qtlb' }
])
// 打开导入对话框
const openImportDialog = () => {
importDialogVisible.value = true
}
// 处理导入成功
const handleImportSuccess = (result) => {
console.log('导入成功的数据:', result)
}
// 处理导入失败
const handleImportError = (error) => {
console.error('导入失败:', error)
}
</script>
<template>
<div>
<!-- 导入按钮 -->
<el-button type="primary" @click="openImportDialog">
<el-icon><upload-filled /></el-icon>
导入数据
</el-button>
<!-- 文件导入组件 -->
<ToChannel
v-model="importDialogVisible"
:title="'导入人员数据'"
:table-columns="tableColumns"
:upload-action="'/api/upload/excel'"
:template-url="'/api/download/template'"
:file-size-limit="5"
@import-success="handleImportSuccess"
@import-error="handleImportError"
/>
</div>
</template>

View File

@ -0,0 +1,76 @@
<template>
<el-dialog v-model="modelValue" :destroy-on-close="true" title="新增人员" @close="close" :close-on-click-modal="false">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform">
</FormMessage>
<template #footer>
<div class="flex just-center">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { ref, watch } from 'vue';
import { getUUid } from '@/utils/tools'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dict: {
type: Object,
default: () => ({})
},
dialogValue: {
type: Object,
default: () => ({})
}
})
const listQuery = ref({})
watch(() => props.dialogValue, (val) => {
if (val) {
listQuery.value = { ...props.dialogValue }
}
})
const elform = ref()
const emit = defineEmits(['update:modelValue', 'changePersonnel'])
const formData = ref([
{ label: "姓名", prop: "xm", type: "input", width: "45%" },
{ label: "身份证号", prop: "sfzh", type: "input", width: "45%" },
{ label: "角色", prop: "js", type: "input", width: "45%" },
{ label: "手机号", prop: "sjh", type: "input", width: "45%" },
{ label: "管辖单位", prop: "gxdwdm",depMc:"gxdw", type: "department", width: "45%" },
{ label: "人员属地", prop: "rysd", type: "select", width: "45%",options:props.dict.D_BZ_XZQHDM },
{ label: "居住地址", prop: "jzdz", type: "input", width: "100%" },
{ label: "备注", prop: "bz", type: "textarea", width: "100%" },
])
const submitForm = (val) => {
if (listQuery.value.id) {
emit('changePersonnel', listQuery.value)
} else {
const promes = {
id: getUUid(),
...listQuery.value
}
emit('changePersonnel', promes)
}
close()
}
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.marks {
width: 100%;
min-height: 32px;
border: 1px solid #e9e9e9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,226 @@
<template>
<div>
<div class="controls">
<div>
<div>
录入总数{{ dataStatistics.TotalNumber }}
异常次数{{ dataStatistics.ExceptionNumber }}
<span @click="repeatingDataShow()">异常数据{{ dataStatistics.ExceptionDataNumber }}</span>
</div>
</div>
<div>
<el-button type="primary" @click="addEdit()">
<el-icon class="icon">
<CirclePlus />
</el-icon>
<span class="icon">新增</span>
</el-button>
<el-button type="primary" @click="openImportDialog">
<el-icon class="icon">
<Edit />
</el-icon>
<span class="icon">批量导入</span>
</el-button>
</div>
</div>
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #rysd="{ row }">
<DictTag :tag="false" :value="row.rysd" :options="props.dict.D_BZ_XZQHDM" />
</template>
<!-- 操作 -->
<template #controls="{ row, index }">
<el-link size="small" type="success" @click="addEdit(row)">修改</el-link>
<el-link size="small" type="danger" @click="del(row)">删除</el-link>
</template>
</MyTable>
</div>
<AddPersonnel :dialogValue="dialogValue" v-model="showDialog" :dict="props.dict" @changePersonnel="changePersonnel" />
<ToChannel @import-success="pushqbcjimportRyData" v-model="importDialogVisible" :title="'导入人员数据'"
aiconUrl="/mosty-gsxt/qbcj/importRyData" :file-size-limit="5" :isUrl="true" />
<RepeatingData v-model="repeatingDataVisible" :dict="props.dict" :dialogValue="repeatingData" />
</template>
<script setup>
import { reactive, ref, watch } from "vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import AddPersonnel from "./addPersonnel.vue";
import ToChannel from '../toChannel.vue'
import { ElMessage } from "element-plus";
import RepeatingData from "../personnel/repeatingData.vue";
const props = defineProps({
dict: {
type: Object,
default: () => ({})
}, perList: {
type: Array,
default: () => []
}
});
watch(() => props.perList, val => {
pageForm.value.tableData = val
dataStatistics.value.TotalNumber = val.length
}, { deep: true })
const showDialog = ref(false)
const pageForm = ref({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHeight: 61, // 修正拼写错误
showSelectType: 'null', // 设置为false以隐藏所有选择框
loading: false
},
controlsWidth: 220,
tableColumn: [
{ label: "姓名", prop: "xm", showOverflowTooltip: true },
{ label: "身份证", prop: "sfzh", showOverflowTooltip: true },
{ label: "角色", prop: "js", showOverflowTooltip: true },
{ label: "手机号码", prop: "sjh", showOverflowTooltip: true },
{ label: "居住地址", prop: "jzdz", showOverflowTooltip: true },
{ label: "管辖单位", prop: "gxdw", showOverflowTooltip: true },
{ label: "人员属地", prop: "rysd", showOverflowTooltip: true, showSolt: true },
{ label: "备注", prop: "bz", showOverflowTooltip: true },
]
});
const changePersonnel = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.id == val.id)
if (index != -1) {
pageForm.value.tableData[index] = val
} else {
pageForm.value.tableData.push(val)
}
dataStatistics.value.TotalNumber = pageForm.value.tableData.length
}
const dataStatistics = ref({
TotalNumber: 0,
ExceptionNumber: 0,
ExceptionDataNumber: 0,
})
const dialogValue = ref()
const addEdit = (val) => {
showDialog.value = true
dialogValue.value = val
}
const del = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.id == val.id)
if (index != -1) {
pageForm.value.tableData.splice(index, 1)
ElMessage.success('删除成功')
}
}
const listData = () => {
return pageForm.value.tableData
}
const repeatingData=ref([])
// 导入
const importDialogVisible = ref(false)
const openImportDialog = () => {
importDialogVisible.value = true
}
const pushqbcjimportRyData = (val) => {
if (!val) {
dataStatistics.value.ExceptionNumber++
ElMessage.error('请求异常,导入失败,重新导入')
return
}
if (val.length == 0) {
dataStatistics.value.ExceptionNumber++
ElMessage.error('导入数据不能为空')
return
} else {
const transformedData = val.map(item => {
return {
...item,
rysd: props.dict.D_BZ_XZQHDM.filter(items => item.rysd == items.zdmc)[0]?.dm || '',
}
})
const existingChpSet = new Set(pageForm.value.tableData.map(item => item.sfzh))
const filteredData = transformedData.filter(item => {
if (!existingChpSet.has(item.sfzh)) {
return item
} else {
repeatingData.value.push(item)
}
}
)
// 更新数据统计
const duplicateCount = transformedData.length - filteredData.length
if (duplicateCount > 0) {
dataStatistics.value.ExceptionNumber++
dataStatistics.value.ExceptionDataNumber += duplicateCount
ElMessage.warning(`成功导入${filteredData.length}条数据,发现${duplicateCount}条车牌号重复的数据已跳过`)
} else {
ElMessage.success(`成功导入${filteredData.length}条数据`)
}
// 添加过滤后的数据
if (filteredData.length > 0) {
if (pageForm.value.tableData.length > 0) {
pageForm.value.tableData = [...pageForm.value.tableData, ...filteredData]
} else {
pageForm.value.tableData = filteredData
}
}
dataStatistics.value.TotalNumber = pageForm.value.tableData.length
}
}
// 重复数据
const repeatingDataVisible = ref(false)
const repeatingDataShow = () => {
repeatingDataVisible.value = true
}
defineExpose({ listData });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.controls {
padding: 0 20px;
display: flex;
justify-content:space-between;
margin-bottom: 10px;
.icon {
vertical-align: middle
}
}
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
.form_cnt {
// width: 75%;
flex: 1;
}
.person {
padding-left: 20px;
width: 25%;
// height: 100vh;
}
</style>

View File

@ -0,0 +1,81 @@
<template>
<el-dialog v-model="modelValue" :destroy-on-close="true" title="人员异常数据" @close="close" :close-on-click-modal="false">
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" tableHeight="50vh"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #rysd="{ row }">
<DictTag :tag="false" :value="row.rysd" :options="props.dict.D_BZ_XZQHDM" />
</template>
<!-- 操作 -->
<template #controls="{ row, index }">
<el-link size="small" type="success" @click="addEdit(row)">修改</el-link>
<el-link size="small" type="danger" @click="del(row)">删除</el-link>
</template>
</MyTable>
<template #footer>
<div class="flex just-center">
<el-button @click="close">取消</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
import MyTable from "@/components/aboutTable/MyTable.vue";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dict: {
type: Object,
default: () => ({})
},
dialogValue: {
type: Object,
default: () => ({})
}
})
watch(() => props.modelValue, (val) => {
if (val) {
pageForm.value.tableData =props.dialogValue
}
})
const emit = defineEmits(['update:modelValue'])
const pageForm = ref({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
controlsWidth: 220,
tableColumn: [
{ label: "姓名", prop: "xm", showOverflowTooltip: true },
{ label: "身份证", prop: "sfzh", showOverflowTooltip: true },
{ label: "角色", prop: "js", showOverflowTooltip: true },
{ label: "手机号码", prop: "sjh", showOverflowTooltip: true },
{ label: "居住地址", prop: "jzdz", showOverflowTooltip: true },
{ label: "管辖单位", prop: "gxdw", showOverflowTooltip: true },
{ label: "人员属地", prop: "rysd", showOverflowTooltip: true, showSolt: true },
{ label: "备注", prop: "bz", showOverflowTooltip: true },
]
});
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.marks {
width: 100%;
min-height: 32px;
border: 1px solid #e9e9e9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,298 @@
<!-- 文件上传导入组件 -->
<template>
<el-dialog v-model="modelValue" :title="title" :width="width" top="5vh" @close="close" append-to-body>
<!-- 上传区域 -->
<div class="upload-section">
<el-upload class="upload-demo" drag :auto-upload="false" :limit="1" :file-list="fileList"
:before-upload="beforeUpload" :on-change="handleFileChange" :on-exceed="handleExceed">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
<em>点击或拖拽文件到此处上传</em>
</div>
<template #tip>
<div class="el-upload__tip">
只能上传 xlsx/xls 文件且不超过 {{ fileSizeLimit }}MB
</div>
</template>
</el-upload>
<!-- 操作按钮 -->
<div class="upload-actions">
<el-button type="primary" @click="handleImport" :disabled="!canImport">导入数据</el-button>
<el-button @click="handleTemplate">下载模板</el-button>
</div>
</div>
<!-- 数据预览区域 -->
<div v-if="previewData.length > 0" class="preview-section">
<h4 style="margin-bottom: 16px;">数据预览</h4>
<el-table :data="previewData" style="width: 100%;" :max-height="300">
<el-table-column v-for="col in tableColumns" :key="col.prop" :prop="col.prop" :label="col.label"
show-overflow-tooltip></el-table-column>
</el-table>
</div>
<!-- 加载状态 -->
<!-- <el-dialog v-model="loadingVisible" title="导入中" :show-close="false">
<div style="text-align: center; padding: 20px;">
<el-loading :fullscreen="false" text="正在处理数据,请稍候..." :visible="true"></el-loading>
</div>
</el-dialog> -->
<!-- <template #footer>
<div class="dialog-footer">
<el-button @click="close">关闭</el-button>
</div>
</template> -->
</el-dialog>
</template>
<script setup>
import * as XLSX from 'xlsx'
import { ref, computed, defineProps, defineEmits } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { qcckPost } from '@/api/qcckApi'
// Props 定义
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
width: {
type: String,
default: '30%'
},
title: {
type: String,
default: '导入数据'
},
// 文件大小限制(MB)
fileSizeLimit: {
type: Number,
default: 10
},
// 表格列配置
tableColumns: {
type: Array,
default: () => []
},
// 模板下载地址
templateUrl: {
type: String,
default: ''
},
// 图标地址
aiconUrl: {
type: String,
default: ''
},
isUrl: {
type: Boolean,
default: false
}
})
// Emits 定义
const emit = defineEmits(['update:modelValue', 'import-success', 'import-error', 'vSocial'])
// 响应式数据
const fileList = ref([])
const previewData = ref([])
const loadingVisible = ref(false)
// 计算属性:是否可以导入
const canImport = computed(() => {
return fileList.value.length > 0 && !loadingVisible.value
})
// 关闭对话框
const close = () => {
resetState()
emit('update:modelValue', false)
}
// 重置状态
const resetState = () => {
fileList.value = []
previewData.value = []
loadingVisible.value = false
}
// 处理文件选择变化
const handleFileChange = (file) => {
// 清空之前的预览数据
previewData.value = []
// 只保留最后一个文件
fileList.value = [file]
// 读取文件内容进行预览
const reader = new FileReader()
reader.onload = (e) => {
try {
const data = e.target.result
const workbook = XLSX.read(data, { type: 'binary' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
// 转换为JSON数据
const jsonData = XLSX.utils.sheet_to_json(worksheet)
// 如果有表格列配置,过滤和格式化数据
if (props.tableColumns && props.tableColumns.length > 0) {
previewData.value = jsonData.slice(0, 10).map(row => {
const formattedRow = {}
props.tableColumns.forEach(col => {
formattedRow[col.prop] = row[col.label] !== undefined ? row[col.label] : row[col.prop]
})
return formattedRow
})
} else {
// 否则直接使用前10条数据作为预览
previewData.value = jsonData.slice(0, 10)
}
} catch (error) {
ElMessage.error('文件解析失败,请检查文件格式')
console.error('文件解析错误:', error)
}
}
reader.readAsBinaryString(file.raw)
}
// 上传前校验
const beforeUpload = (file) => {
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.type === 'application/vnd.ms-excel'
const isLtLimit = file.size / 1024 / 1024 < props.fileSizeLimit
if (!isExcel) {
ElMessage.error('只能上传 Excel 文件!')
return false
}
if (!isLtLimit) {
ElMessage.error(`文件大小不能超过 ${props.fileSizeLimit}MB`)
return false
}
return true
}
// 处理文件超出限制
const handleExceed = () => {
ElMessage.error('只能上传一个文件')
}
// 处理导入
const handleImport = async () => {
if (!fileList.value[0]) {
ElMessage.warning('请先选择文件')
return
}
loadingVisible.value = true
try {
// 创建FormData对象
const formData = new FormData()
formData.append('file', fileList.value[0].raw)
if (props.isUrl && props.aiconUrl) {
// 调用上传接口
qcckPost(formData, props.aiconUrl).then(res => {
emit('import-success', res)
close()
}).catch(error => {
ElMessage.error(error.message || '文件上传失败')
emit('import-success', null)
loadingVisible.value = false
})
} else {
// 如果没有配置上传接口,只解析文件并返回数据
const reader = new FileReader()
reader.onload = (e) => {
try {
const data = e.target.result
const workbook = XLSX.read(data, { type: 'binary' })
const firstSheetName = workbook.SheetNames[0]
const worksheet = workbook.Sheets[firstSheetName]
const jsonData = XLSX.utils.sheet_to_json(worksheet)
emit('import-success', { data: jsonData })
close()
} catch (error) {
throw error
}
}
reader.readAsBinaryString(fileList.value[0].raw)
}
} catch (error) {
ElMessage.error(error.message || '导入失败')
emit('import-error', error)
loadingVisible.value = false
}
}
// 处理模板下载
const handleTemplate = () => {
if (props.templateUrl) {
window.open(props.templateUrl, '_blank')
} else {
// 如果没有提供模板下载地址,根据列配置生成简单模板
try {
const wb = XLSX.utils.book_new()
// 创建表头数据
const headerData = []
if (props.tableColumns && props.tableColumns.length > 0) {
const headerRow = {}
props.tableColumns.forEach(col => {
headerRow[col.prop] = col.label
})
headerData.push(headerRow)
}
const ws = XLSX.utils.json_to_sheet(headerData)
XLSX.utils.book_append_sheet(wb, ws, '模板')
// 下载模板
XLSX.writeFile(wb, '导入模板.xlsx')
} catch (error) {
ElMessage.error('模板生成失败')
}
}
}
</script>
<style scoped>
.upload-section {
padding: 20px 0;
display: flex;
flex-direction: column;
align-items: center;
}
.upload-demo {
width: 100%;
max-width: 600px;
}
.upload-actions {
margin-top: 20px;
text-align: center;
}
.upload-actions .el-button {
margin: 0 10px;
}
.preview-section {
margin-top: 20px;
border-top: 1px solid #ebeef5;
padding-top: 20px;
width: 100%;
max-width: 1000px;
align-self: center;
margin-left: auto;
margin-right: auto;
}
.el-table {
font-size: 14px;
}
</style>

View File

@ -0,0 +1,99 @@
<template>
<el-dialog v-model="modelValue" :destroy-on-close="true" title="新增车辆" @close="close" :close-on-click-modal="false">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="120px" ref="elform">
</FormMessage>
<template #footer>
<div class="flex just-center">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="submitForm">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { ref, watch } from 'vue';
import { getUUid } from '@/utils/tools'
import { ElMessage } from "element-plus";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dict: {
type: Object,
default: () => ({})
},
dialogValue: {
type: Object,
default: () => ({})
}
})
watch(() => props.dialogValue, (val) => {
if (val) {
listQuery.value = { ...props.dialogValue }
}
})
const elform = ref()
const emit = defineEmits(['update:modelValue', 'change'])
const listQuery = ref({})
const formData = ref([])
watch(() => props.dict, (val) => {
if (val) {
formData.value = [
{ label: "车牌号", prop: "chp", type: "input", width: "45%" },
{ label: "车主姓名", prop: "czxm", type: "input", width: "45%" },
{ label: "证件号码", prop: "zjhm", type: "input", width: "45%" },
{ label: "车主联系方式", prop: "lxfs", type: "input", width: "45%" },
{
label: "车辆品牌",
prop: "clpp",
type: "select",
options: val.D_BZ_CLPP, width: "45%"
},
{
label: "车身颜色",
prop: "csys",
type: "select",
options: props.dict.D_BZ_CLYS, width: "45%"
},
{
label: "车辆类型",
prop: "cllx",
type: "select",
options: props.dict.D_BZ_CLLX, width: "45%"
},
{ label: "备注", prop: "bz", type: "textarea", width: "100%" },
]
}
}, { deep: true, immediate: true })
const submitForm = (val) => {
if (listQuery.value.id) {
emit('changePersonnel', listQuery.value)
} else {
const promes = {
id: getUUid(),
...listQuery.value
}
emit('changePersonnel', promes)
}
close()
}
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.marks {
width: 100%;
min-height: 32px;
border: 1px solid #e9e9e9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,232 @@
<template>
<div>
<div class="controls">
<div>
录入总数{{ dataStatistics.TotalNumber }}
异常次数{{ dataStatistics.ExceptionNumber }}
<span @click="repeatingDataShow()">异常数据{{ dataStatistics.ExceptionDataNumber }}</span>
</div>
<div>
<el-button type="primary" @click="addEdit()">
<el-icon class="icon">
<CirclePlus />
</el-icon>
<span class="icon">新增</span>
</el-button>
<el-button type="primary" @click="openImportDialog">
<el-icon class="icon">
<Edit />
</el-icon>
<span class="icon">批量导入</span>
</el-button>
</div>
</div>
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" :tableHeight="pageForm.tableHeight"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #clpp="{ row }">
<DictTag :value="row.clpp" :tag="false" :options="props.dict.D_BZ_CLPP" />
</template>
<template #csys="{ row }">
<DictTag :value="row.csys" :tag="false" :options="props.dict.D_BZ_CLYS" />
</template>
<template #cllx="{ row }">
<DictTag :value="row.cllx" :tag="false" :options="props.dict.D_BZ_CLLX" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="addEdit(row)">修改</el-link>
<el-link size="small" type="danger" @click="del(row)">删除</el-link>
</template>
</MyTable>
</div>
<AddPersonnel v-model="showDialog" :dict="props.dict" :dialogValue="dialogValue" @changePersonnel="changePersonnel" />
<ToChannel @import-success="pushqbcjimportRyData" v-model="importDialogVisible" :title="'导入人员数据'"
aiconUrl="/mosty-gsxt/qbcj/importClData" :file-size-limit="5" :isUrl="true" />
<RepeatingData v-model="repeatingDataVisible" :dict="props.dict" :dialogValue="repeatingData" />
</template>
<script setup>
import { reactive, ref, watch } from "vue";
import ToChannel from '../toChannel.vue'
import MyTable from "@/components/aboutTable/MyTable.vue";
import AddPersonnel from "./addPersonnel.vue";
import RepeatingData from "../vehicleCar/repeatingData.vue";
import { ElMessage } from "element-plus";
const showDialog = ref(false)
const props = defineProps({
dict: Object,
clList: {
type: Array,
default: () => []
}
});
watch(() => props.clList, val => {
pageForm.value.tableData = val
dataStatistics.value.TotalNumber = val.length
}, { deep: true })
const pageForm = ref({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false
},
controlsWidth: 220,
tableColumn: [
{ label: "车主姓名", prop: "czxm", showOverflowTooltip: true },
{ label: "车牌号", prop: "chp", showOverflowTooltip: true },
{ label: "车主联系方式", prop: "lxfs", showOverflowTooltip: true },
{ label: "证件号码", prop: "zjhm", showOverflowTooltip: true },
{ label: "车辆品牌", prop: "clpp", showOverflowTooltip: true, showSolt: true },
{ label: "车身颜色", prop: "csys", showOverflowTooltip: true, showSolt: true },
{ label: "车辆类型", prop: "cllx", showOverflowTooltip: true, showSolt: true },
{ label: "备注", prop: "bz", showOverflowTooltip: true },
]
});
const dataStatistics = ref({
TotalNumber: 0,
ExceptionNumber: 0,
ExceptionDataNumber: 0,
})
const dialogValue = ref()
const addEdit = (val) => {
showDialog.value = true
dialogValue.value = val
}
const changePersonnel = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.chp == val.chp)
if (index != -1) {
pageForm.value.tableData[index] = val
} else {
pageForm.value.tableData.push(val)
}
dataStatistics.value.TotalNumber = pageForm.value.tableData.length
}
const listData = () => {
return pageForm.value.tableData
}
const repeatingData = ref([])
// 导入
const importDialogVisible = ref(false)
const openImportDialog = () => {
importDialogVisible.value = true
}
const pushqbcjimportRyData = (val) => {
if (!val) {
dataStatistics.value.ExceptionNumber++
ElMessage.error('请求异常,导入失败,重新导入')
return
}
if (val.length == 0) {
dataStatistics.value.ExceptionNumber++
ElMessage.error('导入数据不能为空')
return
} else {
// 转换数据格式
const transformedData = val.map(item => {
return {
...item,
csys: props.dict.D_BZ_CLYS.filter(items => item.csys == items.zdmc)[0]?.dm || '',
cllx: props.dict.D_BZ_CLLX.filter(items => item.cllx == items.zdmc)[0]?.dm || '',
clpp: props.dict.D_BZ_CLPP.filter(items => item.clpp == items.zdmc)[0]?.dm || '',
}
})
// 过滤掉车牌号重复的数据
const existingChpSet = new Set(pageForm.value.tableData.map(item => item.chp))
const filteredData = transformedData.filter(item => {
if (!existingChpSet.has(item.chp)) {
return item
} else {
repeatingData.value.push(item)
}
}
)
// 更新数据统计
const duplicateCount = transformedData.length - filteredData.length
if (duplicateCount > 0) {
dataStatistics.value.ExceptionNumber++
dataStatistics.value.ExceptionDataNumber += duplicateCount
ElMessage.warning(`成功导入${filteredData.length}条数据,发现${duplicateCount}条车牌号重复的数据已跳过`)
} else {
ElMessage.success(`成功导入${filteredData.length}条数据`)
}
// 添加过滤后的数据
if (filteredData.length > 0) {
if (pageForm.value.tableData.length > 0) {
pageForm.value.tableData = [...pageForm.value.tableData, ...filteredData]
} else {
pageForm.value.tableData = filteredData
}
}
dataStatistics.value.TotalNumber = pageForm.value.tableData.length
}
}
// 重复数据
const repeatingDataVisible = ref(false)
const repeatingDataShow = () => {
repeatingDataVisible.value = true
}
const del = (val) => {
const index = pageForm.value.tableData.findIndex(it => it.id == val.id)
if (index != -1) {
pageForm.value.tableData.splice(index, 1)
ElMessage.success('删除成功')
}
}
defineExpose({ listData });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.controls {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
padding: 0 20px;
.icon {
vertical-align: middle
}
}
::v-deep .el-tabs--card>.el-tabs__header .el-tabs__item.is-active {
color: #0072ff;
background: rgba(0, 114, 255, 0.3);
}
::v-deep .avatar-uploader {
display: flex;
align-items: center;
}
::v-deep .el-upload-list {
margin-left: 20px;
display: flex;
align-items: center;
}
::v-deep .el-upload-list__item-name .el-icon {
top: 3px;
}
.form_cnt {
// width: 75%;
flex: 1;
}
.person {
padding-left: 20px;
width: 25%;
// height: 100vh;
}
</style>

View File

@ -0,0 +1,87 @@
<template>
<el-dialog v-model="modelValue" :destroy-on-close="true" title="车辆异常数据" @close="close" :close-on-click-modal="false">
<MyTable :tableData="pageForm.tableData" :tableColumn="pageForm.tableColumn" tableHeight="50vh"
:key="pageForm.keyCount" :tableConfiger="pageForm.tableConfiger" :controlsWidth="pageForm.controlsWidth">
<template #clpp="{ row }">
<DictTag :value="row.clpp" :tag="false" :options="props.dict.D_BZ_CLPP" />
</template>
<template #csys="{ row }">
<DictTag :value="row.csys" :tag="false" :options="props.dict.D_BZ_CLYS" />
</template>
<template #cllx="{ row }">
<DictTag :value="row.cllx" :tag="false" :options="props.dict.D_BZ_CLLX" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="success" @click="addEdit(row)">修改</el-link>
<el-link size="small" type="danger" @click="del(row)">删除</el-link>
</template>
</MyTable>
<template #footer>
<div class="flex just-center">
<el-button @click="close">取消</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch } from 'vue';
import MyTable from "@/components/aboutTable/MyTable.vue";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
dict: {
type: Object,
default: () => ({})
},
dialogValue: {
type: Object,
default: () => ({})
}
})
watch(() => props.modelValue, (val) => {
if (val) {
pageForm.value.tableData =props.dialogValue
}
})
const emit = defineEmits(['update:modelValue'])
const pageForm = ref({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "null",
loading: false,
haveControls: false
},
controlsWidth: 220,
tableColumn: [
{ label: "车主姓名", prop: "czxm", showOverflowTooltip: true },
{ label: "车牌号", prop: "chp", showOverflowTooltip: true },
{ label: "车主联系方式", prop: "lxfs", showOverflowTooltip: true },
{ label: "证件号码", prop: "zjhm", showOverflowTooltip: true },
{ label: "车辆品牌", prop: "clpp", showOverflowTooltip: true, showSolt: true },
{ label: "车身颜色", prop: "csys", showOverflowTooltip: true, showSolt: true },
{ label: "车辆类型", prop: "cllx", showOverflowTooltip: true, showSolt: true },
{ label: "备注", prop: "bz", showOverflowTooltip: true },
]
});
const close = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.marks {
width: 100%;
min-height: 32px;
border: 1px solid #e9e9e9;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,339 @@
<template>
<div>
<div class="titleBox">
<PageTitle :title="titleData">
<el-button type="primary" @click="dologCancel()">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">导出</span>
</el-button>
<el-button v-if="qxkz.deptLevel == '01'" type="primary" :disabled="ids.length === 0" @click="batchMark(ids)">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">批量打标</span>
</el-button>
<el-button type="primary" :disabled="ids.length === 0" @click="delDictItem(ids)">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">批量删除</span>
</el-button>
</PageTitle>
</div>
<!-- 搜索 -->
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" :key="pageData.keyCount" />
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData">
<template #qblx="{ row }">
<DictTag :tag="false" :value="row.qblx" :options="D_GS_XS_LX" />
</template>
<template #cjlx="{ row }">
<DictTag :tag="false" :value="row.cjLx" :options="D_BZ_CJLX" />
</template>
<template #czzt="{ row }">
<DictTag :tag="false" :value="row.czzt" :options="D_BZ_QBCZZT" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link size="small" type="primary" @click="opneMsg(row)" v-if="qxkz.deptLevel == '01'">打标签</el-link>
<el-link size="small" type="primary" @click="checkProcess(row)">查看流程</el-link>
<el-link size="small" type="primary" @click="addEdit('info', row)">详情</el-link>
<el-link size="small" type="danger" @click="delDictItem(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</div>
<!-- 新增 -->
<AddForm ref="detailDiloag" @getList="getList" :titleData="titleData" :dict="{
D_BZ_SF,
D_GS_XS_LY,
D_BZ_SSZT,
D_GS_XS_LX,
D_GS_XS_QTLX,
D_GS_ZDQT_LB,
D_BZ_BMJB,
D_BZ_CLPP,
D_BZ_CLYS,
D_BZ_CLLX,
D_BZ_XZQHDM
}" />
</div>
<ExportFile v-model="exportFileModel" :tableColumn="tableColumn" :dict="{ D_GS_XS_LY, D_GS_XS_LX, D_GS_XS_LX }"
:dataModel="pageData.tableData" />
<MakeTag v-model="chooseRow" :dataList="dataList" :dict="{ D_BZ_CJLX, D_BZ_QBCZZT, D_GS_XS_LX, D_BZ_BQJB }"
@getList="getList" />
<CheckProcess v-model="checkProcessModel" :dataList="dataList" :dict="{ D_BZ_QBCZZT }" />
</template>
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import AddForm from "./components/addForm.vue";
import { useRoute } from 'vue-router'
import { qbcjSelectPage, qbcjDeletes } from "@/api/Intelligence.js";
import { reactive, ref, onMounted, getCurrentInstance, watch } from "vue";
import MakeTag from '../components/maketag.vue'
import ExportFile from './components/exportFile.vue'
import CheckProcess from '../components/checkProcess.vue'
import { getItem } from '@//utils/storage.js'
const { proxy } = getCurrentInstance();
const { D_GS_XS_LY, D_BZ_SSZT, D_BZ_SF, D_GS_XS_LX, D_BZ_BQJB,
D_GS_XS_QTLX, D_GS_ZDQT_LB,
D_BZ_BMJB, D_BZ_CLPP, D_BZ_CLYS, D_BZ_CLLX, D_BZ_XZQHDM, D_BZ_QBCZZT, D_BZ_CJLX } =
proxy.$dict("D_BZ_BMJB", "D_GS_XS_LY",
"D_BZ_SSZT", "D_BZ_SF", "D_GS_XS_LX", "D_GS_XS_QTLX",
"D_GS_ZDQT_LB", "D_BZ_CLPP", "D_BZ_CLYS", "D_BZ_CLLX", "D_BZ_XZQHDM", "D_BZ_QBCZZT", "D_BZ_CJLX", "D_BZ_BQJB"); //获取字典数据
const detailDiloag = ref();
const searchBox = ref(); //搜索框
const ids = ref([])
const tableList = ref([]);
onMounted(() => {
const { deptBizType, deptLevel } = getItem('deptId')[0]
const Jb = deptLevel[0] == '2' ? '01' : deptLevel[0] == '3' ? '02' : '03'
qxkz.deptBizType = deptBizType
qxkz.deptLevel = Jb
getRouter()
tabHeightFn()
if (route.query.id) {
detailDiloag.value.init('edit', {
id: route.query.id
});
return
}
getList()
});
const chooseData = (val) => {
ids.value = val.map(item => {
return item.id
})
tableList.value = val
}
const qxkz = reactive({
deptBizType: "",
deptLevel: ""
})
const list = ref()
const searchConfiger = ref();
watch(() => D_BZ_BQJB, val => {
if (qxkz.deptLevel == '01') {
list.value = val.value.filter(item => {
return item.dm != '00'
})
} else if (qxkz.deptLevel == '02') {
list.value = val.value.filter(item => {
return item.dm == '01' || item.dm == '02'
})
} else {
list.value = []
}
searchConfiger.value = [
{ label: "情报标题", prop: 'qbmc', placeholder: "请输入情报标题", showType: "input" },
{ label: "姓名", prop: 'xssbr', placeholder: "请输入姓名", showType: "input" },
{ label: "身份证号", prop: 'sfzh', placeholder: "请输入身份证号", showType: "input" },
{ label: "群体名称", prop: 'qtmc', placeholder: "请输入群体名称", showType: "input" },
{ label: "指向地点", prop: 'zxdz', placeholder: "请输入指向地点", showType: "input" },
{ label: "指向时间", prop: 'zxkssj', placeholder: "请选择开始时间", showType: "datetimerange" },
{ label: "录入时间", prop: 'lrkssj', placeholder: "请选择开始时间", showType: "datetimerange" },
{ label: "情报类型", prop: 'qblx', placeholder: "请选择情报类型", showType: "select", options: D_GS_XS_LX },
{ label: "情报来源", prop: 'cjLx', placeholder: "请选择情报来源", showType: "select", options: D_BZ_CJLX },
{ label: "情报处置状态", prop: 'czzt', placeholder: "请选择处置状态", showType: "select", options: D_BZ_QBCZZT },
{
label: "标签级别", prop: 'qbjbList', placeholder: "请选择标签", showType: "select", options: list.value
},
{ label: "来源单位", prop: 'ssbmdm', placeholder: "请选择来源单位", showType: "department" },
{ label: "关键字", prop: 'keyword', placeholder: "请输入关键字", showType: "input" },
]
}, { deep: true, immediate: true })
const isShow = ref(false)
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
rowHieght: 61,
showSelectType: "checkBox",
loading: false
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
},
controlsWidth: 240,
tableColumn: [
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报类型", prop: "qblx", showSolt: true },
{ label: "情报来源", prop: "cjlx", showSolt: true },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "指向地点", prop: "zxdz" },
{ label: "消息状态", prop: "czzt", showSolt: true },
{ label: "情报内容", prop: "qbnr" },
]
});
const queryFrom = ref({});
const chooseRow = ref(false)
const dataList = ref()
const opneMsg = (item) => {
chooseRow.value = true
dataList.value = [item]
}
// 批量打标
const batchMark = () => {
chooseRow.value = true
dataList.value = tableList.value
}
// 搜索
const onSearch = (val) => {
const { lrkssj, zxkssj } = val
const promes = {
...val,
...pageData.pageConfiger,
lrkssj: lrkssj ? lrkssj[0] : '',
lrjssj: lrkssj ? lrkssj[1] : '',
zxkssj: zxkssj ? zxkssj[0] : '',
zxjssj: zxkssj ? zxkssj[1] : '',
}
queryFrom.value = { ...promes }
pageData.pageConfiger.pageCurrent = 1;
getList()
}
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList()
}
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList()
}
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let data = { ...pageData.pageConfiger, ...queryFrom.value };
if (queryFrom.value.qbjbList == '' || queryFrom.value.qbjbList == undefined) {
if (qxkz.deptLevel == '02') {
data = { ...data, qbjbList: "01,02" }
}else if(qxkz.deptLevel == '03'){
data = { ...data, qbjbList: "01" }
}
}
qbcjSelectPage(data).then(res => {
pageData.tableData = res.records || [];
pageData.total = res.total;
pageData.tableConfiger.loading = false;
}).catch(() => { pageData.tableConfiger.loading = false; })
}
// 删除
const delDictItem = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
qbcjDeletes({ ids: Array.isArray(id) ? id : [id] }).then((res) => {
proxy.$message({ type: "success", message: "删除成功" });
getList();
}).catch(() => {
})
}).catch(() => { });
}
// 导出数据
const tableColumn = reactive([
{ label: "上报人姓名", prop: "xssbr" },
{ label: "情报编号", prop: "xsBh" },
{ label: "情报标题", prop: "qbmc" },
{ label: "情报类型", prop: "qblx", showSolt: true, zd: 'D_GS_XS_LX' },
{ label: "情报来源", prop: "cjLx", showSolt: true, zd: 'D_BZ_CJLX' },
{ label: "情报上报时间", prop: "sxsbsj" },
{ label: "指向地点", prop: "zxdz" },
{ label: "情报内容", prop: "qbnr", showOverflowTooltip: true },
])
// 详情
const addEdit = (type, row) => {
isShow.value = true;
setTimeout(() => {
detailDiloag.value.init(type, row);
}, 500)
};
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const route = useRoute()
const titleData = ref()
const getRouter = () => {
titleData.value = route.meta.title
}
const exportFileModel = ref(false)
const dologCancel = () => {
exportFileModel.value = true;
}
// 流程
const checkProcessModel = ref()
const checkProcess = (item) => {
checkProcessModel.value = true
dataList.value = item
}
</script>
<style lang="scss" scoped>
.label-pop {
position: relative;
&::before {
position: absolute;
content: '*';
top: 0;
left: -7px;
color: red;
}
}
</style>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
:v-deep .el-dialog {
width: 90% !important;
}
.zdy-model-dialogs {
/* background-color: rgb(50, 148, 214); */
background: url("~@/assets/images/bg46.png") no-repeat center center;
background-size: 100% 100%;
padding: 8px 10px;
box-sizing: border-box;
pointer-events: auto !important;
height: calc(100% - 50px);
overflow: auto;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">人力情报信息收集任务调度{{ title }} </span>
<span class="title">上报任务调度{{ title }} </span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>

View File

@ -1,7 +1,7 @@
<template>
<div>
<div class="titleBox">
<PageTitle title="人力情报信息收集任务调度">
<PageTitle title="上报任务调度">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon style="vertical-align: middle">
<CirclePlus />

View File

@ -0,0 +1,158 @@
<!--文件导出 -->
<template>
<el-dialog v-model="modelValue" :title="title" :width="width" @close="close" append-to-body>
<div style="height: 50vh; overflow: auto;">
<el-timeline style="max-width: 600px">
<el-timeline-item :timestamp="item.czsj" placement="top" v-for="(item,index) in lcList" :key="index">
<el-card class="process-card">
<div class="process-info">
<div class="info-label">处置人</div>
<div class="info-value">{{item.czrxm || '未记录'}}</div>
</div>
<div class="process-info">
<div class="info-label">处置结果</div>
<div class="info-value">
<DictTag :tag="false" :value="item.czzt" :options="dict.D_BZ_QBCZZT" />
</div>
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close">取消</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { onMounted, reactive, watch, ref } from 'vue'
import {qbcjSelectCzlcList } from "@/api/Intelligence.js";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
width: {
type: String,
default: '50%'
}, tableColumn: {
type: Array,
default: () => []
}, dict: {
type: Object,
default: () => ({})
},
dataList: {
type: Object,
default: () => ({})
},
title: {
type: String,
default: '操作流程'
}
})
onMounted(() => {
})
const dxRadio = ref()
const emit = defineEmits(['update:modelValue', 'getList'])
// 当对话框显示时处理表格列配置
watch(() => props.modelValue, (newVal) => {
if (newVal) {
getqbcjPldb()
}
})
const close = () => {
emit('update:modelValue', false)
}
const lcList=ref([])
const getqbcjPldb = () => {
qbcjSelectCzlcList({ qbid: props.dataList.id }).then(res => {
lcList.value=res||[]
})
.catch(() => {
})
}
</script>
<style scoped>
/* 时间线样式优化 */
.el-timeline {
margin-top: 20px;
}
/* 处置流程卡片样式 */
.process-card {
border: none;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
margin-bottom: 16px;
border-left: 3px solid #409EFF;
}
.process-card:hover {
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
/* 卡片内部信息样式 */
.process-info {
display: flex;
align-items: flex-start;
margin-bottom: 12px;
flex-wrap: wrap;
}
.process-info:last-child {
margin-bottom: 0;
}
.info-label {
font-size: 14px;
font-weight: 600;
color: #409EFF;
margin-right: 8px;
min-width: 65px;
}
.info-value {
font-size: 14px;
color: #606266;
line-height: 1.6;
flex: 1;
word-break: break-word;
}
/* 时间戳样式 */
.el-timeline-item__timestamp {
font-size: 13px;
color: #909399;
margin-bottom: 8px;
}
/* 时间线节点样式 */
.el-timeline-item__node {
background-color: #409EFF;
}
/* 响应式设计 */
@media screen and (max-width: 768px) {
.process-info {
flex-direction: column;
}
.info-label {
margin-bottom: 4px;
}
}
</style>

View File

@ -0,0 +1,193 @@
<!--文件导出 -->
<template>
<el-dialog v-model="modelValue" :title="title" :width="width" @close="close" append-to-body>
<div style="height: 50vh; overflow: auto;">
<div class="intelligence-container" v-for="(item, index) in dataList" :key="index">
<div class="info-row">
<div class="info-item">
<div class="info-label">情报标题</div>
<div class="info-value">{{ item.qbmc }}</div>
</div>
<div class="info-item">
<div class="info-label">上报时间</div>
<div class="info-value">{{ item.sxsbsj }}</div>
</div>
</div>
<div class="info-row">
<div class="info-item">
<div class="info-label">情报类型</div>
<div class="info-value">
<DictTag :tag="false" :value="item.qblx" :options="dict.D_GS_XS_LX" />
</div>
</div>
<div class="info-item">
<div class="info-label">情报来源</div>
<div class="info-value">
<DictTag :tag="false" :value="item.cjLx" :options="dict.D_BZ_CJLX" />
</div>
</div>
</div>
<div class="content-section">
<div class="info-label">情报内容</div>
<div class="info-content">{{ item.qbnr }}</div>
</div>
</div>
<div class="content-section">
<div class="info-label">选中标签</div>
<el-radio-group v-model="dxRadio">
<el-radio :label="items.dm" v-for="(items, index) in dictList" :key="index">{{ items.zdmc }}</el-radio>
</el-radio-group>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="submit">
确认
</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import { onMounted, reactive, watch, ref } from 'vue'
import { ElMessage } from 'element-plus'
import { qbcjCzzt, qbcjPldb } from "@/api/Intelligence.js";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
width: {
type: String,
default: '50%'
}, tableColumn: {
type: Array,
default: () => []
}, dict: {
type: Object,
default: () => ({})
},
dataList: {
type: Array,
default: () => ([])
},
title: {
type: String,
default: '打标签'
}
})
onMounted(() => {
})
const dxRadio = ref()
const emit = defineEmits(['update:modelValue', 'getList'])
// 当对话框显示时处理表格列配置
watch(() => props.modelValue, (newVal) => {
if (newVal) {
dxRadio.value = props.dataList[0].qbjb
}
}, { deep: true })
const dictList = ref([])
watch(() => props.dict, (newVal, oldVal) => {
if (newVal) {
dictList.value = newVal.D_BZ_BQJB.filter(item => item.dm != '00')
}
})
const close = () => {
emit('update:modelValue', false)
}
const submit = () => {
if (!dxRadio.value) {
ElMessage({
message: '请选择标签',
type: 'warning',
showClose: true,
})
return
}
getqbcjPldb()
}
const getqbcjPldb = () => {
qbcjPldb({ ids: props.dataList.map(item => item.id), qbjb: dxRadio.value, czzt: '05' }).then(res => {
ElMessage({
message: '操作成功',
type: 'success',
showClose: true,
})
emit('getList')
close()
})
.catch(() => {
})
}
</script>
<style scoped>
.intelligence-container {
padding: 10px;
}
.info-row {
display: flex;
margin-bottom: 20px;
gap: 30px;
flex-wrap: wrap;
}
.info-item {
flex: 1;
min-width: 250px;
}
.info-label {
font-size: 14px;
font-weight: 600;
color: #409EFF;
margin-bottom: 8px;
}
.info-value {
font-size: 14px;
color: #606266;
padding: 8px;
background-color: #f5f7fa;
border-radius: 4px;
min-height: 32px;
line-height: 1.5;
}
.content-section {
margin-top: 10px;
}
.info-content {
font-size: 14px;
color: #606266;
padding: 12px;
background-color: #f5f7fa;
border-radius: 4px;
min-height: 100px;
line-height: 1.8;
white-space: pre-wrap;
word-break: break-word;
border-left: 3px solid #409EFF;
}
/* 响应式设计 */
@media screen and (max-width: 768px) {
.info-row {
flex-direction: column;
gap: 15px;
}
.info-item {
min-width: 100%;
}
}
</style>

View File

@ -20,7 +20,8 @@
<el-form-item label="地图范围" prop="pgis" class="ww100">
<div class="flex ww100">
<el-input v-model="listQuery.pgis" readonly placeholder="请输入地图范围" style="flex: 1;"></el-input>
<el-button :disabled="listQuery.qylx == 'xzqh'" type="primary" style="width: 136px;" class="ml10" @click="chooseMap">
<el-button :disabled="listQuery.qylx == 'xzqh'" type="primary" style="width: 136px;" class="ml10"
@click="chooseMap">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
@ -46,7 +47,7 @@
</div>
</el-form>
</el-dialog>
<ChooseGzy v-model="openDialog" @choose="chooseDataGzy" :roleIds="roleIds"/>
<ChooseGzy v-model="openDialog" @choose="chooseDataGzy" :roleIds="roleIds" />
</template>
@ -116,29 +117,29 @@ const getDateById = (id) => {
res.pgis = res.pgis ? [res.pgis] : [[[]]]
let icon = require('@/assets/point/sp.png');
nextTick(() => {
if (res.qylx=='xzqh') {
if (res.qylx == 'xzqh') {
emitter.emit('setBoundarys', {
data: {
type: "FeatureCollection",
features: [
{
geometry: {
type: "Polygon", // 多边形类型
coordinates: res.pgis // 坐标数组
},
properties: {}, // 属性信息
type: "Feature", // 特征类型
}
]
}
data: {
type: "FeatureCollection",
features: [
{
geometry: {
type: "Polygon", // 多边形类型
coordinates: res.pgis // 坐标数组
},
properties: {}, // 属性信息
type: "Feature", // 特征类型
}
]
}
})
})
} else {
if (res.sxts && res.sxts.length > 0) emitter.emit('addPointArea', { flag: 'gzy_ht', icon, coords: res.sxts });
if (res.pgis) {
let obj = { position: res.pgis, text: '', id: res.id };
emitter.emit("echoPlane", { coords: [obj], flag: "bkqy", type: "polygon" });
}
if (res.pgis) {
let obj = { position: res.pgis, text: '', id: res.id };
emitter.emit("echoPlane", { coords: [obj], flag: "bkqy", type: "polygon" });
}
}
})
@ -181,13 +182,13 @@ const closed = () => {
emitter.emit('removeEara', 'bkqy_ht')
emitter.emit('deletePointArea', 'gzy_ht')
showMap.value = false;
roleIds.value=[]
roleIds.value = []
formRef.value.resetFields();
modelShow.value = false;
};
const changeXzqh = (val) => {
emitter.emit('removeBj')
listQuery.value.pgis=bm[val]
listQuery.value.pgis = bm[val]
emitter.emit('setBoundarys', {
data: {
type: "FeatureCollection",
@ -218,15 +219,16 @@ const changeMap = (val) => {
// 感知源弹窗
const openDialog = ref(false);
const roleIds=ref([])
const roleIds = ref([])
const chooseDataGzy = (val) => {
roleIds.value = val.map(item => item.id)
listQuery.value.sxts = val.map(item => {
listQuery.value.sxts = val.map(item => {
return {
sbbh:item.sbbh,
sblx:item.sblx,
sbmc:item.sbmc,
}}
sbbh: item.sbbh,
sblx: item.sblx,
sbmc: item.sbmc,
}
}
)
}

View File

@ -12,16 +12,12 @@
<div class="form_cnt">
<el-form :model="listQuery" :rules="rules" :disabled="disabled" ref="elform" inline :label-width="100"
label-position="left">
<div class="smallTitle">布控信息</div>
<!-- <el-form-item prop="bkBt" label="布控标题">
<MOSTY.Other v-model="listQuery.bkBt" placeholder="请输入布控标题" clearable />
</el-form-item> -->
<el-form-item prop="bkDx" label="布控对象">
<MOSTY.Select v-model="listQuery.bkDx" @change="shangeDx" :dictEnum="props.dic.D_GS_BK_DX"
placeholder="请选择布控对象" clearable />
</el-form-item>
<div class="ww100 mt10 mb10">
<el-button type="primary" @click="handleAddPeo" v-if="!disabled">
<div style="display: flex; align-items: center;margin-bottom: 10px;">
<el-radio-group v-model="listQuery.bkDx" size="large" fill="#6cf" @change="shangeDx">
<el-radio-button :label="item.dm" v-for="(item, index) in props.dic.D_GS_BK_DX"
:key="index" >{{ item.zdmc }}</el-radio-button>
</el-radio-group>
<el-button type="primary" @click="handleAddPeo" v-if="!disabled" style="margin-left: 10px;">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
@ -33,7 +29,7 @@
:tableHeight="tableDate.tableHeight" :key="tableDate.keyCount" :tableConfiger="tableDate.tableConfiger"
:controlsWidth="tableDate.controlsWidth">
<template #fjZp="{ row }">
<el-image :src="row.fjZp"></el-image>
<el-image :src="setAddress(row.fjZp)"></el-image>
</template>
<template #yjdj="{ row }">
<DictTag :tag="false" :value="row.yjdj" :options="props.dic.D_GS_ZDR_YJDJ" />
@ -56,39 +52,8 @@
</template>
</MyTable>
</div>
<div class="smallTitle">布控范围</div>
<div class=" mapSearch flex">
<el-select v-model="hzfs" placeholder="请选择布控范围" clearable @change="qhhzfs">
<el-option label="区域选择" value="1"></el-option>
<el-option label="自定义范围" value="2"></el-option>
</el-select>
<el-select multiple style="margin-left: 10px;" v-model="bkqyList" placeholder="请选择布控范围" clearable
@change="hzfsChage" v-if="hzfs == '1'">
<el-option :label="item.label" :value="item.value" v-for="(item, index) in bkqyArr" :key="index">{{
item.label
}}</el-option>
</el-select>
<!-- <MOSTY.Select v-model="listQuery.bkqyList" filterable multiple :dictEnum="bkqyArr" style="width:350px"
placeholder="请选择布控范围" clearable /> -->
<el-button type="primary" @click="drawQy" style="margin-left: 10px;" v-else>
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">自定义区域</span>
</el-button>
</div>
<div class="ww100 relative mb10"
style="height: 250px;border: 1px solid #dcdfe6;border-radius: 4px;overflow: hidden;">
<GdMap></GdMap>
</div>
<!-- <el-form-item prop="bkBt" label="布控要素" style="width: 100%;">
<div class="flex align-center">
<el-button @click="listQuery.bkYz = it.dm" :type="listQuery.bkYz == it.dm ? 'primary' : ''"
v-for="it in props.dic.D_GS_BK_BKYS" :key="it">{{ it.zdmc }}</el-button>
</div>
</el-form-item> -->
<div style="width: 100%;" class="mt25">
<el-form-item prop="bkSjKs" label="布控开始时间" label-width="120px">
<el-form-item prop="bkSjKs" label="布控开始时间" label-width="120px" >
<MOSTY.Date v-model="listQuery.bkSjKs" type="datetime" format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择布控开始时间" clearable />
</el-form-item>
@ -96,19 +61,17 @@
<MOSTY.Date v-model="listQuery.bkSjJs" type="datetime" format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择布控结束时间" clearable />
</el-form-item>
</div>
<div style="width: 100%;" class="mt25">
<el-form-item prop="czYq" label="处置要求">
<el-form-item prop="czYq" label="处置要求" label-width="60px" style="width:18% ;">
<MOSTY.Select v-model="listQuery.czYq" :dictEnum="props.dic.D_GS_BK_CZYQ" placeholder="请选择处置要求"
clearable />
</el-form-item>
<el-form-item prop="bkDj" label="布控等级">
<el-form-item prop="bkDj" label="布控等级" label-width="60px" style="width:18% ;">
<MOSTY.Select v-model="listQuery.bkDj" :dictEnum="props.dic.D_GS_BK_DJ" placeholder="请选择布控级别"
clearable />
</el-form-item>
</div>
<div style="width: 100%;" class="mt10">
<el-form-item prop="bkSy" label="布控事由" style="width: 100%;">
<el-form-item prop="bkSy" label="布控事由" style="width: 100%;" >
<MOSTY.Other v-model="listQuery.bkSy" placeholder="请输入布控事由" type="textarea" style="width: 100%;"
clearable />
</el-form-item>
@ -120,6 +83,30 @@
<div>支持pngjpgpdf文件上传</div>
</div>
</el-form-item>
</div>
<div class="smallTitle">布控范围</div>
<div class=" mapSearch flex">
<el-select v-model="hzfs" placeholder="请选择布控范围" clearable @change="qhhzfs">
<el-option label="区域选择" value="1"></el-option>
<el-option label="自定义范围" value="2"></el-option>
</el-select>
<el-select multiple style="margin-left: 10px;" v-model="bkqyList" placeholder="请选择布控范围" clearable
@change="hzfsChage" v-if="hzfs == '1'">
<el-option :label="item.label" :value="item.value" v-for="(item, index) in bkqyArr" :key="index">{{
item.label
}}</el-option>
</el-select>
<el-button type="primary" @click="drawQy" style="margin-left: 10px;" v-else>
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">自定义区域</span>
</el-button>
</div>
<div class="ww100 relative mb10"
style="height: 60vh;border: 1px solid #dcdfe6;border-radius: 4px;overflow: hidden;">
<GdMap></GdMap>
</div>
</el-form>
</div>
@ -158,11 +145,14 @@ import emitter from "@/utils/eventBus.js";
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, nextTick, watch, onMounted } from "vue";
import { queryProcessNode, queryProcessNodeLog, queryProcess } from '@/api/spl'
import ApprovalEcho from "@/components/flowPath/ApprovalEcho.vue";
import { useRouter, useRoute } from 'vue-router'
import { setAddress } from '@/utils/tools.js'
import { tbGsxtBkId } from "@/api/commit.js";
const emit = defineEmits(["change"]);
const props = defineProps({
dic: Object
});
const route = useRoute()
const elform = ref()
const roleIds = ref([]); //角色ID
const chooseVisible_RY = ref(false); //选择布控人员弹窗
@ -357,6 +347,8 @@ const choosed = (val) => {
// 选择人员
const handleAddPeo = () => {
console.log(listQuery.value.bkDx);
if (!listQuery.value.bkDx) return proxy.$message({ type: "warning", message: '请选择布控对象' });
switch (listQuery.value.bkDx) {
case '01':
@ -385,7 +377,13 @@ const handleAddPeo = () => {
const submit = () => {
elform.value.validate((validate) => {
if (!validate) return;
let params = { ...listQuery.value };
let bklx = ''
if (route.name == 'myControl') {
bklx = '01'
} else {
bklx = '02'
}
let params = { ...listQuery.value, bklx: bklx };
params.bkfj = params.bkfj ? params.bkfj.join(',') : '';
params.bkdxList = params.bkdxList ? params.bkdxList : [];
params.bkdxList.forEach(item => { item.fjZp = item.fjZp ? item.fjZp.join(',') : '' })
@ -663,4 +661,11 @@ defineExpose({ init });
color: #18a2dd;
}
}
::v-deep .el-form-item__label{
padding: 0;
}
::v-deep .el-radio-button__inner{
color:#000 !important;
}
</style>

View File

@ -1,7 +1,7 @@
<template>
<div>
<div class="titleBox">
<PageTitle title="我的布控">
<PageTitle :title=" route.meta.title ">
<el-button type="primary" @click="handleAdd('add', null)">发起布控</el-button>
</PageTitle>
</div>
@ -47,12 +47,12 @@
<template v-if="!row.gzlid">
<el-link type="primary" v-if="['01', '03', '06'].includes(row.bkZt)" size="small"
@click="createProcess(row)">送审</el-link>
<el-link type="primary" size="small" @click="tbGsxtBkQuashList( row)" v-else>撤控</el-link>
<el-link type="primary" v-if="['01', '03', '06'].includes(row.bkZt)" size="small"
@click="handleAdd('edit', row)">编辑</el-link>
</template>
<!-- 审核通过后才有轨迹 -->
<el-link type="primary" size="small" @click="handleAdd('detail', row)">轨迹</el-link>
<el-link type="primary" size="small" @click="handleAdd('detail', row)">详情</el-link>
<el-link type="danger" size="small" @click="handleRow(row.id)"
v-if="['01', '03', '06'].includes(row.bkZt)">删除</el-link>
@ -66,14 +66,13 @@
</div>
</div>
<!-- 布控类型 -->
<AddBkdx ref="addBkdxForm" @change="getList"
:dic="{
D_GS_BK_DX, D_GS_BK_BKYS, D_BZ_XB, D_GS_BK_CZYQ,
D_GS_BK_DJ, BD_BK_CLYJBQ, D_GS_BK_CZJSDWLX, D_GS_BK_TJFS,D_GS_ZDR_YJDJ
}" />
<AddBkdx ref="addBkdxForm" @change="getList" :dic="{
D_GS_BK_DX, D_GS_BK_BKYS, D_BZ_XB, D_GS_BK_CZYQ,
D_GS_BK_DJ, BD_BK_CLYJBQ, D_GS_BK_CZJSDWLX, D_GS_BK_TJFS, D_GS_ZDR_YJDJ
}" />
<!-- 预警弹窗 -->
<YjDialog ref="warningkdxForm"></YjDialog>
<SubmissionProcess v-model="showSp" :data="rowData" :userData="{ ajmc: '布控审批', flowType: 'BKSP',modelName:'布控' }"
<SubmissionProcess v-model="showSp" :data="rowData" :userData="{ ajmc: '布控审批', flowType: 'BKSP', modelName: '布控' }"
:path="fixedValue" @getList="getList" />
</template>
@ -86,10 +85,14 @@ import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import SubmissionProcess from '@/components/flowPath/submissionProcess.vue'
import {tbGsxtBkQuash} from '@/api/zdr.js'
import { useRouter, useRoute } from 'vue-router'
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
const router = useRouter()
const route = useRoute()
const { proxy } = getCurrentInstance();
const { D_GS_BK_BKYS, D_BZ_XB, D_GS_BK_SJLX, D_GS_BK_DJ, BD_BK_CLYJBQ,D_GS_ZDR_YJDJ,
D_GS_BK_DX, D_GS_BK_ZT, D_GS_BK_CZYQ, D_GS_BK_CZJSDWLX, D_GS_BK_TJFS } = proxy.$dict("D_GS_ZDR_YJDJ","D_GS_BK_BKYS", "D_BZ_XB", "D_GS_BK_SJLX", "D_GS_BK_DJ", "D_GS_BK_DX", "D_GS_BK_ZT", "D_GS_BK_CZYQ", "D_GS_BK_CZJSDWLX", "D_GS_BK_TJFS", 'BD_BK_CLYJBQ'); //获取字典数据
const { D_GS_BK_BKYS, D_BZ_XB, D_GS_BK_SJLX, D_GS_BK_DJ, BD_BK_CLYJBQ, D_GS_ZDR_YJDJ,
D_GS_BK_DX, D_GS_BK_ZT, D_GS_BK_CZYQ, D_GS_BK_CZJSDWLX, D_GS_BK_TJFS } = proxy.$dict("D_GS_ZDR_YJDJ", "D_GS_BK_BKYS", "D_BZ_XB", "D_GS_BK_SJLX", "D_GS_BK_DJ", "D_GS_BK_DX", "D_GS_BK_ZT", "D_GS_BK_CZYQ", "D_GS_BK_CZJSDWLX", "D_GS_BK_TJFS", 'BD_BK_CLYJBQ'); //获取字典数据
const addBkdxForm = ref(null); //布控对象组件
const warningkdxForm = ref(); //布控对象组件
const searchBox = ref(); //搜索框
@ -144,11 +147,10 @@ const pageData = reactive({
});
// 固定值
const fixedValue = {
clueVerification:'deploymentApproval',
clueVerification: 'deploymentApproval',
byMeansOf: 'tbGsxtBk/gsbkCallback',
nobyMeansOf: 'tbGsxtBk/gsbkCallback',
recycle:'tbGsxtBk/gsbkCallback',
recycle: 'tbGsxtBk/gsbkCallback',
}
const showSp = ref(false);
const rowData = ref()
@ -180,10 +182,19 @@ const changeSize = (val) => {
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let bklx = ''
console.log();
if (route.name == 'myControl') {
bklx = '01'
} else {
bklx = '02'
}
let data = {
...pageData.pageConfiger,
...queryFrom.value,
bkcxlx: '01'
bkcxlx: '01',
bklx: bklx
};
qcckGet(data, "/mosty-gsxt/tbGsxtBk/selectPage").then((res) => {
pageData.tableData = res.records || [];
@ -194,25 +205,10 @@ const getList = () => {
});
};
// 打开预警
const openWarning = (val) => {
warningkdxForm.value.init(val)
}
const handleAdd = (type, row) => {
addBkdxForm.value.init(type, row);
};
// 送审
const handleSend = (id) => {
proxy.$confirm("确定要送审?", "警告", { type: "warning" }).then(() => {
qcckPost({}, "/mosty-gsxt/tbGsxtBk/subExamine/" + id).then(() => {
proxy.$message({ type: "success", message: "送审成功" });
getList();
});
})
}
// 删除
const handleRow = (id) => {
proxy.$confirm("确定要删除?", "警告", { type: "warning" }).then(() => {
@ -229,7 +225,14 @@ const tabHeightFn = () => {
window.onresize = function () {
tabHeightFn();
};
};</script>
};
const tbGsxtBkQuashList = (item) => {
tbGsxtBkQuash({id:item.id}).then(res=>{
proxy.$message({ type: "success", message: "操作成功" });
getList();
})
}
</script>
<style lang="scss" scoped>
.el-loading-mask {

View File

@ -0,0 +1,136 @@
<template>
<el-dialog width="1400px" :draggable="true" custom-class="bgData" :model-value="modelValue" append-to-body
@close="close" :show-close="false">
<template #title>
<div class="title">
<div class="titleName">测试数据</div>
<div>
<el-icon :size="25" class="titleIcon">
<BottomLeft />
</el-icon>
<el-icon :size="25" class="titleIcon">
<FullScreen />
</el-icon>
<el-icon @click="close" :size="25" class="titleIcon">
<Close />
</el-icon>
</div>
</div>
<div class="statusBar">
<div>00:04</div>
<div>正在讲话...</div>
<div>
<el-icon :size="25" class="titleIcon">
<InfoFilled />
</el-icon>
<el-icon :size="25" class="titleIcon">
<CircleCheckFilled />
</el-icon>
<el-icon @click="close" :size="25" class="titleIcon">
<Unlock />
</el-icon>
</div>
</div>
</template>
<div class="content"></div>
<template #footer>
<Footer @close="close" />
</template>
</el-dialog>
</template>
<script setup>
import { ref, watch, reactive, toRaw, computed, getCurrentInstance } from "vue";
import Footer from './footer.vue'
// import useCallModule from '../sdk/call.js'
const { proxy } = getCurrentInstance();
// const Call = useCallModule()
lemon.login.login({
username: "linzhigongan1",
password: "linzhigongan1",
realm: "puc.com",
webpucUrl: "https://192.168.0.1:16888",
}).then(res => {
console.log(res,"登录成功");
}).catch(err => {
console.log(err,"登录失败");
})
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
titleValue: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:modelValue']);
const close = () => {
emit('update:modelValue', false);
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
.title {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #e4e7ed;
padding: 10px;
.titleName {
font-size: 20px;
margin-bottom: 5px;
width: 40%;
}
.titleIcon {
margin-left: 15px;
}
}
.statusBar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 6px;
}
.content {
padding: 0 10px;
height: 60vh;
overflow: auto;
background-color: #000;
}
.tabBoxRadio .el-checkbox__inner {
border-radius: 50% !important;
}
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
display: none;
}
.bgData {
padding: 10px;
}
::v-deep .el-dialog__body {
padding: 0 !important;
}
</style>
<style>
.bgData .el-dialog__header,
.el-dialog__body {
padding: 0;
}
</style>

View File

@ -0,0 +1,88 @@
<template>
<div class="footer">
<div class="footerWidth">
<div>
<div class="icon"><img src="@/assets/images/icon/jyy-k.png" alt=""></div>
<div>麦克风</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/lb-k.png" alt=""></div>
<div>喇叭</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/sp-k.png" alt=""></div>
<div>摄像头</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/fx.png" alt=""></div>
<div>共享</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/hyyq.png" alt=""></div>
<div>邀请参会</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/glcy.png" alt=""></div>
<div>管理成员</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/jt.png" alt=""></div>
<div>截图</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/gb.png" alt=""></div>
<div>视频广播</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/yyjl.png" alt=""></div>
<div>语音激励</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/fz.png" alt=""></div>
<div>画面反转</div>
</div>
<div>
<div class="icon"><img src="@/assets/images/icon/yy.png" alt=""></div>
<div>应用</div>
</div>
</div>
<div class="footerBtn">
<el-button type="danger">结束会议</el-button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const emit=defineEmits(['close'])
const close=()=>{
emit('close')
}
</script>
<style scoped lang="scss">
.footer {
display: flex;
justify-content: space-between;
align-items: center;
height: 50px;
.footerWidth {
display: flex;
justify-content: space-between;
align-items: center;
flex: 1;
.icon{
width: 25px;
margin: 0 auto;
img{
width: 100%;
}
}
}
.footerBtn {
width: 100px;
margin-left: 20px;
}
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<el-dialog width="1400px" title="选择参会人员" :draggable="true" :model-value="modelValue" append-to-body @close="close"
:show-close="false">
<div class="content">
<div class="left">
<el-tabs v-model="activeName" @tab-click="handleClick" :stretch="true">
<el-tab-pane label="全网设备" name="first">
<el-tree-v2 style="max-width: 600px" :data="data" :props="propsData" :height="530" />
</el-tab-pane>
<el-tab-pane label="调度台" name="second">Config</el-tab-pane>
<el-tab-pane label="动态警组" name="third">Role</el-tab-pane>
<el-tab-pane label="第三方会议" name="fourth">Task</el-tab-pane>
<el-tab-pane label="车载" name="fourth">Task</el-tab-pane>
</el-tabs>
<!-- <el-tree-v2
style="max-width: 600px"
:data="data"
:props="propsData"
:height="600"
/> -->
</div>
<div class="right"></div>
</div>
</el-dialog>
</template>
<script setup>
import { ref, watch, reactive, toRaw, computed, getCurrentInstance, onMounted } from "vue";
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
titleValue: {
type: String,
default: ''
}
})
// Tabs 组件
const activeName = ref('first')
const handleClick = (tab) => {
console.log(tab)
}
onMounted(() => {
lemon.basedata.fetchSystemOrg({
flat: true,
key_word: ""
}).then(res => {
console.log(res);
})
})
const getJgList = () => {
}
const getKey = (prefix, id) => {
return `${prefix}-${id}`
}
const createData = (
maxDeep,
maxChildren,
minNodesNumber,
deep = 1,
key = 'node'
) => {
let id = 0
return Array.from({ length: minNodesNumber })
.fill(deep)
.map(() => {
const childrenNumber =
deep === maxDeep ? 0 : Math.round(Math.random() * maxChildren)
const nodeKey = getKey(key, ++id)
return {
id: nodeKey,
label: nodeKey,
children: childrenNumber
? createData(maxDeep, maxChildren, childrenNumber, deep + 1, nodeKey)
: undefined,
}
})
}
const propsData = {
value: 'id',
label: 'label',
children: 'children',
}
const data = createData(4, 30, 40)
const emit = defineEmits(['update:modelValue']);
const close = () => {
emit('update:modelValue', false);
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
.content {
padding: 0 10px;
height: 60vh;
overflow: auto;
display: flex;
.left {
width: 20%;
height: 100%;
// background-color: #3c8aff;
margin-right: 5px;
}
.right {
flex: 1;
height: 99%;
border: 1px solid #ccc;
}
}
::v-deep .el-tabs__nav-wrap::after {
background-color: #ccc;
}
::v-deep .el-tabs__nav-next,
.el-tabs__nav-prev {
color: #000;
}
::v-deep .el-tabs__item {
color: #000;
}
::v-deep .el-tabs__item.is-active {
color: #3c8aff;
}
</style>

View File

@ -13,11 +13,12 @@
<el-input placeholder="请选择关联线索" @click="chooseVisiblexS = true" readonly v-model="listQuery.glxsmc"></el-input>
</template>
<template #chryList>
<el-input placeholder="请选择参会人员" @click="chooseVisible = true" readonly v-model="listQuery.rymc"></el-input>
<el-input placeholder="请选择参会人员" @click="openMeetings = true" readonly v-model="listQuery.rymc"></el-input>
</template>
</FormMessage>
</div>
</div>
<Personnel v-model="openMeetings" />
<ChooseUser v-model="chooseVisible" :Single="false" @choosedUsers="handleUserSelected" :roleIds="roleIds" />
<Xslist v-model="chooseVisiblexS" @choosed="choosed" :roleIds="roleIdsxs"></Xslist>
</template>
@ -27,6 +28,7 @@ import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue";
import Xslist from '@/components/ChooseList/ChooseXs/index.vue'
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import Personnel from '../components/Communications/personnel.vue'
import { ref, defineExpose, reactive, defineEmits, getCurrentInstance, } from "vue";
const emit = defineEmits(["updateDate"]);
@ -109,6 +111,8 @@ const close = () => {
dialogForm.value = false;
loading.value = false;
};
// 选择参会人员
const openMeetings=ref(false)
defineExpose({ init });
</script>

View File

@ -66,6 +66,7 @@
<!-- 详情 -->
<DetailForm ref="detailDiloag" @updateDate="getList" />
<RoomDetail />
<ConferenceRoom v-model="conferenceRoomVisible" titleValue="会议详情" />
</template>
<script setup>
@ -77,7 +78,8 @@
import RoomDetail from "./components/roomDetail.vue";
import { useRoute, useRouter } from 'vue-router';
import { qcckGet, qcckPost, qcckDelete } from "@/api/qcckApi.js";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
import ConferenceRoom from "./components/Communications/conferenceRoom.vue";
const route = useRoute();
const { proxy } = getCurrentInstance();
const detailDiloag = ref();
@ -165,10 +167,11 @@
})
};
// 加入会议
const joinMeeting = (item) => {
qcckPost({id:item.id},'/mosty-gsxt/wshs/addWshyRy').then((res)=>{
getList();
})
const joinMeeting = (item) => {
conferenceRoomVisible.value = true;
// qcckPost({id:item.id},'/mosty-gsxt/wshs/addWshyRy').then((res)=>{
// getList();
// })
};
// 删除
@ -192,7 +195,12 @@ const delDictItem = (id) =>{
window.onresize = function () {
tabHeightFn();
};
};
};
// 会议详情弹窗
const conferenceRoomVisible = ref(false);
</script>
<style lang="scss" scoped>

View File

@ -0,0 +1,714 @@
// import { Notification } from '@arco-design/web-vue';
import { ElNotification, ElMessage } from 'element-plus'
import emitter from "@/utils/eventBus.js";
// import handleCallingNotification from '../hooks/callingNotification';
let call_id;
let hangup_event_cb_id;
let force_hangup_event_cb_id;
let answer_ack_cb_id;
let incoming_cb_id;
let floor_grant_cb_id;
// Whether it is a pushVideoFile call
// 是否为视频推送的呼叫
let pushing_video = false;
// monitor call list
// 值守呼叫列表
const monitor_call_list = [];
export default function useCallModule() {
// we allow only one call exist in demo.but actually,sdk supports more
/**
* make private vioce call,return nothing,receive result in callback
* This interface has been expanded to support makeGroupVoiceCall、makeDispatcherVoiceCall、makeConferenceVoiceCall、makeCrosspatchVoiceCall
* 这个接口已扩展,除了支持语音单呼外,还支持语音组呼、语音呼叫调度员、语音会议、群组呼叫。
* @param record who you wanna call
* @returns
*/
const makeVoiceCall = (record) => {
if (call_id) {
console.warn('we allow only one call exist,please hangup first');
return;
}
window.lemon.call
.makeVoiceCall({ basedata_id: record.basedata_id, hook_flag: 0 })
?.then((resp) => {
call_id = resp.call_id;
console.info('makeVoiceCall succ,registerCallEstablishEvent', call_id);
});
// test
// window.lemon.call.changeCamera({ call_id, target_camera: 0 });
// also can use this makecall method,the method provides the most comprehensive call capability
// For example, Voice private call, ensure that the basedata_id is a private
// window.lemon.call
// .makeCall({
// callee_guid: record.basedata_id,
// attribute: {
// call_type: 0,
// call_mode: 0,
// duplex_flag: 0,
// },
// })
// ?.then((resp) => {
// console.info('makeCall succ,resp', resp);
// call_id = resp.call_id;
// });
// For example, Voice group call,ensure that the basedata_id is a group
// window.lemon.call
// .makeCall({
// callee_guid: record.basedata_id,
// attribute: {
// call_type: 1,
// call_mode: 0,
// duplex_flag: 0, // group call ,the value must be 0
// },
// })
// ?.then((resp) => {
// console.info('makeCall succ,resp', resp);
// call_id = resp.call_id;
// });
};
/**
* make private video call,call with vioce and video,return nothing,receive result in callback
* This interface has been expanded to support makeGroupVideoCall、makeDispatcherVideoCall、makeConferenceVideoCall
* 这个接口已扩展,除了支持视频单呼外,还支持视频组呼、视频呼叫调度员、视频会议
* @param record who you wanna call
* @returns
*/
const makeVideoCall = (record) => {
if (call_id) {
console.warn('we allow only one call exist,please hangup first');
return;
}
window.lemon.call
.makeVideoCall({ basedata_id: record.basedata_id, video_frame_size: 3 })
?.then((resp) => {
call_id = resp.call_id;
console.warn('makeVideoCall succ,call_id=', call_id);
});
// also can use this makecall method,the method provides the most comprehensive call capability
// For example, Video private call (with voice), ensure that the basedata_id is a private
// window.lemon.call
// .makeCall({
// callee_guid: record.basedata_id,
// attribute: {
// call_type: 11,
// call_mode: 2,
// duplex_flag: 1,
// },
// video_frame_size: window.lemon.call.getMaxFrameSize(),
// })
// ?.then((resp) => {
// console.info('makeCall succ,resp', resp);
// call_id = resp.call_id;
// });
// For example, Video group call,ensure that the basedata_id is a group
// window.lemon.call
// .makeCall({
// callee_guid: record.basedata_id,
// attribute: {
// call_type: 13,
// call_mode: 2,
// duplex_flag: 0, // group call ,the value must be 0
// },
// video_frame_size: window.lemon.call.getMaxFrameSize(),
// })
// ?.then((resp) => {
// console.info('makeCall succ,resp', resp);
// call_id = resp.call_id;
// });
};
const makeGroupVideoCall = (record) => {
if (call_id) {
console.warn('we allow only one call exist,please hangup first');
return;
}
window.lemon.call
.makeGroupVideoCall({
basedata_id: record.basedata_id,
video_frame_size: 3,
})
?.then((resp) => {
console.log('makeGroupVideoCall call_id = ', call_id);
call_id = resp.call_id;
});
};
const makeGroupVoiceCall = (record) => {
if (call_id) {
console.warn('we allow only one call exist,please hangup first');
return;
}
window.lemon.call
.makeGroupVoiceCall({
basedata_id: record.basedata_id,
})
?.then((resp) => {
call_id = resp.call_id;
});
};
const makeCrosspatchVoiceCall = (record) => {
window.lemon.call
.makeCrosspatchVoiceCall({ basedata_id: record.basedata_id })
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* 视频上拉
* make pure video call,only video, no voice
* @param record who you wanna call
* @returns
*/
const pureVideoCall = (record) => {
if (call_id) {
console.warn('we allow only one call exist,please hangup first');
return;
}
window.lemon.call
.pullVideo({ basedata_id: record.basedata_id, hook_flag: 0 })
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* 环境监听
* @param record
*/
const voiceDetect = (record) => {
window.lemon.call
.makeCall({
callee_guid: record.basedata_id,
attribute: {
call_type: 0,
call_mode: 0,
duplex_flag: 0,
ambience_flag: 1,
},
})
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* 环境监视
* @param record
*/
const videoDetect = (record) => {
window.lemon.call
.makeCall({
callee_guid: record.basedata_id,
attribute: {
call_type: 11,
call_mode: 2,
duplex_flag: 0,
ambience_flag: 1,
},
})
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* 音频会议
* @param record
*/
const makeConferenceVoiceCall = (record) => {
window.lemon.call
.makeConferenceVoiceCall({
basedata_id: record.basedata_id,
})
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* 音视频会议
* @param record
*/
const makeConferenceVideoCall = (record) => {
window.lemon.call
.makeConferenceVideoCall({
basedata_id: record.basedata_id,
})
?.then((resp) => {
call_id = resp.call_id;
});
};
// 广播呼叫
// Broadcast Call
const makeBroadcastCall = (record) => {
window.lemon.call
.makeCall({
callee_guid: record.basedata_id,
attribute: {
call_type: 3,
call_mode: 0,
},
})
?.then((resp) => {
call_id = resp.call_id;
});
};
/**
* hangup call
*/
const hangup = (id) => {
console.info('try hangup,call_id=', call_id);
console.info('try hangup,id=', id);
window.lemon.call
.hangupCall({ call_id: id || call_id })
?.then(() => {
call_id = undefined;
window.calling_conference = undefined;
// console.log('22222registerCallEstablishEven');
})
.catch((err) => {
console.error('hangup call error,', err);
});
};
/**
* 接听呼叫
* answer call
*/
const answerCall = () => {
ElNotification.close(call_id);
window.lemon.call
.answerCall({ call_id })
?.then(() => {
// display alert ui
ElNotification.close(call_id);
})
.catch((err) => {
console.error('answer call error,', err);
});
};
// 禁麦
// mute the microphone
const setMuteMic = (mute) => {
return window.lemon.call.muteMic({
call_id,
is_mute: mute,
});
};
// 禁摄像头
// disable the camera
const setMuteCamera = (mute) => {
return window.lemon.call.muteCamera({
call_id,
is_mute: mute,
});
};
// 静音
// mute call
const setMuteCall = (mute) => {
return window.lemon.call.muteCall({
call_id,
is_mute: mute,
});
};
const removeMonitorCall = (callId) => {
const index = monitor_call_list.findIndex(
(item) => item.call_id === callId
);
if (index >= 0) {
monitor_call_list.splice(index, 1);
emitter.emit('monitorUpdate');
}
};
const getMonitorCallList = () => {
return monitor_call_list;
};
// 添加 挂断 回调
// After hanging up the call, you can receive a notification and process the style of the current page based on the notification
const registerhangupEvent = () => {
if (hangup_event_cb_id !== undefined) {
return;
}
hangup_event_cb_id = window.lemon.call.addHangupEvt((data) => {
console.info('receive hangup event');
console.info(
'receive hangup event receive call id',
String(data.call_id)
);
console.info('receive hangup event local call id', String(call_id));
if (data.call_id === call_id) {
// remove display alert ui
ElNotification.close(call_id);
call_id = undefined;
window.calling_conference = undefined;
// console.log('2222211111registerCallEstablishEvent');
}
// pushVideoFile uninit
// 如果是视频推送的,挂断是反初始化一些东西。
if (pushing_video) {
window.video.src = undefined;
window.showVideo.value = false;
pushing_video = false;
window.videoViewRoot.style.display = 'none';
}
removeMonitorCall(data.call_id);
});
};
// 添加强拆事件
const registerForceHangupEvent = () => {
if (force_hangup_event_cb_id !== undefined) {
return;
}
force_hangup_event_cb_id = window.lemon.call.addForceHangupEvt((data) => {
// 目前强拆成功,都是走挂断通知事件。 当失败了,才走强拆事件通知。
if (data.result === 0) {
if (data.call_id === call_id) {
ElNotification.close(call_id);
call_id = undefined;
window.calling_conference = undefined;
}
removeMonitorCall(data.call_id);
} else {
// 强拆失败 fail
ElMessage.error("强拆失败");
}
});
};
// 添加接听回调通知 代表呼叫建立
// receive the answer acknowledgement asynchronously after the call is established
const registerCallEstablishEvent = () => {
if (answer_ack_cb_id !== undefined) {
return;
}
answer_ack_cb_id = window.lemon.call.addAnswerAckEvt((data) => {
// console.info('registerCallEstablishEvent0', call_id);
console.info('registerCallEstablishEvent', String(data.call_id));
console.info('registerCallEstablishEvent', JSON.stringify(data));
call_id = data.call_id;
// pushVideoFile init
// 接通后,视频推送的文件开始播放
if (pushing_video) {
window.videoViewRoot.style.display = 'unset';
window.showVideo.value = true;
window.video.play();
}
});
};
// 注册来电通知回调
// add the incoming call callback
const registerReceiveCallEvent = () => {
if (incoming_cb_id !== undefined) {
return;
}
incoming_cb_id = window.lemon.call.addIncomingEvt((session) => {
console.log('receive call------>', session);
call_id = session.call_id;
const callingReq = {
callInfo: session,
equipment: undefined,
text: {
calling: '队列',
answer: '接听',
hangUp: '挂断',
},
};
console.log('receive this------>', useCallModule());
if (session.listen_flag) {
// monitor call,auto answer call
// 值守的来电呼叫,自动接听
window.lemon.call.answerCall({ call_id: session.call_id });
monitor_call_list.push(session);
emitter.emit('monitorUpdate');
} else {
// normal call
// 正常来电,弹框询问接听
// handleCallingNotification(callingReq);
}
});
};
// 申请话权
// apply floor
const applyFloor = () => {
console.info('try applyFloor,call_id=', call_id);
if (!call_id) {
console.warn('no call exits');
return undefined;
}
return window.lemon.floor
.applySpeak({ call_id })
?.then((resp) => {
if (resp.result === 0) {
console.log('applyFloor request sucess');
} else {
ElMessage.error("申请话权失败");
}
})
.catch((err) => {
console.error('applyFloor error,', err);
});
};
// 释放话权
// release floor
const releaseFloor = () => {
console.info('try releaseFloor,call_id=', call_id);
return window.lemon.floor
.releaseSpeak({ call_id })
?.then((resp) => {
if (resp.result === 0) {
console.log('releaseSpeak request sucess');
} else {
ElMessage.error("释放话权失败");
}
})
.catch((err) => {
console.error('releaseSpeak error,', err);
});
};
// add floor event
// 添加话权通知事件
const registerFloorGrantEvent = () => {
if (floor_grant_cb_id !== undefined) {
return;
}
floor_grant_cb_id = window.lemon.floor.addGrantEvt((grantInfo) => {
console.log('registerFloorGrantEvent', grantInfo);
if (grantInfo.result !== 0) {
ElMessage.error("话权申请失败");
}
});
};
// 强拆
// override the call
const forceHangupCall = (callId) => {
return window.lemon.call
.forceHangupCall({ call_id: callId || call_id })
?.then((resp) => {
if (resp.result === 0) {
console.log('forceHangupCall request sucess');
} else {
ElMessage.error("强拆失败");
}
call_id = undefined;
window.calling_conference = undefined;
// console.log('2222233registerCallEstablishEven');
})
.catch((err) => {
console.error('forceHangupCall error,', err);
});
};
// 强插
// interrupt the call during monitoring
const forceApplySpeak = (callId) => {
return window.lemon.floor
.forceApplySpeak({ call_id: callId || call_id })
?.then((resp) => {
if (resp.result === 0) {
console.log('forceApplySpeak request sucess');
call_id = callId;
} else {
ElMessage.error("强插失败");
}
})
.catch((err) => {
console.error('forceApplySpeak error,', err);
});
};
/**
* 会议成员禁言
* mute or unmute a conference member
* @param param
* @param param.conference_basedata_id
*/
const muteMemberInConference = (
conference_basedata_id,
member_basedata_id,
mute
) => {
return window.lemon.call.conferenceMemberSpeakSet({
conference_call_id: call_id,
conference_basedata_id,
member_setting: {
member_basedata_id,
forbid: mute ? 1 : 0,
},
});
};
/**
* 视频推送
* select a local video file and play then push the stream to remote
* @param record
* @param file
* @returns
*/
const pushVideoFile = (record, url) => {
console.info('try pushVideoFile,call_id=', call_id);
if (call_id) {
console.warn('call exits');
return;
}
console.warn('window.video', window.video);
// set the file to video tag
if (window.video) {
const canPlayListener = () => {
window.video.removeEventListener('canplay', canPlayListener);
// capture stream
const stream = (window.video)?.captureStream();
console.info('pushVideoFile,inited stream=', stream);
// register hook listner ,play the video when remote hooked
registerCallEstablishEvent();
// init the call
window.lemon.call
.pushVideoFile({
basedata_id: record?.basedata_id,
stream,
})
?.then((resp) => {
pushing_video = true;
call_id = resp.call_id;
});
};
const endListener = () => {
console.info('pushVideoFile,video play end');
window.video.removeEventListener('ended', endListener);
hangup();
};
// maybe did't finish the video,so that we has listener already,remove it
window.video.removeEventListener('ended', endListener);
console.info('pushVideoFile,add canplay Event Listener', canPlayListener);
window.video.addEventListener('canplay', canPlayListener);
// hangup the call when video finished
console.info('pushVideoFile,add ended Event Listener', endListener);
window.video.addEventListener('ended', endListener);
window.video.autoplay = false;
window.video.src = url;
}
};
/**
* 视频转发
* share a exist call to another device
* @param record
* @param stop
* @returns
*/
const forwardVideoCall = (record, stop) => {
console.info('try forwardVideoCall,call_id=', call_id);
if (!call_id) {
console.warn('no call exits,can not forward');
ElMessage.warning('no call exits');
return undefined;
}
return window.lemon.call
.forwardVideoCall({
basedata_id: record?.basedata_id,
call_id,
action: stop ? 1 : 0,
})
?.then((resp) => {
if (resp.result === 0) {
console.log('forwardVideoCall request sucess');
} else {
ElMessage.error("视频转发失败");
}
})
.catch((err) => {
console.error('forwardVideoCall error,', err);
});
};
const getEmitter = () => {
return emitter;
};
// call sdk unInit
const unInit = () => {
call_id = undefined;
if (hangup_event_cb_id) {
window.lemon.call.removeHangupEvt(hangup_event_cb_id);
hangup_event_cb_id = undefined;
}
if (force_hangup_event_cb_id) {
window.lemon.call.removeForceHangupEvt(force_hangup_event_cb_id);
force_hangup_event_cb_id = undefined;
}
if (answer_ack_cb_id) {
window.lemon.call.removeAnswerAckEvt(answer_ack_cb_id);
answer_ack_cb_id = undefined;
}
if (incoming_cb_id) {
window.lemon.call.removeIncomingEvt(incoming_cb_id);
incoming_cb_id = undefined;
}
if (floor_grant_cb_id) {
window.lemon.floor.removeGrantEvt(floor_grant_cb_id);
floor_grant_cb_id = undefined;
}
monitor_call_list.length = 0;
};
return {
makeVoiceCall,
makeVideoCall,
pureVideoCall,
registerhangupEvent,
registerReceiveCallEvent,
answerCall,
makeGroupVoiceCall,
makeGroupVideoCall,
makeBroadcastCall,
hangup,
voiceDetect,
videoDetect,
applyFloor,
releaseFloor,
setMuteCamera,
setMuteMic,
setMuteCall,
muteMemberInConference,
makeConferenceVoiceCall,
makeConferenceVideoCall,
makeCrosspatchVoiceCall,
registerCallEstablishEvent,
pushVideoFile,
forwardVideoCall,
forceHangupCall,
getMonitorCallList,
getEmitter,
forceApplySpeak,
registerFloorGrantEvent,
registerForceHangupEvent,
unInit,
};
}

View File

@ -0,0 +1,37 @@
// import { h } from 'vue';
// import { Notification } from '@arco-design/web-vue';
// import { IconClose } from '@arco-design/web-vue/es/icon';
// import Content from '@/views/webPuc/callingNotification/components/content.vue';
// import Footer from '@/views/webPuc/callingNotification/components/footer.vue';
// import { formatShowNameFin } from './format-show-name';
// export default function handleCallingNotification(propsObj) {
// const { callInfo, text } = propsObj;
// const { calling, answer = 'answer', hangUp = 'hang up' } = text;
// Notification.info({
// id: callInfo.call_id,
// showIcon: false,
// position: 'bottomLeft',
// closable: true,
// closeIconElement: () => {
// return h(IconClose);
// },
// title: () =>
// h(Content, {
// callInfo,
// calling,
// getName: formatShowNameFin(
// callInfo.caller_alias,
// callInfo.caller_number
// ),
// }),
// content: () =>
// h(Footer, {
// callInfo,
// answer,
// hangUp,
// }),
// duration: 0,
// style: { width: '260px' },
// });
// }

View File

@ -18,17 +18,18 @@
<el-option v-for="item in dictItemList" :key="item.dm" :label="item.zdmc" :value="item.dm" />
</el-select>
</template>
</Search>
</div> -->
</Search>
</div> -->
<div style="background-color: #fff;color: black;padding: 15px;overflow: auto;" :style="{ height: tabHeight + 'px' }"
ref="tableBox">
<div style="border-bottom: 1px #ccc solid;padding-bottom: 30px;">
<h1 class="headline">{{ nd }}年度西藏公安战术研判报告</h1>
<div style="display: flex;align-items: center;justify-content: space-between; color: red;margin-top: 30px;padding: 0 30px;font-size: 18px;font-weight: 700;">
<div>{{ deptId.name }}</div>
<div>{{ deptId?.ord }}</div>
<div>{{ deptId?.time }}</div>
</div>
<h1 class="headline">{{ nd }}年度林芝市公安战术研判报告</h1>
<div
style="display: flex;align-items: center;justify-content: space-between; color: red;margin-top: 30px;padding: 0 30px;font-size: 18px;font-weight: 700;">
<div>{{ deptId.name }}</div>
<div>{{ deptId?.ord }}</div>
<div>{{ deptId?.time }}</div>
</div>
</div>
<p>为全面客观准确掌握全区公安机关的执法状况自治区
@ -72,7 +73,7 @@
</span>
</span>
</p>
<Histogram title="地市分布" :xAxisData="dataList.dyTj.xAxisData" :seriesData="dataList.dyTj.seriesData" />
<Histogram title="地市分布" :xAxisData="dataList.dyTj.xAxisData" :seriesData="dataList.dyTj.seriesData" />
<h2>1.1.4时间维度</h2>
<p>
我们将所有警情按照月份划分进行统计发现每月警情分布
@ -103,10 +104,13 @@
:chartData="dataList.CljgfTj" :innerRadius="0" :outerRadius="150" :padAngle="2" />
<h2>1.2.2效率维度</h2>
<p>从处警效率来看{{ sortingRatioValue.Czlfx[1]?.name }}处警的占到{{ sortingRatioValue.Czlfx[0]?.ratio
}}表明我区公安机关在接警之后能够在第一时间处警
}}表明我区公安机关在接警之后能够在第一时间处警
</p>
<MaleNightingalePicture :title="{ text: '效率维度', left: 'center' }" style="height: 550px;"
:chartData="dataList.withinTj" :innerRadius="0" :outerRadius="150" :padAngle="0" />
<h2>2.总结分析</h2>
<p style="min-height: 100px;" v-loading="loading">{{ textContent }} </p>
</div>
</div>
@ -114,14 +118,12 @@
</template>
<script setup>
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import Search from "@/components/aboutTable/Search.vue";
import MaleNightingalePicture from './components/maleNightingalePicture.vue'
import Histogram from './components/histogram.vue'
import { timeValidate } from '@/utils/tools.js'
import { getItem, setItem } from '@/utils/storage'
import { fxbgDywdtj, getDictItem, fxbgJqlxtj, fxbgJqlytj, fxbgYdfx, fxbgXsfx, fxgbCljgf, fxgbCzlfx, fxbgTj } from '@/api/semanticAnalysis'
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import { completions } from '@/api/semanticAnalysis'
import { reactive, ref, onMounted, getCurrentInstance, nextTick, computed, watch } from "vue";
const props = defineProps({
// 数据
@ -130,6 +132,7 @@ const props = defineProps({
default: null
}
})
const loading = ref(false);
const { proxy } = getCurrentInstance();
const { D_GS_XS_LX } = proxy.$dict("D_GS_XS_LX"); //获取字典数据
const dictItemList = ref([])
@ -214,7 +217,7 @@ const getfxbgDywdtj = () => {
let params = {
...pageData.parameter,
}
fxbgDywdtj(params).then(res => {
return fxbgDywdtj(params).then(res => {
dataList.dyTj.xAxisData = res.map(it => it.ssbm)
dataList.dyTj.seriesData = [];
for (let i = 0; i < res.length; i++) {
@ -242,7 +245,7 @@ const getfxbgJqlxtj = () => {
bjlbList: dictItemList.value.map(item => item.dm).join(',')
}
}
fxbgJqlxtj(params).then(res => {
return fxbgJqlxtj(params).then(res => {
sortingRatioValue.Jqlx = sortingRatio(res)
dataList.jqlxTj = res.map(item => {
return {
@ -257,7 +260,7 @@ const getfxbgJqlytj = () => {
let params = {
...pageData.parameter,
}
fxbgJqlytj(params).then(res => {
return fxbgJqlytj(params).then(res => {
sortingRatioValue.Lyfx = sortingRatio(res)
dataList.jqlyTj = res.map(item => {
return {
@ -273,7 +276,7 @@ const getfxbgYdfx = () => {
let params = {
...pageData.parameter,
}
fxbgYdfx(params).then(res => {
return fxbgYdfx(params).then(res => {
sortingRatioValue.Ydfx = sortingRatio(res)
dataList.ydTj = res.map(item => {
return {
@ -289,7 +292,7 @@ const getfxgbCljgf = () => {
...pageData.parameter,
}
fxgbCljgf(params).then(res => {
return fxgbCljgf(params).then(res => {
sortingRatioValue.Cljgf = sortingRatio(res)
dataList.CljgfTj = res.map(item => {
return {
@ -304,7 +307,7 @@ const getfxgbCzlfx = () => {
let params = {
...pageData.parameter,
}
fxgbCzlfx(params).then(res => {
return fxgbCzlfx(params).then(res => {
dataList.withinTj = [{
name: "超时分流(超过24小时)",
value: res.within24h ? res.within24h : 0
@ -320,7 +323,7 @@ const getfxbgTj = () => {
let params = {
...pageData.parameter,
}
fxbgTj(params).then(res => {
return fxbgTj(params).then(res => {
console.log(res, "xxx");
dataList.XsfxTj = res
})
@ -360,41 +363,46 @@ const Time = () => {
deptId.value.name = devt[0].deptName
nd.value = timeValidate('', 'yd')
deptId.value.time = timeValidate('', 'ydm')
deptId.value.ord=timeValidate('', 'mm')
deptId.value.ord = timeValidate('', 'mm')
TimeValue.value.startTime = `${year}-${month}-${day}`
TimeValue.value.endTime = `${endYear}-${endMonth}-${endDay}`
}
Time()
const funAll = () => {
getfxbgDywdtj()
getfxbgJqlxtj()
getfxbgJqlytj()
getfxgbCljgf()
getfxbgYdfx()
getfxgbCzlfx()
getfxbgTj()
// 使用Promise.all确保所有数据获取函数执行完成
Promise.all([
getfxbgDywdtj(),
getfxbgJqlxtj(),
getfxbgJqlytj(),
getfxgbCljgf(),
getfxbgYdfx(),
getfxgbCzlfx(),
getfxbgTj()
]).then(() => {
extractTextContent()
})
}
const getDictItemList = () => {
const promes = {
startTime: props.search.startTime ,
endTime: props.search.endTime,
startTime: props.search.startTime,
endTime: props.search.endTime,
}
if (props.search.lx) {
const bjlbLists = props.search.lx ? props.search.lx.join(',') : ""
pageData.parameter = { bjlbList: bjlbLists, ...promes }
const bjlbLists = props.search.lx ? props.search.lx.join(',') : ""
pageData.parameter = { bjlbList: bjlbLists, ...promes }
funAll()
} else {
const promesing = {
dictCode: "00000000"
}
dictCode: "00000000"
}
getDictItem(promesing).then(res => {
const bjlbLists = res.map(item=>item.dm).join(',')?res.map(item=>item.dm).join(','):""
pageData.parameter = { bjlbList: bjlbLists, ...promes }
funAll()
})
}
const bjlbLists = res.map(item => item.dm).join(',') ? res.map(item => item.dm).join(',') : ""
pageData.parameter = { bjlbList: bjlbLists, ...promes }
funAll()
})
}
}
@ -404,6 +412,49 @@ watch(() => dictItemList.value, (val) => {
}, { deep: true })
getDictItemList()
const tableBox = ref(null);
const textContent = ref('')
// 获取p标签的所有文字内容去除所有<>包裹的内容
const extractTextContent = () => {
loading.value = true
// 获取当前组件的HTML内容
const componentHtml = tableBox.value ? tableBox.value.innerHTML : '';
// 存储提取的文本内容
const extractedTexts = [];
// 提取p标签的文本内容
const pRegex = /<p[^>]*>(.*?)<\/p>/gs;
let pMatch;
while ((pMatch = pRegex.exec(componentHtml)) !== null) {
let pContent = pMatch[1];
// 去除所有<>包裹的内容
pContent = pContent.replace(/<[^>]*>/g, '');
// 去除HTML注释
pContent = pContent.replace(/<!--[\s\S]*?-->/g, '');
// 清理文本,去除多余空白字符
const cleanText = pContent.replace(/\s+/g, ' ').trim();
if (cleanText) {
extractedTexts.push(cleanText);
}
}
// 合并为一个字符串
const result = extractedTexts.join(' ');
console.log('提取的文本内容:', result);
completions({
model: "deepseek-32b",
prompt: `# 角色定位\n你是一名资深警务人员尤其擅长对警情、案件、线索等非结构化文本数据进行阅读理解并总结各种对象之间的关联关系,对下面数据进行一个分析总结给出一个总结报告。\n${result}`,
max_tokens: 1000,
}).then(res => {
textContent.value = res.choices[0].text
}).finally(() => {
loading.value = false
})
// return result;
};
</script>

View File

@ -602,6 +602,7 @@ const tabHeightFn = () => {
::v-deep .el-table .el-table__cell {
padding: 0;
}
::v-deep .el-table th.el-table__cell>.cell {

View File

@ -37,7 +37,7 @@
<script setup>
import YpModel from '@/components/ypModel/index.vue'
import emitter from "@/utils/eventBus.js";
import { getYjxxPageList,getSsyjpzMxgzxl,mxglYjxqSelectList } from "@/api/model";
import { getYjxxPageList,getSsyjpzMxgzxl,mxglJqxqGetPageList } from "@/api/model";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
@ -67,7 +67,7 @@ const SaveReport = () => {
const opneModel = (row) => {
showModel.value = true
textContent.value = ''
mxglYjxqSelectList({
mxglJqxqGetPageList({
yjid: row.id,
}).then((res) => {
let str = {
@ -75,13 +75,13 @@ const opneModel = (row) => {
prompt: `# 角色定位\n你是一名资深警务人员尤其擅长对警情、案件、线索等非结构化文本数据进行阅读理解并从中提取各种对象特征信息进行结构化并总结各种对象之间的关联关系。\n`,
max_tokens: 1000,
}
res.forEach(item => {
const lx = props.dict.D_BZ_YJLX.find(items => {
res.forEach(item => {
const lx = props.dict.D_BZ_JQLY.find(items => {
return items.value == item.yjlx
}).zdmc
str.prompt+=`预警名称:${item.yjBt},警人姓名:${item.yjRyxm},身份证号:${item.yjRysfzh},车牌号:${item.yjClcph},警地址:${item.yjDz},警类型:${lx},预警内容:${item.yjnr},预警时间:${item.yjsj}\n`
str.prompt+=`警情内容:${item.bjnr},警人姓名:${item.bjrmc},警地址:${item.bjdz},警类型:${lx},警时间:${item.bjsj}\n`
})
str.prompt += `根据以上警信息,总结出一个解决方案`
str.prompt += `根据以上警信息,总结出一个解决方案`
let jsonMatch
completions(str).then(reslve => {
jsonMatch = reslve.choices[0].text
@ -90,7 +90,7 @@ const opneModel = (row) => {
time: timeValidate()
}) + fbtool(`同类事件发生${res.length}次以上预警`)
res.forEach((item,index) => {
const lx = props.dict.D_BZ_YJLX.find((items) => {
const lx = props.dict.D_BZ_JQLY.find((items) => {
return items.value == item.yjlx
}).zdmc
textContent.value +=Subheading(`${index+1}.警情内容`)+textStyle(`预警名称:${item.yjBt},预警人员姓名:${item.yjRyxm},身份证号:${item.yjRysfzh},车牌号:${item.yjClcph},预警地址:${item.yjDz},预警类型:${lx},预警内容:${item.yjnr},预警时间:${item.yjsj}\n`)

View File

@ -30,7 +30,8 @@ const props = defineProps({
item: {
type: Object,
default: () => {},
}
},
})
const { proxy } = getCurrentInstance();
const { D_BB_AJLB,D_BZ_WPLX,D_BZ_RYBQ} = proxy.$dict("D_BB_AJLB","D_BZ_WPLX","D_BZ_RYBQ")

View File

@ -1,8 +1,9 @@
<template>
<div>
<YpHome v-if="showModel == '研判首页'"></YpHome>
<List v-if="showModel == '四色预警规则' || showModel == '预警规则'" :item="itemData"></List>
<YjDetail v-if="showModel == '预警列表'" :item="itemData" :dict="{ D_BZ_TPYJLX,D_BZ_YJLX }"></YjDetail>
<List v-if="showModel == '四色预警规则' || showModel == '预警规则'" :item="itemData" :dict="{ D_BZ_TPYJLX}"></List>
<YjDetail v-if="showModel == '预警列表'" :item="itemData" :dict="{ D_BZ_TPYJLX,D_BZ_YJLX,D_BZ_JQLY }"></YjDetail>
<WarningList v-if="showModel == '预警详情'" :item="itemData" :dict="{ D_BZ_YJLX }"/>
</div>
</template>
@ -14,7 +15,7 @@ import WarningList from "./components/AddModel/warningList.vue"
const { proxy } = getCurrentInstance();
import emitter from "@/utils/eventBus.js";
import { onMounted, ref, getCurrentInstance } from "vue";
const { D_BZ_TPYJLX,D_BZ_YJLX } = proxy.$dict("D_BZ_TPYJLX","D_BZ_YJLX")
const { D_BZ_TPYJLX,D_BZ_YJLX ,D_BZ_JQLY} = proxy.$dict("D_BZ_TPYJLX","D_BZ_YJLX","D_BZ_JQLY")
const showModel = ref('研判首页')
const itemData = ref({})

View File

@ -11,18 +11,18 @@
<div class="content_icon flex align-center">
<div class="icon_img"><img src="@/assets/images/ly-person-icon.png" alt="" srcset=""></div>
<div class="flex align-space-around dir-column">
<div class="publisher">发布者{{ listQuery.ssbm }}{{ listQuery.fbrxm }}</div>
<div>发布于{{ listQuery.fbsj }}</div>
<div class="publisher">发布者{{ listQuery.xtCjbmmc }}{{ listQuery.xssbr }}</div>
<div>发布于{{ listQuery.czsj }}</div>
</div>
</div>
<p class="content_text">{{ listQuery.xsNr }} </p>
<p class="content_text">{{ listQuery.qbnr }} </p>
<div class="itemXs_Xs flex just-between align-center">
<div class=" flex just-between align-center">
<!-- <div class=" flex just-between align-center">
<el-icon class="icon">
<Histogram />
</el-icon>
&nbsp;{{ listQuery.rd ? listQuery.rd : 0 }}
</div>
</div> -->
<div class=" flex just-between align-center">
<el-icon class="icon">
<ChatDotSquare />
@ -30,7 +30,7 @@
&nbsp;{{ pls }}
</div>
<div class="flex align-center">情报类型
<DictTag :tag="false" :value="listQuery.xlLx" color="#5c5c5c" :options="dict.D_GS_XS_LX" />
<DictTag :tag="false" :value="listQuery.qblx" color="#5c5c5c" :options="dict.D_GS_XS_LX" />
</div>
</div>
</div>
@ -107,6 +107,14 @@ const sendComment = () => {
cjid: listQuery.value.id,
dzs: 10
}
if(!textarea2.value){
ElMessage({
message: '请输入评论内容',
type: 'warning',
plain: true,
})
return
}
qcckPost(prmes, '/mosty-gsxt/gsxt/cjpj/add').then((res) => {
textarea2.value = ''; // 清空评论内容
cjpjSelectPage()

View File

@ -7,18 +7,19 @@
<div class="itemXs_time flex ">
<div> {{ item.pldd }}</div>
<div>{{ item.plsj }}</div>
<div><span @click="openReply(index)" class="hf">回复</span>
&nbsp;&nbsp;
<div>
<!-- <span @click="openReply(index)" class="hf">回复</span>
&nbsp;&nbsp; -->
<span class="del" @click="delComment(item)"
v-show="userInfo==item.plrsfzh"
>删除</span></div>
<div @click="showReply(item)" class="ck">查看回复</div>
<div @click="handleLike(item)" class="ck">点赞{{dzs }}</div>
<!-- <div @click="showReply(item)" class="ck">查看回复</div> -->
<!-- <div @click="handleLike(item)" class="ck">点赞{{dzs }}</div> -->
</div>
<div class="pubContent flex" v-if="showInput" style="align-items: flex-end">
<!-- <div class="pubContent flex" v-if="showInput" style="align-items: flex-end">
<el-input v-model="textarea2" style="flex: 1;margin-right: 10px;" type="textarea" placeholder="请输入内容" /><el-button
type="primary" @click="sendComment(item)">回复</el-button>
</div>
</div> -->
<div v-if="show">
<ReplyList :replyId="item" ref="replyList" :userInfo="userInfo"/>
</div>

View File

@ -36,7 +36,6 @@ import ExtractionText from "@/components/ExtractionText/index.vue";
import { lzJcjPjdbSelectPage, tbGsxtBqglSelect, yyfxAdd, completions } from '@/api/semanticAnalysis'
import { qcckGet } from "@/api/qcckApi.js";
import { getCurrentInstance } from 'vue'
import { ParsingText } from '@/api/qcckApi'
import emitter from "@/utils/eventBus.js";
import { useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'

View File

@ -70,12 +70,12 @@ const dialogForm = ref(false); //弹窗
const formData = reactive([
{ label: "标签名称", prop: "bqMc", type: "input" },
{ label: "标签代码", prop: "bqDm", type: "input" },
{
label: "标签等级",
prop: "bqDj",
type: "select",
options: props.dic.D_GS_BQ_DJ
},
// {
// label: "标签等级",
// prop: "bqDj",
// type: "select",
// options: props.dic.D_GS_BQ_DJ
// },
{
label: "标签颜色",
prop: "bqYs",
@ -89,9 +89,9 @@ const formData = reactive([
const rules = reactive({
bqMc: [{ required: true, message: "请输入标签名称", trigger: "blur" }],
bqDm: [{ required: true, message: "请输入标签代码", trigger: "blur" }],
bqDj: [
{ required: true, message: "请选择标签等级", trigger: ["blur", "change"] }
],
// bqDj: [
// { required: true, message: "请选择标签等级", trigger: ["blur", "change"] }
// ],
bqYs: [
{ required: true, message: "请选择标签颜色", trigger: ["blur", "change"] }
],

View File

@ -71,7 +71,7 @@ const type = ref('标签大类')
const show = ref(false)
const searchConfiger = ref([
{ label: "标签名称",prop:'bqMc',placeholder: "请输入标签名称", showType: "input"},
{ label: "标签等级",prop:'bqDj' ,placeholder: "请选择标签等级", showType: "select",options:D_GS_BQ_DJ },
// { label: "标签等级",prop:'bqDj' ,placeholder: "请选择标签等级", showType: "select",options:D_GS_BQ_DJ },
{ label: "标签颜色",prop:'bqYs' ,placeholder: "请选择标签颜色", showType: "select",options:D_GS_SSYJ },
]);
const queryFrom = ref({});
@ -92,7 +92,7 @@ const pageData = reactive({
tableColumn: [
{ label: "标签名称", prop: "bqMc" },
{ label: "标签代码", prop: "bqDm" },
{ label: "标签等级", prop: "bqDj",showSolt:true},
// { label: "标签等级", prop: "bqDj",showSolt:true},
{ label: "标签颜色", prop: "bqYs",showSolt:true},
{ label: "标签说明", prop: "bqSm"},
]

View File

@ -39,7 +39,8 @@ const dialogForm = ref(false); //弹窗
const formData = reactive([
{ label: "标签名称", prop: "bqMc", type: "input" },
{ label: "标签代码", prop: "bqDm", type: "input" },
{ label: "标签等级", prop: "bqDj", type: "select", options: props.dic.D_GS_BQ_DJ },
// 领导要求取消
// { label: "标签等级", prop: "bqDj", type: "select", options: props.dic.D_GS_BQ_DJ },
{ label: "标签颜色", prop: "bqYs", type: "select", options: props.dic.D_GS_SSYJ },
{ label: "标签分值", prop: "bqFz", type: "number" ,max:100},
{ label: "标签说明", prop: "bqSm", type: "textarea",width: '100%' },
@ -48,7 +49,7 @@ const formData = reactive([
const rules = reactive({
bqMc: [{ required: true, message: "请输入标签名称", trigger: "blur" }],
bqDm: [{ required: true, message: "请输入标签代码", trigger: "blur" }],
bqDj: [{ required: true, message: "请选择标签等级", trigger: ['blur','change'] }],
// bqDj: [{ required: true, message: "请选择标签等级", trigger: ['blur','change'] }],
bqYs: [{ required: true, message: "请选择标签颜色", trigger: ['blur','change'] }],
bqFz: [{ required: true, message: "请输入标签分值", trigger: ['blur','change'] }],
});

View File

@ -70,7 +70,7 @@ const type = ref('标签大类')
const show = ref(false)
const searchConfiger = ref([
{ label: "标签名称",prop:'bqMc',placeholder: "请输入标签名称", showType: "input"},
{ label: "标签等级",prop:'bqDj' ,placeholder: "请选择标签等级", showType: "select",options:D_GS_BQ_DJ },
// { label: "标签等级",prop:'bqDj' ,placeholder: "请选择标签等级", showType: "select",options:D_GS_BQ_DJ },
{ label: "标签颜色",prop:'bqYs' ,placeholder: "请选择标签颜色", showType: "select",options:D_GS_SSYJ },
]);
const queryFrom = ref({});
@ -91,7 +91,7 @@ const pageData = reactive({
tableColumn: [
{ label: "标签名称", prop: "bqMc" },
{ label: "标签代码", prop: "bqDm" },
{ label: "标签等级", prop: "bqDj",showSolt:true},
// { label: "标签等级", prop: "bqDj",showSolt:true},
{ label: "标签颜色", prop: "bqYs",showSolt:true},
{ label: "标签说明", prop: "bqSm"},
]

View File

@ -165,12 +165,12 @@ const dialogForm = ref(false); //弹窗
const formData = reactive([
{ label: "组合标签名称", prop: "bqMc", type: "input" },
{ label: "组合标签代码", prop: "bqDm", type: "input" },
{
label: "标签等级",
prop: "bqDj",
type: "select",
options: props.dic.D_GS_BQ_DJ
},
// {
// label: "标签等级",
// prop: "bqDj",
// type: "select",
// options: props.dic.D_GS_BQ_DJ
// },
{
label: "标签颜色",
prop: "bqYs",

View File

@ -74,7 +74,7 @@ const searchBox = ref(); //搜索框
const searchConfiger = ref(
[
{ label: "组合标签名称", prop: 'bqMc', placeholder: "请输入组合标签名称", showType: "input"},
{ label: "组合标签标签等级", prop: 'bqDj', placeholder: "请选择组合标签标签等级", showType: "select",options: D_GS_BQ_DJ },
// { label: "组合标签标签等级", prop: 'bqDj', placeholder: "请选择组合标签标签等级", showType: "select",options: D_GS_BQ_DJ },
{ label: "组合标签颜色", prop: 'bqYs', placeholder: "请选择组合标签标签颜色", showType: "select",options: D_GS_SSYJ },
]);
const queryFrom = ref({});
@ -95,7 +95,7 @@ const pageData = reactive({
tableColumn: [
{ label: "组合标签名称", prop: "bqMc" },
{ label: "标签代码", prop: "bqDm" },
{ label: "组合标签等级", prop: "bqDj",showSolt:true },
// { label: "组合标签等级", prop: "bqDj",showSolt:true },
{ label: "组合标签颜色", prop: "bqYs",showSolt:true },
{ label: "组合标签分值", prop: "bqFz"},
{ label: "组合标签说明", prop: "bqSm",showOverflowTooltip:true },

View File

@ -13,7 +13,7 @@ onMounted(() => {
});
const initCharts = (data) => {
vehicleChart = echarts.init(echart.value)
const colors =['#ff1818', '#0066ff', '#ff9900', '#00cc66']
const colors = ['#ff1818', '#0066ff', '#ff9900', '#00cc66']
const countData = [
{
value: 0,
@ -45,10 +45,10 @@ const initCharts = (data) => {
},
];
data.forEach(item => {
if(item.yj_jb == '10') countData[0].value = item.count;
if(item.yj_jb == '20') countData[1].value = item.count;
if(item.yj_jb == '30') countData[2].value = item.count;
if(item.yj_jb == '40') countData[3].value = item.count;
if (item.yj_jb == '10') countData[0].value = item.count;
if (item.yj_jb == '20') countData[1].value = item.count;
if (item.yj_jb == '30') countData[2].value = item.count;
if (item.yj_jb == '40') countData[3].value = item.count;
});
vehicleChart.setOption(createChartOption(countData, colors))
}
@ -60,8 +60,9 @@ const createChartOption = (data, colors) => {
},
legend: {
orient: 'vertical',
left: '60%',
left: '53%',
top: 'center',
itemGap: 40,
textStyle: {
color: '#fff',
rich: {
@ -69,33 +70,42 @@ const createChartOption = (data, colors) => {
color: '#fff'
},
percentage: {
padding: [0, 0, 0, 10]
padding: [0, 0, 0, 0]
},
red: {
color: colors[0]
color: colors[0],
padding: [2, 0, 2, 0], // 增加上下边距
// lineHeight: 25 // 增加行高
},
orange: {
color: colors[2]
color: colors[2],
padding: [2, 0, 2, 0],
// lineHeight: 25
},
yellow: {
color: colors[3]
color: colors[3],
padding: [2, 0, 2, 0],
// lineHeight: 25
},
blue: {
color: colors[1]
color: colors[1],
padding: [2, 0, 2, 0],
// lineHeight: 25
},
}
},
formatter: (name) => {
const item = data.find(d => d.name === name);
let percentage = ((item.value / total) * 100).toFixed(2);
return `${name} ${item.value} {${item.colorType}|(${percentage}%)}`
}
formatter: (name) => {
const item = data.find(d => d.name === name);
let percentage = ((item.value / total) * 100).toFixed(2);
return `${name} ${item.value} {${item.colorType}|(${percentage}%)}`
}
},
series: [
{
type: 'pie',
radius: ['55%', '70%'],
center: ['28%', '50%'],
center: ['25%', '50%'],
data: data.map(item => ({
...item,
itemStyle: {
@ -116,8 +126,8 @@ const createChartOption = (data, colors) => {
},
{
type: 'pie',
radius: ['65%', '85%'],
center: ['28%', '50%'],
radius: ['35%', '50%'],
center: ['25%', '50%'],
data: data.map(item => ({
...item,
itemStyle: {
@ -145,7 +155,7 @@ const handleResize = () => {
vehicleChart?.resize()
}
defineExpose({initCharts})
defineExpose({ initCharts })
</script>
<style lang='scss' scoped>

View File

@ -79,7 +79,8 @@ const title = ref('')
onMounted(() => {
emitter.on("openFkDialog", (val) => {
showDialog.value = true;
listQuery.value = {yjid:val.id}
listQuery.value = { yjid: val.id }
title.value = val.type;
if(val.type == '查看反馈'){
qcckGet({}, "/mosty-gsxt/tbYjxx/getInfo/"+val.id).then((res) => {
@ -108,13 +109,16 @@ const handleUserSelected = (val) => {
listQuery.value.czzrmjsfzh = val[0].inDustRialId
break;
}
}
const submitForm = () =>{
elform.value.submit((val)=>{
loading.value = true;
qcckPost(val, "/mosty-gsxt/tbYjxx/yjfk").then(() => {
loading.value = true;
const prome = {
...listQuery.value,
}
qcckPost(prome, "/mosty-gsxt/tbYjxx/yjfk").then(() => {
loading.value = false;
proxy.$message({ type: "success", message: "反馈成功" });
emit('change')
@ -122,7 +126,6 @@ const submitForm = () =>{
}).catch(() => {
loading.value = false;
})
})
}
@ -139,4 +142,4 @@ const close = () => {
overflow: hidden;
overflow-y: auto;
}
</style>
</style>

View File

@ -77,83 +77,18 @@ function showOnMap() {
ElMessage({ message: '暂无轨迹数据', type: 'warning' });
return;
}
for (let i = 0; i < 2; i++) {
for (let i = 0; i < mapData.value.length; i++) {
let coords = mapData.value[i].list.map(item => {
return [item.jd, item.wd]
})
// const coords =[ [
// [
// 94.354613,
// 22.658568
// ],
// [
// 94.354613,
// 23.658568
// ],
// [
// 94.354613,
// 24.658568
// ],
// [
// 94.354613,
// 25.658568
// ],
// [
// 94.354613,
// 26.658568
// ],
// [
// 94.354613,
// 27.658568
// ],
// [
// 94.354613,
// 28.658568
// ],
// [
// 94.354613,
// 29.658568
// ]
// ],[
// [
// 89.354613,
// 22.658568
// ],
// [
// 90.354613,
// 23.658568
// ],
// [
// 91.354613,
// 24.658568
// ],
// [
// 92.354613,
// 25.658568
// ],
// [
// 93.354613,
// 26.658568
// ],
// [
// 94.354613,
// 27.658568
// ],
// [
// 95.354613,
// 28.658568
// ],
// [
// 96.354613,
// 29.658568
// ]
// ]]
emitter.emit('drawLineAnimation', {
type: "solid",
coords: coords,
isclear: true,
flag: "yjLine"
flag: "yjLine"
})
}
// const coords = mapData.value.map(item => {

View File

@ -31,7 +31,7 @@
</div>
<!-- 表格 -->
<div class="tabBox" :style="{ height: pageData.tableHeight + 'px' }">
<el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick">
<el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-click="handleClick" style="position: relative;z-index: 1;">
<el-tab-pane label="本地预警" name="local">
<div style="padding:0 10px;"> <el-button type="primary" @click="exportExcel">导出</el-button></div>
<LocalWarning ref="localWarningRef" />