This commit is contained in:
lcw
2025-12-05 21:38:51 +08:00
parent 854a5cd9d2
commit f06032cc69
81 changed files with 2243 additions and 266 deletions

View File

@ -7,15 +7,24 @@
</Watermark>
</keep-alive>
</router-view>
<Fxq >
</Fxq>
</template>
<script setup>
import { ref, nextTick, provide, onMounted } from "vue";
import { ref, nextTick, provide, onMounted,reactive } from "vue";
import { useStore } from "vuex";
import { getItem } from "@/utils/storage";
import Watermark from "@/components/Watermark.vue";
import { timeValidate } from "@/utils/tools.js";
import { qcckPost, qcckGet, qcckPut, qcckDelete } from "@/api/qcckApi.js";
import { generateNewStyle, writeNewStyle } from "@/utils/theme";
import Fxq from '@/components/fzq/index.vue'
import { getItem } from '@/utils/storage.js'
import { getCookie } from '@/utils/cookie'
const store = useStore();
generateNewStyle(store.getters.mainColor).then((newStyle) => {
writeNewStyle(newStyle);
@ -65,56 +74,4 @@ li {
// background:#263445;
}
//只显示一排内容
.one_text_detail {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
}
//只显示二排内容
.two_text_detail {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
//只显示三排内容
.text_detail {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
}
// 不显示滚动条
.noScollLine::-webkit-scrollbar {
width: 0 !important;
}
v-deep .el-loading-mask {
background: rgba(0, 0, 0, 0.5) !important;
}
@font-face {
font-family: "DigifaceWide";
src: url("~@/assets/font/DigifaceWide.ttf");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "HANYILINGXINTIJIAN";
src: url("~@/assets/font/HANYILINGXINTIJIAN-1.TTF");
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: "YSBTH";
src: url("~@/assets/font/YSBTH.ttf");
font-weight: normal;
font-style: normal;
}
</style>

72
src/api/commit.js Normal file
View File

@ -0,0 +1,72 @@
import request from "@/utils/request";
const api = "/mosty-api/mosty-base";
const gsxtApi = "/mosty-api/mosty-gsxt";
// 查询未读消息
export const queryYdxxPageList = (data) => {
return request({
url: api + "/fzmsg/queryYdxxPageList",
method: "POST",
data
});
};
//查看未读详情
export const queryWdxxDetail = (data) => {
return request({
url: api + "/fzmsg/queryWdxxDetail",
method: "POST",
data
});
};
// 查询一睹消息
export const queryWdxxPageList = (data) => {
return request({
url: api + "/fzmsg/queryWdxxPageList ",
method: "POST",
data
});
};
export const queryYdxxDetail = (data) => {
return request({
url: api + "/fzmsg/queryYdxxDetail",
method: "POST",
data
});
};
export const queryXxTj = (data) => {
return request({
url: api + "/fzmsg/queryXxTj",
method: "POST",
data
});
};
// 签收
export const qsXx = (data) => {
return request({
url: api + "/fzmsg/qsXx",
method: "post",
data
});
};
export function upImageFileInfo(data) {
return request({
url: api + '/minio/file/uploadObj',
method: 'post',
data
})
}
export function upImageUploadId(data) {
return request({
url: api + '/minio/image/upload/id',
method: 'post',
data
})
}

View File

@ -628,3 +628,11 @@ export const getSessionForSfzh = (params) => {
params
});
};
const api2 = "/getSession";
export const getSession = (params) => {
return request({
url: api2,
method: "GET",
params
});
};

BIN
src/assets/images/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/assets/images/fk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/images/lxj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
src/assets/images/pcs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
src/assets/images/sst.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 652 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

BIN
src/assets/images/ty.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

View File

@ -0,0 +1,286 @@
<template>
<el-dialog
:title="titleValue"
width="1400px"
:model-value="modelValue"
append-to-body
@close="closed"
>
<div>
<el-form :model="listQuery" class="mosty-from-wrap" :inline="true">
<el-form-item label="所属部门">
<MOSTY.Department width="100%" clearable v-model="listQuery.ssbmdm" />
</el-form-item>
<el-form-item label="用户名">
<el-input
placeholder="请输入用户名"
v-model="listQuery.loginName"
clearable
></el-input>
</el-form-item>
<el-form-item label="电话号码">
<el-input
placeholder="请输入电话号码"
v-model="listQuery.phone"
clearable
></el-input>
</el-form-item>
<el-form-item>
<el-button type="success" @click="handleFilter">查询</el-button>
<el-button type="info" @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
<div
class="tabBox"
:class="props.Single ? 'tabBoxRadio' : ''"
style="margin-top: 0px"
>
<el-table
ref="multipleUserRef"
@selection-change="handleSelectionChange"
:data="tableData"
border
:row-key="keyid"
style="width: 100%"
height="450"
>
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
/>
<el-table-column
prop="loginName"
align="center"
label="用户名"
width="150"
></el-table-column>
<el-table-column
prop="idEntityCard"
align="center"
label="身份证号"
></el-table-column>
<el-table-column
prop="deptName"
align="center"
label="部门"
></el-table-column>
<el-table-column
prop="inDustRialId"
align="center"
width="150"
label="警号"
></el-table-column>
<el-table-column
prop="mobile"
width="150"
align="center"
label="电话"
></el-table-column>
<el-table-column prop="sex" align="center" label="性别">
<template #default="{ row }">
<span> {{ row.sex == 1 ? "男" : "女" }}</span>
</template>
</el-table-column>
</el-table>
</div>
<div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.current"
:page-sizes="[10, 20, 50, 100]"
:page-size="listQuery.size"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closed">取消</el-button>
<el-button type="primary" @click="onComfirm">确认</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { selectUnAccreditPage, selectUserDeptPage } from "@/api/user-manage";
const props = defineProps({
modelValue: {
type: Boolean,
required: true
},
titleValue: {
type: String,
default: "选择用户"
},
LeaderType: {
type: String,
default: ""
},
//是否单选
Single: {
type: Boolean,
default: true
},
roleIds: {
type: Array,
default: []
}
});
const total = ref(0);
const listQuery = ref({
current: 1,
size: 20
});
const form = ref({});
const tableData = ref([]);
const emits = defineEmits(["update:modelValue", "choosedUsers"]);
onMounted(() => {
});
watch(()=>props.modelValue, (val) => {
if (val) {
nextTick(() => {
getListData();
});
}
},{
immediate: true
});
// 监听 roleIds 变化,实时更新选择状态
watch(()=>props.roleIds, () => {
if (props.modelValue && tableData.value && tableData.value.length > 0) {
nextTick(() => {
multipleUser();
});
}
}, { deep: true });
const closed = () => {
// 清空新选择的内容
multipleSelectionUser.value = [];
// 取消表格中所有行的选择状态
if (multipleUserRef.value && tableData.value && tableData.value.length > 0) {
tableData.value.forEach(item => {
multipleUserRef.value.toggleRowSelection(item, false);
});
}
emits("update:modelValue", false);
};
const reset = () => {
listQuery.value = {
current: 1,
size: 20,
loginName: "",
phone: ""
};
getListData();
};
const keyid = (row) => {
return row.id;
};
// 为用户分配角色
const onComfirm = () => {
const userList = multipleSelectionUser.value;
console.log("userList", userList);
let list = [];
let listId = [];
userList.forEach((val) => {
if (listId.indexOf(val.id) == -1) {
list.push(val);
listId.push(val.id);
}
});
emits("choosedUsers", list);
// let data = { type: props.LeaderType, userList: userList };
// emits("choosedUsersLeader", data);
closed();
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.size = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.current = currentPage;
getListData();
};
const getListData = () => {
const params = listQuery.value;
selectUserDeptPage(params).then((res) => {
tableData.value = res?.records;
total.value = Number(res.total);
// 使用 nextTick 确保表格已经渲染完成后再执行回显
nextTick(() => {
multipleUser();
});
});
};
//列表回显
function multipleUser() {
// 先清空之前的选择,确保选择状态的准确性
if (multipleUserRef.value && tableData.value && tableData.value.length > 0) {
tableData.value.forEach(item => {
multipleUserRef.value.toggleRowSelection(item, false);
});
}
// 根据 roleIds 进行回显
tableData.value.forEach((item) => {
if (props.roleIds.some((id) => id == item.id)) {
multipleUserRef.value.toggleRowSelection(item, true);
}
});
}
const handleFilter = () => {
listQuery.value.current = 1;
getListData();
};
const multipleUserRef = ref(null);
const multipleSelectionUser = ref([]);
const handleSelectionChange = (val) => {
if (props.Single) {
if (val.length > 1) {
let del_row = val.shift();
multipleUserRef.value.toggleRowSelection(del_row, false);
}
multipleSelectionUser.value = val;
} else {
multipleSelectionUser.value = val;
}
};
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
</style>
<style>
.tabBoxRadio .el-checkbox__inner {
border-radius: 50% !important;
}
.tabBoxRadio .el-table__header-wrapper .el-checkbox {
display: none;
}
</style>

View File

@ -242,7 +242,7 @@ const handleSelectionChange = (val) => {
display: none;
}
.el-dialog{
background: #050e33;
/* background: #050e33; */
}
.el-dialog__title{
color: #fff;

View File

@ -279,7 +279,7 @@ watch(
</style>
<style lang="scss" >
.el-dialog {
--el-dialog-bg-color: #001238 !important;
// --el-dialog-bg-color: #001238 !important;
}
.el-dialog__title {
color: #fff !important;

View File

@ -0,0 +1,123 @@
<template>
<el-form ref="elform" :model="listQuery" :label-width="props.labelWidth" :rules="props.rules" :inline="props.inline" label-position="right" :disabled="props.disabled">
<el-form-item v-for="(item, idx) in props.formList" :style="item.width && { width: item.width }" :prop="item.prop" :label="item.label" :label-width="item.labelWidth" :key="idx">
<!-- input表单 input-->
<MOSTY.Other v-if="item.type == 'input'" width="100%" clearable v-model="listQuery[item.prop]" :placeholder="`请输入${item.label}`" :disabled="item.disabled" :readonly="item.readonly" />
<el-input v-model="listQuery[item.prop]" v-else-if="item.type == 'textarea'" type="textarea" :rows="3" :placeholder="`请输入${item.label}`" :disabled="item.disabled" />
<!-- 数值 inputNumber-->
<el-input type="number" v-model="listQuery[item.prop]" v-else-if="item.type == 'inputNumber'" :placeholder="`请输入${item.label}`" :disabled="item.disabled" />
<!-- 数值 number-->
<el-input-number v-model="listQuery[item.prop]" v-else-if="item.type == 'number'" style="width: 100%" :min="item.min || 0" :max="item.max || 1000" :disabled="item.disabled" />
<!--选择 select-->
<MOSTY.Select v-else-if="item.type == 'select'" filterable :multiple="item.multiple" v-model="listQuery[item.prop]" :dictEnum="item.options" width="100%" clearable :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
<!-- 部门department -->
<template v-else-if="item.type === 'department'">
<MOSTY.Department style="width: 100%;" clearable :isAll="item.isAll" @getDepValue="getdep($event, item.depMc)" :multiple="item.multiple" v-model="listQuery[item.prop]" :placeholder="listQuery[item.depMc] ? listQuery[item.depMc] : '请选择'" />
</template>
<!-- 上传 upload -->
<MOSTY.Upload v-else-if="item.type == 'upload'" width="100%" v-model="listQuery[item.prop]" :isImg="item.isImg" :limit="item.limit" :disabled="item.disabled" />
<!--选择checkbox -->
<MOSTY.CheckBox v-else-if="item.type == 'checkbox'" width="100%" clearable v-model="listQuery[item.prop]" :checkList="item.options" :placeholder="`请选择${item.label}`" :disabled="item.disabled" />
<!-- 单选radio -->
<el-radio-group v-model="listQuery[item.prop]" v-else-if="item.type == 'radio'" :disabled="item.disabled">
<el-radio v-for="obj in item.options" :key="obj.value" :label="obj.value">{{ obj.label }}</el-radio>
</el-radio-group>
<!-- 时间选择 -->
<el-time-picker v-else-if="item.type == 'time'" v-model="listQuery[item.prop]" placeholder="选择时间" style="width: 100%" :disabled="item.disabled" />
<el-date-picker v-else-if="item.type == 'date'" v-model="listQuery[item.prop]" type="date" value-format="YYYY-MM-DD" placeholder="请选择日期" style="width: 100%" :disabled="item.disabled" />
<el-date-picker v-else-if="item.type == 'datetime'" v-model="listQuery[item.prop]" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择时间" style="width: 100%" :disabled="item.disabled" />
<el-date-picker v-else-if="item.type == 'datetimerange'" v-model="listQuery[item.prop]" type="datetimerange" :shortcuts="shortcuts" range-separator="To" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="选择开始时间" end-placeholder="选择结束时间" style="width: 100%" :disabled="item.disabled" />
<el-date-picker v-else-if="item.type == 'daterange'" v-model="listQuery[item.prop]" type="daterange" range-separator="To" value-format="YYYY-MM-DD" start-placeholder="选择开始日期" end-placeholder="选择开始日期" style="width: 100%" :disabled="item.disabled" />
<el-switch v-else-if="item.type == 'switch'" v-model="listQuery[item.prop]" class="ml-2" :disabled="item.disabled" style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" />
<template v-else-if="item.type === 'slot'">
<slot :name="item.prop"></slot>
</template>
</el-form-item>
</el-form>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { ref, defineProps, defineEmits, defineExpose, watch, watchEffect, readonly } from "vue";
const props = defineProps({
//循环的值
formList: {
default: [],
type: Array
},
rules: {
default: {},
type: Object
},
labelWidth: {
default: "140px",
type: String
},
modelValue: {
type: Object,
default: {}
},
inline: {
type: Boolean,
default: true
},
disabled: {
type: Boolean,
default: false
}
});
const elform = ref();
const listQuery = ref({});
const emits = defineEmits(["update:modelValue"]);
// 提交
const submit = (resfun) => {
elform.value.validate((valid) => {
if (!valid) return false;
resfun(listQuery.value);
});
};
const getdep = (e, val) => {
if (val) {
if (Array.isArray(e)) {
listQuery.value[val] = e ? e.map(item => item.orgName) : '';
} else {
listQuery.value[val] = e ? e.orgName : '';
}
}
}
const reset = () => {
elform.value.resetFields()
}
// 修改这里的watch逻辑避免无限循环
let isUpdatingFromProps = false;
watch(() => listQuery.value, (newVal) => {
if (newVal && !isUpdatingFromProps) {
emits("update:modelValue", newVal);
}
}, { deep: true });
watch(() => props.modelValue, (newVal) => {
// 只有在新值确实变化时才更新(避免空值覆盖)
if (newVal && Object.keys(newVal).length > 0) {
isUpdatingFromProps = true;
listQuery.value = { ...newVal };
setTimeout(() => {
isUpdatingFromProps = false;
}, 0);
}
}, { immediate: true, deep: true });
defineExpose({ submit, reset });
</script>

View File

@ -0,0 +1,133 @@
<!--
* @Date: 2025-08-06 14:49:49
* @Description: 系统切换窗口
-->
<template>
<!-- append-to-body -->
<div class="a">
<el-dialog
:model-value="modelValue"
class="switch-sys-dialog"
modal-class="switch-sys-dialog-modal"
:show-close="false"
width="75%"
align-center
destroy-on-close
@close="handleModalClick"
>
<div class="switch-sys-dialog__content">
<div class="carousel">
<div
:class="['card-item']"
v-for="(item, index) in list"
:key="item.value"
@click="goPage(item, index)"
>
<img :src="item.icon" class="card-item__img" />
<div class="card-item__label">{{ item.label }}</div>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import fk from '@/assets/images/fk.png'
import ty from '@/assets/images/ty.png'
import pcs from '@/assets/images/pcs.png'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['update:modelValue'])
const list = [
{ label: '俯瞰系统', value: 1, url: `https://tyyy.lz.dsj.xz/overlooking/home`, icon: fk },
{ label: '统一门户', value: 2, url: 'https://tyyy.lz.dsj.xz/portal/home', icon: ty },
{ label: '智慧派出所', value: 3, url: 'https://pcs.lz.dsj.xz:9020/index.html', icon: pcs },
]
const goPage = (item) => {
if (item.url) {
window.open(item.url, '_self')
}
}
// 处理遮罩点击事件
const handleModalClick = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss">
</style>
<style lang="scss" scoped>
.a{
::v-deep(.el-dialog){
background-color: transparent !important;
}
}
body .el-overlay .el-overlay-dialog .el-dialog{
background-color: transparent !important;
}
.switch-sys-dialog {
&__content {
display: grid;
grid-template-columns: auto 1fr auto;
width: inherit;
// height: 335px;
align-items: center;
.carousel {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40px;
width: 100%;
height: 100%;
.card-item {
border-radius: 10px;
overflow: hidden;
cursor: pointer;
transition: all 0.25s ease;
&:hover {
transform: scale(1.05);
.card-item__label {
height: 30px;
line-height: 30px;
font-size: 16px;
color: var(--theme-text-color);
font-weight: bold;
}
}
&__img {
width: 100%;
height: auto;
object-fit: cover;
}
&__label {
height: 25px;
line-height: 25px;
background-color: #fff;
text-align: center;
color: var(--text-color-black);
transition: all 0.5s ease;
}
}
}
}
}
</style>

188
src/components/fzq/fxq.vue Normal file
View File

@ -0,0 +1,188 @@
<template>
<div class="floating-ball" :style="ballStyle" @mousedown="startDrag" @touchstart="startDrag" @click="handleClick">
<slot>
</slot>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
const props = defineProps({
// 初始位置
initialPosition: {
type: Object,
default: () => ({ x: 0, y: 0 })
},
// 是否可拖动
draggable: {
type: Boolean,
default: true
},
// 自动吸附边缘的阈值
snapThreshold: {
type: Number,
default: 0
}
});
// watch(() => props.initialPosition, (newVal) => {
// position.value = { x: newVal.x, y: newVal.y };
// },{deep:true})
const emit = defineEmits(['click']);
const position = ref({ x: props.initialPosition.x, y: props.initialPosition.y });
const isDragging = ref(false);
const startPos = ref({ x: 0, y: 0 });
const startMousePos = ref({ x: 0, y: 0 });
const ballStyle = ref({
left: `${position.value.x}px`,
top: `${position.value.y}px`,
cursor: props.draggable ? 'move' : 'pointer'
});
// 开始拖动
const startDrag = (e) => {
if (!props.draggable) return;
isDragging.value = true;
startPos.value = { ...position.value };
// 处理鼠标和触摸事件
if (e.type === 'mousedown') {
startMousePos.value = { x: e.clientX, y: e.clientY };
} else if (e.type === 'touchstart') {
startMousePos.value = { x: e.touches[0].clientX, y: e.touches[0].clientY };
}
// 阻止默认行为和冒泡
e.preventDefault();
e.stopPropagation();
};
// 处理移动
const handleMove = (e) => {
if (!isDragging.value) return;
let clientX, clientY;
if (e.type === 'mousemove') {
clientX = e.clientX;
clientY = e.clientY;
} else if (e.type === 'touchmove') {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
}
const dx = clientX - startMousePos.value.x;
const dy = clientY - startMousePos.value.y;
position.value = {
x: startPos.value.x + dx,
y: startPos.value.y + dy
};
updatePosition();
};
// 结束拖动
const endDrag = () => {
if (!isDragging.value) return;
isDragging.value = false;
snapToEdge();
};
// 自动吸附到边缘
const snapToEdge = () => {
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// 检查是否靠近左右边缘
if (position.value.x < props.snapThreshold) {
position.value.x = 0;
} else if (position.value.x > windowWidth - props.snapThreshold) {
position.value.x = windowWidth;
}
// 检查是否靠近上下边缘
if (position.value.y < props.snapThreshold) {
position.value.y = 0;
} else if (position.value.y > windowHeight - props.snapThreshold) {
position.value.y = windowHeight;
}
updatePosition();
};
// 更新位置样式
const updatePosition = () => {
ballStyle.value = {
...ballStyle.value,
left: `${position.value.x}px`,
top: `${position.value.y}px`
};
};
// 点击事件
const handleClick = (e) => {
if (isDragging.value) {
// 如果是拖动结束的点击,不触发点击事件
isDragging.value = false;
return;
}
emit('click', e);
};
// 添加事件监听
onMounted(() => {
window.addEventListener('mousemove', handleMove);
window.addEventListener('touchmove', handleMove);
window.addEventListener('mouseup', endDrag);
window.addEventListener('touchend', endDrag);
});
// 移除事件监听
onUnmounted(() => {
window.removeEventListener('mousemove', handleMove);
window.removeEventListener('touchmove', handleMove);
window.removeEventListener('mouseup', endDrag);
window.removeEventListener('touchend', endDrag);
});
</script>
<style scoped>
.floating-ball {
position: fixed;
cursor: pointer;
width: 50px;
padding: 10px;
/* height: 50px; */
/* border-radius: 50%; */
/* background-color: #409eff; */
color: white;
/* display: flex;
justify-content: center;
align-items: center; */
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
z-index: 9999;
user-select: none;
/* transition: all 0.3s ease; */
transform: translate(-50%, -50%);
}
.ball-content {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
.icon {
font-size: 24px;
}
.floating-ball:active {
opacity: 0.8;
}
</style>

View File

@ -0,0 +1,57 @@
<template>
<div class="iframe-container">
<el-dialog class="dialog-container" :model-value="modelValue" width="75%" :show-close="false" @close="close">
<div style="height: 75vh;">
<div class="close" @click="close"><el-icon :size="30"><CircleClose /></el-icon></div>
<iframe :src="src" frameborder="0" width="100%" height="100%"></iframe>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
modelValue: {
type: Boolean,
required: true
}, title: {
type: String,
default: '提示'
}, showFooter: {
type: Boolean,
default: true
}, src: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:modelValue', 'submit', 'close'])
const close = () => {
emit('update:modelValue', false)
emit('close')
}
const submit = () => {
emit('submit')
}
</script>
<style lang="scss" scoped>
.iframe-container {
::v-deep .el-dialog__header {
display: none;
}
.close{
position: absolute;
top: 0px;
right: -35px;
cursor: pointer;
border-radius: 50%;
color: #fff;
}
::v-deep .el-dialog__body {
padding: 0 !important;
}
}
</style>

View File

@ -0,0 +1,256 @@
<template>
<Fxq :initial-position="{ x: position.x, y: position.y }" v-if="showFxq" :snapThreshold="50">
<div class="badge-container">
<div>
<div>
<el-tooltip effect="dark" content="林小警" placement="left-start">
<img style="width: 34px;height: 34px;"
@click.stop="skipIframe(`https://tyyy.lz.dsj.xz/embed/home?userId=${userId}&clientKey=${clientKey}&avatar=''`)"
class="box-item" src="@/assets/images/streetBi/lxj.png" />
</el-tooltip>
<el-tooltip effect="dark" content="切换门户" placement="left-start">
<img style="width: 34px;height: 34px;" @click.stop="SwitchSysDialogShow = true" class="box-item"
src="@/assets/images/streetBi/sst.png" />
</el-tooltip>
<el-tooltip effect="dark" content="蜂群消息" placement="left-start">
<img style="width: 34px;height: 34px; margin-bottom: 14px;"
@click.stop="skipIframe('https://fqxt.lz.dsj.xz:9020/fqxt/?source=other')" class="box-item"
src="@/assets/images/streetBi/fq.png" />
</el-tooltip>
</div>
<el-badge :value="xxListData.xtxxNumber" class="item badge-top-left">
<div class='fxq fxq1' @click.stop="opneMsg('xtxx')">
<div class="title">
<img src="@/assets/images/streetBi/xtxx.png" />
<span>系统消息</span>
</div>
</div>
</el-badge>
<el-badge :value="xxListData.tztgNumber" class="item badge-top-left">
<div class='fxq fxq2' @click.stop="opneMsg('tztg')">
<div class="title">
<img src="@/assets/images/streetBi/tztg.png" />
<span>通知通报</span>
</div>
</div>
</el-badge>
</div>
</div>
</Fxq>
<Iframe v-model='showIframe' :src='src' />
<SwitchSysDialog v-model="SwitchSysDialogShow" />
<Information v-model='showDialog' :title='title'>
<systemMessages :dict="{ BD_D_XXLX, BD_D_XXLY }" :idEntityCard='idEntityCard' :xxlx="showMsgLx" />
</Information>
</template>
<script setup>
import { ref, nextTick, provide, onMounted, reactive, getCurrentInstance, onUnmounted } from "vue";
import { queryWdxxPageList, queryWdxxDetail } from '@/api/commit.js'
import SwitchSysDialog from '@/components/fzq/SwitchSysDialog.vue'
import systemMessages from '@/components/fzq/systemMessages.vue'
import Information from '@/components/fzq/information.vue'
import Fxq from '@/components/fzq/fxq.vue'
import { getItem } from '@/utils/storage.js'
import { getCookie } from '@/utils/cookie'
import Iframe from '@/components/fzq/iframe.vue'
import emitter from "@/utils/eventBus.js";
const { proxy } = getCurrentInstance();
const { BD_D_XXLX, BD_D_XXLY } = proxy.$dict('BD_D_XXLX', 'BD_D_XXLY'); //获取字典
const position = reactive({
x: window.innerWidth - 30,
y: window.innerHeight - 160
})
const idEntityCard = ref('')
const xxListData = reactive({
xtxxNumber: 0,
tztgNumber: 0
})
//请求数据
const handleClick = () => {
let promes = {
page: 1,
rows: 1,
jsrid: idEntityCard.value,
xxlx: ""
}
queryWdxxPageList({ ...promes, xxlx: 100 }).then((res) => {
xxListData.xtxxNumber = res.total
});
queryWdxxPageList({ ...promes, xxlx: 200 }).then((res) => {
xxListData.tztgNumber = res.total
});
}
const userId = getItem('USERID')
const clientKey = getCookie('clientKey')
const SwitchSysDialogShow = ref(false)
const src = ref()
const showIframe = ref(false)
const skipIframe = (val) => {
src.value = val
showIframe.value = true
}
const title = ref('系统消息')
const showDialog = ref(false)
const showMsgLx = ref('')
const showFxq = ref(true)
const opneMsg = (val) => {
showDialog.value = true
showMsgLx.value = val
switch (val) {
case 'xtxx':
title.value = '系统消息'
break;
case 'tztg':
title.value = '通知通告'
break;
}
}
const intTime = ref(null)
onMounted(() => {
if (window.parent !== window.self) {
showFxq.value = false
} else {
showFxq.value = true
}
emitter.on("handleClick", () => {
idEntityCard.value = getItem('idEntityCard')
handleClick()
intTime.value = setInterval(() => {
handleClick()
}, 60000)
});
})
onUnmounted(() => {
clearInterval(intTime.value)
emitter.off("handleClick")
})
</script>
<style lang="scss" scoped>
// 蜂群组件样式
.fxqx {
border-radius: 34px;
width: 34px;
background-color: rgb(1, 127, 245);
margin-bottom: 18px;
display: flex;
align-items: center;
position: relative;
.title {
height: 34px;
line-height: 34px;
display: flex;
align-items: center;
white-space: nowrap;
img {
margin-left: 9.5px;
width: 16px;
margin-right: 10px;
vertical-align: middle;
height: 16px;
flex-shrink: 0;
}
span {
opacity: 0;
transition: opacity 0.2s ease 0.1s;
padding-right: 15px;
}
}
}
.fxq {
border-radius: 34px;
width: 34px;
transition: width 0.3s ease;
background-color: rgb(1, 127, 245);
// overflow: hidden;
margin-bottom: 10px;
display: flex;
align-items: center;
position: relative;
.title {
height: 34px;
line-height: 34px;
display: flex;
align-items: center;
white-space: nowrap;
img {
margin-left: 9.5px;
width: 16px;
margin-right: 10px;
vertical-align: middle;
height: 16px;
flex-shrink: 0;
}
span {
opacity: 0;
transition: opacity 0.2s ease 0.1s;
padding-right: 15px;
}
}
}
.fxq2 {
background-color: #9d88f9;
}
.fxq3 {
background-color: #00c07f;
}
.fxq:hover {
width: 120px;
}
.fxq:hover .title span {
opacity: 1;
}
.item {
margin-bottom: 10px;
}
.box-item {
margin-bottom: 10px;
}
.badge-content {
display: flex;
flex-direction: column;
overflow: hidden;
transition: all 0.3s ease;
max-height: 200px;
/* 默认展开的最大高度 */
min-height: 0;
/* 确保收缩时有足够空间显示第一个图标 */
}
.badge-content:not(.expanded) {
max-height: 0;
}
/* 收缩时只显示第一个图标,隐藏其他内容 */
.badge-content:not(.expanded)> :not(:first-child) {
opacity: 0;
max-height: 0;
margin: 0;
padding: 0;
overflow: hidden;
}
::v-deep .el-badge__content.is-fixed {
right: calc(100% + 6px);
}
</style>

View File

@ -0,0 +1,53 @@
<template>
<el-dialog class="dialog-container"
:model-value="modelValue"
:title="title"
:before-close="close" :destroy-on-close="true"
>
<slot></slot>
<template #footer v-if="showFooter">
<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 {ref} from 'vue'
const props=defineProps({
modelValue: {
type: Boolean,
required: true
},title:{
type:String,
default:'提示'
},showFooter:{
type:Boolean,
default:true
}
})
const emit=defineEmits(['update:modelValue','submit','close'])
const close = () => {
emit('update:modelValue',false)
emit('close')
}
const submit=()=>{
emit('submit')
}
</script>
<style lang="scss" scoped>
// @import "@/assets/css/homeScreen.scss";
::v-deep .el-dialog__body{
padding-top: 0 !important;
padding-bottom: 0 !important;
}
</style>

View File

@ -0,0 +1,184 @@
<template>
<!-- <el-button type="success" style='position: absolute;right:30px;'>一键忽略</el-button> -->
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="chageHandle">
<el-tab-pane label="未查看" name="first">
<MyTable customClass="zdy_peo_table" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth">
<template #xxly="{ row }">
<DictTag :tag="false" :value="row.xxly" :options="dict.BD_D_XXLY" />
</template>
<template #xxlx="{ row }">
<DictTag :tag="false" :value="row.xxlx" :options="dict.BD_D_XXLX" />
</template>
<template #controls="{ row }">
<el-button size="small" type="primary" @click="handleDetail(row)">查看</el-button>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</el-tab-pane>
<el-tab-pane label="已查看" name="second">
<MyTable customClass="zdy_peo_table" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth">
<template #xxly="{ row }">
<DictTag :tag="false" :value="row.xxly" :options="dict.BD_D_XXLY" />
</template>
<template #xxlx="{ row }">
<DictTag :tag="false" :value="row.xxlx" :options="dict.BD_D_XXLX" />
</template>
<template #controls="{ row }">
<el-button size="small" type="primary" @click="handleDetail(row)">查看</el-button>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"></Pages>
</el-tab-pane>
</el-tabs>
<Information v-model='showDialog' title='消息详情' :showFooter="false">
<Xtxi :item="msgDetail" v-if="xxlx == 'xtxx'" :dict="dict" />
</Information>
</template>
<script setup>
import { ref, reactive } from 'vue'
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Information from "./information.vue";
import { queryYdxxPageList, queryWdxxPageList, queryWdxxDetail, queryYdxxDetail, qsXx } from '@/api/commit.js'
import Xtxi from './xtxi.vue'
const props = defineProps({
dict: {
type: Object,
default: () => {
}
}, idEntityCard: {
type: String,
default: ''
}, xxlx: {
type: String,
default: 'xtxx'
}
})
const activeName = ref('first')
const pageData = reactive({
tableData: [],
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 40,
haveControls: true,
},
controlsWidth: 160, //操作栏宽度
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
tableColumn: [
{ label: "消息标题", prop: "xxbt", showOverflowTooltip: true },
{ label: "消息来源", prop: "xxly", showOverflowTooltip: true, showSolt: true },
{ label: "消息描述", prop: "xxms", showOverflowTooltip: true },
{ label: "消息类型", prop: "xxlx", showOverflowTooltip: true, showSolt: true },
], tableHeight: "calc(80vh - 350px)",
});
const chageHandle = () => {
pageData.pageConfiger.pageCurrent = 1
pageData.pageConfiger.pageSize = 20
handleClick()
}
//请求数据
const handleClick = async () => {
let promes = {
page: pageData.pageConfiger.pageCurrent,
rows: pageData.pageConfiger.pageSize,
jsrid: props.idEntityCard,
xxlx: ""
}
switch (props.xxlx) {
case 'xtxx':
promes.xxlx = 100
const res = activeName.value == 'first' ? await queryWdxxPageList(promes) : await queryYdxxPageList(promes)
pageData.tableData = res.rows
pageData.total = res.total
break;
case 'tztg':
promes.xxlx = 200
const tztgRes = activeName.value == 'first' ? await queryWdxxPageList(promes) : await queryYdxxPageList(promes)
pageData.tableData = tztgRes.rows
pageData.total = tztgRes.total
break;
default:
break;
}
}
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val
handleClick()
}
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val
handleClick()
}
handleClick()
// 查看详情
const showDialog = ref(false)
const msgDetail = ref({})
const disposition = (item) => {
let arrId = ''
if (Array.isArray(item)) {
const itemMap = item.map(it => {
return it.id
})
arrId = itemMap.join(',')
} else {
arrId = item.id
}
const promes = {
xxlx: '100',
id: arrId
}
qsXx(promes).then((result) => {
handleClick()
}).catch((err) => {
console.log(err);
});
}
const handleDetail = async (item) => {
showDialog.value = true
const res = activeName.value == 'first' ? await queryWdxxDetail({ id: item.id }) : await queryYdxxDetail({ id: item.id })
if (res) {
msgDetail.value = res[0]
if (msgDetail.value.qszt == '0') {
disposition(item)
}
}
}
</script>
<style lang="scss" scoped>
// @import "@/assets/css/homeScreen.scss";
.zdy_peo_table td.el-table__cell {
color: #ffffff !important;
}
.zdy_peo_table th.el-table__cell {
color: #ffffff !important;
font-size: 15px;
}
.zdy_peo_table .el-table__body tr.el-table__row--striped td.el-table__cell {
background: transparent !important;
}
.zdy_peo_table .table_blue_row {
background: linear-gradient(to right, #001D4B 0%, rgba(0, 29, 75, 0.1) 100%) !important;
}
</style>

View File

@ -0,0 +1,53 @@
<template>
<div style="height: 300px;overflow: auto;font-size: 16px;">
<div>通知标题{{ item.xxbt }}</div>
<div class="mt">通知内容{{ item.xxms }}</div>
<div class="flex align-center just-between mt">
<div class="flex align-center">接收类型
<DictTag :tag="false" :value="item.xxlx" :options="dict.BD_D_XXLX" />
</div>
<div class="flex align-center">消息来源
<DictTag :tag="false" :value="item.xxly" :options="dict.BD_D_XXLY" />
</div>
</div>
</div>
</template>
<script setup>
import {ref} from 'vue'
const props = defineProps({
item: {
type: Object,
default: () => {
}
}, dict: {
type: Object,
default: () => {
}
},
})
</script>
<style lang="scss" scoped>
// @import "@/assets/css/homeScreen.scss";
.zdy_peo_table td.el-table__cell {
color: #ffffff !important;
}
.zdy_peo_table th.el-table__cell {
color: #ffffff !important;
font-size: 15px;
}
.zdy_peo_table .el-table__body tr.el-table__row--striped td.el-table__cell {
background: transparent !important;
}
.zdy_peo_table .table_blue_row {
background: linear-gradient(to right, #001D4B 0%, rgba(0, 29, 75, 0.1) 100%) !important;
}
.mt {
margin-top: 20px;
}
</style>

View File

@ -20,15 +20,18 @@
<el-icon :size="20" color="#fff"> <CaretBottom /> </el-icon>
</span>
<template #dropdown>
<el-dropdown-menu class="loginOut" @click="goToHome">
<el-dropdown-item command="logout">前往前台</el-dropdown-item>
</el-dropdown-menu>
<el-dropdown-menu class="loginOut" @click="logout">
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div @click="goToHome">
<!-- <div @click="goToHome">
<img src="@/assets/images/meun.png" />
</div>
</div> -->
</div>
</header>
</template>
@ -63,12 +66,7 @@ onMounted(() => {
active.value = "LZ";
});
const logout = () => {
window.opener = null;
window.open('', '_self');
window.close();
store.commit("app/clearTag", null, { immediate: true });
store.commit("permission/deleteRouter", { immediate: true });
store.commit("user/deleteKeepLiiveRoute", "home");
store.dispatch("user/logout");
};
</script>

View File

@ -229,11 +229,11 @@ export default {
this.commit("permission/deleteRouter");
removeAllItem();
// 待补充 清理权限相关的配置
if (isOatuh) {
window.location.href = `http://80.149.27.78:8001/login`;
} else {
router.push("/login");
}
// if (isOatuh) {
window.location.href = `https://tyyy.lz.dsj.xz/portal/home`;
// } else {
// router.push("/login");
// }
}
}
}

View File

@ -1,12 +1,14 @@
import axios from "axios";
import store from "@/store";
import { ElMessage } from "element-plus";
import { isCheckTimeout } from "@/utils/auth";
import router from '@/router'
import axios from 'axios';
import store from '@/store';
import { ElMessage } from 'element-plus';
import { isCheckTimeout } from '@/utils/auth';
// import { saveAs } from 'file-saver'
// import { tansParams, blobValidate } from "@/utils/ruoyi";
let downloadLoadingInstance;
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 100000
withCredentials: true,
timeout: 100000,
});
// 1.请求拦截器
@ -18,12 +20,12 @@ service.interceptors.request.use(
if (isCheckTimeout()) {
//超时 执行退出
store.dispatch('user/logout');
// router.push('/login');
return Promise.reject(new Error('token 失效'));
}
if (!config.url.startsWith("/jcApi")) {
config.headers.Authorization = `${store.getters.token}`;
}
}
//2.设置headers icode
// config.headers.code = '';
@ -39,37 +41,20 @@ service.interceptors.request.use(
service.interceptors.response.use(
// 请求成功的处理
(response) => {
const { success, code, msg, message, data } = response.data;
console.log("data", code, response.data);
const { success, code, msg, message, data, model } = response.data;
// 需要判断当前请求是否成功
if (success && code === 10000) {
return data; // 成功后返回解析后的数据
// return response.data;
} else if (
code === 200 ||
code == "00000" ||
code == "10000" ||
msg == "success"
) {
return data; // 成功后返回解析后的数据
// return response.data;
return data ? data : response.data; // 成功后返回解析后的数据
} else if (code === 200 || code == "00000" || code == "10000" || msg == 'success' || model) {
return data ? data : response.data; // // 成功后返回解析后的数据
} else if (code === 401) {
store.dispatch('user/logout');
// router.push('/login');
ElMessage.error(message); // 提示错误信息
ElMessage({
message: message || msg,
grouping: true,
type: "error"
});
ElMessage({ message: message || msg, grouping: true, type: 'error' })
} else {
// 失败(请求成功 ,业务失败) 弹出消息提示
ElMessage({
message: message || msg,
grouping: true,
type: "error"
});
return Promise.reject(new Error(message));
ElMessage({ message: message || msg, grouping: true, type: 'error' })
return Promise.reject(new Error(message + '数据格式错误'));
}
},
// 请求失败处理
@ -80,16 +65,36 @@ service.interceptors.response.use(
error.response.data &&
error.response.data.code === 401
) {
console.log("Xxxxx");
store.dispatch('user/logout');
// router.push('/login');
}
// ElMessage({
// message: error.message,
// grouping: true,
// type: 'error'
// })
// return Promise.reject(error);
}
);
// 通用下载方法
// export function download(url, params, filename, config) {
// return service.post(url, params, {
// transformRequest: [(params) => { return tansParams(params) }],
// headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
// responseType: 'blob',
// ...config
// }).then(async (data) => {
// const isBlob = blobValidate(data);
// if (isBlob) {
// const blob = new Blob([data])
// saveAs(blob, filename)
// } else {
// const resText = await data.text();
// const rspObj = JSON.parse(resText);
// const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
// ElMessage.error(errMsg);
// }
// }).catch((r) => {
// ElMessage.error('下载文件出现错误,请联系管理员!')
// })
// }
export default service;

View File

@ -5,31 +5,45 @@
</div>
<!-- 搜索 -->
<div ref="searchBox">
<Search
:searchArr="searchConfiger"
@submit="onSearch"
:key="pageData.keyCount"
/>
<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"
>
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData">
<template #yjTp="{ row }">
<el-image
<template v-if="!row.yjTp || row.yjTp.includes('baidu')">
<img src="@/assets/images/default_male.png" width="100" height="100" />
</template>
<el-image v-else :preview-teleported="true" style="width: 100px; height: 100px" :src="urlImg + row.yjTp"
show-progress :preview-src-list="[urlImg + row.yjTp]" fit="cover">
<template #error>
<div class="image-slot error">
<img src="@/assets/images/default_male.png" width="100" height="100" />
</div>
</template>
</el-image>
<!-- <el-image v-else :preview-teleported="true" style="width: 80px; height: 110px" :src="item.yjTp"
:preview-src-list="[item.yjTp]" show-progress>
<template #error>
<div class="image-slot error">
<img src="@/assets/images/car.png" width="65" height="80" v-if="item.yjLx == 2" />
<img src="@/assets/images/default_male.png" width="80" height="110" v-else />
</div>
</template>
</el-image> -->
<!-- <el-image
style="width: 100px; height: 100px"
:src="urlImg + row.yjTp"
show-progress
:preview-src-list="[urlImg + row.yjTp]"
fit="cover"
/>
/> -->
<!-- <el-image
style="width: 50px; height: 50px"
:src="row.accidentPhoto"
@ -42,15 +56,10 @@
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
></Pages>
}"></Pages>
</div>
<!-- 详情 -->
<DetailForm ref="detailDiloag" :dict="{ D_BZ_XB }" />

View File

@ -54,10 +54,19 @@ const funClick = (index,val) => {
imgBut.value[index].show = !imgBut.value[index].show
switch (val) {
case 'xl':
if (imgBut.value[index].show) {
emitter.emit("deletePointArea", "lx");
} else {
gettbGjclXlxxselectList()
}
break;
case 'zt':
if (imgBut.value[index].show) {
emitter.emit("deletePointArea", "gjz");
} else {
gettbGjZdxxselectList()
}
break;
case 'qc':
clearContents()
@ -91,13 +100,13 @@ const gettbGjclXlxxselectList = () => {
const data = res.filter(item => item.zb && item.zb.length > 0).map((item) => {
return { coords: [item.zb], text: item.xlmc };
});
emitter.emit("echoLine", {
type: "solid",
coords: data,
width: 2,
isclear: true,
flag: "lx",
color: "#46ff71"
color: "#f88a34"
});
}
});
@ -112,6 +121,7 @@ const clearContents = () => {
<style scoped lang="scss">
.data-statistics {
height: 100%;
//
.img_but {
text-align: center;
@ -119,6 +129,7 @@ const clearContents = () => {
.imgBox {
width: 101px;
height: 78px;
img {
width: 100%;
}
@ -127,6 +138,7 @@ const clearContents = () => {
.imgT {
background: url("~@/assets/images/bi/R_T.png") no-repeat center center;
}
.textB {
// width: 38px;
width: 100%;
@ -139,6 +151,7 @@ const clearContents = () => {
line-height: 19px;
}
}
.boxCenter {
margin: 0 15px;
}

View File

@ -1,22 +1,29 @@
<template>
<div class="checkpoint-list noScollLine">
<el-timeline style="max-width: 375px">
<el-timeline-item
v-for="(item, index) in warningList.listData"
:key="index"
:timestamp="item.yjSj"
placement="top"
:hollow="true"
color="#061b44"
>
<el-timeline-item v-for="(item, index) in warningList.listData" :key="index" :timestamp="item.yjSj"
placement="top" :hollow="true" color="#061b44">
<div class="item_card">
<div style="line-height: 18px">
{{ item.yjNr }}
</div>
<el-divider border-style="dashed" class="dashed" />
<div class="flex">
<div class="flex" @click="sendCommand(item)">
<div class="warning-image">
<img :src="item.yjTp" alt="预警图片" />
<!-- <img :src="item.yjTp" alt="预警图片" /> -->
<template v-if="!item.yjTp || item.yjTp.includes('baidu')">
<img src="@/assets/images/car.png" width="65" height="70" v-if="item.yjLx == 2" />
<img src="@/assets/images/default_male.png" width="65" height="70" v-else />
</template>
<el-image v-else :preview-teleported="true" style="width: 80px; height: 110px" :src="item.yjTp"
:preview-src-list="[item.yjTp]" show-progress>
<template #error>
<div class="image-slot error">
<img src="@/assets/images/car.png" width="65" height="80" v-if="item.yjLx == 2" />
<img src="@/assets/images/default_male.png" width="80" height="110" v-else />
</div>
</template>
</el-image>
</div>
<div class="inform">
<div class="flex align-center">
@ -39,12 +46,14 @@
</el-timeline>
<Empty :show="warningList.listData.length == 0" />
</div>
<FzDialog v-model="dialogVisible" :list="dataList"/>
</template>
<script setup>
import { reactive } from "vue";
import { reactive ,ref} from "vue";
import { tbGjYjgetPageList } from "@/api/mosty-zhgj.js";
import Empty from "@/components/Empty/index.vue";
import FzDialog from "../components/fqzl.vue";
const warningList = reactive({
listData: [],
total: 0
@ -68,6 +77,13 @@ const scroll = () => {
linQuery.pageCurrent++;
}
};
// 发送指令
const dialogVisible = ref(false);
const dataList=ref({})
const sendCommand = (item) => {
dialogVisible.value = true;
dataList.value=item
}
gettbGjclselectPage();
</script>
@ -80,6 +96,7 @@ gettbGjclselectPage();
overflow-y: auto;
padding: 4px;
box-sizing: border-box;
.item_card {
font-size: 14px;
color: #fff;
@ -91,22 +108,26 @@ gettbGjclselectPage();
opacity: 0.86;
background: url("~@/assets/images/bi/jmk.png") no-repeat center center;
background-size: 100% 100%;
.dashed {
width: 100%;
border-top: 1px #0468e1 dashed;
margin: 10px 0px 9px;
}
.warning-image {
border: 1px solid #0468e1;
padding: 10px 10px 10px 14px;
width: 103px;
height: 99px;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.inform {
box-sizing: border-box;
margin-left: 11px;
@ -115,9 +136,11 @@ gettbGjclselectPage();
font-weight: 400;
font-size: 14px;
color: #ffffff;
.inform_name {
width: 120px;
}
.inform_tag {
font-family: "Source Han Sans CN";
font-weight: 300;
@ -135,12 +158,15 @@ gettbGjclselectPage();
::v-deep .el-timeline-item__node {
border-color: rgb(13, 216, 37);
}
::v-deep .el-timeline-item__tail {
border-left: 2px solid #06366d;
}
::v-deep .el-timeline-item__wrapper {
padding-left: 10px;
}
::v-deep .is-top {
margin-bottom: 12px;
padding-top: 2px;

View File

@ -0,0 +1,237 @@
<template>
<el-dialog v-model="modelValue" title="发送指令" width="70%" center :append-to-body="true" @close="closed">
<div style="height: 50vh; overflow-y: auto; padding: 10px;">
<div class="info-container">
<!-- 主要信息区域图片和关键信息左右排列 -->
<div class="main-info-section">
<!-- 图片区域 -->
<div class="warning-image">
<template v-if="!props.list.yjTp || props.list.yjTp.includes('baidu')">
<img src="@/assets/images/car.png" width="100" height="100" v-if="props.list.yjLx == 2" />
<img src="@/assets/images/default_male.png" width="100" height="100" v-else />
</template>
<el-image v-else :preview-teleported="true" style="width: 100px; height: 100px" :src="props.list.yjTp"
:preview-src-list="[props.list.yjTp]" show-progress>
<template #error>
<div class="image-slot error">
<img src="@/assets/images/car.png" width="100" height="100" v-if="props.list.yjLx == 2" />
<img src="@/assets/images/default_male.png" width="100" height="100" v-else />
</div>
</template>
</el-image>
</div>
<!-- 关键信息区域垂直排列成一列 -->
<div class="key-info">
<!-- 姓名标签和值左右排列 -->
<div class="info-item info-item-horizontal">
<span class="info-label">姓名:</span>
<span class="info-value">{{ props.list.yjRyxm || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">身份证号:</span>
<span class="info-value">{{ props.list.yjRysfzh || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">相似度:</span>
<span class="info-value">{{ props.list.yjSimi || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">标签:</span>
<span class="info-value">{{ props.list.yjbqmc || '-' }}</span>
</div>
</div>
</div>
<!-- 其他信息区域 -->
<div class="details-section">
<div class="info-grid">
<div class="info-item info-item-horizontal">
<span class="info-label">预警时间:</span>
<span class="info-value">{{ props.list.yjSj || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">预警标题:</span>
<span class="info-value">{{ props.list.yjBt || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">预警类型:</span>
<span class="info-value">{{ props.list.yjLx || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">预警级别:</span>
<span class="info-value">{{ props.list.yjJb || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">目的地:</span>
<span class="info-value">{{ props.list.gmdd || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">检查站名称:</span>
<span class="info-value">{{ props.list.jczmc || '-' }}</span>
</div>
<div class="info-item info-item-horizontal">
<span class="info-label">GPS时间:</span>
<span class="info-value">{{ props.list.gpsj || '-' }}</span>
</div>
<div class="info-item full-width info-item-horizontal">
<span class="info-label">预警内容:</span>
<span class="info-value">{{ props.list.yjNr || '-' }}</span>
</div>
</div>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="modelValue = false">取消</el-button>
<el-button type="primary" @click="handleConfirm( props.list)" >签到</el-button>
<el-button type="primary" @click="openFszl" v-if=" list.czzt == '02'">反馈</el-button>
<el-button type="primary" @click="openFszl" v-if=" list.czzt == '03'">查看反馈</el-button>
</div>
</template>
</el-dialog>
<SendFqzl v-model="fszl" :list="props.list" @close="closed" />
</template>
<script setup>
import { ref, computed, getCurrentInstance } from "vue";
import { qcckPost, qcckGet } from "@/api/qcckApi.js";
import SendFqzl from "@/views/home/components/sendFqzl.vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
list: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['update:modelValue', 'confirm'])
// 处理确认按钮点击
const handleConfirm = (item) => {
proxy.$confirm("是否确定要签收?", "警告", { type: "warning" }).then(() => {
qcckPost({ id: item.id }, "/mosty-gsxt/yjzxXwyj/yjqs").then(() => {
item.czzt = '02'
proxy.$message({ type: "success", message: "签收成功" });
});
})
// emit('confirm', props.list)
// emit('update:modelValue', false)
}
const fszl = ref(false)
const openFszl = () => {
fszl.value = true
}
const closed = () => {
emit('update:modelValue', false)
}
</script>
<style lang="scss" scoped>
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px;
}
.info-container {
display: flex;
flex-direction: column;
gap: 20px;
}
// 主要信息区域样式:图片和关键信息左右排列
.main-info-section {
display: flex;
align-items: flex-start;
gap: 30px;
padding: 20px;
background-color: #f8f9fa;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.warning-image {
display: flex;
justify-content: center;
align-items: center;
width: 120px;
height: 120px;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
flex-shrink: 0;
}
// 关键信息区域垂直排列成一列
.key-info {
display: flex;
flex-direction: column;
gap: 15px;
flex: 1;
}
// 普通信息项:标签和值垂直排列
.info-item {
display: flex;
flex-direction: column;
gap: 4px;
}
// 特殊信息项:标签和值左右排列
.info-item-horizontal {
flex-direction: row;
align-items: center;
gap: 10px;
}
// 其他信息区域样式
.details-section {
background-color: #ffffff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.info-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.info-item.full-width {
grid-column: 1 / -1;
}
.info-label {
font-size: 13px;
font-weight: 600;
color: #606266;
}
.info-value {
font-size: 14px;
color: #303133;
line-height: 1.5;
word-break: break-all;
}
// 滚动条样式
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background-color: #f5f7fa;
}
::-webkit-scrollbar-thumb {
background-color: #c0c4cc;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #909399;
}
</style>

View File

@ -0,0 +1,219 @@
<!--文件导出 -->
<template>
<el-dialog v-model="modelValue" :title="title" :width="width" @close="close" append-to-body>
<div style="height: 50vh; overflow: auto;">
<FormMessage v-model="listQuery" :formList="formData" labelWidth="100px" ref="elform" :rules="rules">
<template #zrSsbmdm>
<MOSTY.Department filterable v-model="listQuery.zrSsbmdm" width="100%" @getDepValue="getDepValue" clearable
placeholder="请选择所属部门" :multiple="true" />
</template>
<template #ry>
<el-input readonly v-model="listQuery.ry" @click="chooseUserVisible = true" placeholder="请选择民警"></el-input>
</template>
</FormMessage>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="close">取消</el-button>
<el-button type="primary" @click="getsendFqzl">
确认
</el-button>
</div>
</template>
</el-dialog>
<ChooseUser v-model="chooseUserVisible" @choosedUsers="handleUserSelected" :roleIds="roleIds" :Single="false" />
</template>
<script setup>
import { reactive, ref, onMounted, watch } from "vue";
import { getItem } from '@/utils/storage'
import * as MOSTY from "@/components/MyComponents/index";
import ChooseUser from "@/components/ChooseList/ChooseUser/index.vue"
import FormMessage from "@/components/aboutTable/FormMessage.vue";
import { ElMessage } from "element-plus";
const props = defineProps({
itemData: {
type: Object,
default: () => { }
}, tacitly: {
type: Object,
default: () => { }
},
modelValue: {
type: Boolean,
default: false
}, title: {
type: String,
default: "发送指令"
}, width: {
type: String,
default: "70%"
}
})
const emit = defineEmits(['handleClose', 'update:modelValue'])
// 表单数据
const listQuery = ref({}); //表单
// 选择人员
const ryStr = ref('')
const elform = ref()
const personnelEntity = ref()
const formData = ref([
{ label: "标题", prop: "title", type: "input", width: "40%" },
{ label: "接收单位", prop: "zrSsbmdm", type: "slot", width: "40%" },
{ label: "指令状态", prop: "status", type: "input", width: "40%" },
{ label: "人员选择", prop: "ry", type: "slot", width: "40%" },
{ label: "附件", prop: "attachmentPath", type: "upload" },
{ label: "指令内容", prop: "instructionContent", type: "textarea", width: "100%" },
])
const rules = reactive({
title: [{ required: true, message: "请输入指令标题", trigger: "blur" }],
zrSsbmdm: [{ required: true, message: "请选择接收单位", trigger: "blur" }],
instructionContent: [{ required: true, message: "请输入指令内容", trigger: "blur" }],
ry: [{ required: true, message: "请选择人员", trigger: "blur" }]
});
const deptId = getItem('deptId')
const getsendFqzl = () => {
elform.value.submit(async (val) => {
if (val) {
const data = { ...listQuery.value }
delete data.ry
const promes = {
instructionsEntity: {
unitCode: deptId[0].deptCode,
unitName: deptId[0].deptName,
...data,
receivingUnitCode: listQuery.value.zrSsbmdm.toString(),
receivingUnit: listQuery.value.receivingUnit.toString(),
attachmentPath: JSON.stringify(listQuery.value.attachmentPath)
}, id: props.itemData.id,
personnelEntity: personnelEntity.value
}
try {
const res = await qbcjZhcSendFqzl(promes)
const str = JSON.parse(res)
if (str.code == 200) {
ElMessage.success('发送成功')
listQuery.value = {}
listQuery.value.attachmentPath = ''
emit('handleClose')
} else {
ElMessage.error(str.msg)
}
} catch (error) {
console.log(error);
}
}
})
}
watch(() => props.itemData, (val) => {
// listQuery.value.title = val[props.tacitly['title']]
// if (props.tacitly['instructionContent']) {
// listQuery.value.instructionContent = val[props.tacitly['instructionContent']]
// }
}, { deep: true, immediate: true })
const chooseUserVisible = ref(false)
const roleIds = ref([])
// 选取角色
const handleUserSelected = (val) => {
personnelEntity.value = val.map((item, index) => {
return {
name: item.userName,
idNumber: item.idEntityCard,
phoneNumber: item.mobile,
personTypeId: "",
personTypeName: "",
domicilePlace: "",
orderId: index + 1
}
})
// ryStr.value
listQuery.value.ry = personnelEntity.value.map(item => item.name)
}
// 选取部门
const getDepValue = (e) => {
listQuery.value.receivingUnit = e.map(item => item.orgName)
}
const close = () => {
listQuery.value = {}
listQuery.value.attachmentPath = ''
emit('update:modelValue', false)
}
defineExpose({
getsendFqzl,
close
})
</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

@ -9,7 +9,21 @@
>
<div class="flex">
<div class="warning-image">
<img :src="item.image" alt="预警图片" />
<!-- <img :src="item.image" alt="预警图片" /> -->
<template v-if="!item.image || item.image.includes('baidu')">
<img src="@/assets/images/car.png" width="65" height="70" />
</template>
<el-image v-else :preview-teleported="true" style="width: 65px; height: 70px" :src="item.image"
:preview-src-list="[item.image]" show-progress>
<template #error>
<div class="image-slot error">
<img src="@/assets/images/car.png" width="65" height="70" />
</div>
</template>
</el-image>
</div>
<div class="personalInfo">
<div class="driver">
@ -150,7 +164,7 @@ const roadmap = (row) => {
border: 1px solid #0468e1;
padding: 10px 10px 10px 14px;
width: 123px;
width: 85px;
height: 69px;
img {
width: 100%;

View File

@ -30,10 +30,10 @@
</div>
</div>
</div>
<!-- 警组弹框弹框 -->
<PoliceGroupInfo v-if="show.jzgroup" :data="jzxqList" />
</div>
</template>
<script setup>
@ -50,6 +50,15 @@ import {
reactive,
onMounted
} from "vue";
const jzxqList = ref({}); //警组列表详情
const show = reactive({
jzgroup: false //展示警组弹窗
@ -141,4 +150,6 @@ onMounted(() => {
box-sizing: border-box;
}
}
</style>

View File

@ -12,6 +12,28 @@
</div> -->
<div class="wd absolute">
<div class="tc">
<div><img src="@/assets/images/peo.png" /></div>
<div class="hd">
<div class="name">姓名{{ username }}</div>
<div class="work">单位{{ deptName }}</div>
</div>
<el-dropdown :hide-on-click="false">
<span class="el-dropdown-link">
<el-icon :size="20" color="#fff">
<CaretBottom />
</el-icon>
</span>
<template #dropdown>
<el-dropdown-menu class="loginOut" @click="goPath">
<el-dropdown-item command="logout" >前往后台</el-dropdown-item>
</el-dropdown-menu>
<el-dropdown-menu class="loginOut" @click="goAot">
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<!-- <el-icon size="25px" style="top: 6px" color="#86C8EB"><Sunny /></el-icon>
<span> 温度 1~7°C </span> -->
</div>
@ -22,22 +44,28 @@
import { useRouter } from "vue-router";
import { getRecentDay, timeValidate } from "@/utils/tools.js";
import { ref, onMounted, defineProps, onUnmounted } from "vue";
import { useStore } from "vuex";
const props = defineProps({
title: {
type: String,
default: "智慧公交"
}
});
const store=useStore()
const datatime = ref(getRecentDay(0));
const minute = ref("00"); //分
const second = ref("00"); //秒
const hour = ref("00"); //时
const day = ref(0);
const timersfm = ref(null);
const deptName = ref()
const username=ref()
const router = useRouter();
onMounted(() => {
//登陆用户信息
deptName.value = localStorage.getItem("deptId") ? JSON.parse(localStorage.getItem("deptId"))[0].deptName : ''
username.value = localStorage.getItem("USERNAME");
timersfm.value = setInterval(() => {
CurrentTime();
}, 1000);
@ -53,7 +81,9 @@ function CurrentTime() {
minute.value = minute.value < 10 ? "0" + minute.value : minute.value;
second.value = second.value < 10 ? "0" + second.value : second.value;
}
const goAot = () => {
store.dispatch("user/logout");
}
function goPath() {
router.push("/editPassword");
}
@ -123,11 +153,25 @@ function goPath() {
top: 10px;
}
.wd {
right: 25%;
right: 20px;
top: 12px;
font-size: 16px;
font-family: "DigifaceWide";
color: #fff;
display: flex;
align-items: center;
.tc{
display: flex;
align-items: center;
font-size: 14px;
.hd{
margin-left: 5px;
}
.el-dropdown-link{
margin-left: 10px;
}
}
}
.zbbb {
position: absolute;

View File

@ -3,34 +3,39 @@
<script setup>
import { ref, onMounted } from "vue";
import { useStore } from "vuex";
import { useRouter } from "vue-router";
import {
getCookie
} from "@/utils/cookie";
import {
setItem
} from "@/utils/storage";
import { getSessionForSfzh, idCardNoLogin } from "@/api/user-manage";
import { getSessionForSfzh, idCardNoLogin, getSession } from "@/api/user-manage";
import {
setTimeStamp
} from "@/utils/auth";
import emitter from "@/utils/eventBus.js";
const loginDialog = ref(false);
const deptList = ref([]);
const store = useStore();
// 处理页面可见性变化的函数
const handleVisibilityChange = () => {
getSession().then(res => {
const { placeId, userId } = res.rows[0]
idCardNoLoginLogin(userId, placeId)
})
};
function redirectAuth() {
handleLogin();
const url = window.location.href
const urlObj = new URL(url);
handleVisibilityChange()
}
const handleLogin = (e) => {
// 先尝试获取cookie中的clientKey
const token = getCookie("clientKey");
if (token) {
// 使用clientKey获取会话信息
getSessionForSfzh({ cookie: token }).then((res) => {
// 使用获取到的idEntityCard进行免登
// 身份证号进行登录
const idCardNoLoginLogin = (idCard, orgId) => {
idCardNoLogin({
idCardNo: res
idCardNo: idCard,
orgCode: orgId
}).then((resIdCard) => {
// 登录成功后设置token和用户信息到store
store.commit("user/setToken", resIdCard.jwtToken);
@ -55,26 +60,52 @@ const handleLogin = (e) => {
setItem("deptId", resIdCard.deptList);
// 保存登录时间
setTimeStamp();
emitter.emit("handleClick")
// 重定向到首页
setTimeout(() => {
if (window.parent !== window.self) {
window.location.hash = window.location.href.split("#")[1];
} else {
console.log("首页");
window.location.hash = "/";
}
}, 1000);
}).catch((error) => {
console.error("免登失败:", error);
// 免登失败时重定向到登录页面
// window.location.hash = "/login";
});
}).catch((error) => {
console.error("获取会话信息失败:", error);
// 获取会话信息失败时重定向到登录页面
// window.location.hash = "/login";
});
} else {
console.error("没有找到clientKey cookie");
// 没有cookie时重定向到登录页面
window.location.hash = "/login";
}
};
onMounted(() => {
redirectAuth();
});

View File

@ -3,8 +3,8 @@ const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
const serverHost = "http://47.108.232.77:9537";
// const serverHost = "http://192.168.0.231:8006";
// const serverHost = "http://47.108.232.77:9537";
const serverHost = "http://192.168.2.206:8006";
module.exports = {
publicPath: "./",
outputDir: "zhgj",

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" name="viewport"><link rel="icon" href="favicon.ico"><title>公安</title><script src="./pgis/eliMapboxgl.min.js"></script><script src="./static/js/vconsole.min.js"></script><script src="./static/js/jquery-1.12.4.min.js"></script><script src="./static/js/moment.js"></script><script src="./static/js/vue.js"></script><script src="./static/js/antd.min.js"></script><script src="./static/js/antd-with-locales.min.js"></script><link href="static/css/chunk-0fdaaf92.0c8b1149.css" rel="prefetch"><link href="static/css/chunk-15d0e086.f2ed914b.css" rel="prefetch"><link href="static/css/chunk-28bd6e9c.0577588b.css" rel="prefetch"><link href="static/css/chunk-2938498a.ea4fa40f.css" rel="prefetch"><link href="static/css/chunk-2cc5efda.ce890925.css" rel="prefetch"><link href="static/css/chunk-418af005.a9f08a65.css" rel="prefetch"><link href="static/css/chunk-455e0e48.6da1c4d0.css" rel="prefetch"><link href="static/css/chunk-48f37632.96c16873.css" rel="prefetch"><link href="static/css/chunk-548a1330.cad1653e.css" rel="prefetch"><link href="static/css/chunk-608198a8.630e98f6.css" rel="prefetch"><link href="static/css/chunk-61c2abd0.3c058eb8.css" rel="prefetch"><link href="static/css/chunk-69e71423.93973246.css" rel="prefetch"><link href="static/css/chunk-8b575eb6.61a130d5.css" rel="prefetch"><link href="static/css/chunk-8c788636.dc818670.css" rel="prefetch"><link href="static/css/chunk-a37f0b78.9266fafe.css" rel="prefetch"><link href="static/css/chunk-ac2f4938.8f7d963a.css" rel="prefetch"><link href="static/css/chunk-e8303676.55ea4f8a.css" rel="prefetch"><link href="static/css/chunk-e94c1e5c.c3628cd2.css" rel="prefetch"><link href="static/css/chunk-f3f588ac.ab45516e.css" rel="prefetch"><link href="static/css/chunk-fc70b89e.d9cdf86b.css" rel="prefetch"><link href="static/css/chunk-fe6900ae.50f8e44f.css" rel="prefetch"><link href="static/js/chunk-0fdaaf92.96513d67.js" rel="prefetch"><link href="static/js/chunk-15d0e086.68c0d93e.js" rel="prefetch"><link href="static/js/chunk-28bd6e9c.d338ef41.js" rel="prefetch"><link href="static/js/chunk-2938498a.878e6ba1.js" rel="prefetch"><link href="static/js/chunk-2cc5efda.83536ac7.js" rel="prefetch"><link href="static/js/chunk-2d0dd6ad.c65603bb.js" rel="prefetch"><link href="static/js/chunk-2d22bd3e.aec990f1.js" rel="prefetch"><link href="static/js/chunk-418af005.ea0aa7b9.js" rel="prefetch"><link href="static/js/chunk-455e0e48.cbe4ca2e.js" rel="prefetch"><link href="static/js/chunk-48f37632.2bc5b22e.js" rel="prefetch"><link href="static/js/chunk-548a1330.f50e10a5.js" rel="prefetch"><link href="static/js/chunk-608198a8.5db1d4c5.js" rel="prefetch"><link href="static/js/chunk-61c2abd0.2a77232d.js" rel="prefetch"><link href="static/js/chunk-69e71423.b7abce56.js" rel="prefetch"><link href="static/js/chunk-8b575eb6.a4230b28.js" rel="prefetch"><link href="static/js/chunk-8c788636.9a21a1dd.js" rel="prefetch"><link href="static/js/chunk-a37f0b78.300ee302.js" rel="prefetch"><link href="static/js/chunk-ac2f4938.3c3c9ae1.js" rel="prefetch"><link href="static/js/chunk-e8303676.5c7cbb20.js" rel="prefetch"><link href="static/js/chunk-e94c1e5c.6ad1f39e.js" rel="prefetch"><link href="static/js/chunk-f3f588ac.6f180c2e.js" rel="prefetch"><link href="static/js/chunk-fc70b89e.aa157a53.js" rel="prefetch"><link href="static/js/chunk-fe6900ae.95533d2a.js" rel="prefetch"><link href="static/css/app.486d424b.css" rel="preload" as="style"><link href="static/css/chunk-vendors.ccb705f1.css" rel="preload" as="style"><link href="static/js/app.fffda7c0.js" rel="preload" as="script"><link href="static/js/chunk-vendors.62ab2f07.js" rel="preload" as="script"><link href="static/css/chunk-vendors.ccb705f1.css" rel="stylesheet"><link href="static/css/app.486d424b.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 公安 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>document.documentElement.addEventListener(
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0" name="viewport"><link rel="icon" href="favicon.ico"><title>公安</title><script src="./pgis/eliMapboxgl.min.js"></script><script src="./static/js/vconsole.min.js"></script><script src="./static/js/jquery-1.12.4.min.js"></script><script src="./static/js/moment.js"></script><script src="./static/js/vue.js"></script><script src="./static/js/antd.min.js"></script><script src="./static/js/antd-with-locales.min.js"></script><link href="static/css/chunk-0fdaaf92.0c8b1149.css" rel="prefetch"><link href="static/css/chunk-10ed8ea9.d9cdf86b.css" rel="prefetch"><link href="static/css/chunk-15d0e086.f2ed914b.css" rel="prefetch"><link href="static/css/chunk-28bd6e9c.0577588b.css" rel="prefetch"><link href="static/css/chunk-2938498a.ea4fa40f.css" rel="prefetch"><link href="static/css/chunk-2cc5efda.ce890925.css" rel="prefetch"><link href="static/css/chunk-30a2f08a.cad1653e.css" rel="prefetch"><link href="static/css/chunk-3994dd3e.630e98f6.css" rel="prefetch"><link href="static/css/chunk-418af005.a9f08a65.css" rel="prefetch"><link href="static/css/chunk-455e0e48.6da1c4d0.css" rel="prefetch"><link href="static/css/chunk-48f37632.96c16873.css" rel="prefetch"><link href="static/css/chunk-5fafc2b3.d795c7b8.css" rel="prefetch"><link href="static/css/chunk-61c2abd0.3c058eb8.css" rel="prefetch"><link href="static/css/chunk-66984dee.55ea4f8a.css" rel="prefetch"><link href="static/css/chunk-69e71423.93973246.css" rel="prefetch"><link href="static/css/chunk-8c788636.dc818670.css" rel="prefetch"><link href="static/css/chunk-90a5863e.0dd6a688.css" rel="prefetch"><link href="static/css/chunk-a37f0b78.9266fafe.css" rel="prefetch"><link href="static/css/chunk-e94c1e5c.c3628cd2.css" rel="prefetch"><link href="static/css/chunk-f3f588ac.ab45516e.css" rel="prefetch"><link href="static/css/chunk-fe6900ae.50f8e44f.css" rel="prefetch"><link href="static/js/chunk-0fdaaf92.96513d67.js" rel="prefetch"><link href="static/js/chunk-10ed8ea9.672c45ca.js" rel="prefetch"><link href="static/js/chunk-15d0e086.dc9f852b.js" rel="prefetch"><link href="static/js/chunk-28bd6e9c.2807bbc8.js" rel="prefetch"><link href="static/js/chunk-2938498a.d137b7ec.js" rel="prefetch"><link href="static/js/chunk-2cc5efda.83536ac7.js" rel="prefetch"><link href="static/js/chunk-2d0dd6ad.88aa7369.js" rel="prefetch"><link href="static/js/chunk-2d22bd3e.aec990f1.js" rel="prefetch"><link href="static/js/chunk-30a2f08a.8ac28871.js" rel="prefetch"><link href="static/js/chunk-3994dd3e.1ffe7686.js" rel="prefetch"><link href="static/js/chunk-418af005.b220bb88.js" rel="prefetch"><link href="static/js/chunk-455e0e48.cbe4ca2e.js" rel="prefetch"><link href="static/js/chunk-48f37632.c0a32cc7.js" rel="prefetch"><link href="static/js/chunk-5fafc2b3.fdd68395.js" rel="prefetch"><link href="static/js/chunk-61c2abd0.2a77232d.js" rel="prefetch"><link href="static/js/chunk-66984dee.07608eef.js" rel="prefetch"><link href="static/js/chunk-69e71423.b7abce56.js" rel="prefetch"><link href="static/js/chunk-8c788636.9a21a1dd.js" rel="prefetch"><link href="static/js/chunk-90a5863e.ae40f38d.js" rel="prefetch"><link href="static/js/chunk-a37f0b78.6a8bf1ff.js" rel="prefetch"><link href="static/js/chunk-e94c1e5c.6ad1f39e.js" rel="prefetch"><link href="static/js/chunk-f3f588ac.d7c61568.js" rel="prefetch"><link href="static/js/chunk-fe6900ae.95533d2a.js" rel="prefetch"><link href="static/css/app.21d684c2.css" rel="preload" as="style"><link href="static/css/chunk-vendors.ccb705f1.css" rel="preload" as="style"><link href="static/js/app.9c9257e9.js" rel="preload" as="script"><link href="static/js/chunk-vendors.62ab2f07.js" rel="preload" as="script"><link href="static/css/chunk-vendors.ccb705f1.css" rel="stylesheet"><link href="static/css/app.21d684c2.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but 公安 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>document.documentElement.addEventListener(
"touchmove",
function (event) {
if (event.touches.length > 1) {
@ -6,4 +6,4 @@
}
},
false
);</script><script src="static/js/chunk-vendors.62ab2f07.js"></script><script src="static/js/app.fffda7c0.js"></script></body></html>
);</script><script src="static/js/chunk-vendors.62ab2f07.js"></script><script src="static/js/app.9c9257e9.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0dd6ad"],{"80fe":function(e,t,s){"use strict";s.r(t);var n=s("7a23"),o=s("5502"),c=(s("f3e4"),s("5d2d")),i=s("92c2"),r=s("5f87"),d={__name:"zeroTrust_login",setup(e){Object(n["ref"])(!1),Object(n["ref"])([]);const t=Object(o["b"])(),s=()=>{Object(i["r"])().then(e=>{const{placeId:t,userId:s}=e.rows[0];u(s,t)})};function d(){const e=window.location.href;new URL(e);s()}const u=(e,s)=>{Object(i["z"])({idCardNo:e,orgCode:s}).then(e=>{t.commit("user/setToken",e.jwtToken),t.commit("user/setDeptList",e.deptList),t.commit("user/setUserName",e.userName),t.commit("user/setMenuList",e.menuList),t.commit("user/setUserInfo",{token:e.jwtToken,permission:{buttonPermission:["removeTest","viewTest"],menus:e.menuCodeSet},menuList:e.menuList,deptList:e.deptList}),Object(c["c"])("USERNAME",e.userName),Object(c["c"])("SFRH",e.sfrh),Object(c["c"])("USERID",e.userId),Object(c["c"])("menusPermission",e.menuCodeSet),Object(c["c"])("idEntityCard",e.idEntityCard),Object(c["c"])("deptId",e.deptList),Object(r["b"])(),setTimeout(()=>{window.location.hash="/"},1e3)}).catch(e=>{console.error("免登失败:",e)})};return Object(n["onMounted"])(()=>{d()}),(e,t)=>null}};const u=d;t["default"]=u}}]);

View File

@ -1 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-2d0dd6ad"],{"80fe":function(e,t,o){"use strict";o.r(t);var s=o("7a23"),n=o("5502"),c=o("f3e4"),i=o("5d2d"),r=o("92c2"),u=o("5f87"),d={__name:"zeroTrust_login",setup(e){Object(s["ref"])(!1),Object(s["ref"])([]);const t=Object(n["b"])();function o(){d()}const d=e=>{const o=Object(c["a"])("clientKey");o?Object(r["r"])({cookie:o}).then(e=>{Object(r["z"])({idCardNo:e}).then(e=>{t.commit("user/setToken",e.jwtToken),t.commit("user/setDeptList",e.deptList),t.commit("user/setUserName",e.userName),t.commit("user/setMenuList",e.menuList),t.commit("user/setUserInfo",{token:e.jwtToken,permission:{buttonPermission:["removeTest","viewTest"],menus:e.menuCodeSet},menuList:e.menuList,deptList:e.deptList}),Object(i["c"])("USERNAME",e.userName),Object(i["c"])("SFRH",e.sfrh),Object(i["c"])("USERID",e.userId),Object(i["c"])("menusPermission",e.menuCodeSet),Object(i["c"])("idEntityCard",e.idEntityCard),Object(i["c"])("deptId",e.deptList),Object(u["b"])(),setTimeout(()=>{window.location.hash="/"},1e3)}).catch(e=>{console.error("免登失败:",e)})}).catch(e=>{console.error("获取会话信息失败:",e)}):(console.error("没有找到clientKey cookie"),window.location.hash="/login")};return Object(s["onMounted"])(()=>{o()}),(e,t)=>null}};const m=d;t["default"]=m}}]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.