This commit is contained in:
lcw
2025-06-08 22:23:25 +08:00
commit d9f272ca7d
1154 changed files with 276763 additions and 0 deletions

View File

@ -0,0 +1,164 @@
<template>
<div>
<el-dialog
v-model="dialogAdd"
:title="title"
width="70%"
:before-close="handleClose"
:destroy-on-close="true"
:close-on-click-modal="false"
>
<el-form
ref="formRef"
:model="formDate"
:rules="rules"
:disabled="disabled"
:inline="true"
:label-width="130"
>
<el-form-item prop="sxrxm" label="送修人姓名" style="width: 48%">
<el-input v-model="formDate.sxrxm" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="sxrsfzh" label="送修人身份证号" style="width: 48%">
<el-input v-model="formDate.sxrsfzh" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="wxkssj" label="维修开始时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.wxkssj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="wxjssj" label="维修结束时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.wxjssj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="wxdwmc" label="维修单位名称" style="width: 48%">
<el-input v-model="formDate.wxdwmc" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="wxdwdz" label="维修单位地址" style="width: 48%">
<el-input v-model="formDate.wxdwdz" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="jhrxm" label="接回人姓名" style="width: 48%">
<el-input v-model="formDate.jhrxm" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="jhrsfzh" label="接回人身份证号" style="width: 48%">
<el-input v-model="formDate.jhrsfzh" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="wxyy" label="维修原因" style="width: 100%">
<el-input
v-model="formDate.wxyy"
type="textarea"
style="width: 100%"
></el-input>
</el-form-item>
</el-form>
<div style="width: 100%; text-align: center">
<el-button @click="saveDate" v-loading="loading" v-if="!disabled"
>保存</el-button
>
<el-button @click="handleClose">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import {WxjlSave,WxjlUpdate,WxjlId} from "@/api/lzqwzx/index.js";
import {
reactive,
ref,
getCurrentInstance,
defineExpose,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
xfclId: String
});
const emits = defineEmits(["updateList"]);
const dialogAdd = ref(false);
const loading = ref(false);
const formRef = ref();
const formDate = ref({});
const title = ref("新增");
const disabled = ref(false);
const rules = reactive({
sxrxm: [{ required: true, message: "请输入领用人姓名", trigger: "blur" }],
jhrxm: [{ required: true, message: "请输入接回人姓名", trigger: "blur" }],
...rule.identityCardRule({ validator: true, require: true }, "sxrsfzh"), //身份证校验
...rule.identityCardRule({ validator: true, require: true }, "jhrsfzh"), //身份证校验
wxkssj: [
{ required: true, message: "请选择维修开始时间", trigger: "change" }
],
wxdwmc: [
{ required: true, message: "请输入维修单位名称", trigger: "change" }
],
wxdwdz: [{ required: true, message: "请输入维修单位地址", trigger: "change" }]
});
// 初始化
const init = (type, id) => {
dialogAdd.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
disabled.value = type == "detail" ? true : false;
if (type != "add") getInfoById(id);
};
// 根据数据id获取数据
const getInfoById = (id) => {
WxjlId(id).then((res) => {
formDate.value = res;
});
};
// 保存数据
const saveDate = () => {
formRef.value.validate((valid) => {
if (!valid) return false;
let params = { ...formDate.value };
params.xfclId = props.xfclId;
if (title.value == "新增") {
loading.value = true;
WxjlSave(params)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
} else {
WxjlUpdate(params)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
}
});
};
// 关闭弹窗
const handleClose = () => {
dialogAdd.value = false;
loading.value = false;
formDate.value = {};
};
defineExpose({ init });
</script>
<style>
</style>

View File

@ -0,0 +1,146 @@
<template>
<div>
<el-dialog
v-model="dialogAdd"
:title="title"
width="70%"
:before-close="handleClose"
:destroy-on-close="true"
:close-on-click-modal="false"
>
<el-form
ref="formRef"
:model="formDate"
:rules="rules"
:disabled="disabled"
:inline="true"
:label-width="130"
>
<el-form-item prop="ycrxm" label="用车人姓名" style="width: 48%">
<el-input v-model="formDate.ycrxm" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="ycrsfzh" label="用车人身份证号" style="width: 48%">
<el-input v-model="formDate.ycrsfzh" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="yckssj" label="用车开始时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.yckssj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="用车结束时间" label="归还时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.ycjssj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="ycjslcs" label="用车结束里程数" style="width: 48%">
<el-input v-model="formDate.ycjslcs" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="bz" label="备注" style="width: 100%">
<el-input
v-model="formDate.bz"
type="textarea"
style="width: 100%"
></el-input>
</el-form-item>
</el-form>
<div style="width: 100%; text-align: center">
<el-button @click="saveDate" v-loading="loading" v-if="!disabled"
>保存</el-button
>
<el-button @click="handleClose">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup>
import {YcjSave,YcjUpdate,YcjId} from "@/api/lzqwzx/index.js";
import {
reactive,
ref,
getCurrentInstance,
defineExpose,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
xfclId: String
});
const emits = defineEmits(["updateList"]);
const dialogAdd = ref(false);
const loading = ref(false);
const formRef = ref();
const formDate = ref({});
const title = ref("新增");
const disabled = ref(false);
const rules = reactive({
ycrxm: [{ required: true, message: "请输入领用人姓名", trigger: "blur" }],
// ...rule.identityCardRule({ validator: true, require: true }, "ycrsfzh"), //身份证校验
lysl: [{ required: true, message: "请输入领用数量", trigger: "change" }],
yckssj: [{ required: true, message: "请选择领用时间", trigger: "change" }],
ycjslcs: [{ required: true, message: "请输入里程数", trigger: "change" }]
});
// 初始化
const init = (type, id) => {
dialogAdd.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
disabled.value = type == "detail" ? true : false;
if (type != "add") getInfoById(id);
};
// 根据数据id获取数据
const getInfoById = (id) => {
YcjId(id).then((res) => {
formDate.value = res;
});
};
// 保存数据
const saveDate = () => {
formRef.value.validate((valid) => {
if (!valid) return false;
let params = { ...formDate.value };
params.xfclId = props.xfclId;
if (title.value == "新增") {
loading.value = true;
YcjSave(params)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
} else {
YcjUpdate(params)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
}
});
};
// 关闭弹窗
const handleClose = () => {
dialogAdd.value = false;
loading.value = false;
formDate.value = {};
};
defineExpose({ init });
</script>
<style>
</style>

View File

@ -0,0 +1,223 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-if="!disabled">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="formCnt">
<el-form ref="elform" :model="formData" :label-width="110" :rules="rules" :inline="true" :disabled="disabled">
<div class="label">基础信息</div>
<div class="infoItem">
<el-form-item label="车辆名称" prop="clmc">
<el-input v-model="formData.clmc" placeholder="请输入车辆名称"></el-input>
</el-form-item>
<el-form-item label="大类别" prop="jyjtfwlb">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_JYCL_JYJTFWLB" placeholder="请选择大类别" v-model="formData.jyjtfwlb" />
</el-form-item>
<el-form-item label="小类别" prop="jyjtgjlb">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_JYCL_JYJTGJLB" placeholder="请选择小类别" v-model="formData.jyjtgjlb" />
</el-form-item>
<el-form-item label="用途">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_JYCL_JYJTYTLB" placeholder="请选择用途" v-model="formData.jyjtytlb" />
</el-form-item>
<el-form-item label="警种" prop="jzlx">
<MOSTY.Select :dictEnum="props.dic.D_BZ_RYJZLB" placeholder="请选择警种" v-model="formData.jzlx" />
</el-form-item>
<el-form-item label="号牌类别" prop="hpyslb">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_JYCL_HPYSLB" placeholder="请选择号牌类别" v-model="formData.hpyslb" />
</el-form-item>
<el-form-item label="号牌号码" prop="cph">
<el-input v-model="formData.cph" placeholder="号牌号码"></el-input>
</el-form-item>
<el-form-item label="车架号" prop="cjh">
<el-input v-model="formData.cjh" placeholder="车架号"></el-input>
</el-form-item>
<el-form-item label="购买日期" prop="gmrq">
<el-date-picker style="width: 100%" v-model="formData.gmrq" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"></el-date-picker>
</el-form-item>
<el-form-item label="使用年限" prop="synx">
<el-input type="number" v-model="formData.synx" placeholder="使用年限"></el-input>
</el-form-item>
<el-form-item label="报废日期" >
<el-date-picker disabled style="width: 100%" v-model="bfrqTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"></el-date-picker>
</el-form-item>
<el-form-item label="车辆年款" prop="clnk">
<el-input v-model="formData.clnk" placeholder="车辆年款"></el-input>
</el-form-item>
<el-form-item label="载客量" prop="zkl">
<el-input type="number" v-model="formData.zkl" placeholder="载客量"></el-input>
</el-form-item>
<el-form-item label="车载电台" prop="czdt">
<el-input v-model="formData.czdt" placeholder="车载电台"></el-input>
</el-form-item>
<el-form-item label="管理单位" prop="ssbmdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue" v-model="formData.ssbmdm" :placeholder="formData.ssbm" />
</el-form-item>
<el-form-item label="使用单位" prop="sydwdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue1" v-model="formData.sydwdm" :placeholder="formData.sydwmc" />
</el-form-item>
<el-form-item label="年检日期" prop="njrq">
<el-date-picker style="width: 100%" v-model="formData.njrq" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD"></el-date-picker>
</el-form-item>
<el-form-item label="年检结果" prop="njjg">
<el-input v-model="formData.njjg" placeholder="年检结果"></el-input>
</el-form-item>
<el-form-item label="备注" style="width: 100%">
<el-input placeholder="请输入备注" v-model="formData.bz" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea"></el-input>
</el-form-item>
</div>
<div class="label">关联信息</div>
<div class="infoItem">
<el-form-item label="关联人员" prop="glryxm">
<el-input v-model="formData.glryxm" placeholder="请输入关联人员"></el-input>
</el-form-item>
<el-form-item label="关联GPSID" prop="gpsId">
<el-input v-model="formData.gpsId" placeholder="请输入关联GPSID"></el-input>
</el-form-item>
</div>
</el-form>
<div style="padding: 2rem 12rem 0rem 12rem">
<!-- 借用记录 -->
<div class="label" v-if="disabled">车辆信息</div>
<div class="infoItem" v-if="disabled">
<YCJL :xfclId="formData.cid" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import YCJL from "./ycjl.vue";
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, servicePost, servicePut } from "@/api/serviceApi.js";
import { getDifferTime, timeValidate } from "@/utils/tools.js";
import {xfclAddXfcl,xfclUpdateXfcl} from '@/api/lzqwzx/index.js'
import * as rule from "@/utils/rules.js";
import { ref, defineExpose, reactive, getCurrentInstance,computed } from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF, D_JC_XFJY_JYLX } = proxy.$dict("D_BZ_SF", "D_JC_XFJY_JYLX");
const emits = defineEmits(["updateDate"]);
const props = defineProps({
dic: { type: Object, default: {} }
});
const title = ref("新增");
const elform = ref();
const disabled = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const formData = ref({});
const bfrqTime=computed(()=>{
const gmrq= new Date(formData.value.gmrq)
gmrq.setFullYear(gmrq.getFullYear()+Number(formData.value.synx))
let year=gmrq.getFullYear()
let moth=String(gmrq.getMonth()+1).padStart(2,'0')
let day=String(gmrq.getDate()).padStart(2,'0')
formData.value.bfrq= `${year}-${moth}-${day}`
return `${year}-${moth}-${day}`
})
const rules = reactive({
clmc: [{ required: true, message: "请输入设备编号", trigger: "blur" }],
jyjtfwlb: [{ required: true, message: "请选择大类别", trigger: "change" }],
jyjtgjlb: [{ required: true, message: "请选择小类别", trigger: "change" }],
// jyjtytlb: [{ required: true, message: "请选择用途", trigger: "change" }],
jzlx: [{ required: true, message: "请选择警种", trigger: "change" }],
hpyslb: [{ required: true, message: "请选择号牌类别", trigger: "change" }],
cph: [{ required: true, message: "请输入号牌号码", trigger: "blur" }],
cjh: [{ required: true, message: "请输入车架号", trigger: "blur" }],
gmrq: [{ required: true, message: "请输入购买日期", trigger: "blur" }],
synx: [{ required: true, message: "请输入使用年限", trigger: "blur" }],
zkl: [
{ required: true, message: "请输入载客量", trigger: ["blur", "change"] }
],
czdt: [
{ required: true, message: "请输入车载电台", trigger: ["blur", "change"] }
],
ssbmdm: [{ required: true, message: "请选择单位管理", trigger: "change" }],
sydwdm: [{ required: true, message: "请选择使用单位", trigger: "change" }],
glryxm: [{ required: true, message: "请输入关联人员", trigger: "blur" }],
gpsId: [{ required: true, message: "请输入关联GPSID", trigger: "blur" }]
});
// 初始化数据
const init = (type, row) => {
console.log(row);
dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "修改" : "详情";
disabled.value = type == "detail" ? true : false;
if (row) formData.value =row; //根据id查询详情
};
const getDepValue = (val) => {
formData.value.ssbm = val ? val.orgJc : "";
};
const getDepValue1 = (val) => {
formData.value.sydwmc = val ? val.orgJc : "";
};
// 关闭
const close = () => {
formData.value = {};
dialogForm.value = false;
loading.value = false;
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
let data = { ...formData.value };
if (title.value == "新增") {
xfclAddXfcl(data)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
} else {
xfclUpdateXfcl(data)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
}
});
};
defineExpose({ init });
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.formCnt {
height: calc(100% - 60px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.label {
font-weight: 600;
margin-bottom: 10px;
width: 100%;
}
.infoItem {
width: 100%;
}
.el-form--inline .el-form-item {
width: 47%;
}
}
</style>

View File

@ -0,0 +1,281 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree @changeSsbm="changeSsbm" width="300px" placeholder="管理部门ID" clearable filterable :isBmId="true" v-model="listQuery.ssbmdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增车辆</span>
</el-button>
<el-button type="primary" @click="handleDelete('')" :disabled="multipleTable.length == 0">
<el-icon>
<Delete />
</el-icon>
<span>批量删除</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable @chooseData="chooseData" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth">
<template #jyjtfwlb="{ row }">
<dict-tag :options="D_JCGL_JYCL_JYJTFWLB" :value="row.jyjtfwlb" :tag="false"></dict-tag>
</template>
<template #jyjtgjlb="{ row }">
<dict-tag :options="D_JCGL_JYCL_JYJTGJLB" :value="row.jyjtgjlb" :tag="false"></dict-tag>
</template>
<!-- <template #jzlx="{ row }">
<dict-tag :options="D_BZ_RYJZLB" :value="row.jzlx" :tag="false"></dict-tag>
</template> -->
<template #jyjtytlb="{ row }">
<dict-tag :options="D_JCGL_JYCL_JYJTYTLB" :value="row.jyjtytlb" :tag="false"></dict-tag>
</template>
<template #hpyslb="{ row }">
<dict-tag :options="D_JCGL_JYCL_HPYSLB" :value="row.hpyslb" :tag="false"></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.cid)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" :dic="{
D_JCGL_JYCL_JYJTYTLB,
D_BZ_RYJZLB,
D_JCGL_JYCL_JYJTGJLB,
D_JCGL_JYCL_JYJTFWLB,
D_JCGL_JYCL_HPYSLB
}" @updateDate="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import {xfclList,xfcldeleteXfcl} from '@/api/lzqwzx/index.js'
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const deptId = JSON.parse(localStorage.getItem("deptId"));
const {
D_JCGL_JYCL_JYJTYTLB,
D_JCGL_JYCL_JYJTFWLB,
D_JCGL_JYCL_JYJTGJLB,
D_BZ_RYJZLB,
D_JCGL_JYCL_HPYSLB
} = proxy.$dict(
"D_JCGL_JYCL_JYJTYTLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_JCGL_JYCL_JYJTGJLB",
"D_BZ_RYJZLB",
"D_JCGL_JYCL_HPYSLB"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const searchConfiger = reactive([
{
showType: "input",
prop: "cph",
placeholder: "请输入车牌号",
label: "车牌号"
},
{
showType: "select",
prop: "jyjtfwlb",
placeholder: "请选择大类别",
label: "大类别",
options: D_JCGL_JYCL_JYJTFWLB
},
{
showType: "select",
prop: "jyjtgjlb",
placeholder: "请选择小类别",
label: "小类别",
options: D_JCGL_JYCL_JYJTGJLB
},
{
showType: "select",
prop: "hpyslb",
placeholder: "请选择号牌类别",
label: "号牌类别",
options: D_JCGL_JYCL_HPYSLB
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 150, //操作栏宽度
tableColumn: [
{ label: "车辆名称", prop: "clmc" },
{ label: "用途", prop: "jyjtytlb", showSolt: true },
// { label: "警种", prop: "jzlx", showSolt: true },
// { label: "号牌类别", prop: "hpyslb", showSolt: true },
// { label: "号牌号码", prop: "cph", showOverflowTooltip: true },
{ label: "管理单位", prop: "ssbm", showOverflowTooltip: true },
// { label: "使用单位", prop: "sydwmc", showOverflowTooltip: true },
{ label: "大类别", prop: "jyjtfwlb", showSolt: true },
{ label: "小类别", prop: "jyjtgjlb", showSolt: true },
{ label: "号牌号码", prop: "cph", showOverflowTooltip: true },
{ label: "号牌类别", prop: "hpyslb", showSolt: true },
{ label: "年检日期", prop: "njrq" },
{ label: "年检结果", prop: "njjg" },
{ label: "购入时间", prop: "gmrq" },
{ label: "报废日期", prop: "bfrq" },
{ label: "车辆年限", prop: "synx" },
// { label: "领用人", prop: "lyr" }
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: deptId[0].deptName,
gldwdm: deptId[0].deptCode
});
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.ssbmdm = val.orgCode;
baseInfo.value.orgName = val.orgName;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.ssbmdm = baseInfo.value.ssbmdm;
pageData.tableConfiger.loading = true;
xfclList(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (val) => {
let ids = val ? [val] : multipleTable.value;
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
xfcldeleteXfcl(ids).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,243 @@
<template>
<div class="jybox">
<div class="titleBox">
<el-tabs type="card" @tab-click="changeCar" v-model="active">
<el-tab-pane label="用车记录" name="ycjl"></el-tab-pane>
<el-tab-pane label="维修记录" name="wxjl"></el-tab-pane>
</el-tabs>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<Search :searchArr="searchConfiger" @submit="onSearch" :key="active" />
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
/>
<!-- 新增编辑用车 -->
<AddDialogYc @updateList="onSearch" ref="addjy" :xfclId="props.xfclId" />
<AddDialogWx @updateList="onSearch" ref="addwx" :xfclId="props.xfclId" />
</div>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import AddDialogYc from "./addDialogYc.vue";
import AddDialogWx from "./addDialogWx.vue";
import {YcjSelectPage,WxjlSelectPage,WxjlDelete,YcjDelete} from "@/api/lzqwzx/index.js";
import { ref, reactive, onMounted, defineProps, getCurrentInstance } from "vue";
const props = defineProps({
xfclId: String
});
const { proxy } = getCurrentInstance();
const active = ref("ycjl");
const searchConfiger = ref([
{
showType: "input",
prop: "ycrxm",
placeholder: "请输入用车人姓名",
label: "用车人姓名"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
tableHeight: 400,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 150, //操作栏宽度
tableColumn: [
{ label: "用车人姓名", prop: "ycrxm", showOverflowTooltip: true },
{ label: "用车人身份证号", prop: "ycrsfzh", showOverflowTooltip: true },
{ label: "用车开始时间", prop: "yckssj", showOverflowTooltip: true },
{ label: "用车结束时间", prop: "ycjssj", showOverflowTooltip: true },
{ label: "用车结束里程数", prop: "ycjslcs", showOverflowTooltip: true }
]
});
const listQuery = ref({});
const addjy = ref();
const addwx = ref();
onMounted(() => {
getList();
});
// 切换车辆
const changeCar = () => {
pageData.tableData = [];
pageData.pageConfiger.pageCurrent = 1;
if (active.value == "ycjl") {
pageData.tableColumn = [
{ label: "用车人姓名", prop: "ycrxm", showOverflowTooltip: true },
{ label: "用车人身份证号", prop: "ycrsfzh", showOverflowTooltip: true },
{ label: "用车开始时间", prop: "yckssj", showOverflowTooltip: true },
{ label: "用车结束时间", prop: "ycjssj", showOverflowTooltip: true },
{ label: "用车结束里程数", prop: "ycjslcs", showOverflowTooltip: true }
];
searchConfiger.value = [
{
showType: "input",
prop: "ycrxm",
placeholder: "请输入用车人姓名",
label: "用车人姓名"
}
];
}
if (active.value == "wxjl") {
pageData.tableColumn = [
{ label: "送修人姓名", prop: "sxrxm", showOverflowTooltip: true },
{ label: "送修人身份证号", prop: "sxrsfzh", showOverflowTooltip: true },
{ label: "维修开始时间", prop: "wxkssj", showOverflowTooltip: true },
{ label: "维修结束时间", prop: "wxjssj", showOverflowTooltip: true },
{ label: "维修单位名称", prop: "wxdwmc", showOverflowTooltip: true },
{ label: "维修原因", prop: "wxyy", showOverflowTooltip: true },
{ label: "接回人姓名", prop: "jhrxm", showOverflowTooltip: true },
{ label: "接回人身份证号", prop: "jhrsfzh", showOverflowTooltip: true }
];
searchConfiger.value = [
{
showType: "input",
prop: "sxrxm",
placeholder: "请输入送修人姓名",
label: "送修人姓名"
}
];
}
getList();
};
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.xfclId = props.xfclId;
pageData.tableConfiger.loading = true;
if (active.value == "wxjl") {
WxjlSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
} else if (active.value == "ycjl") {
YcjSelectPage(params).then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
}
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
if (active.value == "wxjl") {
WxjlDelete( id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
} else if (active.value == "ycjl") {
YcjDelete( id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
}
// let url = "";
// if (active.value == "wxjl") url = "/mosty-jcgl/tbJcglXfclWxjl/"; //维修记录
// if (active.value == "ycjl") url = "/mosty-jcgl/tbJcglXfclYcjl/"; //用车记录
// serviceDelete({}, url + id).then((res) => {
// proxy.$message.success("删除成功");
// getList({});
// });
})
.catch(() => {
proxy.$message.info("已取消");
});
};
const addEdit = (type, row) => {
if (active.value == "ycjl") addjy.value.init(type, row.id);
if (active.value == "wxjl") addwx.value.init(type, row.id);
};
</script>
<style lang="scss" scoped>
.jybox {
width: 100%;
height: 100%;
}
::v-deep .el-tabs--border-card > .el-tabs__content {
padding: 0;
}
::v-deep .el-tabs__header {
margin: 0 0 3px;
}
.app-main .titleBox {
padding-left: 0;
}
::v-deep .el-tabs--card > .el-tabs__header .el-tabs__item.is-active {
background: rgb(55, 197, 240);
border-bottom-color: rgb(55, 197, 240);
color: #fff;
}
::v-deep .el-tabs__item {
height: 45px;
}
</style>

View File

@ -0,0 +1,159 @@
<template>
<div>
<el-dialog
v-model="dialogAdd"
:title="title"
width="70%"
:before-close="handleClose"
:destroy-on-close="true"
:close-on-click-modal="false"
>
<el-form
ref="formRef"
:model="formDate"
:rules="rules"
:disabled="disabled"
:inline="true"
:label-width="130"
>
<el-form-item prop="lyrxm" label="领用人姓名" style="width: 48%">
<el-input v-model="formDate.lyrxm" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="lyrsfzh" label="领用人身份证号" style="width: 48%">
<el-input v-model="formDate.lyrsfzh" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="lysl" label="领用数量" style="width: 48%">
<el-input
v-model="formDate.lysl"
type="number"
style="width: 100%"
></el-input>
</el-form-item>
<el-form-item prop="lysj" label="领用时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.lysj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="xhsl" label="消耗数量" style="width: 48%">
<el-input
v-model="formDate.xhsl"
type="number"
style="width: 100%"
></el-input>
</el-form-item>
<el-form-item prop="ghsj" label="归还时间" style="width: 48%">
<el-date-picker
style="width: 100%"
v-model="formDate.ghsj"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
></el-date-picker>
</el-form-item>
<el-form-item prop="ghsl" label="归还数量" style="width: 48%">
<el-input v-model="formDate.ghsl" style="width: 100%"></el-input>
</el-form-item>
<el-form-item prop="bz" label="备注" style="width: 100%">
<el-input
v-model="formDate.bz"
type="textarea"
style="width: 100%"
></el-input>
</el-form-item>
</el-form>
<div style="width: 100%; text-align: center">
<el-button @click="saveDate" v-loading="loading" v-if="!disabled"
>保存</el-button
>
<el-button @click="handleClose">关闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import {qxjyjlSave,qxjyjlUpdate,qxjyjlId} from "@/api/lzqwzx/index.js"
import {
reactive,
ref,
getCurrentInstance,
defineExpose,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
jyqxId: String
});
const emits = defineEmits(["updateList"]);
const dialogAdd = ref(false);
const loading = ref(false);
const formRef = ref();
const formDate = ref({});
const title = ref("新增");
const disabled = ref(false);
const rules = reactive({
lyrxm: [{ required: true, message: "请输入领用人姓名", trigger: "blur" }],
...rule.identityCardRule({ validator: true, require: true }, "lyrsfzh"), //身份证校验
lysl: [{ required: true, message: "请输入领用数量", trigger: "change" }],
lysj: [{ required: true, message: "请选择领用时间", trigger: "change" }]
});
// 初始化
const init = (type, id) => {
dialogAdd.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "编辑" : "详情";
disabled.value = type == "detail" ? true : false;
if (type != "add") getInfoById(id);
};
// 根据数据id获取数据
const getInfoById = (id) => {
qxjyjlId(id).then((res) => {
formDate.value = res;
});
};
// 保存数据
const saveDate = () => {
formRef.value.validate((valid) => {
if (!valid) return false;
let params = { ...formDate.value };
params.jyqxId = props.jyqxId;
if (title.value == "新增") {
loading.value = true;
qxjyjlSave(params)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
} else {
qxjyjlUpdate(params)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
handleClose();
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
}
});
};
// 关闭弹窗
const handleClose = () => {
dialogAdd.value = false;
loading.value = false;
formDate.value = {};
};
defineExpose({ init });
</script>
<style>
</style>

View File

@ -0,0 +1,179 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="!disabledFoem" v-if="!disabled">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="formCnt">
<el-form ref="elform" :model="formData" :label-width="110" :rules="rules" :inline="true" :disabled="disabled">
<div class="label">基础信息</div>
<div class="infoItem">
<el-form-item label="器械编号" prop="qxbh">
<el-input v-model="formData.qxbh" placeholder="请输入器械编号"></el-input>
</el-form-item>
<el-form-item label="器械名称" prop="qxMc">
<el-input v-model="formData.qxMc" placeholder="请输入器械名称"></el-input>
</el-form-item>
<el-form-item label="器械类型" prop="scode">
<MOSTY.Select :dictEnum="props.dic.D_BZ_JYQXFL" placeholder="请选择器械类型" v-model="formData.scode" />
</el-form-item>
<el-form-item label="数量" prop="sl">
<el-input type="number" v-model="formData.sl" placeholder="数量"></el-input>
</el-form-item>
<br />
<el-form-item label="单位管理" prop="ssbmdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue" v-model="formData.ssbmdm" :placeholder="formData.ssbm" />
</el-form-item>
<el-form-item label="使用单位" prop="sydwdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue1" v-model="formData.sydwdm" :placeholder="formData.sydwmc" />
</el-form-item>
<el-form-item prop="cgrq" label="生产日期">
<el-date-picker format="YYYY/MM/DD" value-format="YYYY-MM-DD" v-model="formData.cgrq" type="date" placeholder="请选择日期" style="width: 100%" />
</el-form-item>
<el-form-item prop="dqsj" label="到期日期">
<el-date-picker format="YYYY/MM/DD" value-format="YYYY-MM-DD" v-model="formData.dqsj" type="date" placeholder="请选择日期" style="width: 100%" />
</el-form-item>
<el-form-item prop="sccs" label="器械厂商">
<el-input v-model="formData.sccs" placeholder="请输入器械厂商" clearable style="width: 100%" />
</el-form-item>
<el-form-item label="备注" style="width: 96%">
<el-input placeholder="请输入备注" v-model="formData.bz" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea"></el-input>
</el-form-item>
</div>
<div class="label">关联信息</div>
<div class="infoItem">
<el-form-item label="关联人员" prop="glryxm">
<el-input v-model="formData.glryxm" placeholder="请输入关联人员"></el-input>
</el-form-item>
<el-form-item label="关联GPSID" prop="glgpsid">
<el-input v-model="formData.glgpsid" placeholder="请输入关联GPSID"></el-input>
</el-form-item>
</div>
</el-form>
<div style="padding: 2rem 12rem 0rem 12rem">
<!-- 借用记录 -->
<div class="label" v-if="disabled">借用信息</div>
<div class="infoItem" v-if="disabled">
<JYJL :jyqxId="formData.id" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import JYJL from "./jyjl.vue";
import { serviceGet, servicePost, servicePut } from "@/api/serviceApi.js";
import { getDifferTime } from "@/utils/tools.js";
import{JyqxSave,JyqxUpdate} from "@/api/lzqwzx/index.js"
import { ref, defineExpose, reactive, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF, D_JC_XFJY_JYLX } = proxy.$dict("D_BZ_SF", "D_JC_XFJY_JYLX");
const emits = defineEmits(["updateDate"]);
const props = defineProps({
dic: { type: Object, default: {} }
});
const title = ref("新增");
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const formData = ref({});
const disabled = ref(false);
const rules = reactive({
qxbh: [{ required: true, message: "请输入设备编号", trigger: "blur" }],
qxMc: [{ required: true, message: "请输入设备名称", trigger: "blur" }],
ssbmdm: [{ required: true, message: "请选择单位管理", trigger: "change" }],
dqsj: [{ required: true, message: "请选择到期日期", trigger: "change" }],
cgrq: [{ required: true, message: "请选择生产日期", trigger: "change" }],
qxlx: [{ required: true, message: "请选择设备类型", trigger: "change" }],
sbwllx: [
{ required: true, message: "请选择设备网络类型", trigger: "change" }
],
sydwdm: [{ required: true, message: "请选择使用单位", trigger: "change" }],
sl: [{ required: true, message: "请输入SIM卡号", trigger: "blur" }],
glryxm: [{ required: true, message: "请输入关联人员", trigger: "blur" }],
glgpsid: [{ required: true, message: "请输入关联GPSID", trigger: "blur" }]
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = type == "add" ? "新增" : type == "edit" ? "修改" : "详情";
disabled.value = type == "detail" ? true : false;
if (row) formData.value = JSON.parse(JSON.stringify(row)); //根据id查询详情
};
const getDepValue = (val) => {
formData.value.ssbm = val ? val.orgJc : "";
};
const getDepValue1 = (val) => {
formData.value.sydwmc = val ? val.orgJc : "";
};
// 关闭
const close = () => {
formData.value = {};
dialogForm.value = false;
loading.value = false;
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
let params = { ...formData.value };
// params.scode = "99";
if (title.value == "新增") {
JyqxSave(params)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
} else {
JyqxUpdate(params)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
}
});
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
// @import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.formCnt {
height: calc(100% - 60px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.label {
font-weight: 600;
margin-bottom: 10px;
width: 100%;
}
.infoItem {
width: 100%;
}
.el-form--inline .el-form-item {
width: 47%;
}
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree @changeSsbm="changeSsbm" width="300px" placeholder="管理部门ID" clearable filterable :isBmId="true" v-model="listQuery.gldwdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
<el-button type="primary" @click="handleDelete('')" :disabled="multipleTable.length == 0">
<el-icon>
<Delete />
</el-icon>
<span>批量删除</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable @chooseData="chooseData" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth">
<template #qxlx="{ row }">
<dict-tag :options="D_BZ_JYQXFL" :value="row.scode" :tag="false"></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" :dic="{ D_BZ_JYQXFL }" @updateDate="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import{JyqxselectJyqx,JyqxbDelete} from "@/api/lzqwzx/index.js"
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
onUnmounted,
watch,
onMounted,
getCurrentInstance,
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_JYQXFL } = proxy.$dict("D_BZ_JYQXFL");
const deptId = JSON.parse(localStorage.getItem("deptId"));
const addEditDialog = ref();
const multipleTable = ref([]);
const searchConfiger = reactive([
{
showType: "input",
prop: "qxbh",
placeholder: "请输入器械编号",
label: "器械编号"
},
{
showType: "input",
prop: "qxMc",
placeholder: "请输入器械名称",
label: "器械名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageNo: 1
}, //分页
controlsWidth: 150, //操作栏宽度
tableColumn: [
{ label: "器械编号", prop: "qxbh" },
{ label: "器械名称", prop: "qxMc" },
{ label: "器械类型", prop: "qxlx", showSolt: true },
{ label: "数量", prop: "sl" },
{ label: "管理单位", prop: "ssbm", showOverflowTooltip: true },
{ label: "使用单位", prop: "sydwmc", showOverflowTooltip: true },
{ label: "关联人员", prop: "glryxm" },
{ label: "关联GPSID", prop: "glgpsid" }
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: deptId[0].deptName,
gldwdm: deptId[0].deptCode,
});
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageNo = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgJc;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageNo = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.gldwdm = baseInfo.value.gldwdm;
pageData.tableConfiger.loading = true;
JyqxselectJyqx(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (val) => {
let ids = val ? [val] : multipleTable.value;
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
JyqxbDelete(ids).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
// @import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,149 @@
<template>
<div class="jybox">
<div class="titleBox">
<div class="title">借用记录</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<Search :searchArr="searchConfiger" @submit="onSearch" />
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="addEdit('detail', row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
/>
<!-- 新增编辑就 -->
<AddDialog @updateList="onSearch" ref="addjy" :jyqxId="props.jyqxId" />
</div>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import AddDialog from "./addDialog.vue";
import {qxjyjlSelectPage,qxjyjlDelete} from "@/api/lzqwzx/index.js"
import { ref, reactive, onMounted, defineProps, getCurrentInstance } from "vue";
const props = defineProps({
jyqxId: String
});
const { proxy } = getCurrentInstance();
const searchConfiger = reactive([
{
showType: "input",
prop: "lyrxm",
placeholder: "请输入领用人姓名",
label: "领用人姓名"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
tableHeight: 400,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 150, //操作栏宽度
tableColumn: [
{ label: "领用人姓名", prop: "lyrxm", showOverflowTooltip: true },
{ label: "身份证号", prop: "lyrsfzh", showOverflowTooltip: true },
{ label: "领用数量", prop: "lysl" },
{ label: "领用时间", prop: "lysj", showOverflowTooltip: true },
{ label: "消耗数量", prop: "xhsl" },
{ label: "归还时间", prop: "ghsj", showOverflowTooltip: true },
{ label: "归还数量", prop: "ghsl" }
]
});
const listQuery = ref({});
const addjy = ref();
onMounted(() => {
getList();
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.jyqxId = props.jyqxId;
pageData.tableConfiger.loading = true;
qxjyjlSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
qxjyjlDelete( id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
const addEdit = (type, row) => {
addjy.value.init(type, row.id);
};
</script>
<style lang="scss" scoped>
.jybox {
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,128 @@
<template>
<el-dialog title="装备检索" v-model="modelValue" :destroy-on-close="true" @close="closed" width="70%" :append-to-body="true">
<div style="width:100%">
<div> <Search :searchArr="searchConfiger" /></div>
<div class="map">
<div style=" width:500px;height:500px" > <Map /> </div>
<div class="table">
<MyTable :tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth" tableHeight="450px">
<template #sblx="{ row }">
<dict-tag
:options="dic.D_JCGL_TCSB_SBLX"
:value="row.sblx"
:tag="false"
></dict-tag>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" /></div> <div >
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
import { ElMessage } from "element-plus";
import Pages from "@/components/aboutTable/Pages.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Search from "@/components/aboutTable/Search.vue";
import Map from "@/components/GdMap/index.vue";
import {reactive,ref,defineEmits} from 'vue'
import { servicePost, serviceGet,serviceDelete } from "@/api/serviceApi.js";
const emit = defineEmits(["update:modelValue"]);
defineProps({
dic:Object,
modelValue:Boolean
})
const searchConfiger = reactive([
{
showType: "input",
prop: "sbbh",
placeholder: "请输入设备编号",
label: "设备编号"
},
{
showType: "input",
prop: "sbmc",
placeholder: "请输入设备名称",
label: "设备名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "设备编号", prop: "sbbh" },
{ label: "设备名称", prop: "sbmc" },
{ label: "设备类型", prop: "sblx",showSolt:true },
{ label: "使用单位", prop: "sydwmc",showOverflowTooltip:true },
{ label: "关联人员", prop: "glryxm" },
{ label: "关联GPSID", prop: "glgpsid" }
]
});
const closed=()=>{
emit("update:modelValue", false);
}
// 切换部门
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = {...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
serviceGet(params, "/mosty-jcgl/tbJcglTcsb/selectPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
getList()
</script>
<style lang="scss" scoped>
.map{
display:flex;
width: 100%;
height: 500px;
}
.table{
overflow:auto;
width:calc(100% - 500px);
}
</style>

View File

@ -0,0 +1,157 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="!disabledFoem">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="formCnt">
<el-form ref="elform" :model="formData" :label-width="110" :rules="rules" :inline="true">
<div class="label">基础信息</div>
<div class="infoItem">
<el-form-item label="设备编号" prop="sbbh">
<el-input v-model="formData.sbbh" placeholder="请输入设备编号"></el-input>
</el-form-item>
<el-form-item label="设备名称" prop="sbmc">
<el-input v-model="formData.sbmc" placeholder="请输入设备名称"></el-input>
</el-form-item>
<el-form-item label="设备类型" prop="sblx">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_TCSB_SBLX" placeholder="请选择设备类型" v-model="formData.sblx" />
</el-form-item>
<el-form-item label="设备网络类型" prop="sbwllx">
<MOSTY.Select :dictEnum="props.dic.D_JCGL_TCSB_WLLX" placeholder="请选择设备网络类型" v-model="formData.sbwllx" />
</el-form-item>
<el-form-item label="SIM卡号" prop="sbsim">
<el-input v-model="formData.sbsim" placeholder="请输入SIM卡号"></el-input>
</el-form-item>
<br />
<el-form-item label="单位管理" prop="gldwdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue" v-model="formData.gldwdm" :placeholder="formData.gldwmc" />
</el-form-item>
<el-form-item label="使用单位" prop="sydwdm">
<MOSTY.Department width="100%" clearable @getDepValue="getDepValue1" v-model="formData.sydwdm" :placeholder="formData.sydwmc" />
</el-form-item>
<el-form-item label="备注" style="width: 100%">
<el-input placeholder="请输入备注" v-model="formData.bz" :autosize="{ minRows: 2, maxRows: 4 }" type="textarea"></el-input>
</el-form-item>
</div>
<div class="label">关联信息</div>
<div class="infoItem">
<el-form-item label="关联人员" prop="glryxm">
<el-input v-model="formData.glryxm" placeholder="请输入关联人员"></el-input>
</el-form-item>
<el-form-item label="关联GPSID" prop="glgpsid">
<el-input v-model="formData.glgpsid" placeholder="请输入关联GPSID"></el-input>
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import{tcsbSave,tcsbsSetBbzt} from "@/api/lzqwzx/index.js"
import { serviceGet, servicePost, servicePut } from "@/api/serviceApi.js";
import { getDifferTime } from "@/utils/tools.js";
import * as rule from "@/utils/rules.js";
import { ref, defineExpose, reactive, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF, D_JC_XFJY_JYLX } = proxy.$dict("D_BZ_SF", "D_JC_XFJY_JYLX");
const emits = defineEmits(["updateDate"]);
const props = defineProps({
dic: { type: Object, default: {} }
});
const title = ref("新增");
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const formData = ref({});
const rules = reactive({
sbbh: [{ required: true, message: "请输入设备编号", trigger: "blur" }],
sbmc: [{ required: true, message: "请输入设备名称", trigger: "blur" }],
gldwdm: [{ required: true, message: "请选择单位管理", trigger: "change" }],
sblx: [{ required: true, message: "请选择设备类型", trigger: "change" }],
sbwllx: [
{ required: true, message: "请选择设备网络类型", trigger: "change" }
],
sydwdm: [{ required: true, message: "请选择使用单位", trigger: "change" }],
sbsim: [{ required: true, message: "请输入SIM卡号", trigger: "blur" }],
glryxm: [{ required: true, message: "请输入关联人员", trigger: "blur" }],
glgpsid: [{ required: true, message: "请输入关联GPSID", trigger: "blur" }]
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = row ? "修改" : "新增";
if (row) formData.value = JSON.parse(JSON.stringify(row)); //根据id查询详情
};
const getDepValue = (val) => {
formData.value.gldwmc = val ? val.orgJc : "";
};
const getDepValue1 = (val) => {
formData.value.sydwmc = val ? val.orgJc : "";
};
// 关闭
const close = () => {
formData.value = {};
dialogForm.value = false;
loading.value = false;
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
if (title.value == "新增") {
tcsbSave(formData.value)
.then((res) => {
proxy.$message({ type: "success", message: "新增成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
} else {
tcsbsSetBbzt(formData.value)
.then((res) => {
proxy.$message({ type: "success", message: "修改成功" });
close();
emits("updateDate");
})
.catch(() => {
loading.value = false;
});
}
});
};
defineExpose({ init });
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.formCnt {
height: calc(100% - 60px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.label {
font-weight: 600;
margin-bottom: 10px;
width: 100%;
}
.infoItem {
width: 100%;
}
.el-form--inline .el-form-item {
width: 47%;
}
}
</style>

View File

@ -0,0 +1,259 @@
<template>
<div class="main-box">
<!-- 点位检索 -->
<div class="treeBox">
<MOSTY.DepartmentTree @changeSsbm="changeSsbm" width="300px" placeholder="管理部门ID" clearable filterable :isBmId="true" v-model="listQuery.gldwdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
<el-button type="primary" @click="handleDelete('')" :disabled="multipleTable.length==0">
<el-icon>
<Delete />
</el-icon>
<span>批量删除</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
<!-- <el-button type="primary" @click="openDialog" >
设备检索
</el-button> -->
</div>
<div class="tabBox">
<MyTable @chooseData="chooseData" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #sblx="{ row }">
<dict-tag
:options="D_JCGL_TCSB_SBLX"
:value="row.sblx"
:tag="false"
></dict-tag>
</template>
<template #sbwllx="{ row }">
<dict-tag
:options="D_JCGL_TCSB_WLLX"
:value="row.sbwllx"
:tag="false"
></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
<!-- <DialogMap v-model:modelValue="showDialog" :dic="{D_JCGL_TCSB_SBLX}"><GdMap
/></DialogMap> -->
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" :dic="{D_JCGL_TCSB_SBLX,D_JCGL_TCSB_WLLX}" @updateDate="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import{tcsbSelectPage,tcsbsDeletebzt} from "@/api/lzqwzx/index.js"
import * as MOSTY from "@/components/MyComponents/index";
import {
ref,
reactive,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_JCGL_TCSB_SBLX, D_JCGL_TCSB_WLLX } = proxy.$dict("D_JCGL_TCSB_SBLX", "D_JCGL_TCSB_WLLX");
const addEditDialog = ref();
const multipleTable = ref([]);
const deptId = JSON.parse(localStorage.getItem("deptId"));
const searchConfiger = reactive([
{
showType: "input",
prop: "sbbh",
placeholder: "请输入设备编号",
label: "设备编号"
},
{
showType: "input",
prop: "sbmc",
placeholder: "请输入设备名称",
label: "设备名称"
},
{
showType: "department",
prop: "gldwdm",
label:'所属部门'
},
{
showType: "select",
prop: "sblx",
placeholder: "请输入设备类型",
label: "设备类型",
options:D_JCGL_TCSB_SBLX
},
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "设备编号", prop: "sbbh" },
{ label: "设备名称", prop: "sbmc" },
{ label: "设备类型", prop: "sblx",showSolt:true },
{ label: "分流类型", prop: "sbwllx",showSolt:true },
{ label: "sim卡", prop: "sbsim" },
{ label: "管理单位", prop: "gldwmc" ,showOverflowTooltip:true},
{ label: "使用单位", prop: "sydwmc",showOverflowTooltip:true },
{ label: "关联人员", prop: "glryxm" },
{ label: "关联GPSID", prop: "glgpsid" }
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: deptId[0].deptName,
gldwdm: deptId[0].deptCode,
})
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList()
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
baseInfo.value.gldwdm =val.gldwdm
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgName;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.gldwdm = baseInfo.value.gldwdm;
pageData.tableConfiger.loading = true;
tcsbSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (val) =>{
let ids = val ? [val] :multipleTable.value;
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
let count = 0
ids.forEach(id => {
count++
tcsbsDeletebzt (id).then(res=>{
getList({})
}).catch(()=>{
proxy.$message.error("删除失败");
})
});
if (count==ids.length) {
proxy.$message.success("删除成功");
}
}).catch(() => {
proxy.$message.info("已取消");
});
}
// 列表多选
const chooseData = (val) =>{
if(Array.isArray(val)) multipleTable.value = val.map(v=>{return v.id})
}
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const showDialog=ref(false)
const openDialog=()=>{
showDialog.value=true
}
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,193 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button
type="primary"
size="small"
:loading="loading"
@click="submit"
v-show="!disabledFoem"
>保存</el-button
>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="formCnt">
<el-form
ref="elform"
:model="formData"
:label-width="100"
:rules="rules"
:inline="true"
>
<div class="label">基础信息</div>
<div class="infoItem">
<el-form-item label="设备编号" prop="sbbh">
<el-input v-model="formData.sbbh" placeholder="请输入设备编号"></el-input>
</el-form-item>
<el-form-item label="设备名称" prop="sbmc">
<el-input v-model="formData.sbmc" placeholder="请输入设备名称"></el-input>
</el-form-item>
<el-form-item label="终端类型" prop="sblx">
<MOSTY.Select
:dictEnum="props.dic.D_JCGL_ZDSB_SBLX"
placeholder="请选择设备类型"
v-model="formData.sblx"
/>
</el-form-item>
<el-form-item label="设备类别" prop="sblb">
<MOSTY.Select
:dictEnum="props.dic.D_JCGL_ZDSB_SBLB"
placeholder="请选择设备类别"
v-model="formData.sblb"
/>
</el-form-item>
<el-form-item label="是否报备" prop="sfbb">
<MOSTY.Select
:dictEnum="props.dic.D_BZ_SF"
placeholder="请选择是否报备"
v-model="formData.sfbb"
/>
</el-form-item>
<el-form-item label="设备卡号" prop="sbkh">
<el-input v-model="formData.sbkh" placeholder="请输入设备卡号"></el-input>
</el-form-item>
<br />
<el-form-item label="单位管理" prop="gldwdm">
<MOSTY.Department
width="100%"
clearable
@getDepValue="getDepValue"
v-model="formData.gldwdm"
/>
</el-form-item>
<el-form-item label="使用单位" prop="sydwdm">
<MOSTY.Department
width="100%"
clearable
@getDepValue="getDepValue1"
v-model="formData.sydwdm"
/>
</el-form-item>
<el-form-item label="备注" style="width: 100%">
<el-input
placeholder="请输入备注"
v-model="formData.bz"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
></el-input>
</el-form-item>
</div>
<div class="label">关联信息</div>
<div class="infoItem">
<el-form-item label="关联人员" prop="glryxm">
<el-input v-model="formData.glryxm" placeholder="请输入关联人员"></el-input>
</el-form-item>
<el-form-item label="关联GPSID" prop="glgpsid">
<el-input v-model="formData.glgpsid" placeholder="请输入关联GPSID"></el-input>
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
// import { getDifferTime } from "@/utils/tools.js";
import{ZdsbSave,ZdsbUpdate,ZdsbId} from "@/api/lzqwzx/index.js"
import { ref, defineExpose, reactive, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF, D_JC_XFJY_JYLX } = proxy.$dict("D_BZ_SF", "D_JC_XFJY_JYLX");
const emits = defineEmits(["updateDate"]);
const props = defineProps({
dic: { type: Object, default: {} }
});
const title = ref("新增");
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const formData = ref({});
const rules = reactive({
sbbh: [{ required: true, message: "请输入设备编号", trigger: "blur" }],
sbmc: [{ required: true, message: "请输入设备名称", trigger: "blur" }],
gldwdm: [{ required: true, message: "请选择单位管理", trigger: "change" }],
sblx: [{ required: true, message: "请选择设备类型", trigger: "change" }],
sblb: [{ required: true, message: "请选择设备类别", trigger: "change" }],
sydwdm: [{ required: true, message: "请选择使用单位", trigger: "change" }],
sbkh: [{ required: true, message: "请输入设备卡号", trigger: "blur" }],
glryxm: [{ required: true, message: "请输入关联人员", trigger: "blur" }],
glgpsid: [{ required: true, message: "请输入关联GPSID", trigger: "blur" }]
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = row ? "修改" : "新增";
if (row) getDataById(row.id); //根据id查询详情
};
// 根据id查询详情
const getDataById = (id) => {
ZdsbId(id).then(res=>{
formData.value = res;
});
};
const getDepValue = (val) => {
formData.value.gldwmc = val ? val.orgName : "";
};
const getDepValue1 = (val) => {
formData.value.sydwmc = val ? val.orgName : "";
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
if (title.value == "新增") {
ZdsbSave(formData.value).then(res=>{
proxy.$message({type: "success", message: "新增成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
} else {
ZdsbUpdate(formData.value).then(res=>{
proxy.$message({type: "success", message: "修改成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
}
});
};
// 关闭
const close = () => {
formData.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";
.formCnt {
height: calc(100% - 60px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.label {
font-weight: 600;
margin-bottom: 10px;
width: 100%;
}
.infoItem{
width: 100%;
}
.el-form--inline .el-form-item {
width: 47%;
}
}
</style>

View File

@ -0,0 +1,288 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="true"
v-model="listQuery.gldwdm"
/>
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
<el-button
type="primary"
@click="handleDelete('')"
:disabled="multipleTable.length == 0"
>
<el-icon>
<Delete />
</el-icon>
<span>批量删除</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #sblx="{ row }">
<dict-tag
:options="D_JCGL_ZDSB_SBLX"
:value="row.sblx"
:tag="false"
/>
</template>
<template #sblb="{ row }">
<dict-tag
:options="D_JCGL_ZDSB_SBLB"
:value="row.sblb"
:tag="false"
/>
</template>
<template #sfbb="{ row }">
<dict-tag :options="D_BZ_SF" :value="row.sfbb" :tag="false" />
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="tableHeight"
:pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
/>
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm
ref="addEditDialog"
:dic="{ D_BZ_SF, D_JCGL_ZDSB_SBLX, D_JCGL_ZDSB_SBLB }"
@updateDate="getList"
/>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import{ZdsbselectPage,Zdsbdelete,ZdsbOnline} from "@/api/lzqwzx/index.js"
import * as MOSTY from "@/components/MyComponents/index";
import {
ref,
reactive,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_JCGL_ZDSB_SBLX, D_JCGL_ZDSB_SBLB, D_BZ_SF } = proxy.$dict(
"D_JCGL_ZDSB_SBLX",
"D_JCGL_ZDSB_SBLB",
"D_BZ_SF"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const searchConfiger = reactive([
{
showType: "input",
prop: "sbbh",
placeholder: "请输入设备编号",
label: "设备编号"
},
{
showType: "input",
prop: "sbmc",
placeholder: "请输入设备名称",
label: "设备名称"
},
{
showType: "select",
prop: "sblb",
placeholder: "请选择设备类型",
label: "设备类型",
options: D_JCGL_ZDSB_SBLX
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "设备编号", prop: "sbbh" },
{ label: "设备名称", prop: "sbmc" },
{ label: "终端类别", prop: "sblb", showSolt: true },
{ label: "设备类型", prop: "sblx", showSolt: true },
{ label: "设备卡号", prop: "sbkh" },
{ label: "是否报备", prop: "sfbb" },
{ label: "管理单位", prop: "gldwmc", showOverflowTooltip: true },
{ label: "使用单位", prop: "sydwmc", showOverflowTooltip: true },
{ label: "关联人员", prop: "glryxm" },
{ label: "关联GPSID", prop: "glgpsid" }
]
});
const deptId = JSON.parse(localStorage.getItem("deptId"));
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: deptId[0].deptName,
gldwdm: deptId[0].deptCode
});
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgName;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.gldwdm = baseInfo.value.gldwdm;
pageData.tableConfiger.loading = true;
ZdsbselectPage(params)
.then(async (res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = await Promise.all(
res.records.map(async (item) => {
item.sfbb = await getSbzx(item.sbbh);
return item;
})
);
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 获取
const getSbzx = (sbbh) => {
return new Promise((ok) => {
ZdsbOnline(sbbh).then(
(res) => {
console.log(res, "res");
ok(res);
}
);
});
};
// 处理删除数据
const handleDelete = (val) => {
let ids = val ? [val] : multipleTable.value;
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
ids.forEach((id) => {
Zdsbdelete(id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,279 @@
<template>
<!-- 勤务作息编辑新增 -->
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title">{{ isAdd ? "新增" : "修改" }}</span>
<div>
<el-button
type="primary"
size="small"
@click="onSave"
:loading="buttonLoading"
>保存</el-button
>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="form-content">
<el-form
ref="formRef"
:label-width="140"
:model="formData"
:rules="rules"
inline
>
<div class="content">
<el-form-item
v-if="isAdd"
style="width: 48%"
class="form-item"
prop="dqwd"
label="地球经度"
>
<el-input
type="number"
v-model="formData.dqwd"
:disabled="isDetail"
placeholder="请输入地球经度"
></el-input>
</el-form-item>
<el-form-item
v-if="isAdd"
style="width: 48%"
class="form-item"
prop="dqjd"
label="地球纬度"
>
<el-input
type="number"
v-model="formData.dqjd"
:disabled="isDetail"
placeholder="请输入地球纬度"
></el-input>
</el-form-item>
<el-form-item
style="width: 48%"
class="form-item"
prop="qzDd"
label="签注地点"
>
<el-input
v-model="formData.qzDd"
:disabled="!isAdd"
placeholder="请输入签注地点"
></el-input>
</el-form-item>
<el-form-item
style="width: 48%"
class="form-item"
prop="qzSm"
label="签注说明"
>
<el-input
v-model="formData.qzSm"
:disabled="isDetail"
placeholder="请输入签注说明"
></el-input>
</el-form-item>
<el-form-item
v-if="isDetail"
style="width: 48%"
class="form-item"
prop="qzrSfzh"
label="签注人身份证号"
>
<el-input
v-model="formData.qzrSfzh"
disabled
placeholder="请输入"
></el-input>
</el-form-item>
<el-form-item
v-if="isDetail"
style="width: 48%"
class="form-item"
prop="qzrXm"
label="签注人姓名"
>
<el-input
v-model="formData.qzrXm"
disabled
placeholder="请输入"
></el-input>
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import { reactive, ref, getCurrentInstance, defineEmits } from "vue";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
// import Department from "./department.vue";
const { proxy } = getCurrentInstance();
// const { D_BZ_SF} = proxy.$dict("D_BZ_SF");
const props = defineProps({
// dic: Object
});
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
const formData = ref({});
const isAdd = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
dqjd: [{ required: false, message: "请填写地球纬度", trigger: "blur" }],
dqwd: [{ required: false, message: "请填写地球经度", trigger: "blur" }],
qzDd: [{ required: true, message: "请输入签注地点", trigger: "blur" }],
qzSm: [{ message: "请输入签注说明", trigger: "blur" }]
// qzrSfzh: [{ required: true, message: "请输入签注人身份证号", trigger: "blur" }],
// qzrXm: [{ required: true, message: "请输入签注人姓名", trigger: "blur" }]
});
/**部门id对照对象 */
let departmentIdObj = {};
const init = (type, row) => {
isShowDialog.value = true; // 显示新增编辑dialog框
isAdd.value = type == "add" ? true : false;
dialogType.value = type;
isDetail.value = type === "detail";
// 是否有填充数据
departmentIdObj = {};
if (row) {
let {
id,
dqjd,
dqwd,
qzDd,
qzSm,
qzrSfzh,
qzrXm
} = row;
// 新增从本地取
if (type == "add") {
qzrSfzh = localStorage.getItem("idEntityCard"); // 身份证
qzrXm = localStorage.getItem("USERNAME"); //姓名
}
formData.value = {
id,
dqwd,
dqjd,
qzDd,
qzSm,
qzrSfzh,
qzrXm
};
// 新增
} else {
}
};
// 重置表单
const reserForm = () => {
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 保存
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let params = { ...formData.value };
params.qzrSfzh = localStorage.getItem("idEntityCard"); // 身份证
params.qzrXm = localStorage.getItem("USERNAME"); // 姓名
if (params.dqjd) params.dqjd = Number(params.dqjd);
if (params.dqwd) params.dqwd = Number(params.dqwd);
let url = isAdd.value ? "/tbQwglZxqz/save" : "/tbQwglZxqz/update";
let text = isAdd.value ? "新增成功" : "编辑成功";
servicePost(params, `/mosty-qwzx${url}`)
.then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
});
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.form-content {
margin-top: 20px;
}
.bblxItem {
line-height: 40px;
min-height: 40px;
// display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
}
.content {
padding: 10px 40px;
}
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
.department-list {
padding: 10px 20px;
}
.department-item {
color: #000;
margin-left: 20px;
height: 35px;
line-height: 35px;
}
</style>

View File

@ -0,0 +1,244 @@
<template>
<!-- <div> 作息签注</div> -->
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">作息签注</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增签注</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 部门列表 -->
<template #bmList="{ row }">
<!-- {{row}} -->
<div>
<span v-for="item in row.bmList" :key="item.id">{{item.ssbm}};</span>
</div>
</template>
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">注销</el-link>
<span class="linkGapLine">|</span>
<!-- [创建][停止]只能"开启",[开启]只能"停用" -->
<el-link type="primary" @click="seeDetail('detail',row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import Search from "@/components/aboutTable/Search.vue";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ElMessage } from "element-plus";
import EditAddForm from "./editAddForm.vue";
const { proxy } = getCurrentInstance();
// const { D_QW_FA_QWDJ, D_QW_FA_BMDJ, D_QW_FA_ZT } = proxy.$dict(
// "D_QW_FA_QWDJ",
// "D_QW_FA_BMDJ",
// "D_QW_FA_ZT"
// );
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "qzDd",
placeholder: "请输入签注地点",
label: "签注地点"
},
{
showType: "input",
prop: "qzrXm",
placeholder: "请输入姓名",
label: "姓名"
},
{
showType: "input",
prop: "qzrSfzh",
placeholder: "请输入签注人身份证号",
label: "签注人身份证号"
},
]);
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{ label: "签注地点", prop: "qzDd", showOverflowTooltip: true },
{
label: "签注时间",
prop: "qzSj",
showOverflowTooltip: true,
// width: 100
},
{
label: "签注人姓名",
prop: "qzrXm",
showOverflowTooltip: true,
width: 100
},
{
label: "签注说明",
prop: "qzSm",
showOverflowTooltip: true,
// width: 100
},
{
label: "签注人身份证号",
prop: "qzrSfzh",
showOverflowTooltip: true,
// noDateDisabled: true,
// width: 100
},
{
label: "所属部门",
prop: "ssbm",
showOverflowTooltip: true,
},
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
// mounted
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 详情借用新增和修改的页面
const seeDetail = (type, row) => {
addEdit(type, row);
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = false;
serviceGet(params, "/mosty-qwzx/tbQwglZxqz/selectPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要注销", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
serviceDelete({}, "/mosty-qwzx/tbQwglZxqz/" + id).then((res) => {
proxy.$message.success("注销成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,115 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-13 09:54:39
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">详情</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="外出类型"><dict-tag :options="D_QW_CC_LX" :value="data.detail.ccLx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{ data.detail.ccSjKsrq + '时' + " — " + data.detail.ccSjJsrq + '时' }}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="外出原因">{{data.detail.ccYy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span class="ml10" v-show="item.kqShyj && item.kqShyj !=''"> 审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_CC_LX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_CC_LX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true;
getDataById(id) //根据id查询详情
}
// 根据id查询详情
const getDataById = (id)=>{
loading.value = true;
serviceGet({},`/mosty-qwzx/tbQwCc/selectVOById/${id}`).then(res=>{
data.detail = res;
loading.value = false;
})
}
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,165 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="!disabledFoem">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="data.formData" :rules="rules" :inline="true" :disabled="disabledFoem" label-position="top">
<el-form-item prop="sqrLx" label="申请人类型" class="ww31">
<el-select placeholder="请选择申请人类型" style="width: 100%" v-model="data.formData.sqrLx">
<el-option v-for="dict in D_BZ_SQRLX" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item prop="sqrXm" label="申请人" class="ww31">
<el-input @click="chooseUserVisible = true" v-model="data.formData.sqrXm" placeholder="请选择申请人" clearable/>
</el-form-item>
<el-form-item prop="ccLx" label="出差类型" class="ww31">
<el-select style="width: 100%" v-model="data.formData.ccLx" filterable placeholder="请选择出差类型" @change="getLc">
<el-option v-for="item in D_QW_CC_LX" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item prop="qzrqForm" required label="起止日期" class="ww31">
<el-date-picker
style="width: 100%"
v-model="data.formData.qzrqForm"
type="daterange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="upQzrqForm"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item prop="sfsh" label="是否审核" class="ww31">
<el-select style="width: 100%" v-model="data.formData.sfsh" filterable placeholder="是否审核" >
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="审批人" class="ww31" v-if="data.formData.sfsh==1">
<el-input v-model="data.spObj.shryXms" placeholder="请选择审批人" readonly/>
</el-form-item>
<el-form-item label="抄送人" class="ww31">
<el-input v-model="data.spObj.csryXms" placeholder="请选择抄送人" readonly/>
</el-form-item>
<el-form-item label="出差原因" prop="ccYy" class="ww100">
<el-input v-model="data.formData.ccYy" placeholder="请输入出差原因" show-word-limit type="textarea"/>
</el-form-item>
</el-form>
</div>
<ChooseUser v-model="chooseUserVisible" :PoliceType="data.formData.sqrLx == '01' ? 'MJ' : 'FJ'" :Single="true" @choosedPolice="hanlderChoose" />
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import ChooseUser from "@/components/MyComponents/choosePolice";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import {getDifferTime} from "@/utils/tools.js";
import * as rule from "@/utils/rules.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_CC_LX, D_BZ_SQRLX,D_BZ_SF } = proxy.$dict("D_QW_CC_LX", "D_BZ_SQRLX","D_BZ_SF");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const chooseUserVisible = ref(false);//人员弹窗
const loading = ref(false);
const data = reactive({
formData: {sqrLx:"01",sfsh:"1"},
spObj:{}, //审核对象
});
const rules = reactive({
sqrLx: [{ required: true, message: "请选择申请人类型", trigger: "change" }],
sqrXm: [{ required: true, message: "请选中申请人", trigger: ['blur','change'] }],
ccLx: [{ required: true, message: "请输入出差类型", trigger: "change" }],
qzrqForm: [{ required: true, message: "请选择请假日期", trigger: "blur" }],
ccYy: [{ required: true, message: "请输入出差原因", trigger: "blur" }],
sfsh: [{ required: true, message: "请选择是否审核", trigger: "blur" }],
})
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true
if(id){
title.value = '修改'
getDataById(id) //根据id查询详情
}else{
title.value = '新增'
}
}
// 根据id查询详情
const getDataById = (id)=>{
getQwQxjInfo(id).then((res) => {
data.formData = res;
data.formData.qzrqForm = [res.ccSjKsrq, res.ccSjJsrq];
});
}
//根据请休假时间和出差类型获取配置流程
const getLc = () => {
if(data.formData.ccSjKsrq && data.formData.ccSjKsrq!='' && data.formData.ccSjJsrq && data.formData.ccSjJsrq != '' && data.formData.ccLx && data.formData.ccLx!=''){
let arrt = {kqlx:'03',kqywlx:data.formData.ccLx,kqsc:getDifferTime(data.formData.ccSjKsrq,data.formData.ccSjJsrq)};
serviceGet(arrt,'/mosty-qwzx/tbQwQxjShlc/selectForAuditsCheck').then(res=>{
data.spObj = res ? res : {};
data.formData.kqShlcId = res?.id;
});
}
};
//时间
function upQzrqForm(val) {
data.formData.ccSjKsrq = val.length > 0 ? val[0] : "";
data.formData.ccSjJsrq = val.length > 0 ? val[1] : "";
getLc()
}
//选择用户
const hanlderChoose = (users) => {
const user = users[0];
data.formData.sqrXm = user.xm;
data.formData.sqrSsbm = user.ssbm;
data.formData.sqrSsbmdm = user.ssbmdm;
data.formData.sqrSfzh = user.sfzh;
data.formData.sqrLxfs = user.lxdh;
};
// 提交
const submit = ()=>{
elform.value.validate((valid) => {
if (!valid) return false;
if(data.formData.sfsh=='1'){
if(!data.formData.kqShlcId || data.formData.kqShlcId=='') return proxy.$message({type: "warning", message: "暂无相关请休假的流程配置!"});
}else{
delete data.formData.kqShlcId;
}
loading.value = true;
delete data.formData.qzrqForm;
if(title.value == '新增'){
servicePost(data.formData,`/mosty-qwzx/tbQwCc/save`).then(res=>{
proxy.$message({type: "success", message: "申请成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
}
});
}
// 关闭
const close = ()=>{
data.formData={sqrLx:"01"};
data.spObj={}
dialogForm.value = false;
loading.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
</style>

View File

@ -0,0 +1,191 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="出差管理">
<el-button type="primary" @click="addEdit('add', '')">
<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">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrLx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrLx" :tag="false" />
</template>
<template #ccSjKsrq="{ row }">
{{ row.ccSjKsrq + '时' + " — " + row.ccSjJsrq + '时' }}
</template>
<template #ccLx="{ row }">
<dict-tag :options="D_QW_CC_LX" :value="row.ccLx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="delDictItem(row)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" @updateDate="getData"/>
<!-- 详情 -->
<Detail ref="detailDialog"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 EditAddForm from './editAddForm.vue';
import Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_CC_LX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_CC_LX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const addEditDialog = ref();
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrLx",
placeholder: "请选择出差类型",
label: "出差类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入申请人姓名",
label: "申请人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "申请人部门", prop: "sqrSsbm" },
{ label: "申请人类型", prop: "sqrLx", showSolt :true},
{ label: "申请人姓名", prop: "sqrXm"},
{ label: "起止日期", prop: "ccSjKsrq", showSolt :true, width:"260" },
{ label: "出差类型", prop: "ccLx", showSolt :true },
{ label: "申请时间", prop: "xtCjsj"},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.ccSjKsrq = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.ccSjJsrq = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
let attr = { ...pageData.pageConfiger, ...searchObj.value };
serviceGet(attr,`/mosty-qwzx/tbQwCc/selectPage`).then(res=>{
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
});
}
// 新增
const addEdit = (type,id)=>{
addEditDialog.value.init(type,id)
}
// 新增
const detailHland = (type,id)=>{
detailDialog.value.init(type,id)
}
// 批量删除
function delDictItem(row) {
proxy.$confirm("确定删除该数据?", "警告", { type: "warning" }).then(() => {
serviceDelete({},`/mosty-qwzx/tbQwCc/${row.id}`).then(res=>{
getData();
proxy.$message({ type: "success", message: "删除成功" });
});
}).catch(() => {
proxy.$message.info("已取消");
});
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,143 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-13 09:54:23
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{title}}</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="外出类型"><dict-tag :options="D_QW_CC_LX" :value="data.detail.ccLx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{ data.detail.ccSjKsrq + '时' + " — " + data.detail.ccSjJsrq + '时' }}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="外出原因">{{data.detail.ccYy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span class="ml10" v-show="item.kqShyj && item.kqShyj !=''"> 审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
<div v-if="title == '审批'" class="flex just-center">
<el-button type="primary" @click="submit('ok')" plain>通过</el-button>
<el-button type="danger" @click="submit('no')" plain>不通过</el-button>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_QW_CC_LX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_CC_LX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id,val)=> {
dialogForm.value = true;
data.detail = JSON.parse(JSON.stringify(val));
if(type == 'detail') title.value = '详情';
else title.value = '审批';
}
// 同意或者驳回
const spRequset = (status,content)=>{
let params = { kqShzt:status == 'no' ? '03' :'02',id:data.detail.kqShry.id }
if(status == 'no') params.kqShyj = content
servicePost(params,`/mosty-qwzx/tbQwKqScry/audits`).then(res=>{
let text = status == 'no' ? '驳回成功' :'审核成功'
proxy.$message({ type: "success", message: text });
emits('updateDate')
close();
})
}
//审批
const submit = (status) => {
if(status == 'no'){
ElMessageBox.prompt("请输入不通过原因", "不通过原因", {
confirmButtonText:"提交",
cancelButtonText:"取消",
inputPattern:/\S+/,
inputPlaceholder:"请输入不通过原因",
inputErrorMessage:'请输入不通过原因',
}).then((res) => {
let content = res.value
spRequset(status,content)
}).catch(()=>{});
}else{
spRequset(status)
}
};
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="出差审批" />
</div>
<!-- 搜索 -->
<div ref="searchBox">
<!-- <Search :searchArr="searchConfiger" @submit="onSearch">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search> -->
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrLx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrLx" :tag="false" />
</template>
<template #ccSjKsrq="{ row }">
{{ row.ccSjKsrq + '时' + " — " + row.ccSjJsrq + '时' }}
</template>
<template #ccLx="{ row }">
<dict-tag :options="D_QW_CC_LX" :value="row.ccLx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id,row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" v-if="row?.kqShry?.kqShzt == '01'" @click="detailHland('sp', row.id,row)">审批</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 详情 -->
<Detail ref="detailDialog" @updateDate="getData"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_CC_LX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_CC_LX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrLx",
placeholder: "请选择出差类型",
label: "出差类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入请假人姓名",
label: "请假人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "申请人部门", prop: "sqrSsbm" },
{ label: "申请人类型", prop: "sqrLx", showSolt :true},
{ label: "申请人姓名", prop: "sqrXm"},
{ label: "起止日期", prop: "ccSjKsrq", showSolt :true, width:"260" },
{ label: "出差类型", prop: "ccLx", showSolt :true },
{ label: "申请时间", prop: "xtCjsj"},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.ccSjKsrq = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.ccSjJsrq = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchObj.value,...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
// let attr = { ...pageData.pageConfiger, ...searchObj.value };
serviceGet(pageData.pageConfiger,`/mosty-qwzx/tbQwCc/selectAuditsWcPage`).then(res=>{
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
});
}
// 详情
const detailHland = (type,id,data)=>{
detailDialog.value.init(type,id,data)
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,513 @@
<template>
<div class="box">
<div class="titles">
<span class="title"></span>
<div>
<el-button
type="primary"
size="small"
@click="onSave"
v-if="str != 'orglist'"
>保存</el-button
>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<el-form
class="mosty-from-wrap"
ref="editRef"
:inline="true"
label-position="top"
:model="dialogForm"
>
<el-form-item v-if="str == 'addorg'"
label="已有部门"
label-width="140px"
>
<MOSTY.Department
width="100%"
clearable
v-model="ssbmdm" @getDepValue="getSelectData"
/>
</el-form-item>
<el-form-item
label="部门名称"
:rules="[{ required: true, message: '请填写部门名称' }]"
prop="orgName"
label-width="140px"
>
<el-input
placeholder="请填写部门名称"
v-model="dialogForm.orgName"
show-word-limit
maxlength="30"
></el-input>
</el-form-item>
<el-form-item
label="部门全称"
show-word-limit
maxlength="30"
prop="orgQc"
required
label-width="140px"
:rules="[{ required: true, message: '请填写部门全称' }]"
>
<el-input
placeholder="请填写部门全称"
v-model="dialogForm.orgQc"
show-word-limit
maxlength="30"
></el-input>
</el-form-item>
<el-form-item
label="部门简称"
:rules="[{ required: true, message: '请填写部门简称' }]"
prop="orgJc"
required
label-width="140px"
>
<el-input
placeholder="请填写部门简称"
v-model="dialogForm.orgJc"
show-word-limit
maxlength="30"
></el-input>
</el-form-item>
<el-form-item
label="部门类型"
:rules="[{ required: true, message: '请选择部门类型' }]"
prop="orgType"
required
label-width="140px"
>
<el-select
style="width: 100%"
v-model="dialogForm.orgType"
class="m-4"
placeholder="请选择部门类型"
>
<el-option
v-for="item in D_BZ_BMLX"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item
label="部门代码"
:rules="[{ required: true, message: '请填写部门代码' }]"
prop="orgCode"
required
label-width="140px"
>
<el-input
placeholder="请填写部门代码"
show-word-limit
maxlength="30"
v-model="dialogForm.orgCode"
></el-input>
</el-form-item>
<el-form-item
label="部门等级"
:rules="[{ required: true, message: '请选择部门等级' }]"
prop="orgLevel"
required
label-width="140px"
>
<el-select
style="width: 100%"
v-model="dialogForm.orgLevel"
class="m-4"
placeholder="请选择部门等级"
>
<el-option
v-for="dict in D_BZ_BMDJ"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="部门顺序号" label-width="140px">
<el-input-number
style="width: 100%"
v-model="dialogForm.orgNo"
class="mx-4"
placeholder="请填写部门顺序号"
:min="1"
:max="100"
controls-position="right"
/>
</el-form-item>
<el-form-item label="部门电话" prop="linkTel" label-width="140px">
<el-input
v-model="dialogForm.linkTel"
maxlength="11"
placeholder="请填写部门电话"
></el-input>
</el-form-item>
<el-form-item
label="部门业务类型"
:rules="[{ required: true, message: '请选择部门业务类型' }]"
prop="orgBizType"
required
label-width="140px"
>
<el-select
style="width: 100%"
v-model="dialogForm.orgBizType"
class="m-4"
placeholder="请选择部门业务类型"
>
<el-option
v-for="item in D_BZ_BMYWLX"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- <el-form-item
label="部门业务处"
:rules="[{ required: true, message: '请选择部门业务类型' }]"
required
label-width="140px"
>
<el-select
style="width: 100%"
v-model="dialogForm.ywc"
class="m-4"
placeholder="请选择部门业务类型"
>
<el-option
v-for="item in D_BZ_BMYWLX"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> -->
<!-- <el-form-item
label="职能部门"
:rules="[{ required: true, message: '请选择部门业务类型' }]"
required
label-width="140px"
>
<el-select
style="width: 100%"
v-model="dialogForm.znbm"
class="m-4"
placeholder="请选择部门业务类型"
>
<el-option
v-for="item in D_BMGL_ZNBM"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item> -->
<el-form-item label="部门联系人电话" label-width="140px">
<el-input
placeholder="请填写部门联系人电话"
maxlength="11"
v-model="dialogForm.linkManTel"
></el-input>
</el-form-item>
<el-form-item label="部门联系人" label-width="140px">
<el-input
show-word-limit
placeholder="请填写部门联系人"
maxlength="30"
v-model="dialogForm.linkMan"
></el-input>
</el-form-item>
<el-form-item label="部门邮箱" label-width="140px">
<el-input
v-model="dialogForm.email"
maxlength="32"
show-word-limit
placeholder="请填写部门邮箱"
></el-input>
</el-form-item>
<el-form-item label="部门名称拼音" label-width="140px">
<el-input
show-word-limit
maxlength="30"
placeholder="请填写部门名称拼音"
v-model="dialogForm.bmpyszm"
></el-input>
</el-form-item>
<el-form-item label="部门主页" label-width="140px">
<el-input
show-word-limit
placeholder="请填写部门主页"
maxlength="50"
v-model="dialogForm.webUrl"
></el-input>
</el-form-item>
<el-form-item label="部门所属行政区划" label-width="140px">
<el-input
show-word-limit
placeholder="请填写部门所属行政区划"
maxlength="50"
v-model="dialogForm.xzqh"
></el-input>
</el-form-item>
<el-form-item label="部门图标" style="width: 48%">
<MOSTY.Upload
width="100%"
v-model="dialogForm.bmtg"
@handleChange="handleChange1"
/>
<!-- <MOSTY.Upload width="100%" :isImg="true" :limit="1" v-model="dialogForm.bmtg" @handleChange="handleChange1"></MOSTY.Upload> -->
</el-form-item>
<el-form-item style="width: 100%" prop="jd" label="坐标位置">
<div class="latlng">
<el-input v-model="dialogForm.jd" clearable style="width: 45%" />
<el-input v-model="dialogForm.wd" clearable style="width: 45%" />
<el-button @click="seachLat">确定</el-button>
<el-button @click="zdyLat">自定义坐标</el-button>
</div>
</el-form-item>
<el-form-item style="width: 100%">
<div class="map">
<GdMap :isShowDraw="true" />
</div>
</el-form-item>
<el-form-item style="width: 100%" label="部门地址" label-width="140px">
<el-input
show-word-limit
placeholder="请填写部门地址"
maxlength="200"
v-model="dialogForm.address"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
></el-input>
</el-form-item>
<el-form-item style="width: 100%" label="备注" label-width="140px">
<el-input
v-model="dialogForm.bz"
show-word-limit
maxlength="200"
:autosize="{ minRows: 2, maxRows: 4 }"
type="textarea"
></el-input>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ElMessage } from "element-plus";
import * as MOSTY from "@/components/MyComponents/index";
import { servicePost } from "@/api/serviceApi.js";
import {
ref,
defineEmits,
getCurrentInstance,
onMounted,
computed,
watch
} from "vue";
import GdMap from "@/components/GdMap/index.vue";
import { addSysDept, updateSysDept } from "@/api/jlytz.js";
import emitter from "@/utils/eventBus.js";
const props = defineProps({
peopleDialog: Boolean,
dialog: Boolean,
orgData: {},
str: String
});
const { proxy } = getCurrentInstance();
const {
D_BZ_BMYWLX,
D_BMGL_YWC,
D_BZ_BMDJ,
D_BMGL_ZNBM,
D_BZ_BMLX,
D_BZ_BMJB,
D_BZ_RYMFJLB,
D_BZ_SF
} = proxy.$dict(
"D_BZ_BMYWLX",
"D_BMGL_ZNBM",
"D_BMGL_YWC",
"D_BZ_BMDJ",
"D_BZ_BMLX",
"D_BZ_BMJB",
"D_BZ_RYMFJLB",
"D_BZ_SF"
);
const emits = defineEmits(["updateList", "dialogBox", "modegenx"]);
const editRef = ref(null);
const dialogForm = ref({ orgNo: 1, parentId: 0, bmtg: [] });
const isEdit = ref();
const dialogFormVisible = ref(false);
const title = ref("");
const buttonLoading = ref(false);
const id = ref("");
const listOrg=ref([])
const onSave = () => {
editRef.value.validate((valid) => {
if (!valid) return;
buttonLoading.value = true;
if (props.str == "add"||props.str == "addorg") {
dialogForm.value.parentId = props.orgData.id;
let params = { ...dialogForm.value };
addSysDept(params)
.then((res) => {
ElMessage.success("新增成功");
buttonLoading.value = false;
closeDialog();
emits("modegenx");
})
.catch(() => {});
} else {
dialogForm.value.bmtg.toString()
updateSysDept(dialogForm.value)
.then((res) => {
buttonLoading.value = false;
closeDialog();
emits("modegenx");
})
.catch(() => {
buttonLoading.value = false;
});
}
});
};
// 关闭弹窗
const closeDialog = () => {
emits("dialogBox", "", true, "");
dialogForm.value = {};
};
function zdyLat() {
dialogForm.value.jd = "";
dialogForm.value.wd = "";
emitter.emit("drawShape", { type: "point", flag: "zqd", isclear: true });
emitter.on("drawLngLat", (res) => {
//如果点位存在 删除点位
if (store.getters.points.length > 0) {
for (let i = 0; i < store.getters.points.length; i++) {
const item = store.getters.points[i];
egis.removePlotFeature(item);
}
store.commit("map/setPoints", []);
}
if (res.properties.t == "Point") {
store.commit("map/setPoints", [res.properties.id]);
form.value.jd = res.properties.conteolPoint[0];
form.value.wd = res.properties.conteolPoint[1];
} else {
proxy.$message.warning("请选择绘制点位");
egis.removePlotFeature(res.properties.id);
return;
}
});
}
function seachLat() {
emitter.emit("deletePointArea", "zqd");
if (dialogForm.value.jd && dialogForm.value.wd) {
let item = { jd: dialogForm.value.jd, wd: dialogForm.value.wd };
emitter.emit("addPointArea", {
coords: [item],
icon: require("@/assets/point/jwz.png"),
flag: "zqd"
});
emitter.emit("setMapCenter", {
location: [dialogForm.value.jd, dialogForm.value.wd],
zoomLevel: 10
});
} else {
proxy.$message.info("经度,纬度不能未空");
}
}
const ces = ref(false);
onMounted(() => {
//获取地图选点坐标
emitter.on("coordString", (res) => {
if (res.type === "point") {
dialogForm.value.jd = res.coord[0];
dialogForm.value.wd = res.coord[1];
}
});
});
const orgList = ref(true);
watch(
() => {
return props.str;
},
(val) => {
if (val == "add") {
dialogForm.value = {};
dialogForm.value.cjlx='01'
} else if (val == "addorg") {
dialogForm.value = {};
} else {
dialogForm.value = { ...props.orgData };
if (props.orgData.bmtg) {
dialogForm.value.bmtg = props.orgData.bmtg.split(",");
}
}
},
{ deep: true, immediate: true }
);
const handleChange1 = (val) => {
console.log(val);
dialogForm.value.bmtg = val.toString();
};
//获取详细数据
const ssbmdm=ref()
const getSelectData=(val)=>{
dialogForm.value = { ...val ,cjlx:'02'};
}
</script>
<style lang="scss" scoped>
::v-deep .el-form-item--default {
width: 23%;
}
.box {
height: 100%;
overflow: auto;
padding: 0 20px;
}
.latlng {
width: 100%;
display: flex;
justify-content: space-between;
}
.map {
width: 100%;
height: 400px;
}
.titles {
height: 48px;
margin: 0 20px;
border-bottom: 1px solid #e9e9e9;
display: flex;
justify-content: space-between;
line-height: 48px;
.title {
color: #131313;
}
}
</style>

View File

@ -0,0 +1,272 @@
<template>
<div class="main-box">
<div class="treeBox">
<Trre ref="trre"
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="true"
v-model="listQuery.ssbmdm"
@dialogBox="dialogBox"
@orgList="orgList"
/>
</div>
<div class="tableCnt" v-if="dialog">
<el-form :model="searchConfiger" :inline="true">
<el-form-item label="起止时间">
<el-date-picker
v-model="searchConfiger.queryTime"
unlink-panels
type="daterange"
range-separator=""
start-placeholder="开始时间"
end-placeholder="结束时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleFilter"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
<div :style="{ height: tableHeight + 'px' }" class="tjbox" v-loading="loading">
<div class="box" v-for="(item, index) in EchartsData" :key="index">
<div class="ItemTitle">{{ item.title }}</div>
<div class="barEcharts">
<BarEcharts
v-if="item.data.length > 0"
:data="item.data"
:Xdata="Xdata"
/>
</div>
</div>
</div>
<div class="map">
<GdMap />
</div>
</div>
<div v-else><editAddForm :dialog="dialog" :orgData="orgData" :str="title" @dialogBox="dialogBox" @modegenx="modegenx" /></div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import GdMap from "@/components/GdMap/index.vue";
import { getjltj, getqxjtj, getwctj, getcctj } from "@/api/file.js";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/components/barEcharts.vue";
import editAddForm from "./editAddForm.vue";
import Trre from "./trre.vue";
import emitter from "@/utils/eventBus.js";
import { ElMessage } from "element-plus";
// import Search from "@/components/aboutTable/Search.vue";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const deptId = JSON.parse(localStorage.getItem("deptId"));
const searchConfiger = reactive({
queryTime: []
});
const {
D_JCGL_JYCL_JYJTYTLB,
D_JCGL_JYCL_JYJTFWLB,
D_JCGL_JYCL_JYJTGJLB,
D_BZ_RYJZLB,
D_JCGL_JYCL_HPYSLB
} = proxy.$dict(
"D_JCGL_JYCL_JYJTYTLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_JCGL_JYCL_JYJTGJLB",
"D_BZ_RYJZLB",
"D_JCGL_JYCL_HPYSLB"
);
const listQuery = ref({ ssbmdm: "", kssj: "", jssj: "" });
const changeSsbm = (val) => {
listQuery.value.id = val.id;
ArrData();
};
const loading=ref(false)
const Xdata = ref(["民警", "辅警"]);
const EchartsData = ref([]);
const ArrData = async () => {
loading.value=true
const pormes = {
id: listQuery.value.id,
kssj: listQuery.value.kssj,
jssj: listQuery.value.jssj,
};
try{
EchartsData.value = [];
const jltj = await getjltj(pormes);
const qxjtj = await getqxjtj(pormes);
const cctj = await getcctj(pormes);
EchartsData.value.push({
title: "总警力",
data: [
{
name: "总警力",
data: [jltj.mjsl, jltj.fjsl],
type: "bar",
barWidth: 10
}
]
});
EchartsData.value.push({
title: "在岗数",
data: [
{
name: "在岗数",
data: [jltj.mjsl-cctj.mjsl,jltj.fjsl- cctj.fjsl-qxjtj.fjsl],
type: "bar",
barWidth: 10
}
]
});
EchartsData.value.push({
title: "请休假",
data: [
{
name: "请休假",
data: [qxjtj.mjsl, qxjtj.fjsl],
type: "bar",
barWidth: 10
}
]
});
EchartsData.value.push({
title: "出差",
data: [
{ name: "出差", data: [cctj.mjsl, cctj.fjsl], type: "bar", barWidth: 10 }
]
});
}catch{}finally{
loading.value=false
}
};
// ArrData();
const handleFilter = () => {
if (searchConfiger.queryTime.length > 0) {
listQuery.value.jssj = searchConfiger.queryTime[1];
listQuery.value.kssj = searchConfiger.queryTime[0];
} else {
listQuery.value.jssj = "";
listQuery.value.kssj = "";
}
ArrData();
};
const reset = () => {
searchConfiger.queryTime = [];
};
onMounted(() => {
tabHeightFn();
});
const tableHeight = ref();
const tabHeightFn = () => {
tableHeight.value = window.innerHeight -520 - 144;
console.log(tableHeight.value);
window.onresize = function () {
tabHeightFn();
};
};
const dialog = ref(true);
const orgData=ref()
const title=ref()
const dialogBox = (val,bool,str) => {
orgData.value=val
dialog.value =bool;
title.value=str
};
const orgList=(val)=>{
if(val.length&&val[0].orgCode=='510300000000'){
listQuery.value.id=val[0].id
ArrData();
}
const a= val.filter(item=>item.jd&&item.wd)
a.map(item=>{
emitter.emit("addPointArea", {
coords: [{ jd: item.jd, wd:item.wd ,jzMc:item.orgName}],
showTitle:true,
icon:item.bmtg?`/mosty-api/mosty-base/minio/image/download/${item.bmtg}`:require("@/assets/point/jwz.png"),
flag: "zqd"
});
return { jd: item.jd, wd:item.wd };
})
}
const trre=ref()
const modegenx=()=>{
trre.value.modegenx()
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
font-size: 16px;
.tjbox {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.box {
width: calc(99% / 4);
height: 300px;
border: 1px solid #000;
.title {
font-size: 18x;
}
}
}
}
}
.map {
height: 520px;
width: 100%;
// height: calc(100% - 370px);
}
.barEcharts {
height: calc(100% - 30px);
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<div class="departmentTree-box" :style="{ width: width, height: '100%' }">
<div class="depar_hear">
<el-input v-model="listQuery.deptname" v-if="filterable" clearable :debounce="500" @input="filterTextChange"
placeholder="请输入筛选条件" />
</div>
<div class="depar_foot">
<el-tree @node-contextmenu="a" ref="treeRef" class="filter-tree" :props="endProps" lazy :load="loadNode"
@node-click="nodeClick" :filter-node-method="filterNode" :data="treeData" />
</div>
</div>
<el-menu v-if="showContentMeni" class="dropdown" :style="{ top: menu.menuY + 'px', left: menu.menuX + 'px' }">
<el-menu-item class="item" index=1 @click="openBox('add')">新增</el-menu-item>
<el-menu-item class="item" index=2 @click="openBox('addorg')">现有部门新增</el-menu-item>
<el-menu-item class="item" index=3 @click="openBox('orglist')">详情</el-menu-item>
<el-menu-item class="item" index=4 @click="openBox('updete')">修改</el-menu-item>
<el-menu-item class="item" index=5 @click="deleteTrre">删除</el-menu-item>
</el-menu>
</template>
<script setup>
import { debounce } from "lodash";
import { getItem } from "@/utils/storage";
import { COMPONENT_WIDTH } from "@/constant";
import {
ref,
defineProps,
defineEmits,
watch,
computed,
onMounted,
reactive, getCurrentInstance
} from "vue";
// import { selectDeptPage, getAllChildDeptList } from "@/api/user-manage";
import { getDeptNotUser, selectDept, deleteSysDept } from '@/api/jlytz.js'
const { proxy } = getCurrentInstance();
const props = defineProps({
//获取组件传值
placeholder: {
default: "请选择",
type: String
},
multiple: {
default: false,
type: Boolean
},
filterable: {
default: false,
type: Boolean
},
modelValue: {
type: Number
},
width: {
default: COMPONENT_WIDTH,
type: String
},
isBmId: {
type: Boolean,
default: false
}
});
const listQuery = ref({
deptname: "",
deptcode: "",
parentid: ""
});
const treeRef = ref(null);
const node_had = ref([]);
const resolve_had = ref([]);
//防抖处理
const filterTextChange = debounce(inputChange, 500);
onMounted(() => {
document.addEventListener('click', () => {
showContentMeni.value = false
})
});
const datalist=ref([])
//获取部门数据
function getTreeData() {
selectDept(listQuery.value).then((res) => {
for (let i = 0; i < res.length; i++) {
res[i].leaf = !res[i].hasChildren;
}
treeData.value = res;
emits("orgList",res)
});
}
//搜索查询
function inputChange(e) {
selectDept(listQuery.value).then((res) => {
treeData.value = res;
});
}
watch(
() => listQuery.value.deptname,
(val) => {
treeRef.value.filter("tree", val);
}
);
const endProps = {
children: "childDeptList",
value: "orgCode",
label: "orgName",
isLeaf: "xflx"
};
const treeData = ref([]);
// //懒加载方法
async function loadNode(node, resolve) {
listQuery.value.parentid = node.data.id;
if (node.level === 0) {
node_had.value = node;
resolve_had.value = resolve;
getTreeData();
}
if (node.level >= 1) {
selectDept(listQuery.value).then((res) => {
for (let i = 0; i < res.length; i++) {
res[i].leaf = !res[i].hasChildren;
}
emits("orgList",res)
resolve(res);
});
}
}
const filterNode = (value, data) => {
if (!value) return true;
return data.orgName.includes(value);
};
const nodeClick = (node) => {
if (props.isBmId) {
emits("update:modelValue", node.id);
} else {
emits("update:modelValue", node.orgCode);
}
emits("changeSsbm", node);
};
const emits = defineEmits(["update:modelValue", "changeSsbm", "dialogBox","orgList"]);
const menu = reactive({
menuX: 0,
menuY: 0
});
const dataValues = ref()
const a = (e, data) => {
dataValues.value = data
menu.menuX = e.clientX -100
menu.menuY = e.clientY -100
showContentMeni.value = true;
};
const showContentMeni = ref(false);
const openBox = (str) => {
emits("dialogBox", dataValues.value, false, str);
}
const deleteTrre = () => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
deleteSysDept({ id: dataValues.value.id }).then(res => {
listQuery.value.parentid=""
emits("dialogBox", "", true, "");
getTreeData()
proxy.$message.success("删除成功");
}).catch((err) => {
})
})
.catch(() => {
proxy.$message.info("已取消");
});
}
const modegenx=()=>{
listQuery.value.parentid=""
getTreeData()
}
defineExpose({
modegenx
})
</script>
<style lang="scss" scoped>
.depar_hear {
height: 32px;
}
.depar_foot {
height: calc(100% - 32px);
overflow: auto;
width: 280px;
width: 100%;
min-width: 300px;
}
.departmentTree-box {
overflow: auto;
}
::v-deep .el-input__inner {
background-color: rgba(240, 240, 240, 0.8) !important;
}
.dropdown {
position: absolute;
width: 150px;
height:calc(35 * 5px) ;
z-index: 999;
border-radius: 5px;
border: 1px #ccc solid;
.item {
height: 35px;
border-bottom: 1px rgb(194, 194, 194) solid;
}
}
</style>

View File

@ -0,0 +1,180 @@
<template>
<div class="dialog" v-if="dialogForm" v-loading="loading">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" @click="submit" v-show="!disabledFoem">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="data.formData" :rules="rules" :inline="true" :disabled="disabledFoem" label-position="top" v-if="dialogForm">
<el-form-item prop="kqlx" label="考勤类型" class="ww31">
<el-select placeholder="请选择考勤类型" style="width: 100%" v-model="data.formData.kqlx" @change="kqlxHland" :disabled="title=='修改'?true:false">
<el-option v-for="dict in D_QW_KQ_KQLX" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item prop="kqywlxArr" label="业务类型" class="ww31">
<el-select multiple placeholder="请选择业务类型" style="width: 100%" v-model="data.formData.kqywlxArr" :disabled="title=='修改'?true:false">
<template v-if="data.formData.kqlx=='01'">
<el-option v-for="dict in D_BZ_QXJLX" :key="dict.value" :label="dict.label" :value="dict.value" />
</template>
<template v-if="data.formData.kqlx=='02'">
<el-option v-for="dict in D_QW_WC_LX" :key="dict.value" :label="dict.label" :value="dict.value" />
</template>
<template v-if="data.formData.kqlx=='03'">
<el-option v-for="dict in D_QW_CC_LX" :key="dict.value" :label="dict.label" :value="dict.value" />
</template>
</el-select>
</el-form-item>
<el-form-item prop="kqsc" label="考勤时长" class="ww31">
<div class="flex just-between align-center ww100">
<el-input-number style="width: 70%" v-model="data.formData.kqsc" precision="0" :min="1" :disabled="title=='修改'?true:false" />
<span class="fr">时长单位({{data.formData.kqlx=='02'?'小时':'天'}})</span>
</div>
</el-form-item>
<el-form-item prop="tgtj" label="通过条件" class="ww31">
<el-select placeholder="请选择通过条件" style="width: 100%" v-model="data.formData.tgtj">
<el-option v-for="dict in D_QW_KQ_SHLC_TGTJ" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item prop="shryXms" label="审核人员" class="ww31">
<el-input @click="chooseType('shr',data.formData.shrySfzhs)" v-model="data.formData.shryXms" placeholder="请选择审核人员" clearable/>
</el-form-item>
<el-form-item prop="csryXms" label="抄送人员" class="ww31">
<el-input @click="chooseType('csr',data.formData.csrySfzhs)" v-model="data.formData.csryXms" placeholder="请选择抄送人员" clearable/>
</el-form-item>
</el-form>
</div>
<ChooseUser :PoliceType="configerUser.PoliceType" v-if="configerUser.chooseUserVisible" v-model="configerUser.chooseUserVisible" rowKey="sfzh" :defaultSelectKeys="configerUser.chooseUser" @choosedPolice="hanlderChoose" />
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import ChooseUser from "@/components/MyComponents/choosePolice";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import { getItem } from "@/utils/storage";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_KQ_KQLX, D_BZ_QXJLX, D_QW_KQ_SHLC_TGTJ,D_QW_WC_LX,D_QW_CC_LX } = proxy.$dict("D_QW_KQ_KQLX", "D_BZ_QXJLX","D_QW_KQ_SHLC_TGTJ","D_QW_WC_LX","D_QW_CC_LX");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
let dept = getItem("deptId");
const configerUser = reactive({ //选择人员配置
chooseUserVisible:false,
titleValue: "人员选择",
PoliceType:"MJ",
chooseUser:[],
});
const data = reactive({
formData: {},
});
const rules = reactive({
kqlx: [{ required: true, message: "请选择考勤类型", trigger: ['blur','change'] }],
kqywlxArr: [{ required: true, message: "请选择业务类型", trigger: "blur" }],
tgtj: [{ required: true, message: "请选择通过条件", trigger: "blur" }],
shryXms: [{ required: true, message: "请选择审核人员", trigger: ['blur','change'] }],
csryXms: [{ required: true, message: "请选择抄送人员", trigger: ['blur','change'] }],
kqsc: [{ required: true, message: "请输入考勤时长", trigger: ['blur','change'] }],
})
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true
if(id){
title.value = '修改'
getDataById(id); //根据id查询详情
}else{
title.value = '新增'
}
}
// 根据id查询详情
const getDataById = (id)=>{
loading.value = true;
serviceGet({},`/mosty-qwzx/tbQwQxjShlc/selectVOById/${id}`).then(res=>{
data.formData = res;
data.formData.kqywlxArr = data.formData.kqywlx.split(",");
loading.value = false;
})
}
//考勤类型选择回调
const kqlxHland = (e) => {
data.formData.kqywlx = []
}
const chooseType = (type,value='') => {
configerUser.chooseUserVisible = true;
switch (type) {
case 'shr': // 审核人
configerUser.titleValue = "选择审核人";
configerUser.chooseUser = value && value != '' ? value.split(","):[];
break;
case 'csr': // 抄送人
configerUser.titleValue = "选择抄送人";
configerUser.chooseUser = value && value != '' ? value.split(","):[];
break;
}
};
//选择用户
const hanlderChoose = (val) => {
if (!val) return false;
let sfzh = val.userList.map(item=>{ return item.sfzh});
let xm = val.userList.map(item=>{ return item.xm});
switch (configerUser.titleValue) {
case "选择审核人":
if(sfzh.length > 10) return proxy.$message({type: "warning", message: "审核人不超过10人"});
data.formData.shrySfzhs = sfzh.join(",")
data.formData.shryXms = xm.join(",")
break;
case "选择抄送人":
if(sfzh.length > 20) return proxy.$message({type: "warning", message: "抄送人不超过20人"});
data.formData.csrySfzhs = sfzh.join(",")
data.formData.csryXms = xm.join(",")
break;
}
};
// 提交
const submit = ()=>{
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
data.formData.kqywlx = data.formData.kqywlxArr.join(",")
delete data.formData.kqywlxArr;
if(title.value == '新增'){
servicePost(data.formData,'/mosty-qwzx/tbQwQxjShlc/save').then(res=>{
proxy.$message({type: "success", message: "新增成功"});
close();
emits('updateDate');
}).catch(() => {
loading.value = false;
});
}else{
servicePost(data.formData,'/mosty-qwzx/tbQwQxjShlc/update').then(res=>{
proxy.$message({type: "success", message: "编辑成功"});
close();
emits('updateDate');
}).catch(() => {
loading.value = false;
});
}
});
}
// 关闭
const close = ()=>{
data.formData={};
dialogForm.value = false;
loading.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
</style>

View File

@ -0,0 +1,151 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="流程管理">
<el-button type="primary" @click="addEdit('add', '')">
<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" />
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger">
<template #kqlx="{ row }">
<dict-tag :options="D_QW_KQ_KQLX" :value="row.kqlx" :tag="false" />
</template>
<template #tgtj="{ row }">
<dict-tag :options="D_QW_KQ_SHLC_TGTJ" :value="row.tgtj" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row.id)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="delDictItem(row)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="pageData.tableHeight" :pageConfiger="pageData.pageConfiger"></Pages>
</div>
<!-- 编辑详情 -->
<EditAddForm ref="addEditDialog" @updateDate="getData" />
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 EditAddForm from "./editAddForm.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import { deleteQwQxj } from "@/api/service/pleaseTake.js";
import { reactive, ref, onMounted, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const { D_QW_KQ_KQLX, D_QW_KQ_SHLC_TGTJ } = proxy.$dict(
"D_QW_KQ_KQLX",
"D_QW_KQ_SHLC_TGTJ"
);
const addEditDialog = ref();
const ids = ref([]); //多选
const searchBox = ref(); //搜索框
let searchObj = reactive({}); //搜索数据
const searchConfiger = reactive([
{
showType: "select",
prop: "kqlx",
placeholder: "请选择考勤类型",
label: "考勤类型",
options: D_QW_KQ_KQLX
},
{
showType: "select",
prop: "tgtj",
placeholder: "请选择通过条件",
label: "通过条件",
options: D_QW_KQ_SHLC_TGTJ
}
]);
const queryFrom = ref({});
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading: false
},
pageConfiger: {
//分页
pageCurrent: 1,
pageSize: 20,
total: 0
},
tableColumn: [
{ label: "考勤类型", prop: "kqlx", showSolt: true },
{ label: "业务类型", prop: "kqywlxzh" },
{ label: "考勤时长", prop: "kqscZh" },
{ label: "通过条件", prop: "tgtj", showSolt: true }
]
});
onMounted(() => {
getData(); //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj) => {
let searchItem = JSON.parse(JSON.stringify(obj));
if (obj.cz) searchObj.ssbmdm = "";
delete searchObj.cz;
searchObj = { ...searchItem };
pageData.pageConfiger.pageCurrent = 1;
getData(); //获取数据
};
// 获取数据
const getData = () => {
pageData.tableConfiger.loading = true;
let attr = { ...pageData.pageConfiger, ...searchObj };
serviceGet(attr, "/mosty-qwzx/tbQwQxjShlc/selectPage").then((res) => {
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false;
});
};
// 新增\编辑
const addEdit = (type, id) => {
addEditDialog.value.init(type, id);
};
// 删除
function delDictItem(row) {
proxy.$confirm("确定删除该数据?", "警告", { type: "warning" }).then(() => {
serviceDelete({}, `/mosty-qwzx/tbQwQxjShlc/${row.id}`).then((res) => {
getData();
proxy.$message({ type: "success", message: "删除成功" });
});
});
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight =
window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style>
.el-loading-mask {
background: rgba(0, 0, 0, 0.3);
}
</style>

View File

@ -0,0 +1,313 @@
<template>
<!-- 勤务作息编辑新增 -->
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title">{{ isAdd ? "新增" : "修改" }}</span>
<div>
<el-button
type="primary"
size="small"
@click="onSave"
:loading="buttonLoading"
>保存</el-button
>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="form-content">
<el-form
ref="formRef"
:label-width="140"
:model="formData"
:rules="rules"
inline
>
<div class="content">
<el-form-item :disabled="isAdd" style="width: 48%" class="form-item" prop="kqlx" label="考勤类型">
<MOSTY.Select :dictEnum="D_QW_KQ_KQLX" placeholder="请选择考勤类型" @change="attendanceChange" v-model="formData.kqlx" />
</el-form-item>
<!-- 考勤业务类型多选 请休假时为 D_BZ_QXJLX 外出时为 D_QW_WC_LX 出差时为 D_QW_CC_LX -->
<el-form-item
:disabled="isAdd || !formData.kqlx"
style="width: 48%"
class="form-item"
prop="kqywlx"
label="业务类型"
>
<MOSTY.Select
:dictEnum="
[D_BZ_QXJLX, D_QW_WC_LX, D_QW_CC_LX][Number(formData.kqlx) - 1]
"
placeholder="请选择业务类型"
v-model="formData.kqywlx"
/>
</el-form-item>
<!-- </div > -->
<el-form-item
:disabled="isAdd"
style="width: 48%"
class="form-item"
prop="kqsc"
label="考勤时长"
>
<el-input-number v-model="formData.kqsc"></el-input-number>
<span class="time-text"
>时长单位{{ formData.kqlx > 1 ? "(小时)" : "(天)" }}</span
>
</el-form-item>
<el-form-item
style="width: 48%"
class="form-item"
prop="tgtj"
label="通过条件"
>
<MOSTY.Select
:dictEnum="D_QW_KQ_SHLC_TGTJ"
placeholder="通过条件"
v-model="formData.tgtj"
/>
</el-form-item>
<el-form-item
style="width: 48%"
class="form-item"
prop="shrySfzhs"
label="审核人员"
>
<!-- <ChooseTable
:configer="{ lx: 'mj' }"
v-model="formData.zbldZbStr"
:dic="{
D_QW_BC_KTS,
D_QW_BBZL,
D_BZ_WZLX,
D_BZ_XLFS,
D_BZ_ZZLX,
D_BZ_RYXFBBZW,
D_JCGL_JYQX_QXLX,
D_BZ_PDDTLX,
D_BZ_SF,
D_BZ_RYJZLB,
D_BZ_RYMFJLB,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTFWLB,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_JYCL_JYJTGJLB
}"
/> -->
</el-form-item>
<el-form-item
style="width: 48%"
class="form-item"
prop="qzrSfzh"
label="抄送人员"
>
<el-input
v-model="formData.qzrSfzh"
disabled
placeholder="请输入"
></el-input>
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import { reactive, ref, getCurrentInstance, defineEmits } from "vue";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
const { proxy } = getCurrentInstance();
const {
D_QW_KQ_KQLX,
D_BZ_QXJLX,
D_QW_WC_LX,
D_QW_CC_LX,
D_QW_KQ_SHLC_TGTJ,
// tableDic start--
D_QW_BC_KTS,
D_QW_BBZL,
D_BZ_WZLX,
D_BZ_XLFS,
D_BZ_ZZLX,
D_BZ_RYXFBBZW,
D_JCGL_JYQX_QXLX,
D_BZ_PDDTLX,
D_BZ_SF,
D_BZ_RYJZLB,
D_BZ_RYMFJLB,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTFWLB,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_JYCL_JYJTGJLB
} = proxy.$dict(
"D_QW_KQ_KQLX",
"D_BZ_QXJLX",
"D_QW_WC_LX",
"D_QW_CC_LX",
"D_QW_KQ_SHLC_TGTJ",
// table dic start
"D_QW_BC_KTS",
"D_QW_BBZL",
"D_BZ_WZLX",
"D_BZ_XLFS",
"D_BZ_ZZLX",
"D_BZ_RYXFBBZW",
"D_JCGL_JYQX_QXLX",
"D_BZ_PDDTLX",
"D_BZ_SF",
"D_BZ_RYJZLB",
"D_BZ_RYMFJLB",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_ZDSB_SBLX",
"D_JCGL_JYCL_JYJTFWLB",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_JYCL_JYJTGJLB"
);
// const personTableDic = ;
const props = defineProps({
// dic: Object
});
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
const formData = ref({});
const isAdd = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
dqjd: [{ required: false, message: "请填写地球纬度", trigger: "blur" }],
dqwd: [{ required: false, message: "请填写地球经度", trigger: "blur" }],
qzDd: [{ required: true, message: "请输入签注地点", trigger: "blur" }],
qzSm: [{ message: "请输入签注说明", trigger: "blur" }]
// qzrSfzh: [{ required: true, message: "请输入签注人身份证号", trigger: "blur" }],
// qzrXm: [{ required: true, message: "请输入签注人姓名", trigger: "blur" }]
});
/**部门id对照对象 */
let departmentIdObj = {};
/** 初始化数据 */
const init = (type, row) => {
isShowDialog.value = true; // 显示新增编辑dialog框
isAdd.value = type == "add" ? true : false;
dialogType.value = type;
isDetail.value = type === "detail";
// 是否有填充数据
departmentIdObj = {};
if (row) {
let {
id,
dqjd,
dqwd,
qzDd,
qzSm,
qzrSfzh,
qzrXm
} = row;
// 新增从本地取
if (type == "add") {
qzrSfzh = localStorage.getItem("idEntityCard"); // 身份证
qzrXm = localStorage.getItem("USERNAME"); //姓名
}
formData.value = {
id,
dqwd,
dqjd,
qzDd,
qzSm,
qzrSfzh,
qzrXm
};
// 新增
} else {
}
};
/**考勤类型改变 */
const attendanceChange = () => {
formData.value.kqywlx = undefined;
};
// 重置表单
const reserForm = () => {
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 保存
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let params = { ...formData.value };
params.qzrSfzh = localStorage.getItem("idEntityCard"); // 身份证
params.qzrXm = localStorage.getItem("USERNAME"); // 姓名
if (params.dqjd) params.dqjd = Number(params.dqjd);
if (params.dqwd) params.dqwd = Number(params.dqwd);
let url = isAdd.value ? "/tbQwglZxqz/save" : "/tbQwglZxqz/update";
let text = isAdd.value ? "新增成功" : "编辑成功";
servicePost(params, `/mosty-qwzx${url}`)
.then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
});
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.form-content {
margin-top: 20px;
}
.content {
padding: 10px 40px;
}
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
.time-text {
display: inline-block;
margin-left: 20px;
}
</style>

View File

@ -0,0 +1,211 @@
<template>
<!-- <div> 作息签注</div> -->
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">流程管理</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import Search from "@/components/aboutTable/Search.vue";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ElMessage } from "element-plus";
import EditAddForm from "./editAddForm.vue";
const { proxy } = getCurrentInstance();
// const { D_QW_FA_QWDJ, D_QW_FA_BMDJ, D_QW_FA_ZT } = proxy.$dict(
// "D_QW_FA_QWDJ",
// "D_QW_FA_BMDJ",
// "D_QW_FA_ZT"
// );
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "qzDd",
placeholder: "请输入考勤类型",
label: "考勤类型"
},
{
showType: "input",
prop: "qzrXm",
placeholder: "请输入通过条件",
label: "通过条件"
},
]);
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
// 考勤类型 业务类型, 考勤时长, 通过条件
{ label: "考勤类型", prop: "qzDd", showOverflowTooltip: true },
{
label: "业务类型",
prop: "qzSj",
showOverflowTooltip: true,
// width: 100
},
{
label: "考勤时长",
prop: "qzrXm",
showOverflowTooltip: true,
// width: 100
},
{
label: "通过条件",
prop: "qzSm",
showOverflowTooltip: true,
// width: 100
},
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
// mounted
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
console.log('组件刷新值data',data);
keyCount.value = data;
});
});
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 详情借用新增和修改的页面
const seeDetail = (type, row) => {
addEdit(type, row);
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = false;
serviceGet(params, "/mosty-qwzx/tbQwglZxqz/selectPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要注销", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
serviceDelete({}, "/mosty-qwzx/tbQwglZxqz/" + id).then((res) => {
proxy.$message.success("注销成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,116 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-10 20:07:01
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">详情</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="请假类型"><dict-tag :options="D_BZ_QXJLX" :value="data.detail.qjlx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{data.detail.kssj + ' ~ ' + data.detail.jssj}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="请假原因">{{data.detail.qjyy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="备注">{{data.detail.bz}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span v-show="item.kqShyj && item.kqShyj !=''">审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_BZ_QXJLX, D_QW_KQ_SHZT } = proxy.$dict("D_BZ_QXJLX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true;
getDataById(id) //根据id查询详情
}
// 根据id查询详情
const getDataById = (id)=>{
loading.value = true;
serviceGet({},`/mosty-qwzx//tbQwQxj/queryVOById/${id}`).then(res=>{
data.detail = res;
loading.value = false;
})
}
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,177 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="!disabledFoem">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="data.formData" :rules="rules" :inline="true" :disabled="disabledFoem" label-position="top">
<el-form-item prop="sqrlx" label="申请人类型" class="ww31">
<el-select placeholder="请选择申请人类型" style="width: 100%" v-model="data.formData.sqrlx">
<el-option v-for="dict in D_BZ_SQRLX" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item prop="sqrXm" label="申请人" class="ww31">
<el-input @click="chooseUserVisible = true" v-model="data.formData.sqrXm" placeholder="请选择申请人" clearable/>
</el-form-item>
<el-form-item prop="qjlx" label="请假类型" class="ww31">
<el-select style="width: 100%" v-model="data.formData.qjlx" filterable placeholder="请选择请假类型" @change="getLc">
<el-option v-for="item in D_BZ_QXJLX" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item prop="qzrqForm" required label="起止日期" class="ww31">
<el-date-picker
style="width: 100%"
v-model="data.formData.qzrqForm"
type="daterange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="upQzrqForm"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item prop="sfsh" label="是否审核" class="ww31">
<el-select style="width: 100%" v-model="data.formData.sfsh" filterable placeholder="是否审核" @change="getLc">
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="审批人" class="ww31" v-if="data.formData.sfsh==1" >
<el-input v-model="data.spObj.shryXms" placeholder="请选择审批人" readonly/>
</el-form-item>
<el-form-item label="抄送人" class="ww31">
<el-input v-model="data.spObj.csryXms" placeholder="请选择抄送人" readonly/>
</el-form-item>
<el-form-item label="请假原因" prop="qjyy" class="ww100">
<el-input v-model="data.formData.qjyy" placeholder="请输入请假原因" show-word-limit type="textarea"/>
</el-form-item>
<el-form-item label="备注" class="ww100">
<el-input v-model="data.formData.bz" placeholder="请输入关键字" show-word-limit type="textarea"/>
</el-form-item>
</el-form>
</div>
<ChooseUser v-model="chooseUserVisible" :PoliceType="data.formData.sqrlx == '01' ? 'MJ' : 'FJ'" :Single="true" @choosedPolice="hanlderChoose" />
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import ChooseUser from "@/components/MyComponents/choosePolice";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import {getDifferTime} from "@/utils/tools.js";
import { addQwQxj, getQwQxjInfo, updateQwQxj } from "@/api/service/pleaseTake.js";
import * as rule from "@/utils/rules.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_BZ_QXJLX, D_BZ_SQRLX ,D_BZ_SF} = proxy.$dict("D_BZ_QXJLX", "D_BZ_SQRLX","D_BZ_SF");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const chooseUserVisible = ref(false);//人员弹窗
const loading = ref(false);
const data = reactive({
formData: {sqrlx:"01",sfsh:"1",shryXms:""},
spObj:{}, //审核对象
});
const rules = reactive({
sqrlx: [{ required: true, message: "请选择申请人类型", trigger: "change" }],
sqrXm: [{ required: true, message: "请选中申请人", trigger: ['blur','change'] }],
qjlx: [{ required: true, message: "请输入请假类型", trigger: "change" }],
qzrqForm: [{ required: true, message: "请选择请假日期", trigger: "blur" }],
qjyy: [{ required: true, message: "请输入请假原因", trigger: "blur" }],
shryXms:[{required: true, message: "请选择后审核人", trigger: "blur"}],
sfsh: [{ required: true, message: "请选择是否审核", trigger: "blur" }],
})
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true
if(id){
title.value = '修改'
getDataById(id) //根据id查询详情
}else{
title.value = '新增'
}
}
// 根据id查询详情
const getDataById = (id)=>{
getQwQxjInfo(id).then((res) => {
data.formData = res;
data.formData.qzrqForm = [res.kssj, res.jssj];
});
}
//根据请休假时间和请假类型获取配置流程
const getLc = () => {
if(data.formData.kssj && data.formData.kssj!='' && data.formData.jssj && data.formData.jssj != '' && data.formData.qjlx && data.formData.qjlx!=''){
let arrt = {kqlx:'01',kqywlx:data.formData.qjlx,kqsc:getDifferTime(data.formData.kssj,data.formData.jssj)};
serviceGet(arrt,'/mosty-qwzx/tbQwQxjShlc/selectForAuditsCheck').then(res=>{
data.spObj = res ? res : {};
data.formData.kqShlcId = res?.id;
});
}
};
//时间
function upQzrqForm(val) {
data.formData.kssj = val.length > 0 ? val[0] : "";
data.formData.jssj = val.length > 0 ? val[1] : "";
getLc()
}
//选择用户
const hanlderChoose = (users) => {
const user = users[0];
data.formData.sqrXm = user.xm;
data.formData.sqrId = user.fl === "01" ? user.ryid : user.id;
data.formData.sqbm = user.ssbm;
data.formData.sqbmdm = user.ssbmdm;
data.formData.sqrSfzh = user.sfzh;
data.formData.lxdh = user.lxdh;
};
// 提交
const submit = ()=>{
elform.value.validate((valid) => {
if (!valid) return false;
if(data.formData.sfsh=='1'){
if(!data.formData.kqShlcId || data.formData.kqShlcId=='') return proxy.$message({type: "warning", message: "暂无相关请休假的流程配置!"});
}else{
delete data.formData.kqShlcId;
}
loading.value = true;
delete data.formData.qzrqForm;
if(title.value == '新增'){
addQwQxj(data.formData).then((res) => {
proxy.$message({type: "success", message: "新增成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
}else{
updateQwQxj(data.formData).then(() => {
proxy.$message({type: "success", message: "编辑成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
}
});
}
// 关闭
const close = ()=>{
data.formData={sqrlx:"01"};
dialogForm.value = false;
data.spObj={}
loading.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
</style>

View File

@ -0,0 +1,192 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="请休假管理">
<el-button type="primary" @click="addEdit('add', '')">
<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">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrlx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrlx" :tag="false" />
</template>
<template #kssj="{ row }">
{{ row.kssj.substring(0, 10) + " — " + row.jssj.substring(0, 10) }}
</template>
<template #qjlx="{ row }">
<dict-tag :options="D_BZ_QXJLX" :value="row.qjlx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="delDictItem(row)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" @updateDate="getData"/>
<!-- 详情 -->
<Detail ref="detailDialog"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 EditAddForm from './editAddForm.vue';
import Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { getQwQxj, addQwQxj, deleteQwQxj, getQwQxjInfo, updateQwQxj } from "@/api/service/pleaseTake.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_BZ_QXJLX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_BZ_QXJLX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const addEditDialog = ref();
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrlx",
placeholder: "请选择请假人类型",
label: "请假人类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入请假人姓名",
label: "请假人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "请假人类型", prop: "sqrlx", showSolt :true},
{ label: "请假人", prop: "sqrXm"},
{ label: "请假人部门", prop: "sqbm" },
{ label: "起止日期", prop: "kssj", showSolt :true, width:"200" },
{ label: "请假类型", prop: "qjlx", showSolt :true },
{ label: "申请时间", prop: "xtCjsj"},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.kssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.jssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
let attr = { ...pageData.pageConfiger, ...searchObj.value };
getQwQxj(attr).then((res) => {
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
});
}
// 新增
const addEdit = (type,id)=>{
addEditDialog.value.init(type,id)
}
// 新增
const detailHland = (type,id)=>{
detailDialog.value.init(type,id)
}
// 批量删除
function delDictItem(row) {
proxy.$confirm("确定删除该数据?", "警告", { type: "warning" }).then(() => {
deleteQwQxj(row.id).then(() => {
getData();
proxy.$message({ type: "success", message: "删除成功" });
});
}).catch(() => {
proxy.$message.info("已取消");
});
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,146 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-10 20:23:56
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{title}}</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="请假类型"><dict-tag :options="D_BZ_QXJLX" :value="data.detail.qjlx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{data.detail.kssj + ' ~ ' + data.detail.jssj}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="请假原因">{{data.detail.qjyy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="备注">{{data.detail.bz}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span class="ml10" v-show="item.kqShyj && item.kqShyj !=''"> 审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
<div v-if="title == '审批'" class="flex just-center">
<el-button type="primary" @click="submit('ok')" plain>通过</el-button>
<el-button type="danger" @click="submit('no')" plain>不通过</el-button>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_BZ_QXJLX, D_QW_KQ_SHZT } = proxy.$dict("D_BZ_QXJLX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id,val)=> {
dialogForm.value = true;
data.detail = JSON.parse(JSON.stringify(val));
if(type == 'detail') title.value = '详情';
else title.value = '审批';
}
// 同意或者驳回
const spRequset = (status,content)=>{
let params = { kqShzt:status == 'no' ? '03' :'02',id:data.detail.kqShry.id }
if(status == 'no') params.kqShyj = content
servicePost(params,`/mosty-qwzx/tbQwKqScry/audits`).then(res=>{
let text = status == 'no' ? '驳回成功' :'审核成功'
proxy.$message({ type: "success", message: text });
emits('updateDate')
close();
})
}
//审批
const submit = (status) => {
if(status == 'no'){
ElMessageBox.prompt("请输入不通过原因", "不通过原因", {
confirmButtonText:"提交",
cancelButtonText:"取消",
inputPattern:/\S+/,
inputPlaceholder:"请输入不通过原因",
inputErrorMessage:'请输入不通过原因',
}).then((res) => {
let content = res.value
spRequset(status,content)
}).catch(()=>{});
}else{
spRequset(status)
}
};
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,181 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="请休假审批" />
</div>
<!-- 搜索 -->
<div ref="searchBox">
<!-- <Search :searchArr="searchConfiger" @submit="onSearch">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search> -->
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrlx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrlx" :tag="false" />
</template>
<template #kssj="{ row }">
{{ row.kssj.substring(0, 10) + " — " + row.jssj.substring(0, 10) }}
</template>
<template #qjlx="{ row }">
<dict-tag :options="D_BZ_QXJLX" :value="row.qjlx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id,row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" v-if="row.kqShry.kqShzt == '01'" @click="detailHland('sp', row.id,row)">审批</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 详情 -->
<Detail ref="detailDialog" @updateDate="getData"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { getQwQxj, addQwQxj, deleteQwQxj, getQwQxjInfo, updateQwQxj } from "@/api/service/pleaseTake.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_BZ_QXJLX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_BZ_QXJLX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrlx",
placeholder: "请选择请假人类型",
label: "请假人类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入请假人姓名",
label: "请假人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "请假人部门", prop: "sqbm",showOverflowTooltip:true },
{ label: "请假人类型", prop: "sqrlx", showSolt :true},
{ label: "请假人", prop: "sqrXm"},
{ label: "请假类型", prop: "qjlx", showSolt :true },
{ label: "起止日期", prop: "kssj", showSolt :true, width:"200" },
{ label: "申请时间", prop: "xtCjsj",showOverflowTooltip:true},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.kssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.jssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchObj.value,...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
let attr = { ...pageData.pageConfiger, ...searchObj.value };
serviceGet({},`/mosty-qwzx/tbQwQxj/paginAuditsQuery`).then(res=>{
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
}).catch(()=>{
pageData.tableConfiger.loading = false
});
}
// 详情
const detailHland = (type,id,data)=>{
detailDialog.value.init(type,id,data)
}
// 批量删除
function delDictItem(row) {
proxy.$confirm("确定删除该数据?", "警告", { type: "warning" }).then(() => {
deleteQwQxj(row.id).then(() => {
getData();
proxy.$message({ type: "success", message: "删除成功" });
});
}).catch(() => {
proxy.$message.info("已取消");
});
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,197 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:11:44
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="bbl-box">
<div class="popTitle">{{ childTitle }}巡防报备情况</div>
<div class="popBody" style="max-height: 600px">
<div class="tjtitle">
<el-date-picker v-model="searchDay" type="date" placeholder="选择日期" style="width: 150px" value-format="YYYY-MM-DD" @change="changeDay" />
<div class="tjli lightblue">
当日应报备<span>{{ allNums > 0 ? allNums:0 }}</span>
</div>
<div class="tjli green">
当日已报备<span>{{ alreadyNums > 0 ? alreadyNums : 0 }}</span>
</div>
<div class="tjli orange">
当日未报备<span>{{
Number(allNums) - Number(alreadyNums) > 0
?
Number(allNums) - Number(alreadyNums) : 0
}}</span>
</div>
</div>
<el-table ref="table" :data="tableChildData" border class="table flex-auto overflow-auto margin-tp-10" row-class-name="table-row" cell-class-name="table-cell" header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell" style="width: 100%">
<el-table-column label="报备详情" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="ybb" label="应报备" align="center" />
<el-table-column prop="zsbb" label="最少报备" align="center" />
<el-table-column prop="sjbb" label="已报备" align="center" />
<el-table-column label="未报备" align="center">
<template #default="{ row }">
{{ row.wbb >= 0 ? row.wbb : 0}}
</template>
</el-table-column>
<el-table-column prop="bbf" label="报备分" align="center" />
<el-table-column prop="bbkf" label="报备扣分" align="center" />
<el-table-column label="报备完成率" align="center" prop="xlbl">
<template #default="{ row }">
<p v-if="row.ybb">
{{ ((Number(row.sjbb) / Number(row.ybb)) * 100).toFixed(2) }}%
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination class="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="childlistQuery.pageCurrent" :page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { ZHJMXF_URL, ASSESS_SCORE_URL } from "@/settings";
// import dictData from "@utils/dicts";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
onMounted(() => {
searchDay.value = timeValidate(new Date(), "ymd");
childlistQuery.value.kssj = timeValidate(new Date(), "ymd");
childlistQuery.value.jssj = timeValidate(new Date(), "ymd");
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjbb;
allNums.value = res.ybb;
});
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent = 1;
getChildTableList();
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #000000;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
.bbl-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
::v-deep .el-dialog__body {
color: #fff !important;
}
</style>
<style >
</style>

View File

@ -0,0 +1,199 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}指令签收情况</div>
<div class="tjtitle">
<el-date-picker
v-model="searchDay"
type="date"
placeholder="选择日期"
style="width: 150px"
value-format="YYYY-MM-DD"
@change="changeDay"
/>
<div class="tjli lightblue">
当日应巡逻<span>{{ allNums <= 0 ? 0 : allNums }}</span>
</div>
<div class="tjli green">
当日已巡逻<span>{{ alreadyNums <= 0 ? 0 : alreadyNums}}</span>
</div>
<div class="tjli orange">
当日未巡逻<span>{{
Number(allNums) - Number(alreadyNums) <= 0 ? 0 : (Number(allNums) - Number(alreadyNums)%100).toFixed(0)
}}</span>
</div>
</div>
</div>
<div style="height:600px;">
<GdMap id="mapDivDialog" v-if="mapShow"/>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { ZHJMXF_URL, ASSESS_SCORE_URL } from "@/settings";
import { JXgetPageList, getStatistics } from "@/api/file";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import GdMap from "@/components/GdMap/index.vue";
import emitter from "@/utils/eventBus.js";
import { parseTime, timestampToStr } from "@/utils/index";
import { queryListfzyc } from "@/api/dpApi/home.js";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
const mapShow = ref(false);
onMounted(() => {
nextTick(()=>{ mapShow.value = true; })
searchDay.value = timeValidate(new Date(),'ymd');
childlistQuery.value.kssj = timeValidate(new Date(),'ymd');;
childlistQuery.value.jssj = timeValidate(new Date(),'ymd');;
getChildTableList();
_getStatistics();
showFZYC();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
showFZYC();
},
{ deep: true }
);
// 地图撒点
function showFZYC() {
emitter.emit("deletePointArea", "zdxl_fzyc");
let { kssj, jssj, ssbmdm } = childlistQuery.value;
let param = { ssbmdm: ssbmdm, kssj: kssj, jssj: jssj, pageCurrent: 1, pageSize: 1000};
queryListfzyc(param).then((res) => {
if(res.length == 0 ) return false;
let cc = []
let list = res.map((el, index) => {
let centerPoint = [el.zxX,el.zxY]
if(index == 0) cc = centerPoint;
let position = [[Number(el.x1),Number(el.y1)],[Number(el.x2),Number(el.y2)]]
let text = el.realDate + ' ' + el.bc
let obj = { position:position,text, id: el.id ,userData:el}
return obj;
});
let arr1 = list.filter(v=>{return v.sfxl == 1})
let arr2 = list.filter(v=>{return v.sfxl != 1})
let params1 = { fontColor:'#12fdb8',coords: arr2, type:'rectangle', flag:'zdxl_fzyc',color:'rgba(2,20,51,0.5)',linecolor:'#f51616'}
let params2 = { fontColor:'#12fdb8',coords: arr1, type:'rectangle', flag:'zdxl_fzyc',color:'rgba(2,20,51,0.5)',linecolor:'#1C97FF'}
emitter.emit("echoPlane", params1);
emitter.emit("echoPlane", params2);
emitter.emit("setMapCenter", { location: cc, zoomLevel: 14 });
});
}
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjxl;
allNums.value = res.yxl;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
getChildTableList();
_getStatistics();
showFZYC();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #000;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
::v-deep .el-table th.el-table__cell {
background: #0d2944 !important;
color: #61f9ff;
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,209 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}巡逻里程情况</div>
<div class="popBody" style="max-height: 600px; overflow: auto">
<div class="tjtitle">
<el-date-picker
v-model="searchDay"
type="date"
placeholder="选择日期"
style="width: 150px"
value-format="YYYY-MM-DD"
@change="changeDay"
/>
<div class="tjli lightblue">
当日应巡逻里程<span>{{ allNums <= 0 ? 0 : allNums}}</span>
</div>
<div class="tjli green">
当日实际巡逻里程<span>{{ alreadyNums <=0 ? 0 : alreadyNums }}</span>
</div>
<div class="tjli orange">
当日未巡逻里程<span>{{ notNums <= 0 ? 0 : notNums }}</span>
</div>
</div>
<el-table
ref="table"
:data="tableChildData"
border
class="table flex-auto overflow-auto margin-tp-10"
row-class-name="table-row"
cell-class-name="table-cell"
header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell"
style="width: 100%"
>
<!-- @row-click="getScore" -->
<el-table-column label="巡逻里程率" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="yxllc" label="应巡逻里程" align="center" />
<el-table-column prop="sjxllc" label="实际巡逻里程" align="center" />
<el-table-column label="未巡逻里程" align="center" prop="wxllc" />
<el-table-column label="巡逻里程得扣分" align="center" prop="xllckf" />
<el-table-column label="巡逻里程得分" align="center" prop="xllcf" />
<el-table-column label="比例" align="center" prop="pccbl">
<template #default="{ row }">
<p v-if="row.yxllc">
{{
((Number(row.sjxllc) / Number(row.yxllc)) * 100).toFixed(2)
}}%
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="childlistQuery.pageCurrent"
:page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
onMounted(() => {
searchDay.value = timeValidate(new Date(),'ymd');
childlistQuery.value.kssj = timeValidate(new Date(),'ymd');;
childlistQuery.value.jssj = timeValidate(new Date(),'ymd');;
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjxllc;
allNums.value = res.yxllc;
notNums.value = res.wxllc;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent=1
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #000;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,208 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}盘查情况</div>
<div class="popBody" style="max-height: 600px; overflow: auto">
<div class="tjtitle">
<el-date-picker
v-model="searchDay"
type="date"
placeholder="选择日期"
style="width: 150px"
value-format="YYYY-MM-DD"
@change="changeDay"
/>
<div class="tjli lightblue">
当日应盘查<span>{{ allNums <= 0 ? 0 : allNums}}</span>
</div>
<div class="tjli green">
当日已盘查<span>{{ alreadyNums <=0 ? 0 : alreadyNums }}</span>
</div>
<div class="tjli orange">
当日未盘查<span>{{ notNums <= 0 ? 0 : notNums }}</span>
</div>
</div>
<el-table
ref="table"
:data="tableChildData"
border
class="table flex-auto overflow-auto margin-tp-10"
row-class-name="table-row"
cell-class-name="table-cell"
header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell"
style="width: 100%"
>
<!-- @row-click="getScore" -->
<el-table-column label="盘查详情" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="ycc" label="应盘查" align="center" />
<el-table-column prop="sjcc" label="实际盘查人" align="center" />
<el-table-column label="未盘查" align="center" prop="wcc" />
<el-table-column label="比例" align="center" prop="pccbl">
<template #default="{ row }">
<p v-if="row.ycc">
{{ ((Number(row.sjcc) / Number(row.ycc)) * 100).toFixed(2) }}%
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="childlistQuery.pageCurrent"
:page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
onMounted(() => {
searchDay.value = timeValidate(new Date(),'ymd');
childlistQuery.value.kssj = timeValidate(new Date(),'ymd');;
childlistQuery.value.jssj = timeValidate(new Date(),'ymd');;
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjcc;
allNums.value = res.ycc;
notNums.value = res.wcc;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent=1
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #72d8ff;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
::v-deep .el-table th.el-table__cell {
background: #0d2944 !important;
color: #61f9ff;
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,208 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}盘查情况</div>
<div class="popBody" style="max-height: 600px; overflow: auto">
<div class="tjtitle">
<el-date-picker
v-model="searchDay"
type="date"
placeholder="选择日期"
style="width: 150px"
value-format="YYYY-MM-DD"
@change="changeDay"
/>
<div class="tjli lightblue">
当日应盘查<span>{{ allNums <= 0 ? 0 : allNums}}</span>
</div>
<div class="tjli green">
当日已盘查<span>{{ alreadyNums <=0 ? 0 : alreadyNums }}</span>
</div>
<div class="tjli orange">
当日未盘查<span>{{ notNums <= 0 ? 0 : notNums }}</span>
</div>
</div>
<el-table
ref="table"
:data="tableChildData"
border
class="table flex-auto overflow-auto margin-tp-10"
row-class-name="table-row"
cell-class-name="table-cell"
header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell"
style="width: 100%"
>
<!-- @row-click="getScore" -->
<el-table-column label="盘查详情" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="ycr" label="应盘查" align="center" />
<el-table-column prop="sjcr" label="实际盘查人" align="center" />
<el-table-column label="未盘查" align="center" prop="wcr" />
<el-table-column label="比例" align="center" prop="qsbl">
<template #default="{ row }">
<p v-if="row.ycr">
{{ ((Number(row.sjcr) / Number(row.ycr)) * 100).toFixed(2) }}%
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="childlistQuery.pageCurrent"
:page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
onMounted(() => {
searchDay.value = timeValidate(new Date(),'ymd');
childlistQuery.value.kssj = timeValidate(new Date(),'ymd');;
childlistQuery.value.jssj = timeValidate(new Date(),'ymd');;
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjcr;
allNums.value = res.ycr;
notNums.value = res.wcr;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent=1
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #72d8ff;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
::v-deep .el-table th.el-table__cell {
background: #0d2944 !important;
color: #61f9ff;
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,189 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}指令签收情况</div>
<div class="popBody" style="max-height: 600px; overflow: auto">
<div class="tjtitle">
<el-date-picker v-model="searchDay" type="date" placeholder="选择日期" style="width: 150px" value-format="YYYY-MM-DD" @change="changeDay" />
<div class="tjli lightblue">
当日应签收<span>{{ allNums >0 ? allNums:0 }}</span>
</div>
<div class="tjli green">
当日已签收<span>{{ alreadyNums >0 ? alreadyNums: 0 }}</span>
</div>
<div class="tjli orange">
当日未签收<span>{{ Number(allNums) - Number(alreadyNums) > 0 ? Number(allNums) - Number(alreadyNums): 0 }}</span>
</div>
</div>
<el-table ref="table" :data="tableChildData" border class="table flex-auto overflow-auto margin-tp-10" row-class-name="table-row" cell-class-name="table-cell" header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell" style="width: 100%">
<!-- @row-click="getScore" -->
<el-table-column label="签收详情" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="yqs" label="应签收" align="center" />
<el-table-column prop="sjqs" label="已签收" align="center" />
<el-table-column label="未签收" align="center" prop="wqs">
<template #default="{ row }">
<p>{{ row.wqs>0 ? row.wqs:0 }}</p>
</template>
</el-table-column>
<el-table-column label="比例" align="center" prop="qsbl">
<template #default="{ row }">
<p v-if="row.yqs">
{{ ((Number(row.sjqs) / Number(row.yqs))*100).toFixed(2) }}
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination class="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="childlistQuery.pageCurrent" :page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { ZHJMXF_URL, ASSESS_SCORE_URL } from "@/settings";
// import dictData from "@utils/dicts";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
onMounted(() => {
searchDay.value = timeValidate(new Date(), "ymd");
childlistQuery.value.kssj = timeValidate(new Date(), "ymd");
childlistQuery.value.jssj = timeValidate(new Date(), "ymd");
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjqs;
allNums.value = res.yqs;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent = 1;
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #72d8ff;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
::v-deep .el-table th.el-table__cell {
background: #0d2944 !important;
color: #61f9ff;
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,211 @@
<!--
* @Author: your name
* @Date: 2020-03-22 11:36:21
* @LastEditTime: 2023-04-10 17:02:18
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \xfxt_web\src\views\xfxt\home\componets\left-home.vue
-->
<template>
<div class="qs-box">
<div class="popTitle">{{ childTitle }}时长情况</div>
<div class="popBody" style="max-height: 600px; overflow: auto">
<div class="tjtitle">
<el-date-picker
v-model="searchDay"
type="date"
placeholder="选择日期"
style="width: 150px"
value-format="YYYY-MM-DD"
@change="changeDay"
/>
<div class="tjli lightblue">
当日应巡逻时长<span>{{ allNums <= 0 ? 0 : allNums }}</span>
</div>
<div class="tjli green">
当日实际巡逻时长<span>{{
alreadyNums <= 0 ? 0 : alreadyNums
}}</span>
</div>
<div class="tjli orange">
当日未巡逻时长<span>{{ notNums <= 0 ? 0 : notNums }}</span>
</div>
</div>
<el-table
ref="table"
:data="tableChildData"
border
class="table flex-auto overflow-auto margin-tp-10"
row-class-name="table-row"
cell-class-name="table-cell"
header-row-class-name="table-header-row"
header-cell-class-name="table-header-cell"
style="width: 100%"
>
<!-- @row-click="getScore" -->
<el-table-column label="盘查详情" align="center">
<el-table-column prop="ssbm" label="单位" align="center">
<template #default="{ row }">
<el-tooltip effect="dark" :content="row.ssbm" placement="right">
<span>{{ row.ssbm }}</span>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="yxlsc" label="应巡逻时长" align="center" />
<el-table-column prop="sjxlsc" label="实际巡逻时长" align="center" />
<el-table-column label="未巡逻时长" align="center" prop="wxlsc" />
<el-table-column label="巡逻时长扣分" align="center" prop="xlsckf" />
<el-table-column label="巡逻时长分" align="center" prop="xlscf" />
<el-table-column label="比例" align="center" prop="pccbl">
<template #default="{ row }">
<p v-if="row.yxlsc">
{{
((Number(row.sjxlsc) / Number(row.yxlsc)) * 100).toFixed(2)
}}%
</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
</el-table>
<div class="fenye">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="childlistQuery.pageCurrent"
:page-sizes="[10, 20, 50, 100]"
:page-size="childlistQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import { timeValidate } from "@/utils/tools";
import { JXgetPageList, getStatistics } from "@/api/file.js";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import { parseTime, timestampToStr } from "@/utils/index";
const props = defineProps({
childTitle: {
default: "",
type: String
},
searchType: {
default: "",
type: String
},
ssbmdm: {
default: "",
type: String
}
});
const childlistQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: props.searchType,
kssj: "",
jssj: "",
ssbmdm: props.ssbmdm,
cxcj: "02"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const searchDay = ref("");
const allNums = ref("");
const tableChildData = ref([]);
const alreadyNums = ref("");
const notNums = ref("");
const total = ref(0);
const allList = ref([]);
onMounted(() => {
searchDay.value = timeValidate(new Date(), "ymd");
childlistQuery.value.kssj = timeValidate(new Date(), "ymd");
childlistQuery.value.jssj = timeValidate(new Date(), "ymd");
getChildTableList();
_getStatistics();
});
watch(
() => [props.ssbmdm, props.searchType],
() => {
childlistQuery.value.ssbmdm = props.ssbmdm;
childlistQuery.value.searchType = props.searchType;
getChildTableList();
_getStatistics();
},
{ deep: true }
);
// 获取弹窗表格初始化数据
const getChildTableList = () => {
JXgetPageList(childlistQuery.value).then((res) => {
tableChildData.value = res.records;
total.value = res.total;
});
};
const _getStatistics = () => {
let { searchType, ssbmdm, kssj } = childlistQuery.value;
let params = {
searchType: searchType,
ssbmdm: ssbmdm,
time: kssj
};
getStatistics(params).then((res) => {
alreadyNums.value = res.sjxlsc;
allNums.value = res.yxlsc;
notNums.value = res.wxlsc;
});
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
childlistQuery.value.pageSize = currentSize;
getChildTableList();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
childlistQuery.value.pageCurrent = currentPage;
getChildTableList();
};
const changeDay = (val) => {
childlistQuery.value.kssj = val;
childlistQuery.value.jssj = val;
childlistQuery.value.pageCurrent = 1;
getChildTableList();
};
</script>
<style lang="scss" scoped>
.popTitle {
color: #000;
line-height: 24px;
font-size: 18px;
text-align: center;
}
.tjtitle {
margin-top: 30px;
margin-bottom: 30px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.tjli {
flex: 1;
text-align: center;
font-size: 18px;
}
}
.qs-box {
::v-deep .el-table__body-wrapper {
height: 40vh;
overflow: auto;
}
}
</style>

View File

@ -0,0 +1,581 @@
<template>
<PageTitle title="数据分析">
<el-button type="primary" @click="exportExcel()">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">导出</span>
</el-button>
</PageTitle>
<div class="flexboc">
<div class="flexb">
<el-date-picker v-model="dayValue" :value-format="formatValue" style="width: 270px" :type="TypeValue"
range-separator="" start-placeholder="开始时间" end-placeholder="结束时间" />
<!-- <el-select v-if="dayType === 'QUARTER'" v-model="listQuery.quarter" @change="quarterChange">
<el-option v-for="item in quarterList" :key="item.value" :label="item.label" :value="item.value" />
</el-select> -->
<el-button style="margin-left:10px" type="primary" @click="dayChange()">
<span style="vertical-align: middle; ">搜索</span>
</el-button>
<el-button type="primary" @click="reset()">
<span style="vertical-align: middle">重置</span>
</el-button>
</div>
</div>
<el-table ref="table" :data="tableData" v-loading="loading" border :height="tableHeight" @cell-click="cellClick">
<el-table-column width="230" label="单位名称" show-overflow-tooltip prop="ssbm">
</el-table-column>
<el-table-column label="报备率" align="center" prop="bbl">
<el-table-column prop="ybb" label="应报备" align="center" />
<el-table-column prop="sjbb" label="已报备" align="center" />
<el-table-column label="未报备" align="center" prop="wbb" />
<el-table-column label="比例" align="center" prop="bbbl">
<template #default="{ row }">
<p v-if="row.ybb">{{ ((Number(row.sjbb) / Number(row.ybb)) * 100).toFixed(2) }}%</p>
<p v-else>0%</p>
</template>
</el-table-column>
<el-table-column label="报备扣分" align="center" prop="bbkf" />
</el-table-column>
<el-table-column label="重点区域巡逻率" align="center" prop="xll">
<el-table-column prop="yxl" label="应巡逻" align="center" />
<el-table-column prop="zsxl" label="最少巡逻" align="center" />
<el-table-column prop="sjxl" label="已巡逻" align="center" />
<el-table-column prop="wxl" label="未巡逻" align="center" />
<el-table-column prop="xlbl" label="巡逻比例" align="center">
<template #default="{ row }">
<p v-if="row.yxl">{{ ((Number(row.sjxl) / Number(row.yxl)) * 100).toFixed(2) }}%</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="巡逻时长率" align="center" prop="xlscl">
<el-table-column prop="yxlsc" label="应巡时长" align="center" />
<el-table-column prop="sjxlsc" label="已巡时长" align="center" />
<el-table-column prop="wxlsc" label="未巡时长" align="center" />
<el-table-column prop="xlscbl" label="巡逻时长比例" align="center">
<template #default="{ row }">
<p v-if="row.yxlsc">{{((Number(row.sjxlsc) / Number(row.yxlsc)) * 100).toFixed(2)}}%</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="巡逻里程率" align="center">
<el-table-column prop="yxllc" label="应巡里程" align="center" />
<el-table-column prop="sjxllc" label="已巡里程" align="center" />
<el-table-column prop="wxllc" label="未巡里程" align="center" />
<el-table-column label="巡逻里程比例" align="center" prop="xllcbl">
<template #default="{ row }">
<p v-if="row.yxllc">{{((Number(row.sjxllc) / Number(row.yxllc)) * 100).toFixed(2)}}%</p>
<p v-else>0%</p>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="三项扣分" fixed="right" align="center" prop="sxkf" />
<el-table-column label="三项得分" fixed="right" align="center" prop="total" />
</el-table>
<el-pagination class="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.pageCurrent" :page-sizes="[10, 20, 50, 100]" :page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination>
<el-dialog v-model="bblPopVisible" width="90%" v-if="bblPopVisible">
<BblComp :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
</el-dialog>
<el-dialog v-model="qslPopVisible" width="90%" v-if="qslPopVisible">
<QslComp :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
</el-dialog>
<el-dialog v-model="chlPopVisible" width="90%" v-if="chlPopVisible">
<ChlComp :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
</el-dialog>
<!-- 盘查人 -->
<el-dialog :title="dialogTitle" v-model="pcrPopVisible" width="90%" v-if="pcrPopVisible">
<PrlComp v-if="searchType == '04'" :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
<PclComp v-if="searchType == '05'" :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
<SclComp v-if="searchType == '06'" :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
<LclComp v-if="searchType == '07'" :childTitle="childTitle" :ssbmdm="ssbmdm" :searchType="searchType" />
</el-dialog>
</template>
<script setup>
import * as XLSX from "xlsx";
import PageTitle from "@/components/aboutTable/PageTitle.vue";
import { getItem } from "@/utils/storage";
import { timeValidate } from "@/utils/tools";
import { JXgetPageList } from "@/api/file.js";
import eventBus from "@/utils/eventBus";
import { download } from "@/utils/request";
import { ZHJMXF_URL, ASSESS_SCORE_URL } from "@/settings";
import { defineProps, watch, ref, onMounted, nextTick } from "vue";
import BblComp from "./componets/bbl-comp";
import QslComp from "./componets/qsl-comp";
import ChlComp from "./componets/chl-comp";
import PrlComp from "./componets/pr-comp";
import PclComp from "./componets/pc-comp";
import SclComp from "./componets/sc-comp";
import LclComp from "./componets/lc-comp";
const tableHeight = ref(); // 表格高度
let resource = ref({
checkItem: {
// list: ["报备率", "重点区域巡逻率", "巡逻时长率",'巡逻里程率','盘查人','盘查车','盘查物品','签收率'],
// hasChoose: ["报备率", "重点区域巡逻率", "巡逻时长率",'巡逻里程率']
list: [],
hasChoose: []
}
});
onMounted(() => {
tabHeightFn();
formatValue.value = "YYYY-MM-DD";
getDay();
getTableList();
tabHeightFn();
window.onresize = function () {
tabHeightFn();
};
});
const ssbmdm = ref(""); //给子弹窗传的ssbmdm
const searchType = ref(""); //给子弹窗传的searchType
const pickerOptions = ref({
disabledDate(time) {
return time.getItem > Date.now() - 8.64e6;
}
});
const dialogTitle = ref("");
const listQuery = ref({
pageCurrent: 1,
pageSize: 20,
type: "01",
// searchType: "",
kssj: "",
jssj: ""
// month: "",
// quarter: "",
// year: "",
// ssbmdm: "",
// cxcj: "01"
});
const userInfo = ref(JSON.parse(localStorage.getItem("userInfo")));
const btnVisibe = ref(false);
const rate = ref({});
const liData = ref({});
const loading = ref(false);
const bblPopVisible = ref(false);
const qslPopVisible = ref(false);
const chlPopVisible = ref(false);
const pcrPopVisible = ref(false); //盘查人
const loading2 = ref(false);
const searchDay = ref("");
const dayTypeValue = ref("01");
const dayType = ref("DAY");
const list = ref([]);
const list2 = ref([]);
const tableData = ref([]);
const total = ref(0);
const childTitle = ref(""); //弹窗表格的title
const dateList = ref("");
const TypeValue = ref("daterange");
const formatValue = ref("");
const dayValue = ref(""); //日期的v-model
const quarterList = ref([
{
value: "01",
label: "1季度"
},
{
value: "02",
label: "2季度"
},
{
value: "03",
label: "3季度"
},
{
value: "04",
label: "4季度"
}
]);
// 顶部年月日切换
const dayTypeChange = (val) => {
dayType.value = val;
searchDay.value = "";
listQuery.value.quarter = "";
// listQuery.value.kssj = "";
// listQuery.value.jssj = "";
listQuery.value.month = "";
listQuery.value.year = "";
switch (val) {
case "YEAR":
handleDate("04", "year", "YYYY");
dayValue.value = "";
const d = new Date();
dayTypeValue.value = d.getFullYear();
break;
case "QUARTER":
handleDate("03", "year", "YYYY");
dayValue.value = "";
break;
case "MONTH":
handleDate("02", "month", "YYYY-MM");
dayValue.value = "";
getMonth();
break;
case "DAY":
listQuery.value.type = "01";
getDay();
break;
}
};
// 算汇总率
const changeDataItem = (val) => {
resource.value.checkItem.hasChoose = val;
tableData.value.forEach((item) => {
let hz_bbl = val.includes("报备率") ? item.bbf : 0;
let hz_zdqyxll = val.includes("重点区域巡逻率") ? item.xlf : 0;
let hz_xlscl = val.includes("巡逻时长率") ? item.xlscf : 0;
let hz_xllcl = val.includes("巡逻里程率") ? item.xllcf : 0;
let hz_pcr = val.includes("盘查人") ? item.crf : 0;
let hz_pcc = val.includes("盘查车") ? item.ccf : 0;
let hz_pcwp = val.includes("盘查物品") ? item.cwf : 0;
let hz_qsl = val.includes("签收率") ? item.qsf : 0;
let sxkf = item.sxkf || 0;
let numz = 10 - sxkf.toFixed(2);
item.total = numz < 0 ? 0 : numz;
item.wxl = item.wxl < 0 ? 0 : item.wxl;
item.wbb = item.wbb < 0 ? 0 : item.wbb;
item.hz =
Number(hz_bbl) +
Number(hz_qsl) +
Number(hz_pcwp) +
Number(hz_zdqyxll) +
Number(hz_xlscl) +
Number(hz_xllcl) +
Number(hz_pcr) +
Number(hz_pcc);
});
};
// 点击年月日切换
const handleDate = (type, val, format) => {
listQuery.value.type = type;
TypeValue.value = val;
formatValue.value = format;
};
const quarterChange = (val) => {
listQuery.value.quarter = val;
if (dayType.value == "QUARTER" && listQuery.value.year) {
getTableList(true);
}
};
// 切换天
const dayChange = (val) => {
if (typeof val == "string") {
if (dayType.value == "QUARTER" || dayType.value == "YEAR") {
listQuery.value.year = val;
if (dayType.value == "QUARTER" && listQuery.value.quarter) {
getTableList(true);
}
if (dayType.value == "YEAR") {
getTableList(true);
}
} else {
listQuery.value.month = val;
getTableList(true);
}
listQuery.value.kssj = "";
listQuery.value.jssj = "";
} else {
listQuery.value.kssj = dayValue.value[0];
listQuery.value.jssj = dayValue.value[1];
getTableList(true);
}
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 240;
};
// 导出
function exportExcel() {
const headers = [
"单位名称",
"应报备",
"已报备",
"未报备",
"比例",
"报备扣分",
"应巡逻",
"最少巡逻",
"已巡逻",
"未巡逻",
"巡逻比例",
// "巡逻扣分",
"应巡时长",
"已巡时长",
"未巡时长",
"巡逻时长比例",
// "巡逻时长扣分",
"应巡里程",
"已巡里程",
"未巡里程",
"巡逻里程比例",
// "巡逻里程扣分",
"三项扣分",
"三项得分"
];
const data = tableData.value.map((item) => [
item.ssbm,
item.ybb,
item.sjbb,
item.wbb,
((Number(item.sjbb) / Number(item.ybb)) * 100).toFixed(2) + "%",
item.bbkf,
item.yxl,
item.zsxl,
item.sjxl,
item.wxl,
((Number(item.sjxl) / Number(item.yxl)) * 100).toFixed(2) + "%",
// item.xlkf,
item.yxlsc,
item.sjxlsc,
item.wxlsc,
((Number(item.sjxlsc) / Number(item.yxlsc)) * 100).toFixed(2) + "%",
// item.xlsckf,
item.yxllc,
item.sjxllc,
item.wxllc,
((Number(item.sjxllc) / Number(item.yxllc)) * 100).toFixed(2) + "%",
// item.xllckf,
item.sxkf,
item.total
]);
const worksheet = XLSX.utils.aoa_to_sheet([headers, ...data]);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "sheet1");
XLSX.writeFile(workbook, "绩效考核.xlsx");
// download( "/mosty-api/mosty-jcgl/khtj/export",listQuery.value, `绩效考核_${new Date().getTime()}.xlsx`);
}
// function exportExcelXq() {
// download(
// "/mosty-api/mosty-jcgl/khtj/export",
// listQuery.value,
// `绩效考核_${new Date().getTime()}.xlsx`
// );
// }
// 获取初始化数据
const getTableList = (fyShow) => {
if (fyShow) {
listQuery.value.pageCurrent = 1;
}
JXgetPageList(listQuery.value).then((res) => {
let list = res.records ? res.records : [];
let arr = resource.value.checkItem.hasChoose;
list.forEach((item) => {
let hz_bbl = arr.includes("报备率") ? item.bbf : 0;
let hz_zdqyxll = arr.includes("重点区域巡逻率") ? item.xlf : 0;
let hz_xlscl = arr.includes("巡逻时长率") ? item.xlscf : 0;
let hz_xllcl = arr.includes("巡逻里程率") ? item.xllcf : 0;
let hz_pcr = arr.includes("盘查人") ? item.crf : 0;
let hz_pcc = arr.includes("盘查车") ? item.ccf : 0;
let hz_pcwp = arr.includes("盘查物品") ? item.cwf : 0;
let hz_qsl = arr.includes("签收率") ? item.qsf : 0;
let sxkf = item.sxkf || 0;
let numz = 10 - sxkf.toFixed(2);
item.total = numz < 0 ? 0 : numz;
item.wxl = item.wxl < 0 ? 0 : item.wxl;
item.wbb = item.wbb < 0 ? 0 : item.wbb;
item.hz =
Number(hz_bbl) +
Number(hz_qsl) +
Number(hz_pcwp) +
Number(hz_zdqyxll) +
Number(hz_xlscl) +
Number(hz_xllcl) +
Number(hz_pcr) +
Number(hz_pcc);
});
tableData.value = list;
total.value = res.total;
});
};
// 获取昨天
const getDay = () => {
dayValue.value = [
timeValidate(new Date(), "ymd"),
timeValidate(new Date(), "ymd")
];
listQuery.value.kssj = timeValidate(new Date(), "ymd");
listQuery.value.jssj = timeValidate(new Date(), "ymd");
};
// 获取当前月
const getMonth = () => {
const d = new Date();
const m = d.getMonth() + 1;
dayTypeValue.value = m;
};
// 获取当前季度
const getQuarter = () => {
const d = new Date();
const m = d.getMonth() + 1;
if (m <= 3) {
dayTypeValue.value = "01";
} else if (m <= 6) {
dayTypeValue.value = "02";
} else if (m <= 9) {
dayTypeValue.value = "03";
} else if (m <= 12) {
dayTypeValue.value = "04";
}
};
// 单元格点击事件
const cellClick = (row, column, cell, event) => {
console.log(row, column, cell, event);
listQuery.value.cxcj = "02";
childTitle.value = row.ssbm;
ssbmdm.value = row.ssbmdm;
bblPopVisible.value = false;
qslPopVisible.value = false;
chlPopVisible.value = false;
if (column.label != "单位名称") {
switch (column.property) {
case "ybb":
case "sjbb":
case "wbb":
case "bbbl":
searchType.value = "01";
bblPopVisible.value = true;
break;
case "yxl":
case "sjxl":
case "wxl":
case "xlbl":
searchType.value = "02";
chlPopVisible.value = true;
break;
case "yqs":
case "sjqs":
case "wqs":
case "qsbl":
searchType.value = "03";
qslPopVisible.value = true;
break;
case "ycr":
case "sjcr":
case "wcr":
case "pcrbl":
searchType.value = "04";
pcrPopVisible.value = true;
dialogTitle.value = "盘查人数";
break;
case "ycc":
case "sjcc":
case "wcc":
case "pccbl":
searchType.value = "05";
dialogTitle.value = "盘查车辆";
pcrPopVisible.value = true;
break;
case "yxlsc":
case "sjxlsc":
case "wxlsc":
case "xlscbl":
searchType.value = "06";
dialogTitle.value = "时长详情";
pcrPopVisible.value = true;
break;
case "yxllc":
case "sjxllc":
case "wxllc":
case "xllcbl":
searchType.value = "07";
dialogTitle.value = "里程详情";
pcrPopVisible.value = true;
break;
}
}
};
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getTableList(false);
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageCurrent = currentPage;
getTableList(false);
};
// 重置
const reset = () => {
dayType.value = "DAY";
listQuery.value = {
pageCurrent: 1,
pageSize: 20,
type: "01",
searchType: "",
kssj: "",
jssj: ""
// month: "",
// quarter: "",
// year: "",
// ssbmdm: "",
// cxcj: "01"
};
getDay();
getTableList();
};
const fromattDate = (str) => {
const format = "yyyy-mm-dd hh:mi:ss";
return parseTime(str);
};
// 格式化得分类型
const fromartType = (str) => {
let s = "";
switch (str) {
case 1:
s = "巡逻";
break;
case 2:
s = "报备";
break;
case 3:
s = "指令签收";
break;
default:
s = "巡逻";
break;
}
return s;
};
const upQzrq = () => {};
</script>
<style lang="scss" scoped>
.flexb {
display: flex;
align-items: center;
}
.flexboc {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

View File

@ -0,0 +1,115 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-13 09:54:39
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">详情</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="外出类型"><dict-tag :options="D_QW_WC_LX" :value="data.detail.wcLx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{ data.detail.wcSjKssj + '时' + " — " + data.detail.wcSjJssj + '时' }}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="外出原因">{{data.detail.wcYy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span class="ml10" v-show="item.kqShyj && item.kqShyj !=''"> 审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_WC_LX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_WC_LX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true;
getDataById(id) //根据id查询详情
}
// 根据id查询详情
const getDataById = (id)=>{
loading.value = true;
serviceGet({},`/mosty-qwzx/tbQwWc/selectVOById/${id}`).then(res=>{
data.detail = res;
loading.value = false;
})
}
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,163 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" :loading="loading" @click="submit" v-show="!disabledFoem">保存</el-button>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="data.formData" :rules="rules" :inline="true" :disabled="disabledFoem" label-position="top">
<el-form-item prop="sqrLx" label="申请人类型" class="ww31">
<el-select placeholder="请选择申请人类型" style="width: 100%" v-model="data.formData.sqrLx">
<el-option v-for="dict in D_BZ_SQRLX" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select>
</el-form-item>
<el-form-item prop="sqrXm" label="申请人" class="ww31">
<el-input @click="chooseUserVisible = true" v-model="data.formData.sqrXm" placeholder="请选择申请人" clearable/>
</el-form-item>
<el-form-item prop="wcLx" label="外出类型" class="ww31">
<el-select style="width: 100%" v-model="data.formData.wcLx" filterable placeholder="请选择外出类型" @change="getLc">
<el-option v-for="item in D_QW_WC_LX" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item prop="qzrqForm" required label="起止日期" class="ww31">
<el-date-picker
style="width: 100%"
v-model="data.formData.qzrqForm"
type="datetimerange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="upQzrqForm"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
<el-form-item prop="sfsh" label="是否审核" class="ww31">
<el-select style="width: 100%" v-model="data.formData.sfsh" filterable placeholder="是否审核" @change="getLc">
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
<el-form-item label="审批人" class="ww31" v-if="data.formData.sfsh==1">
<el-input v-model="data.spObj.shryXms" placeholder="请选择审批人" readonly/>
</el-form-item>
<el-form-item label="抄送人" class="ww31">
<el-input v-model="data.spObj.csryXms" placeholder="请选择抄送人" readonly/>
</el-form-item>
<el-form-item label="外出原因" prop="wcYy" class="ww100">
<el-input v-model="data.formData.wcYy" placeholder="请输入外出原因" show-word-limit type="textarea"/>
</el-form-item>
</el-form>
</div>
<ChooseUser v-model="chooseUserVisible" :PoliceType="data.formData.sqrLx == '01' ? 'MJ' : 'FJ'" :Single="true" @choosedPolice="hanlderChoose" />
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import ChooseUser from "@/components/MyComponents/choosePolice";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import {getDifferTime} from "@/utils/tools.js";
import * as rule from "@/utils/rules.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_WC_LX, D_BZ_SQRLX,D_BZ_SF } = proxy.$dict("D_QW_WC_LX", "D_BZ_SQRLX","D_BZ_SF");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const chooseUserVisible = ref(false);//人员弹窗
const loading = ref(false);
const data = reactive({
formData: {sqrLx:"01"},
spObj:{}, //审核对象
});
const rules = reactive({
sqrLx: [{ required: true, message: "请选择申请人类型", trigger: "change" }],
sqrXm: [{ required: true, message: "请选中申请人", trigger: ['blur','change'] }],
wcLx: [{ required: true, message: "请输入外出类型", trigger: "change" }],
qzrqForm: [{ required: true, message: "请选择请假日期", trigger: "blur" }],
wcYy: [{ required: true, message: "请输入外出原因", trigger: "blur" }],
})
// 初始化数据
const init = (type,id)=> {
dialogForm.value = true
if(id){
title.value = '修改'
getDataById(id) //根据id查询详情
}else{
title.value = '新增'
}
}
// 根据id查询详情
const getDataById = (id)=>{
getQwQxjInfo(id).then((res) => {
data.formData = res;
data.formData.qzrqForm = [res.wcSjKssj, res.wcSjJssj];
});
}
//根据请休假时间和外出类型获取配置流程
const getLc = () => {
if(data.formData.wcSjKssj && data.formData.wcSjKssj!='' && data.formData.wcSjJssj && data.formData.wcSjJssj != '' && data.formData.wcLx && data.formData.wcLx!=''){
let arrt = {kqlx:'02',kqywlx:data.formData.wcLx,kqsc:getDifferTime(data.formData.wcSjKssj,data.formData.wcSjJssj,'hour')};
serviceGet(arrt,'/mosty-qwzx/tbQwQxjShlc/selectForAuditsCheck').then(res=>{
data.spObj = res ? res : {};
data.formData.kqShlcId = res?.id;
});
}
};
//时间
function upQzrqForm(val) {
data.formData.wcSjKssj = val.length > 0 ? val[0] : "";
data.formData.wcSjJssj = val.length > 0 ? val[1] : "";
getLc()
}
//选择用户
const hanlderChoose = (users) => {
const user = users[0];
data.formData.sqrXm = user.xm;
data.formData.sqrSsbm = user.ssbm;
data.formData.sqrSsbmdm = user.ssbmdm;
data.formData.sqrSfzh = user.sfzh;
data.formData.sqrLxfs = user.lxdh;
};
// 提交
const submit = ()=>{
elform.value.validate((valid) => {
if (!valid) return false;
if(data.formData.sfsh=='1'){
if(!data.formData.kqShlcId || data.formData.kqShlcId=='') return proxy.$message({type: "warning", message: "暂无相关请休假的流程配置!"});
}else{
delete data.formData.kqShlcId;
}
loading.value = true;
delete data.formData.qzrqForm;
if(title.value == '新增'){
servicePost(data.formData,`/mosty-qwzx/tbQwWc/save`).then(res=>{
proxy.$message({type: "success", message: "申请成功"});
close();
emits('updateDate');
}).catch(()=>{ loading.value = false; })
}
});
}
// 关闭
const close = ()=>{
data.formData={sqrLx:"01"};
data.spObj={}
dialogForm.value = false;
loading.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
</style>

View File

@ -0,0 +1,191 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="外出管理">
<el-button type="primary" @click="addEdit('add', '')">
<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">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search>
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrLx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrLx" :tag="false" />
</template>
<template #wcSjKssj="{ row }">
{{ row.wcSjKssj + '时' + " — " + row.wcSjJssj + '时' }}
</template>
<template #wcLx="{ row }">
<dict-tag :options="D_QW_WC_LX" :value="row.wcLx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="delDictItem(row)">删除</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" @updateDate="getData"/>
<!-- 详情 -->
<Detail ref="detailDialog"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 EditAddForm from './editAddForm.vue';
import Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_WC_LX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_WC_LX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const addEditDialog = ref();
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrLx",
placeholder: "请选择外出类型",
label: "外出类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入申请人姓名",
label: "申请人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "申请人部门", prop: "sqrSsbm" },
{ label: "申请人类型", prop: "sqrLx", showSolt :true},
{ label: "申请人姓名", prop: "sqrXm"},
{ label: "起止日期", prop: "wcSjKssj", showSolt :true, width:"260" },
{ label: "外出类型", prop: "wcLx", showSolt :true },
{ label: "申请时间", prop: "xtCjsj"},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.wcSjKssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.wcSjJssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
let attr = { ...pageData.pageConfiger, ...searchObj.value };
serviceGet(attr,`/mosty-qwzx/tbQwWc/selectPage`).then(res=>{
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
});
}
// 新增
const addEdit = (type,id)=>{
addEditDialog.value.init(type,id)
}
// 新增
const detailHland = (type,id)=>{
detailDialog.value.init(type,id)
}
// 批量删除
function delDictItem(row) {
proxy.$confirm("确定删除该数据?", "警告", { type: "warning" }).then(() => {
serviceDelete({},`/mosty-qwzx/tbQwWc/${row.id}`).then(res=>{
getData();
proxy.$message({ type: "success", message: "删除成功" });
});
}).catch(() => {
proxy.$message.info("已取消");
});
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,145 @@
<!--
* @Author: your name
* @Date: 2024-05-09 19:17:34
* @LastEditTime: 2024-05-13 09:54:23
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \zg_web_new\src\views\backOfficeSystem\kqManagement\qxjsp\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{title}}</span>
<div>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="description pd20" v-loading="loading">
<el-descriptions :column="4" border>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="申请人">{{data.detail.sqrXm}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="外出类型"><dict-tag :options="D_QW_WC_LX" :value="data.detail.wcLx" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="审核状态"><dict-tag :options="D_QW_KQ_SHZT" :value="data.detail.kqShzt" :tag="false" /></el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="2" label="起止时间">{{ data.detail.wcSjKssj + '时' + " — " + data.detail.wcSjJssj + '时' }}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="外出原因">{{data.detail.wcYy}}</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="审批人">
<div class="flex align-center">
<div v-for="(item,index) in data.detail.kqShryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 flex">(<dict-tag :options="D_QW_KQ_SHZT" :value="item.kqShzt" :tag="false" />)</span>
<span class="ml10" v-show="item.kqShyj && item.kqShyj !=''"> 审核意见({{item.kqShyj}})</span>
<span class="ml10 mr10" v-show="index < data.detail.kqShryList.length-1">|</span>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item class-name="my-content" label-class-name="my-label" :span="4" label="抄送人">
<div class="flex align-center flex-warp">
<div v-for="(item,index) in data.detail.kqCsryList" :key="index" class="flex align-center">
<span>{{item.scryXm}}</span>
<span class="ml10 mr10" v-show="index < data.detail.kqCsryList.length-1"></span>
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
<div v-if="title == '审批'" class="flex just-center">
<el-button type="primary" @click="submit('ok')" plain>通过</el-button>
<el-button type="danger" @click="submit('no')" plain>不通过</el-button>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { ref,defineExpose, reactive,getCurrentInstance} from 'vue';
import { ElMessage, ElMessageBox } from "element-plus";
const { proxy } = getCurrentInstance();
const { D_QW_WC_LX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_WC_LX", "D_QW_KQ_SHZT");
const emits = defineEmits(['updateDate'])
const props = defineProps({
dic:{ type:Object, default:{} }
})
const title = ref('新增');
const elform = ref();
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const data = reactive({
detail:{},
});
// 初始化数据
const init = (type,id,val)=> {
dialogForm.value = true;
data.detail = JSON.parse(JSON.stringify(val));
if(type == 'detail') title.value = '详情';
else title.value = '审批';
}
// 同意或者驳回
const spRequset = (status,content)=>{
let params = { kqShzt:status == 'no' ? '03' :'02',id:data.detail.kqShry.id }
if(status == 'no') params.kqShyj = content
servicePost(params,`/mosty-qwzx/tbQwKqScry/audits`).then(res=>{
let text = status == 'no' ? '驳回成功' :'审核成功'
proxy.$message({ type: "success", message: text });
emits('updateDate')
close();
})
}
//审批
const submit = (status) => {
if(status == 'no'){
ElMessageBox.prompt("请输入不通过原因", "不通过原因", {
confirmButtonText:"提交",
cancelButtonText:"取消",
inputPattern:/\S+/,
inputPlaceholder:"请输入不通过原因",
inputErrorMessage:'请输入不通过原因',
}).then((res) => {
let content = res.value
spRequset(status,content)
}).catch(()=>{});
}else{
spRequset(status)
}
};
// 关闭
const close = ()=>{
data.detail={};
dialogForm.value = false;
}
defineExpose({init});
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-descriptions__table{
width: 70%;
margin: 0 auto;
}
.description {
:deep(.my-label) {
width: 140px;
height: 40px;
font-size: 14px;
font-weight: 400;
background-color: #fff;
color: #aaa;
border-color: #ccc !important;
}
:deep(.my-content) {
font-size: 14px;
// background-color: #061b33;
color: #000;
border-color: #ccc !important;
}
.tab-red {
box-shadow: inset 0 0 10px #ff2323;
border: 1px solid #ff2323;
border-radius: 4px;
margin-right: 6px;
}
}
</style>

View File

@ -0,0 +1,168 @@
<template>
<div>
<div class="titleBox">
<!-- 头部 -->
<PageTitle title="外出审批" />
</div>
<!-- 搜索 -->
<div ref="searchBox">
<!-- <Search :searchArr="searchConfiger" @submit="onSearch">
<template #defaultSlot>
<MOSTY.Department width="100%" clearable v-model="searchObj.sqbmdm" />
</template>
</Search> -->
</div>
<!-- 表格 -->
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="pageData.tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="210"
>
<template #sqrLx="{ row }">
<dict-tag :options="D_BZ_SQRLX" :value="row.sqrLx" :tag="false" />
</template>
<template #wcSjKssj="{ row }">
{{ row.wcSjKssj + '时' + " — " + row.wcSjJssj + '时' }}
</template>
<template #wcLx="{ row }">
<dict-tag :options="D_QW_WC_LX" :value="row.wcLx" :tag="false" />
</template>
<template #kqShzt="{ row }">
<dict-tag :options="D_QW_KQ_SHZT" :value="row?.kqShzt" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-link type="primary" @click="detailHland('detail', row.id,row)">详情</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" v-if="row?.kqShry?.kqShzt == '01'" @click="detailHland('sp', row.id,row)">审批</el-link>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="pageData.tableHeight"
:pageConfiger="pageData.pageConfiger"
></Pages>
</div>
<!-- 详情 -->
<Detail ref="detailDialog" @updateDate="getData"/>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
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 Detail from './detail.vue';
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { reactive, ref ,onMounted,getCurrentInstance } from 'vue';
const { proxy } = getCurrentInstance();
const { D_QW_WC_LX, D_BZ_SQRLX, D_QW_KQ_SHZT } = proxy.$dict("D_QW_WC_LX", "D_BZ_SQRLX","D_QW_KQ_SHZT");
const detailDialog = ref();
const ids = ref([]);//多选
const searchBox = ref() //搜索框
let searchObj = ref({}); //搜索数据
const searchConfiger = reactive([
{
showType: "daterange",
prop: "daterangeKey",
defaultVal: "",
label: "起止时间"
},
{
showType: "defaultSlot",
prop: "sqbmdm",
options: [],
placeholder: "请选择单位",
label: "归属单位"
},
{
showType: "select",
prop: "sqrlx",
placeholder: "请选择请假人类型",
label: "请假人类型",
options:D_BZ_SQRLX
},
{
showType: "input",
prop: "sqrXm",
placeholder: "请输入请假人姓名",
label: "请假人姓名"
},
])
const queryFrom = ref({})
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
rowHieght: 61,
loading:false
},
pageConfiger: { //分页
pageCurrent: 1,
pageSize: 20,
total: 0,
},
tableColumn: [
{ label: "申请人部门", prop: "sqrSsbm" },
{ label: "申请人类型", prop: "sqrLx", showSolt :true},
{ label: "申请人姓名", prop: "sqrXm"},
{ label: "起止日期", prop: "wcSjKssj", showSolt :true, width:"260" },
{ label: "外出类型", prop: "wcLx", showSolt :true },
{ label: "申请时间", prop: "xtCjsj"},
{ label: "审核状态", prop: "kqShzt", showSolt :true },
]
});
onMounted(() => {
getData() //获取数据
tabHeightFn();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (obj)=>{
let searchItem = JSON.parse(JSON.stringify(obj));
searchItem.wcSjKssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[0] : null;
searchItem.wcSjJssj = obj.daterangeKey && obj.daterangeKey.length ? obj.daterangeKey[1] : null;
delete searchItem.daterangeKey;
if(obj.cz) searchObj.value.sqbmdm = '';
searchObj.value = {...searchObj.value,...searchItem};
delete searchObj.value.cz;
pageData.pageConfiger.pageCurrent = 1;
getData() //获取数据
}
// 获取数据
const getData = ()=>{
pageData.tableConfiger.loading = true
// let attr = { ...pageData.pageConfiger, ...searchObj.value };
serviceGet(pageData.pageConfiger,`/mosty-qwzx/tbQwWc/selectAuditsWcPage`).then(res=>{
pageData.tableData = res.records || [];
pageData.pageConfiger.total = res.total;
pageData.tableConfiger.loading = false
});
}
// 详情
const detailHland = (type,id,data)=>{
detailDialog.value.init(type,id,data)
}
// 表格高度计算
const tabHeightFn = () => {
pageData.tableHeight = window.innerHeight - searchBox.value.offsetHeight - 244;
window.onresize = function () { tabHeightFn(); };
};
</script>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.3);
}
</style>

View File

@ -0,0 +1,119 @@
<template>
<div v-if="dialogFormVisible" class="dialog">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" @click="onSave" :loading="buttonLoading" >保存</el-button>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="formData" :label-width="110" :rules="rules" :inline="true">
<el-form-item label="班次名称" prop="bcMc" style="width:48%">
<el-input v-model="formData.bcMc" placeholder="请输入班次名称" style="width:100%"></el-input>
</el-form-item>
<el-form-item label="班次类型" prop="bcQwBbzl" style="width:48%">
<MOSTY.Select :dictEnum="props.dic.D_QW_BBZL" placeholder="请选择班次类型" v-model="formData.bcQwBbzl"/>
</el-form-item>
<el-form-item label="开始时间" prop="bcKssj" style="width:48%">
<el-time-picker v-model="formData.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss" placeholder="请输入开始时间" style="width:100%;"></el-time-picker>
</el-form-item>
<el-form-item prop="bcKtsDict" label="跨天数" style="width:48%">
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" placeholder="请输入跨天数" v-model="formData.bcKtsDict"/>
</el-form-item>
<el-form-item label="结束时间" prop="bcJssj" style="width:48%">
<el-time-picker v-model="formData.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss" placeholder="请输入结束时间" style="width:100%;"></el-time-picker>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { serviceGet, servicePost } from "@/api/serviceApi.js"; bcglUpdate
import { bcglSave,bcglUpdate} from '@/api/lzqwzx/index'
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import { ref, reactive ,defineEmits,defineProps,getCurrentInstance, onMounted} from "vue";
const props = defineProps({
dic: { type: Object, default: {} }
});
const emits = defineEmits(["updateList"]);
const { proxy } = getCurrentInstance();
const dialogFormVisible = ref(false);
const title = ref("");
const buttonLoading = ref(false);
const elform = ref(null);
const formDefault = ref({});
const formData = ref({
bcQwBbzl:'01',
bcKssj:'00:00:00',
bcJssj:'23:59:59',
bcKtsDict:'01'
});
const rules = reactive({
bcMc: [{ required: true, message: "请输入班次名称", trigger: "blur" }],
bcQwBbzl: [{ required: true, message: "请选择班次类型", trigger: "change" }],
bcKssj: [{ required: true, message: "请选择时间", trigger: "change" }],
bcKtsDict: [{ required: true, message: "请选择跨天数", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
});
onMounted(()=>{
formDefault.value = JSON.parse(JSON.stringify(formData.value))
})
const handleChange = (val) => {
formData.value.tpid = val
};
const handleChange1 = (val) => {
formData.value.dwYz = val
};
// 审核
const init = (type, row) => {
dialogFormVisible.value = true;
title.value = type == "add" ? "新增" : "编辑";
if(row) formData.value = JSON.parse(JSON.stringify(row));
};
// 新增
const onSave = () => {
elform.value.validate((valid) => {
if (!valid) return;
buttonLoading.value = true;
if ( title.value == '新增') {
bcglSave(formData.value).then(res => {
buttonLoading.value = false;
proxy.$message.success(`${title.value}成功`);
emits("updateList", {});
closeDialog();
}).catch(() => {
console.log("添加出错");
}).finally(() => { buttonLoading.value = false;})
} else {
bcglUpdate(formData.value).then(res => {
buttonLoading.value = false;
proxy.$message.success(`${title.value}成功`);
emits("updateList", {});
closeDialog();
}).catch(() => {
console.log("修改出错");
}).finally(() => { buttonLoading.value = false;})
}
// let url = title.value == '新增' ? '/tbQwglQwbc/save':'/tbQwglQwbc/update';
// servicePost(formData.value, `/mosty-qwzx${url}`).then((res) => {
// buttonLoading.value = false;
// proxy.$message.success(`${title.value}成功`);
// emits("updateList", {});
// closeDialog();
// }).catch(() => {
// buttonLoading.value = false;
// });
});
};
// 关闭弹窗
const closeDialog = () => {
formData.value = JSON.parse(JSON.stringify(formDefault.value))
dialogFormVisible.value = false;
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,178 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title"></div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #bcQwBbzl="{ row }">
<dict-tag :options="D_QW_BBZL" :value="row.bcQwBbzl" :tag="false"></dict-tag>
</template>
<template #bcKtsDict="{ row }">
<dict-tag :options="D_QW_BC_KTS" :value="row.bcKtsDict" :tag="false"></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{ ...pageData.pageConfiger, total: pageData.total}" />
</div>
</div>
</div>
<!-- 新增编辑 -->
<EditAddForm @updateList="onSearch" ref="addEditForm" :dic="{D_QW_BC_KTS,D_QW_BBZL}"/>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from './editAddForm.vue'
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import { bcglDelete,bcglSelectPage} from '@/api/lzqwzx/index'
import * as rule from "@/utils/rules.js";
import { ElMessage } from "element-plus";
import { ref, reactive, computed, watch, onMounted, getCurrentInstance, onUnmounted } from "vue";
const { proxy } = getCurrentInstance();
const { D_QW_BBZL,D_QW_BC_KTS } = proxy.$dict("D_QW_BBZL","D_QW_BC_KTS");
const addEditForm = ref()
const searchConfiger = reactive([
{
showType: "input",
prop: "bcMc",
placeholder: "请输入班次名称",
label: "班次名称"
},
{
showType: "select",
prop: "bcQwBbzl",
placeholder: "请选择班次类型",
label: "班次类型",
options:D_QW_BBZL
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "班次名称", prop: "bcMc" },
{ label: "班次类型", prop: "bcQwBbzl",showSolt: true },
{ label: "开始时间", prop: "bcKssj" },
{ label: "结束时间", prop: "bcJssj" },
{ label: "跨越天数", prop: "bcKtsDict",showSolt: true },
]
});
const loading = ref(false)
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
bcglSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
bcglDelete(id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
}).catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () { tabHeightFn(); };
};
// 修改数据
const addEdit = (type,row) =>{
addEditForm.value.init(type,row)
}
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,97 @@
<template>
<div style="width:100%;height:100%" ref="barEchrats"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted, defineProps, watchEffect, nextTick } from "vue";
const props = defineProps({
data: {
type: Array,
default: []
},
Xdata: {
type: Array,
default: []
},
colorList: {
type: Array,
default: [
["#4285f4", "#4285f4", "#4285f4"],
["#34B877", "#34B877", "#34B877"],
["#01C2FF", "#01C2FF", "#01C2FF"]
]
}
});
const barEchrats = ref();
const initEchrats = (data, Xdata) => {
const options = {
grid: {
top: "10%",
left: "10%",
bottom: "15%",
right: "10%",
containLabel: true
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
xAxis: [
{
axisLine: {
show: true,
lineStyle: {
type: "solid",
width: "1"
}
},
axisTick: {
show: false
},
axisLabel: {
color: "#000"
},
data: Xdata
}
],
yAxis: [
{
nameTextStyle: {
fontSize: 13 // y轴name的样式调整
},
splitLine: {
show: true, // 不显示网格线
lineStyle: {
color: "rgba(15,36,90,0.4)",
type: "dashed"
}
},
axisLabel: {
color: "#000"
},
type: "value"
}
],
series: data
};
var myChart = echarts.init(barEchrats.value);
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data && props.Xdata) {
nextTick(() => {
initEchrats(props.data, props.Xdata); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,337 @@
<template>
<div>
<el-dialog
:title="titleValue"
width="1400px"
v-model="modelValue"
@close="closed"
>
<div v-if="modelValue">
<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
v-model="listQuery.jczmc"
placeholder="请输入检查站名称"
clearable
/>
</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" style="margin-top: 0px" v-if="modelValue">
<el-table
ref="multipleUserRef"
@selection-change="handleSelectionChange"
:data="tableData"
:highlight-current-row="props.Single"
border
v-loading="loading"
style="width: 100%"
:row-key="keyid"
height="450"
>
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
v-if="!props.Single"
/>
<el-table-column width="55" #default="{ row }" v-else>
<el-radio v-model="ridioIndex" :label="row.id"></el-radio>
</el-table-column>
<el-table-column
label="序号"
type="index"
align="center"
sortable
width="80"
/>
<el-table-column
sortable
prop="ssbm"
label="所属部门"
show-overflow-tooltip
align="center"
></el-table-column>
<el-table-column
sortable
prop="jczmc"
show-overflow-tooltip
align="center"
label="检查站名称"
>
</el-table-column>
<el-table-column
show-overflow-tooltip
align="center"
label="检查站类型"
prop="jczlx"
>
<template #default="{ row }">
<dict-tag
:options="D_BZ_JCZLX"
:value="row.jczlx"
:tag="false"
/>
</template>
</el-table-column>
<el-table-column
prop="xxdz"
show-overflow-tooltip
align="center"
label="检查站地址"
>
</el-table-column>
<el-table-column
sortable
prop="jd"
show-overflow-tooltip
label="经度"
align="center"
>
</el-table-column>
<el-table-column
sortable
prop="wd"
show-overflow-tooltip
label="纬度"
align="center"
>
</el-table-column>
</el-table>
</div>
<div class="fenye" >
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.pageCurrent"
:page-sizes="[2, 5, 10, 20]"
:page-size="listQuery.pageSize"
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>
</div>
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import { JczSelectJczList } from "@/api/lzjcz/index.js";
import {
defineProps,
watch,
ref,
onMounted,
nextTick,
getCurrentInstance
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_JCZLX } = proxy.$dict("D_BZ_JCZLX");
const props = defineProps({
//是否显示
modelValue: {
type: Boolean,
required: true
},
//标题
titleValue: {
type: String,
default: "选择检查站"
},
//是否单选
Single: {
type: Boolean,
default: false
},
//已经选中得数据回显
data: {
type: Array,
default: []
}
});
const keyid = (row) => {
return row.id;
};
const ridioIndex = ref(null);
const total = ref(0);
const listQuery = ref({
pageCurrent: 1,
pageSize: 20,
jczmc: "",
ssbmdm: ""
});
const form = ref({});
const tableData = ref([]);
const loading = ref(false)
const emits = defineEmits(["update:modelValue", "choosedJcz"]);
const closed = () => {
listQuery.value.jczmc = "";
emits("update:modelValue", false);
};
const reset = () => {
listQuery.value = {
pageCurrent: 1,
pageSize: 20,
jczmc: "",
ssbmdm: ""
};
getListData();
};
// 判断传进来的选中数据和加载的选中数据不满足的数据
const checkopenList = ref([]);
// 确定选中
const onComfirm = () => {
//单选
if (props.Single) {
if (![ridioIndex.value][0]) {
proxy.$message.warning("请选择检查站");
return;
}
const info = tableData.value.find((item) => {
return item.id === ridioIndex.value;
});
emits("choosedJcz", [JSON.parse(JSON.stringify(info))]);
} else {
//多选
const jczList = JSON.parse(JSON.stringify(multipleSelectionUser.value));
if (jczList.length === 0) {
proxy.$message.warning("请选择检查站");
return;
}
emits("choosedJcz", [...jczList, ...checkopenList.value]);
}
closed();
};
onMounted(() => {
getListData();
});
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageCurrent = currentPage;
getListData();
};
//检查站数据
const getListData = async () => {
loading.value = true
JczSelectJczList(listQuery.value).then((res) => {
tableData.value = res?.records;
loading.value = false
multipleUser(props.data, tableData.value);
total.value = Number(res.total);
}).catch(()=>{ loading.value = false });
};
const handleFilter = () => {
listQuery.value.pageCurrent = 1;
getListData();
};
const multipleUserRef = ref(null);
const multipleSelectionUser = ref([]);
const handleSelectionChange = (val) => {
multipleSelectionUser.value = val;
if (checkopenList.value) {
for (let i = 0; i < multipleSelectionUser.value.length; i++) {
const l = multipleSelectionUser.value[i];
for (let j = 0; j < checkopenList.value.length; j++) {
const z = checkopenList.value[j];
if (l.id == z.id) {
checkopenList.value.splice(j, 1);
}
}
}
}
};
//回显--用于多选表格
function multipleUser(row, list) {
if (row) {
if (props.Single) {
row.forEach((item) => {
list.forEach((select) => {
if (typeof item == "object") {
if (item.id == select.id) {
ridioIndex.value = item.id;
}
} else {
if (item == select.id) {
ridioIndex.value = item;
}
}
});
});
} else {
row.forEach((item) => {
list.forEach((select) => {
if (item.id == select.id) {
if (multipleUserRef.value) {
multipleUserRef.value.toggleRowSelection(select, true);
}
}
});
});
}
}
}
watch(
() => props.modelValue,
(val) => {
if (val === true) {
ridioIndex.value = "";
handleFilter();
}
}
);
watch(
() => props.data,
(val) => {
if (multipleUserRef.value) multipleUser(val, tableData.value);
checkopenList.value = JSON.parse(JSON.stringify(val));
}
);
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
::v-deep .el-form--inline {
padding-left: 0 !important;
}
::v-deep .el-radio__label {
display: none;
}
::v-deep .el-table__body tr.current-row > td.el-table__cell {
background: #106fdc;
}
</style>

View File

@ -0,0 +1,416 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree width="300px" placeholder="管理部门ID" @changeSsbm='changeSsbm' clearable filterable :isBmId="true" v-model="listQuery.ssbmdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构{{ssbmmc}}</div>
<div class="flex align-center">
<div class="flex align-center" style="margin-right:10px">
<div>是否包含:</div>
<el-select style="flex:1" v-model="listQuery.isChild" placeholder="请选择是否包含">
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="flex align-center">
<div>查询时间:</div>
<div class="time_box">
<div class="item_time" :class="activeIndex==index?'active_timebg':''" @click="changeTime(item,index)" v-for="(item,index) in timeArr" :key="item">{{item}}</div>
</div>
<el-date-picker v-if="listQuery.dateType=='04'" value-format="YYYY-MM-DD" @change='zdyChangeTime' v-model="zdyTime" type="daterange" range-separator="To" start-placeholder="开始时间" end-placeholder="结束时间" />
</div>
<el-button type='primary' @click="searchFn">搜索</el-button>
</div>
</div>
<div class="echartsBox">
<!-- 第一模块 -->
<ul class="itemBox">
<li class="item" v-for="item in date.oneList" :key="item.label">
<div class="ItemTitle">{{item.label}}</div>
<div class="echartsCnt">
<BatteryEharts v-if="item.value.length>0" :data='item.value' />
</div>
</li>
</ul>
<!-- 第2模块 -->
<ul class="itemBoxSmall">
<li class="item" v-for="item in date.twoList" :key="item.label">
<div class="ItemTitle">{{item.label}}</div>
<ul class="itemCnt">
<li class="itemCntChild" v-for="(it,idx) in item.list" :key="idx">
<span class="icon"><img :src="it.icon" alt="" :style="{width:idx==2?'26px':'30px'}"></span>
<span class="title">{{it.title}} :</span>
<span class="num">{{it.num}} {{it.dw}}</span>
</li>
</ul>
</li>
</ul>
<div class="itemBoxBottom">
<Tablelist :headerShow='false'
:dic="{D_QW_BBZT, D_BZ_PDDTLX, D_BZ_RYMFJLB, D_BZ_RYJZLB, D_QW_BC_KTS, D_BZ_RYZBBBZW, D_QW_BBZL, D_BZ_SF, D_QW_XQLB, D_QW_XQLX, D_JCGL_ZDSB_SBLB, D_JCGL_ZDSB_SBLX, D_JCGL_JYCL_JYJTGJLB, D_JCGL_JYCL_JYJTFWLB, D_BZ_RYXFBBZW, D_BZ_XLFS, D_BZ_WZLX, D_BZ_ZZLX, D_JCGL_JYQX_QXLX}" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import BatteryEharts from "@/views/backOfficeSystem/qwManagement/qwts/components/batteryEharts.vue";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/qwts/components/barEcharts.vue";
import { timeValidate } from "@/utils/tools.js";
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import LineEcharts from "@/views/backOfficeSystem/qwManagement/qwts/components/lineEcharts.vue";
import Tablelist from "@/views/backOfficeSystem/qwManagement/qwgl/tablelist.vue";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const {
D_QW_BBZT,
D_BZ_PDDTLX,
D_BZ_RYMFJLB,
D_BZ_RYJZLB,
D_QW_BC_KTS,
D_BZ_RYZBBBZW,
D_QW_BBZL,
D_BZ_SF,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTGJLB,
D_JCGL_JYCL_JYJTFWLB,
D_BZ_RYXFBBZW,
D_BZ_XLFS,
D_BZ_WZLX,
D_BZ_ZZLX,
D_JCGL_JYQX_QXLX
} = proxy.$dict(
"D_QW_BBZT",
"D_BZ_PDDTLX",
"D_BZ_RYMFJLB",
"D_BZ_RYJZLB",
"D_QW_BC_KTS",
"D_BZ_RYZBBBZW",
"D_QW_BBZL",
"D_BZ_SF",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_ZDSB_SBLX",
"D_JCGL_JYCL_JYJTGJLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_BZ_RYXFBBZW",
"D_BZ_XLFS",
"D_BZ_WZLX",
"D_BZ_ZZLX",
"D_JCGL_JYQX_QXLX"
);
const deptId = JSON.parse(localStorage.getItem("deptId"));
const activeIndex = ref();
const listQuery = ref({
// tjrq: "2024-08-13", //单日统计
tjrq: timeValidate(new Date(), "ymd"), //单日统计
dateType: "03",
ssbmdm: deptId[0].deptCode
});
const zdyTime = ref([]);
const timeArr = ref(["当日", "当周", "当月", "自定义"]);
const ssbmmc = ref(deptId[0].deptName);
const date = reactive({
oneList: [
{ label: "街面警力", value: [] },
{ label: "可抽调警力", value: [] },
{ label: "报备警力", value: [] },
{ label: "报备总量", value: [] }
],
twoList: [
{
label: "峰值00:00:00 ~ 235959",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
},
{
label: "报备总量",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
}
]
});
// 获取上面柱状图的数据
const handleJlData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDateJYBMFCCount"
).then((res) => {
date.oneList[0].value = [res.jmjlMjsl, res.jmjlFjsl, res.jmjlClsl];
date.oneList[1].value = [res.yjkcdjlMjsl, res.yjkcdjlFjsl, res.yjkcdjlClsl];
date.oneList[2].value = [res.bbjlMjsl, res.bbjlFjsl, res.bbjlClsl];
date.oneList[3].value = [res.bbzlMjsl, res.bbzlFjsl, res.bbzlClsl];
});
};
// 获取中间柱状图的数据
const handleFzData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDateMFCPartCount"
).then((res) => {
date.twoList[0].list[0].num = res.fzMjsl;
date.twoList[0].list[1].num = res.fzFjsl;
date.twoList[0].list[2].num = res.fzClsl;
date.twoList[1].list[0].num = res.gzMjsl;
date.twoList[1].list[1].num = res.gzFjsl;
date.twoList[1].list[2].num = res.gzClsl;
});
};
const changeTime = (item, index) => {
console.log(item, "item");
activeIndex.value = index;
switch (item) {
case "当日":
listQuery.value.dateType = "03";
break;
case "当周":
listQuery.value.dateType = "02";
break;
case "当月":
listQuery.value.dateType = "01";
break;
case "自定义":
listQuery.value.dateType = "04";
break;
}
};
// 自定义时间
const zdyChangeTime = (val) => {
listQuery.value.ksrq = val[0];
listQuery.value.jsrq = val[1];
};
const changeSfbhFn = (val) => {
handleJlData();
handleFzData();
};
const searchFn = () => {
// if (listQuery.value.ksrq && listQuery.value.jsrq) {
// listQuery.value.tjrq = "";
// }
handleJlData();
handleFzData();
};
const changeSsbm = (val) => {
ssbmmc.value = val.orgName;
listQuery.value.ssbmdm = val.orgCode;
handleJlData();
handleFzData();
};
onMounted(() => {
handleJlData();
handleFzData();
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
font-size: 16px;
.tableCnt {
flex: 1;
margin-left: 10px;
.echartsBox {
height: calc(100% - 50px);
display: flex;
flex-direction: column;
.itemBox {
flex: 1;
display: flex;
height: 100%;
margin: 2px 0;
}
.itemBoxSmall {
height: 110px;
display: flex;
margin: 2px 0;
border-bottom: 1px solid #ccc;
}
.itemBoxBottom {
height: 460px;
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: calc(100% - 30px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
li {
display: flex;
.head {
width: 50%;
background: #f0f0f0;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
font-size: 16px;
line-height: 30px;
}
.num {
width: 50%;
line-height: 30px;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
border: 1px solid #f0f0f0;
border-top: 0;
}
.num1 {
border-right: 0;
}
}
.numlabel {
width: 80px;
text-align: center;
font-size: 14px;
white-space: nowrap;
border: 1px solid #cac8c8;
background: #f0f0f0;
line-height: 38px;
border-top: 0;
}
.topNum {
border-top: 1px solid #cac8c8;
}
.numValue {
width: calc(100% - 80px);
line-height: 38px;
span {
border: 1px solid #cac8c8;
font-size: 14px;
display: inline-block;
width: calc(100% / 24);
text-align: center;
border-top: 0;
border-left: 0;
white-space: nowrap;
}
.topSpan {
border-top: 1px solid #cac8c8;
}
}
}
.itemCnt {
width: 100%;
display: flex;
flex-wrap: wrap;
overflow: hidden;
.itemCntChild {
width: 50%;
padding: 5px 20px;
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
.icon {
display: inline-block;
text-align: center;
width: 30px;
}
.title {
color: #000;
font-size: 14px;
margin: 0 12px;
white-space: nowrap;
}
.num {
color: #142232;
font-size: 16px;
white-space: nowrap;
}
}
}
.item {
flex: 1;
height: 100%;
margin: 0 2px;
}
}
}
}
.time_box {
display: flex;
.item_time {
background: skyblue;
border-radius: 4px;
text-align: center;
font-size: 12px;
padding: 4px;
margin: 0 2px;
}
}
.active_timebg {
background: #39adc4 !important;
}
</style>

View File

@ -0,0 +1,160 @@
<template>
<!-- 勤务作息编辑新增 -->
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" @click="onSave" :loading="buttonLoading">保存</el-button>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="mt20">
<el-form ref="formRef" :label-width="180" :model="formData" :rules="rules" inline>
<div class="pl10 pr10 pt40 pb40">
<el-form-item style="width: 48%" class="form-item" prop="xxMc" label="学校名称">
<MOSTY.Other placeholder="请输入学校名称" v-model="formData.xxMc" style="width: 100%" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="xxLx" label="学校类型">
<MOSTY.Select :dictEnum="props.dic.D_NBGL_NBHY_XXLX" placeholder="请选择学校类型" v-model="formData.xxLx" />
</el-form-item>
<el-form-item style="width: 100%" class="form-item" prop="xxDz" label="学校地址">
<MOSTY.Other placeholder="请输入学校地址" v-model="formData.xxDz" style="width: 100%" />
</el-form-item>
<el-divider content-position="left">
<div class="flex align-center"><span class="f18 mr4">时间段</span><el-icon @click="addTime" :size="24"><CirclePlus/></el-icon></div>
</el-divider>
<div class="ww100 flex align-center pl10 mb10" v-for="(item,idx) in formData.sdList" :key="idx">
<el-time-select class="ml20" v-model="item.kssj" start="00:00" end="23:59" step="00:30" :max-time="item.jssj" placeholder="开始时段"></el-time-select>
<el-time-select class="ml20" v-model="item.jssj" start="00:00" end="23:59" step="00:30" :min-time="item.kssj" placeholder="结束时段"></el-time-select>
<el-icon class="ml20" @click="deleteTime(idx)" :size="24"><CircleClose/></el-icon>
</div>
<el-form-item style="width: 48%" class="form-item" prop="sfHxdjl" label="护校队是否建立">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="护校队是否建立" v-model="formData.sfHxdjl" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfYjbjzbaz" label="一键报警装备是否安装">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="一键报警装备是否安装" v-model="formData.sfYjbjzbaz" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfSpjkaz" label="视频监控是否安装">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="视频监控是否安装" v-model="formData.sfSpjkaz" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfLsfbsgl" label="是否落实封闭式管理">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="是否落实封闭式管理" v-model="formData.sfLsfbsgl" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfAzfclczzz" label="是否安装防车辆冲撞装置 ">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="是否安装防车辆冲撞装置 " v-model="formData.sfAzfclczzz" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfJlxsfqlzd" label="是否建立学生防欺凌制度 ">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="是否建立学生防欺凌制度 " v-model="formData.sfJlxsfqlzd" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="sfZdnbhy" label="是否重点内保行业 ">
<MOSTY.Select :dictEnum="props.dic.D_BZ_SF" placeholder="是否重点内保行业 " v-model="formData.sfZdnbhy" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="zdnbhyDj" label="重点内保行业等级 ">
<MOSTY.Select :dictEnum="props.dic.D_NBGL_NBHY_ZDNBHYDJ" placeholder="重点内保行业等级 " v-model="formData.zdnbhyDj" />
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import {hxgId,hxgSave,hxgUpdate } from "@/api/lzqwzx/index.js";
import { reactive, ref, getCurrentInstance, defineEmits } from "vue";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
const props = defineProps({
dic: Object
});
const { proxy } = getCurrentInstance();
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
const formData = ref({});
const title = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
xxMc: [{ required: true, message: "请输入学校名称", trigger: "blur" }],
});
/** 初始化数据 */
const init = (type, row) => {
title.value = type == 'add' ? '新增护学岗':'编辑护学岗'
isShowDialog.value = true;
if(row){
hxgId(row.id).then((res) => {
formData.value = res;
})
}
};
// 新增加时间
const addTime = () =>{
if(!formData.value.sdList) formData.value.sdList = [];
formData.value.sdList.push({})
}
// 删除数据
const deleteTime = (idx) =>{
formData.value.sdList.splice(idx,1)
}
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 保存
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let params = { ...formData.value };
params.sdList = params.sdList.map(it=>{
it.kssj = it.kssj.slice(0,5)+':00';
it.jssj = it.jssj.slice(0,5)+':00';
return it;
})
let text = title.value =='新增护学岗' ? "新增成功" : "编辑成功";
if (title.value =='新增护学岗') {
hxgSave(params).then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
}).catch(() => {
loading.value = false;
});
} else {
hxgUpdate(params).then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
}).catch(() => {
loading.value = false;
});
}
});
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,196 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">护学岗</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', null)">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #xxLx="{ row }">
<dict-tag :options="D_NBGL_NBHY_XXLX" :value="row.xxLx" :tag="false"></dict-tag>
</template>
<template #sdList="{ row }">
<div v-for="(it,idxx) in row.sdList" :key="idxx"> {{it.kssj}} - {{it.jssj}} </div>
</template>
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" :dic="{D_NBGL_NBHY_XXLX,D_BZ_SF,D_NBGL_NBHY_ZDNBHYDJ}" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import Search from "@/components/aboutTable/Search.vue";
import {hxgSelectPage,hxgDelete} from "@/api/lzqwzx/index.js";
import { ElMessage } from "element-plus";
import EditAddForm from "./editAddForm.vue";
const { proxy } = getCurrentInstance();
const { D_NBGL_NBHY_XXLX,D_BZ_SF,D_NBGL_NBHY_ZDNBHYDJ } = proxy.$dict( "D_NBGL_NBHY_XXLX","D_BZ_SF","D_NBGL_NBHY_ZDNBHYDJ");
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "xxMc",
placeholder: "请输入学校名称",
label: "学校名称"
},
{
showType: "select",
prop: "xxLx",
placeholder: "请输选择学校类型",
label: "学校类型",
options:D_NBGL_NBHY_XXLX
},
]);
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{
label: "学校名称",
prop: "xxMc",
showOverflowTooltip: true,
},
{
label: "学校类型",
prop: "xxLx",
showSolt:true
},
{
label: "时间段",
prop: "sdList",
showSolt:true
},
{
label: "学校地址",
prop: "xxDz",
showOverflowTooltip: true,
},
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = false;
hxgSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy.$confirm("确定要注销", "警告", { type: "warning" }).then(() => {
hxgDelete(id).then((res) => {
proxy.$message.success("注销成功");
getList({});
});
}).catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<!-- 勤务作息编辑新增 -->
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" @click="onSave" :loading="buttonLoading">保存</el-button>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="mt20">
<el-form ref="formRef" :label-width="140" :model="formData" :rules="rules" inline>
<div class="pl10 pr10 pt40 pb40">
<el-form-item label="所属部门" style="width: 48%" prop="ssbmdm">
<MOSTY.Department width="100%" clearable v-model="formData.ssbmdm"/>
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="jwzMc" label="警务站名称">
<MOSTY.Other placeholder="请输入警务站名称" v-model="formData.jwzMc" style="width: 100%" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="jwzLx" label="警务站类型">
<MOSTY.Select :dictEnum="props.dic.D_BZ_JWZLX" placeholder="请选择警务站类型" v-model="formData.jwzLx" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="xjSj" label="建立时间">
<el-date-picker
v-model="formData.xjSj"
type="date"
placeholder="选择日期"
format="YYYY-MM-DD"
/>
</el-form-item>
<el-form-item style="width: 100%" class="form-item" prop="jwzDz" label="详细地址">
<MOSTY.Other placeholder="请输入详细地址址" v-model="formData.jwzDz" style="width: 100%" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="fzrXm" label="负责人">
<MOSTY.Other placeholder="请输入负责人" @click="configerUser.chooseUserVisible = true;" readonly v-model="formData.fzrXm" style="width: 100%" />
</el-form-item>
<el-form-item style="width: 48%" class="form-item" prop="fzrSfzh" label="负责人身份证号码">
<MOSTY.Other placeholder="请输入负责人身份证号码" readonly v-model="formData.fzrSfzh" style="width: 100%" />
</el-form-item>
<el-form-item class="one" prop="jd" label="坐标位置">
<div class="flex">
<el-input v-model="formData.jd" clearable style="width: 45%"/>
<el-input v-model="formData.wd" clearable style="width: 45%"/>
<el-button @click="chackLat">选取坐标</el-button>
</div>
</el-form-item>
<!-- <el-form-item prop="xfqyList" label="巡区边界" @change="yfzChange" style="width: 100%" >
<el-input v-model="formData.xfqyList" clearable style="width: 70%" />
<el-button @click="chackLatY('xfqyList')">开始绘制</el-button>
</el-form-item> -->
<el-form-item class="one">
<div class="map"><GdMap /> </div>
</el-form-item>
</div>
</el-form>
</div>
<ChooseUser
:PoliceType="configerUser.PoliceType"
v-if="configerUser.chooseUserVisible"
v-model="configerUser.chooseUserVisible"
rowKey="sfzh"
:Single="true"
:defaultSelectKeys="configerUser.chooseUser"
@choosedPolice="hanlderChoose"
/>
</div>
</template>
<script setup>
import GdMap from "@/components/GdMap/index.vue";
import emitter from "@/utils/eventBus.js";
import { JwzAddJwz,JwzUpdateJwz ,JwzselectByid } from "@/api/lzjmxf/index.js";
import { reactive, ref, getCurrentInstance, defineEmits, onMounted } from "vue";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import ChooseUser from "@/components/MyComponents/choosePolice";
const props = defineProps({
dic: Object
});
const configerUser = reactive({ //选择人员配置
chooseUserVisible:false,
titleValue: "人员选择",
PoliceType:"MJ",
chooseUser:[],
});
const { proxy } = getCurrentInstance();
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
const formData = ref({});
const title = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
jwzMc: [{ required: true, message: "请输入警务站名称", trigger: "blur" }],
ssbmdm: [{ required: true, message: "请选择所属部门", trigger: "blur" }],
});
/**部门id对照对象 */
let departmentIdObj = {};
onMounted(()=>{
emitter.on("coordString", (res) => {
if (res.type === "polygon") formData.value.xfqyList = res.coord[0];
});
emitter.on("coordString", (res) => {
if (res.type === "point") {
formData.value.jd = res.coord[0];
formData.value.wd = res.coord[1];
}
});
})
const hanlderChoose = (val) => {
formData.value.fzrXm = val[0].xm;
formData.value.fzrSfzh = val[0].sfzh;
};
/** 初始化数据 */
const init = (type, row) => {
title.value = type == 'add' ? '新增警务站':'编辑警务站'
isShowDialog.value = true;
if(row){
JwzselectByid({id:row.jwzId}).then((res) => {
formData.value = res;
console.log(res);
hshow(res)
})
}
};
//获取经纬度 - 圈层范围清空
function chackLat(type) {
formData.value.jd = "";
formData.value.wd = "";
emitter.emit("deletePointArea", "jcz_ht");
emitter.emit("drawShape", { type: "point", flag: "jcz_ht" ,isclear:true});
}
// 回显
const hshow=(res)=>{
if (res.jd && res.wd) {
setTimeout(() => {
emitter.emit("addPointArea", { coords: [res], icon: require("@/assets/point/jwz.png"), flag: "jwz" });
emitter.emit("setMapCenter", { location: [res.jd, res.wd], zoomLevel: 14 });
if(res.xfqyList){
let obj = { position:[res.xfqyList]}
emitter.emit("echoPlane", { type:'polygon', coords: [obj], flag: "xfqyList",isclear: false });
}
}, 1000);
}
}
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 保存
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let text = title.value =='新增警务站' ? "新增成功" : "编辑成功";
let params = { ...formData.value }
if (title.value =='新增警务站') {
JwzAddJwz(params).then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
}).catch(() => {
loading.value = false;
});
} else {
JwzUpdateJwz(params).then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
}).catch(() => {
loading.value = false;
});
}
let url = title.value =='新增警务站' ? "/mosty-jcgl/tbJcglJwz/addJwz" : "/mosty-jcgl/tbJcglJwz/updateJwz";
});
};
// function chackLatY(type) {
// emitter.emit("deletePointArea",type); //清除巡防区高亮
// emitter.emit("drawShape", { type: "polygon", flag: type, isclear:false});
// formData.value[type] = "";
// console.log(formData.value);
// // form.value[type] = "";
// }
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
.map{
width: 100%;
height: 500px;
}
</style>

View File

@ -0,0 +1,182 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">警务站</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', null)">
<el-icon><CirclePlus /></el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #jwzLx="{ row }">
<dict-tag :options="D_BZ_JWZLX" :value="row.jwzLx" :tag="false"></dict-tag>
</template>
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.jwzId)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" :dic="{D_BZ_JWZLX}" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import Search from "@/components/aboutTable/Search.vue";
import { JwzselectJwzList,JwzDeleteJwz } from "@/api/lzjmxf/index.js";
import { ElMessage } from "element-plus";
import EditAddForm from "./editAddForm.vue";
const { proxy } = getCurrentInstance();
const { D_BZ_JWZLX } = proxy.$dict( "D_BZ_JWZLX");
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "jwzMc",
placeholder: "请输入警务站名称",
label: "警务站名称"
},
]);
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageNo: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{
label: "警务站名称",
prop: "jwzMc",
showOverflowTooltip: true,
},
{
label: "警务站类型",
prop: "jwzLx",
showSolt:true
},
{
label: "负责人姓名",
prop: "fzrXm",
},
{
label: "建立时间",
prop: "xjSj",
},
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
const onSearch = (val) => {
pageData.pageConfiger.pageNo = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageNo = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = false;
JwzselectJwzList(params).then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy.$confirm("确定要注销", "警告", { type: "warning" }).then(() => {
JwzDeleteJwz([id], "/mosty-jcgl/tbJcglJwz/deleteJwz").then((res) => {
proxy.$message.success("注销成功");
getList({});
});
}).catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,546 @@
<template>
<div class="dialog" v-if="isShowDialog">
<el-form ref="formRef" :model="formData" :rules="rules">
<div class="bblxItem">
<div class="btItem"></div>
<div class="info flex">
<el-form-item prop="jzMc" label="警组名称">
<el-input v-model="formData.jzMc" placeholder="请输入警组名称"></el-input>
</el-form-item>
<el-form-item prop="jzQwBbzl" label="报备类型">
<MOSTY.Select :dictEnum="props.dic.D_QW_BBZL" :disabled="isAdd ? false:true" placeholder="请选择班次类型" v-model="formData.jzQwBbzl" />
</el-form-item>
<el-form-item label="巡防部门" v-if="formData.jzQwBbzl == '02'">
<MOSTY.Department width="180px" clearable filterable v-model="formData.ssbmdm" />
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '01'">
<div class="btItem">值班人员</div>
<div class="info">
<dl class="dl-car">
<dt class="peo flex just-between align-center"><span>机关人员</span></dt>
<dd class="flex dir-column pr20 pt10">
<el-form-item prop="zbldZbStr" label="值班领导(主班)" :label-width="135">
<div class="flex">
<div class="num">{{formData.zbldZbStr ? formData.zbldZbStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbldZbStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbldZbStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbldFbStr" label="值班领导(副班)" :label-width="135">
<div class="flex">
<div class="num">{{formData.zbldFbStr ? formData.zbldFbStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbldFbStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbldFbStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zhzZbStr" label="指挥长(主班)" :label-width="135">
<div class="flex">
<div class="num">{{formData.zhzZbStr ? formData.zhzZbStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zhzZbStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zhzZbStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zhzFbStr" label="指挥长(副班)" :label-width="135">
<div class="flex">
<div class="num">{{formData.zhzFbStr ? formData.zhzFbStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zhzFbStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zhzFbStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbzStr" label="值班长" :label-width="135">
<div class="flex">
<div class="num">{{formData.zbzStr ? formData.zbzStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbzStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbzStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbmjStr" label="当班民警" :label-width="135">
<div class="flex">
<div class="num">{{formData.zbmjStr ? formData.zbmjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="it in formData.zbmjStr" :key="it.id">{{it.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="值班辅警" :label-width="135">
<div class="flex">
<div class="num">{{formData.zbfjStr ? formData.zbfjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'fj'}" v-model="formData.zbfjStr" :dic="props.dic" />
<el-tag type="primary" v-for="it in formData.zbfjStr" :key="it.id">{{it.xm}}</el-tag>
</div>
</el-form-item>
</dd>
</dl>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">负责人</div>
<div class="info flex">
<el-form-item>
<ChooseTable :deptment="props.dep" @change="handleFzr" :configer="{lx:'mj',rowKey:'id',isRadio:true}" v-model="formData.fzrList" :dic="props.dic" />
</el-form-item>
<el-form-item prop="ddMjxm">
<el-input readonly v-model="formData.ddMjxm" placeholder="负责人" clearable />
</el-form-item>
<el-form-item prop="ddMjsfzh">
<el-input readonly v-model="formData.ddMjsfzh" placeholder="身份证" clearable />
</el-form-item>
<el-form-item prop="ddDh">
<el-input readonly v-model="formData.ddDh" placeholder="负责人电话" clearable />
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">终端报备</div>
<div class="info">
<el-form-item label="终端设备" prop="zbzdsbStr" label-width="96px">
<ChooseTable :configer="{lx:'zdsb'}" v-model="formData.zbzdsbStr" :dic="props.dic" />
<el-tag type="primary" v-for="it in formData.zbzdsbStr" :key="it.id">{{it.sbmc}}</el-tag>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">智能装备</div>
<div class="info">
<el-form-item label="执法记录仪" label-width="96px">
<ChooseTable :deptment="props.dep" :configer="{lx:'zfjly'}" v-model="formData.tcsbStr" :dic="props.dic" />
<el-tag type="primary" v-for="itchid in formData.tcsbStr" :key="itchid">{{itchid.sbmc}}</el-tag>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">装备类型</div>
<div class="info flex flex-warp">
<el-form-item :label="item.label" :label-width="120" v-for="item in formData.zbzbStr" :key="item">
<el-input-number v-model="item.qxsl" :min="0" :max="1000"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">巡逻类型</div>
<div class="info">
<CheckBox :data="baseInfo.xlfs" @changeData="changeDataxl" />
<div>
<el-form-item style="padding-top: 26px;" prop="zbclStr" v-if="baseInfo.xlfs.hasChoose.includes('车巡')">
<template #label>
<ChooseTable :configer="{lx:'cl',selectName:'选择车辆'}" v-model="formData.zbclStr" @change="changeCl" :dic="props.dic" />
</template>
<dl class="dl-car" v-for="item in formData.zbclStr" :key="item.cid">
<dt class="flex just-between align-center"><span>{{item.cph}}</span></dt>
<dd class="flex dir-column pr20 pt10">
<el-form-item v-for="it in item.tcryList" :label="it.label" :key="it.vlaue">
<div class="flex">
<div class="num">{{it.list ? it.list.length : 0}}</div>
<ChooseTable :configer="{lx: it.label == '同行辅警'?'fj':'mj'}" v-model="it.list" :key="it" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(itchid,idx) in it.list" :key="idx">{{itchid.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</el-form-item>
<el-form-item style="padding-top: 26px;" v-if="baseInfo.xlfs.hasChoose.includes('步巡')">
<template #label>
<div class="mr20" style="width:70px">步巡人员</div>
</template>
<dl class="dl-car">
<dt class="peo flex just-between align-center"><span>步巡人员</span></dt>
<dd class="flex dir-column pr20 pt10">
<el-form-item prop="zbmjStr" label="当班民警">
<div class="flex">
<div class="num">{{formData.zbmjStr ? formData.zbmjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbmjStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="当班辅警">
<div class="flex">
<div class="num">{{formData.zbfjStr ? formData.zbfjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'fj'}" v-model="formData.zbfjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbfjStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</el-form-item>
</div>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">武装着装</div>
<div class="info flex">
<el-form-item label="武装类型" prop="xfwzlx" :label-width="120">
<MOSTY.Radio :options="props.dic.D_BZ_WZLX" v-model="formData.xfwzlx" />
</el-form-item>
<el-form-item label="着装类型" prop="xfzzlx" :label-width="120">
<MOSTY.Radio :options="props.dic.D_BZ_ZZLX" v-model="formData.xfzzlx" />
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl != '02' && formData.jzQwBbzl != '01'">
<div class="btItem">
<dict-tag :options="props.dic.D_QW_BBZL" :value="formData.jzQwBbzl" :tag="false"></dict-tag>
</div>
<div class="info flex">
<dl class="dl-car">
<dt class="peo flex just-between align-center">
<dict-tag :options="props.dic.D_QW_BBZL" :value="formData.jzQwBbzl" :tag="false"></dict-tag>
</dt>
<dd class="flex dir-column pr20 pt10">
<el-form-item prop="zbmjStr" label="当班民警">
<div class="flex">
<div class="num">{{formData.zbmjStr ? formData.zbmjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'mj'}" v-model="formData.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbmjStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="当班辅警">
<div class="flex">
<div class="num">{{formData.zbfjStr ? formData.zbfjStr.length : 0}}</div>
<ChooseTable :configer="{lx:'fj'}" v-model="formData.zbfjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="(item,idx) in formData.zbfjStr" :key="idx">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</div>
</div>
<div class="bblxItem">
<div class="btItem">班次设置</div>
<div class="info flex">
<el-form-item prop="bcMc" label="班次名称">
<el-input readonly placeholder="班次名称" v-model="formData.bcMc" style="width: 60%"></el-input>
<ChooseTable :configer="{width:615,isRadio:true,lx:'zbbc',bclx:formData.jzQwBbzl,placement:'top-end'}" @change="changeBc" :dic="props.dic" />
</el-form-item>
<span class="f16">(</span>
<el-form-item prop="bcKssj">
<el-time-picker readonly v-model="formData.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<span class="f16"></span>
<el-form-item prop="bcKtsDict" style="width: 90px">
<MOSTY.Select :disabled="true" :dictEnum="props.dic.D_QW_BC_KTS" placeholder="跨天数" v-model="formData.bcKtsDict" style="width: 100%" />
</el-form-item>
<el-form-item prop="bcJssj">
<el-time-picker readonly v-model="formData.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<span class="f16">)</span>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02' || formData.jzQwBbzl == '01'">
<div class="btItem">{{formData.jzQwBbzl == '01' ? '值班电话':'通讯设置'}} </div>
<div class="info flex">
<!-- prop="zbpdmc" readonly readonly-->
<el-form-item label="频道号">
<ChooseTable :configer="{isRadio:true,lx:'pdh',placement:'top-end'}" @change="changePdh" :dic="props.dic" />
<el-input v-model="formData.zbpdmc" placeholder="频道号名称" style="width: 150px"></el-input> &nbsp;
<el-input v-model="formData.zbpdh" placeholder="频道号" style="width: 150px"></el-input>
</el-form-item>
<el-form-item prop="zbpdhh" label="呼号">
<el-input v-model="formData.zbpdhh"></el-input>
</el-form-item>
<el-form-item prop="zbdh" label="值班电话" v-if="formData.jzQwBbzl == '01'">
<el-input v-model="formData.zbdh"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="formData.jzQwBbzl == '02'">
<div class="btItem">巡区设置</div>
<div class="info flex">
<!-- prop="zbzdsbStr" -->
<el-form-item label="巡区设置">
<ChooseTable :configer="{width:600,isRadio:true,lx:'xfq',placement:'top-end'}" @change="changeXq" :dic="props.dic" />
</el-form-item>
<!-- readonly -->
<el-form-item prop="xqmc" label="巡区名称">
<el-input placeholder="巡区名称" v-model="formData.xqmc"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="onSave" v-loading="loading">{{isAdd?'新增':'修改'}}报备</el-button>
<el-button @click="reserForm" v-if="!isAdd ? false:true">重置</el-button>
<el-button @click="closeDialog">取消</el-button>
</div>
</div>
</el-form>
</div>
</template>
<script setup>
import CheckBox from "@/components/checkBox/index";
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import { reactive, ref, getCurrentInstance, defineEmits } from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
dic: Object
});
const baseInfo = reactive({
xlfs: {
list: ["车巡", "步巡"],
hasChoose: []
}
});
const emits = defineEmits(["updateList"]);
const loading = ref(false); //加载
const formRef = ref(); //表单校验
const formDataDefault = ref({});
const formData = ref({
xfzzlx: "1",
xfwzlx: "1",
jzQwBbzl: "01",
zbclStr: [],
zbzbStr: []
}); //表单数据
const isAdd = ref(false); //是否是洗新增状态
const isShowDialog = ref(false); //弹窗
const rules = reactive({
bcMc: [
{ required: true, message: "请填写班次名称", trigger: ["change", "blur"] }
],
bcKssj: [{ required: true, message: "请选择开始时间", trigger: "change" }],
bcKtsDict: [{ required: true, message: "请选择跨天数", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
jzMc: [{ required: true, message: "请输入警组名称", trigger: "blur" }],
jzQwBbzl: [{ required: true, message: "请输入报备类型", trigger: "change" }],
zbpdmc: [
{ required: true, message: "请输入频道号", trigger: ["change", "blur"] }
],
zbpdhh: [
{ required: true, message: "请输入呼号", trigger: ["change", "blur"] }
],
zbldZbStr: [
{ required: true, message: "请选择值班领导(主班)", trigger: "change" }
],
xqmc: [{ required: true, message: "请选择巡区名称", trigger: "change" }],
...rule.phoneRule({ validator: true, require: true }, "zbdh") //值班电话
});
const init = (type, row) => {
formDataDefault.value = JSON.parse(JSON.stringify(formData.value));
isShowDialog.value = true;
isAdd.value = type == "add" ? true : false;
if (row) {
serviceGet({}, `/mosty-qwzx/tbQwglJz/` + row.id).then((res) => {
console.log(res);
res.tcsbStr = res.tcsbStr ? JSON.parse(res.tcsbStr) : [];
res.zbclStr = res.zbclStr ? JSON.parse(res.zbclStr) : [];
res.zbfjStr = res.zbfjStr ? JSON.parse(res.zbfjStr) : [];
res.zbmjStr = res.zbmjStr ? JSON.parse(res.zbmjStr) : [];
res.zbldZbStr = res.zbldZbStr ? JSON.parse(res.zbldZbStr) : [];
res.zbldFbStr = res.zbldFbStr ? JSON.parse(res.zbldFbStr) : [];
res.zbzbStr = res.zbzbStr ? JSON.parse(res.zbzbStr) : [];
res.zbzdsbStr = res.zbzdsbStr ? JSON.parse(res.zbzdsbStr) : [];
res.zhzFbStr = res.zhzFbStr ? JSON.parse(res.zhzFbStr) : [];
res.zhzZbStr = res.zhzZbStr ? JSON.parse(res.zhzZbStr) : [];
res.zbzStr = res.zbzStr ? JSON.parse(res.zbzStr) : [];
formData.value = res;
let arr = [];
row.xfxlfs.forEach((it) => {
let obj = props.dic.D_BZ_XLFS.find((v) => {
return v.value == it;
});
if (obj) arr.push(obj.label);
});
baseInfo.xlfs.hasChoose = arr;
});
} else {
formData.value.zbzbStr = props.dic.D_JCGL_JYQX_QXLX;
}
};
// 改变频道号
const changePdh = (val) => {
formData.value.zbpdh = val ? val[0].pdh : "";
formData.value.zbpdmc = val ? val[0].pdmc : "";
};
// 选择班次
const changeBc = (val) => {
formData.value.bcMc = val ? val[0].bcMc : "";
formData.value.glQwbcId = val ? val[0].id : "";
formData.value.bcKssj = val ? val[0].bcKssj : "";
formData.value.bcJssj = val ? val[0].bcJssj : "";
formData.value.bcKtsDict = val ? val[0].bcKtsDict : "";
};
// 选择巡区
const changeXq = (val) => {
formData.value.xqmc = val ? val[0].xqmc : "";
formData.value.glXfqyId = val ? val[0].id : "";
};
//车辆选择
const changeCl = (val) => {
formData.value.zbclStr.forEach((item) => {
item.tcryList = props.dic.D_BZ_RYXFBBZW;
});
};
// 巡逻方式
const changeDataxl = (val) => {
baseInfo.xlfs.hasChoose = val;
};
// 重置表单
const reserForm = () => {
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 处理负责人
const handleFzr = (val) => {
formData.value.ddMjxm = val.length > 0 ? val[0].xm : "";
formData.value.ddMjsfzh = val.length > 0 ? val[0].sfzh : "";
formData.value.ddDh = val.length > 0 ? val[0].lxdh : "";
};
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let params = { ...formData.value };
for (let key in params) {
if (Array.isArray(params[key])) params[key] = JSON.stringify(params[key]);
}
let arr = baseInfo.xlfs.hasChoose.map((it) => {
let obj = props.dic.D_BZ_XLFS.find((v) => {
return v.label == it;
});
return obj ? obj.value : "";
});
params.xfxlfs = arr.join(",");
let url = isAdd.value ? "/tbQwglJz/save" : "/tbQwglJz/update";
let text = isAdd.value ? "新增成功" : "编辑成功";
servicePost(params, `/mosty-qwzx${url}`)
.then((res) => {
closeDialog();
proxy.$message.success(text);
emits("updateList", {});
})
.catch(() => {
loading.value = false;
});
});
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.bblxItem {
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
}
.dl-car {
display: inline-block;
border: solid 1px #66cbff;
min-width: 50%;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
background: #fff;
position: relative;
dt {
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 40px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -9px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
::v-deep .el-form-item--default {
// width: 23%;
padding-bottom: 10px;
margin-bottom: 18px !important;
}
</style>

View File

@ -0,0 +1,329 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">警组规划</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增警组</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 值班领导主班 -->
<template #zbldZbStr="{ row }">
<span class="tag" v-for="item in row.zbldZbStr" :key="item">{{item.xm}}</span>
</template>
<!-- 值班领导副班 -->
<template #zbldFbStr="{ row }">
<span class="tag" v-for="item in row.zbldFbStr" :key="item">{{item.xm}}</span>
</template>
<!-- 指挥长主班 -->
<template #zhzZbStr="{ row }">
<span class="tag" v-for="item in row.zhzZbStr" :key="item">{{item.xm}}</span>
</template>
<!-- 指挥长副班 -->
<template #zhzFbStr="{ row }">
<span class="tag" v-for="item in row.zhzFbStr" :key="item">{{item.xm}}</span>
</template>
<!-- 值班长 -->
<template #zbzStr="{ row }">
<span class="tag" v-for="item in row.zbzStr" :key="item">{{item.xm}}</span>
</template>
<!-- 民警明细 -->
<template #zbmjStr="{ row }">
<span class="tag" v-for="item in row.zbmjStr" :key="item">{{item.xm}}</span>
</template>
<!-- 协警人数 -->
<template #zbfjStr="{ row }">
<span class="tag" v-for="item in row.zbfjStr" :key="item">{{item.xm}}</span>
</template>
<!-- 终端 -->
<template #zbzdsbStr="{ row }">
<span class="tag" v-for="item in row.zbzdsbStr" :key="item">{{item.sbmc}}</span>
</template>
<!-- 报备种类 -->
<template #jzQwBbzl="{ row }">
<dict-tag :options="D_QW_BBZL" :value="row.jzQwBbzl" :tag="false"></dict-tag>
</template>
<!-- 巡防巡逻方式 -->
<template #xfxlfs="{ row }">
<div class="flex">
<dict-tag v-for="it in row.xfxlfs" :key="it" :options="D_BZ_XLFS" :value="it"></dict-tag>
</div>
</template>
<!-- 武装名称 -->
<template #xfwzlx="{ row }">
<dict-tag :options="D_BZ_WZLX" :value="row.xfwzlx" :tag="false"></dict-tag>
</template>
<!-- 巡防着装类型 -->
<template #xfzzlx="{ row }">
<dict-tag :options="D_BZ_ZZLX" :value="row.xfzzlx" :tag="false"></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{...pageData.pageConfiger,total: pageData.total}" />
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm ref="addEditDialog" @updateList="getList" :dic="{D_QW_BC_KTS,
D_QW_BBZL,
D_BZ_WZLX,
D_BZ_XLFS,D_BZ_ZZLX ,
D_BZ_RYXFBBZW,
D_JCGL_JYQX_QXLX,
D_BZ_PDDTLX,
D_BZ_SF,
D_BZ_RYJZLB,
D_BZ_RYMFJLB,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTFWLB,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_JYCL_JYJTGJLB}" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const {
D_QW_BC_KTS,
D_QW_BBZL,
D_BZ_WZLX,
D_BZ_XLFS,
D_BZ_ZZLX,
D_BZ_RYXFBBZW,
D_JCGL_JYQX_QXLX,
D_BZ_PDDTLX,
D_BZ_SF,
D_BZ_RYJZLB,
D_BZ_RYMFJLB,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTFWLB,
D_JCGL_JYCL_JYJTGJLB,
D_QW_XQLB,
D_QW_XQLX
} = proxy.$dict(
"D_QW_BC_KTS",
"D_QW_BBZL",
"D_BZ_WZLX",
"D_BZ_XLFS",
"D_BZ_ZZLX",
"D_BZ_RYXFBBZW",
"D_JCGL_JYQX_QXLX",
"D_BZ_PDDTLX",
"D_BZ_SF",
"D_BZ_RYJZLB",
"D_BZ_RYMFJLB",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_JCGL_JYCL_JYJTGJLB",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_ZDSB_SBLX"
);
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "jzMc",
placeholder: "请输入警组名称",
label: "警组名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 100, //操作栏宽度
tableColumn: [
{ label: "警组名称", prop: "jzMc", showOverflowTooltip: true, width: 100 },
{
label: "报备类型",
prop: "jzQwBbzl",
showSolt: true,
showOverflowTooltip: true,
width: 120
},
{ label: "巡逻方式", prop: "xfxlfs", showSolt: true, width: 140 },
{
label: "值班领导(主班)",
prop: "zbldZbStr",
showSolt: true,
width: 150
},
{
label: "值班领导(副班)",
prop: "zbldFbStr",
showSolt: true,
width: 150
},
{ label: "指挥长(主班)", prop: "zhzZbStr", showSolt: true, width: 150 },
{ label: "指挥长(副班)", prop: "zhzFbStr", showSolt: true, width: 150 },
{ label: "值班长", prop: "zbzStr", showSolt: true, width: 100 },
{ label: "民警人数", prop: "mjsl", width: 100 },
{ label: "民警明细", prop: "zbmjStr", showSolt: true, width: 150 },
{ label: "协警人数", prop: "fjsl", width: 100 },
{ label: "协警人数", prop: "zbfjStr", showSolt: true, width: 150 },
{ label: "终端", prop: "zbzdsbStr", showSolt: true, width: 150 },
{ label: "频道名称", prop: "zbpdh", width: 150 },
{ label: "呼号", prop: "zbpdhh" },
{ label: "武装名称", prop: "xfwzlx", showSolt: true, width: 150 },
{ label: "着装名称", prop: "xfzzlx", showSolt: true, width: 150 }
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
serviceGet(params, "/mosty-qwzx/tbQwglJz/selectPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.tableData.forEach((item) => {
item.zbfjStr = item.zbfjStr ? JSON.parse(item.zbfjStr) : [];
item.fjsl = item.zbfjStr.length + "人";
item.zbldFbStr = item.zbldFbStr ? JSON.parse(item.zbldFbStr) : [];
item.zbldZbStr = item.zbldZbStr ? JSON.parse(item.zbldZbStr) : [];
item.zbmjStr = item.zbmjStr ? JSON.parse(item.zbmjStr) : [];
item.mjsl = item.zbmjStr.length + "人";
item.zbzStr = item.zbzStr ? JSON.parse(item.zbzStr) : [];
item.zhzFbStr = item.zhzFbStr ? JSON.parse(item.zhzFbStr) : [];
item.zhzZbStr = item.zhzZbStr ? JSON.parse(item.zhzZbStr) : [];
item.zbzdsbStr = item.zbzdsbStr ? JSON.parse(item.zbzdsbStr) : [];
item.zbzbStr = item.zbzbStr ? JSON.parse(item.zbzbStr) : [];
item.zbclStr = item.zbclStr ? JSON.parse(item.zbclStr) : [];
item.xfxlfs = item.xfxlfs ? item.xfxlfs.split(",") : [];
});
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
serviceDelete({}, "/mosty-qwzx/tbQwglJz/" + id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,401 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree width="300px" placeholder="管理部门ID" @changeSsbm='changeSsbm' clearable filterable :isBmId="true" v-model="listQuery.ssbmdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构{{ssbmmc}}</div>
<div class="flex align-center" style="width:40%">
<div>是否包含下级:</div>
<el-select style="flex:1" v-model="listQuery.isChild" placeholder="请选择是否包含">
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-date-picker v-model="listQuery.tjrq" type="date" value-format="YYYY-MM-DD" />
<el-button type='primary' @click="searchFn">搜索</el-button>
</div>
</div>
<div class="echartsBox">
<!-- 第2模块 -->
<ul class="itemBoxSmall">
<li class="item" v-for="item in date.twoList" :key="item.label">
<div class="ItemTitle">{{item.label}}</div>
<ul class="itemCnt">
<li class="itemCntChild" v-for="(it,idx) in item.list" :key="idx">
<span class="icon"><img :src="it.icon" alt="" :style="{width:idx==2?'26px':'30px'}"></span>
<span class="title">{{it.title}} :</span>
<span class="num">{{it.num}} {{it.dw}}</span>
</li>
</ul>
</li>
</ul>
<ul class="itemBox">
<li class="item">
<div class="ItemTitle">勤务类型统计图</div>
<div class="echartsCnt">
<BarEcharts v-if="EchartsData.length>0" :data='EchartsData' :Xdata='Xdata' />
</div>
</li>
</ul>
<div class="tab_box">
<el-table ref="multipleTableRef" :data="tjList" style="width: 100%">
<el-table-column property="tjxMc" label="勤务类型" />
<el-table-column property="mjsl" label="民警" />
<el-table-column property="fjsl" label="辅警" />
<el-table-column property="clsl" label="车辆" />
</el-table>
</div>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/components/barEcharts.vue";
import { timeValidate } from "@/utils/tools.js";
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import Tablelist from "@/views/backOfficeSystem/qwManagement/qwgl/tablelist.vue";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const {
D_QW_BBZT,
D_BZ_PDDTLX,
D_BZ_RYMFJLB,
D_BZ_RYJZLB,
D_QW_BC_KTS,
D_BZ_RYZBBBZW,
D_QW_BBZL,
D_BZ_SF,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTGJLB,
D_JCGL_JYCL_JYJTFWLB,
D_BZ_RYXFBBZW,
D_BZ_XLFS,
D_BZ_WZLX,
D_BZ_ZZLX,
D_JCGL_JYQX_QXLX
} = proxy.$dict(
"D_QW_BBZT",
"D_BZ_PDDTLX",
"D_BZ_RYMFJLB",
"D_BZ_RYJZLB",
"D_QW_BC_KTS",
"D_BZ_RYZBBBZW",
"D_QW_BBZL",
"D_BZ_SF",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_ZDSB_SBLX",
"D_JCGL_JYCL_JYJTGJLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_BZ_RYXFBBZW",
"D_BZ_XLFS",
"D_BZ_WZLX",
"D_BZ_ZZLX",
"D_JCGL_JYQX_QXLX"
);
const deptId = JSON.parse(localStorage.getItem("deptId"));
const Xdata = ref([]);
const EchartsData = ref([]);
const listQuery = ref({
// tjrq: "2024-08-13", //单日统计
tjrq: timeValidate(new Date(), "ymd"), //单日统计
dateType: "03",
ssbmdm: deptId[0].deptCode
});
const ssbmmc = ref(deptId[0].deptName);
const tjList = ref([]);
const date = reactive({
twoList: [
{
label: "当日当前时刻",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
},
{
label: "峰值00:00:00 ~ 235959",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
},
{
label: "报备总量",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
}
]
});
// 获取中间柱状图的数据
const handleFzData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDateMFCPartCount"
).then((res) => {
date.twoList[0].list[0].num = res.dqskMjsl;
date.twoList[0].list[1].num = res.dqskFjsl;
date.twoList[0].list[2].num = res.dqskClsl;
date.twoList[1].list[0].num = res.fzMjsl;
date.twoList[1].list[1].num = res.fzFjsl;
date.twoList[1].list[2].num = res.fzClsl;
date.twoList[2].list[0].num = res.gzMjsl;
date.twoList[2].list[1].num = res.gzFjsl;
date.twoList[2].list[2].num = res.gzClsl;
});
};
// 获取中间柱状图的数据
const handleTjData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDayBbzlMFCCount"
).then((res) => {
console.log(res, "res");
if (res.bbzlCountList) {
let mjsl = [];
let fjsl = [];
let clsl = [];
mjsl = res.bbzlCountList.map((item) => item.mjsl);
fjsl = res.bbzlCountList.map((item) => item.fjsl);
clsl = res.bbzlCountList.map((item) => item.clsl);
console.log(res.bbzlCountList, "res.bbzlCountList");
Xdata.value = res.bbzlCountList.map((item) => item.tjxMc);
console.log(Xdata.value, "Xdata.value");
EchartsData.value = [
{ name: "民警", data: mjsl, type: "bar", barWidth: 10 },
{ name: "辅警", data: fjsl, type: "bar", barWidth: 10 },
{ name: "车辆", data: clsl, type: "bar", barWidth: 10 }
];
tjList.value = res.bbzlCountList;
}
});
};
const searchFn = (val) => {
handleFzData();
handleTjData();
};
const changeSsbm = (val) => {
ssbmmc.value = val.orgName;
listQuery.value.ssbmdm = val.orgCode;
handleFzData();
handleTjData();
};
onMounted(() => {
handleFzData();
handleTjData();
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
font-size: 16px;
.tableCnt {
flex: 1;
margin-left: 10px;
.echartsBox {
height: calc(100% - 50px);
display: flex;
flex-direction: column;
.itemBox {
flex: 1;
display: flex;
height: 100%;
margin: 2px 0;
}
.itemBoxSmall {
height: 110px;
display: flex;
margin: 2px 0;
border-bottom: 1px solid #ccc;
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: calc(100% - 30px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
li {
display: flex;
.head {
width: 50%;
background: #f0f0f0;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
font-size: 16px;
line-height: 30px;
}
.num {
width: 50%;
line-height: 30px;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
border: 1px solid #f0f0f0;
border-top: 0;
}
.num1 {
border-right: 0;
}
}
.numlabel {
width: 80px;
text-align: center;
font-size: 14px;
white-space: nowrap;
border: 1px solid #cac8c8;
background: #f0f0f0;
line-height: 38px;
border-top: 0;
}
.topNum {
border-top: 1px solid #cac8c8;
}
.numValue {
width: calc(100% - 80px);
line-height: 38px;
span {
border: 1px solid #cac8c8;
font-size: 14px;
display: inline-block;
width: calc(100% / 24);
text-align: center;
border-top: 0;
border-left: 0;
white-space: nowrap;
}
.topSpan {
border-top: 1px solid #cac8c8;
}
}
}
.itemCnt {
width: 100%;
display: flex;
flex-wrap: wrap;
overflow: hidden;
.itemCntChild {
width: 50%;
padding: 5px 20px;
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
.icon {
display: inline-block;
text-align: center;
width: 30px;
}
.title {
color: #000;
font-size: 14px;
margin: 0 12px;
white-space: nowrap;
}
.num {
color: #142232;
font-size: 16px;
white-space: nowrap;
}
}
}
.item {
flex: 1;
height: 100%;
margin: 0 2px;
}
}
}
}
.tabBox {
height: calc(100% - 500px);
}
</style>

View File

@ -0,0 +1,293 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">排班审核</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch">
<template #defaultSlot>
<el-select v-model="baseDate.bbzt" @change="getList">
<el-option v-for="item in D_QW_BBZL" :key="item.label" :label="item.label" :value="item.label" />
</el-select>
</template>
</Search>
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bbZt="{ row }">
<dict-tag :options="D_QW_BBZT" :value="row.bbZt" :tag="true"></dict-tag>
</template>
<template #shZt="{ row }">
<dict-tag :options="D_QW_BBSHZT" :value="row.shZt" :tag="true"></dict-tag>
</template>
<template #controls="{ row }">
<el-popover placement="left" width="235px" :visible="row.visible" trigger="click">
<template #reference>
<el-link type="primary" @click="row.visible = true" v-if="row.shZt == '01'">审核</el-link>
</template>
<div class="flex align-center">
<div style="white-space: nowrap;margin-right:4px">是否通过审核</div>
<MOSTY.Radio :options="D_BZ_SF" v-model="row.sftg" width="120px" />
</div>
<div style="text-align:center;">
<el-button size="small" @click="handleSh(row)">确定</el-button>
<el-button size="small" @click="row.visible = false">取消</el-button>
</div>
</el-popover>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="addEdit(row)">详情</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{ ...pageData.pageConfiger, total: pageData.total}" />
</div>
</div>
<!-- 新增编辑 -->
<BbInfo v-if="isShowBb" :isDetail="true" v-model="isShowBb" :data="baseDate" @updateData="getList"
:dic="{D_QW_BBZT, D_BZ_PDDTLX, D_BZ_RYMFJLB, D_BZ_RYJZLB, D_QW_BC_KTS, D_BZ_RYZBBBZW, D_QW_BBZL, D_BZ_SF, D_QW_XQLB, D_QW_XQLX, D_JCGL_ZDSB_SBLB, D_JCGL_ZDSB_SBLX, D_JCGL_JYCL_JYJTGJLB, D_JCGL_JYCL_JYJTFWLB, D_BZ_RYXFBBZW, D_BZ_XLFS, D_BZ_WZLX, D_BZ_ZZLX, D_JCGL_JYQX_QXLX}" />
</div>
</template>
<script setup>
import { getItem } from "@/utils/storage";
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import BbInfo from "../qwgl/components/bbInfo.vue";
import { timeValidate, weekValidate } from "@/utils/tools.js";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted,
defineEmits,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const {
D_QW_BBSHZT,
D_QW_BBZT,
D_BZ_PDDTLX,
D_BZ_RYMFJLB,
D_BZ_RYJZLB,
D_QW_BC_KTS,
D_BZ_RYZBBBZW,
D_QW_BBZL,
D_BZ_SF,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTGJLB,
D_JCGL_JYCL_JYJTFWLB,
D_BZ_RYXFBBZW,
D_BZ_XLFS,
D_BZ_WZLX,
D_BZ_ZZLX,
D_JCGL_JYQX_QXLX
} = proxy.$dict(
"D_QW_BBSHZT",
"D_QW_BBZT",
"D_BZ_PDDTLX",
"D_BZ_RYMFJLB",
"D_BZ_RYJZLB",
"D_QW_BC_KTS",
"D_BZ_RYZBBBZW",
"D_QW_BBZL",
"D_BZ_SF",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_ZDSB_SBLX",
"D_JCGL_JYCL_JYJTGJLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_BZ_RYXFBBZW",
"D_BZ_XLFS",
"D_BZ_WZLX",
"D_BZ_ZZLX",
"D_JCGL_JYQX_QXLX"
);
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
dic: Object
});
const visible = ref(false);
const okdate = ref("1");
const addEditForm = ref();
const isShowBb = ref(false);
const searchConfiger = reactive([
{
showType: "defaultSlot",
label: "报备类型"
},
{
showType: "input",
prop: "jzMc",
placeholder: "请输入警组名称",
label: "警组名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "警组名称", prop: "jzMc" },
{ label: "报备开始时间", prop: "bbSjKssj" },
{ label: "报备结束时间", prop: "bbSjJssj" },
{ label: "所属部门 ", prop: "ssbm" },
{ label: "报备状态 ", prop: "bbZt", showSolt: true },
{ label: "审核状态 ", prop: "shZt", showSolt: true },
{ label: "审核人姓名 ", prop: "shrXm" },
{ label: "审核人身份证 ", prop: "shrSfzh" }
]
});
const loading = ref(false);
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const bblx = ref();
const listQuery = ref({});
const baseDate = reactive({
year: timeValidate(null, "ymd"),
week: weekValidate(timeValidate(null, "ymd")),
bbzt: "值班报备",
info: null
});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
val.startTime = val.daterange ? val.daterange[0] + " 00:00:00" : "";
val.endTime = val.daterange ? val.daterange[1] + " 23:59:59" : "";
listQuery.value = { ...listQuery.value, ...val };
delete listQuery.value.daterange;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let params = { ...listQuery.value, ...pageData.pageConfiger };
params.shrSfzh = localStorage.getItem("idEntityCard")
? localStorage.getItem("idEntityCard")
: "";
let url = "";
if (baseDate.bbzt == "值班报备") url = "/mosty-qwzx/tbQwglZbbb/selectPage";
else if (baseDate.bbzt == "街面勤务报备")
url = "/mosty-qwzx/tbQwglXfbb/selectPage";
else url = "/mosty-qwzx/tbQwglBb/selectPage";
if (baseDate.bbzt != "值班报备" && baseDate.bbzt != "街面勤务报备") {
let obj = D_QW_BBZL.value.find((it) => {
return it.label == baseDate.bbzt;
});
params.qwBbzl = obj.dm;
}
serviceGet(params, url)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleSh = (row) => {
console.log(row, "row");
if (!row.sftg) return proxy.$message.warning("请选择是否通过审核");
let tips = "";
if (row.sftg == "0") {
tips = "是否确定不通过审核?";
} else if (row.sftg == "1") {
tips = "是否确定通过审核?";
}
proxy
.$confirm(tips, "警告", { type: "warning" })
.then(() => {
let url = "";
if (baseDate.bbzt == "值班报备") url = "/mosty-qwzx/tbQwglZbbb/audits";
else if (baseDate.bbzt == "街面勤务报备")
url = "/mosty-qwzx/tbQwglXfbb/audits";
else url = "/mosty-qwzx/tbQwglBb/audits";
let data = { id: row.id, sftg: row.sftg };
servicePost(data, url).then((res) => {
getList({});
proxy.$message.success("审核成功");
row.visible = false;
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
// 修改数据
const addEdit = (row) => {
baseDate.info = JSON.parse(JSON.stringify(row));
isShowBb.value = true;
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
::v-deep .dialog .el-form--inline {
padding: 0 !important;
}
</style>

View File

@ -0,0 +1,278 @@
<!--
* @Author: your name
* @Date: 2024-01-25 16:21:46
* @LastEditTime: 2024-01-26 10:10:33
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \my_web_new\src\views\backOfficeSystem\patrolManagement\task\editAddForm.vue
-->
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<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>
</div>
</div>
<el-form ref="elform" :model="listQuery" :rules="rules" :inline="true" label-position="top">
<el-form-item style="width: 48%" prop="ssbmdm" label="所属部门">
<MOSTY.Department width="100%" clearable v-model="listQuery.ssbmdm" :placeholder="listQuery.ssbm ? listQuery.ssbm : '请选择所属部门'" />
</el-form-item>
<el-form-item style="width: 48%" prop="qcmc" label="圈层名称">
<el-input v-model="listQuery.qcmc" placeholder="请输入圈层名称" style="width: 100%" clearable />
</el-form-item>
<el-form-item style="width: 48%" prop="qclx" label="圈层类型">
<el-select v-model="listQuery.qclx" placeholder="请选择圈层类型">
<el-option v-for="dict in props.dic.D_BZ_QCLX" :key="dict.value" :value="dict.value" :label="dict.label"></el-option>
</el-select>
</el-form-item>
<el-form-item style="width: 48%" prop="qcjb" label="圈层级别">
<el-select v-model="listQuery.qcjb" placeholder="请选择圈层级别">
<el-option v-for="dict in props.dic.D_BZ_QCDJ" :key="dict.value" :value="dict.value" :label="dict.label" />
</el-select>
</el-form-item>
<el-form-item label="备注" style="width: 100%">
<el-input v-model="listQuery.bz" placeholder="请输入备注" style="width: 100%" clearable />
</el-form-item>
<el-form-item label="关联检查站" style="width: 100%" @click="jczVisible = true">
<el-input placeholder="请选择关联检查站" style="width: 100%" clearable readonly suffix-icon="ArrowDown" />
<MyTable v-if="listQuery.jczList != null" :tableData="listQuery.jczList" :tableColumn="pageData.tableColumn" :key="pageData.keyCount" :tableHeight="300" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
>
<template #jczlx="{ row }">
<dict-tag
:options="dic.D_BZ_JCZLX"
:value="row.jczlx"
:tag="false"
/>
</template>
</MyTable>
<!-- <MOSTY.GljczTable v-model="listQuery.jczList" v-else/> -->
</el-form-item>
<el-form-item label="圈层颜色" style="width: 10%" prop="qcys">
<el-color-picker v-model="listQuery.qcys"></el-color-picker>
</el-form-item>
<el-form-item style="width: 85%" prop="zbList" label="坐标位置">
<div class="latlng">
<el-input v-model="listQuery.zbList" clearable style="width: 90%" @blur="handleBlur" />
<el-button @click="chackLat">绘制区域</el-button>
</div>
</el-form-item>
<el-form-item style="width: 100%">
<div class="mapBox">
<GdMap />
</div>
</el-form-item>
</el-form>
<JczLoad v-model="jczVisible" titleValue="选择检查站" @choosedJcz="choosedJcz" :data="listQuery.jczList" />
</div>
</template>
<script setup>
import { choseRbgb } from "@/utils/tools.js";
import JczLoad from "@/views/backOfficeSystem/qwManagement/components/jczLoad.vue";
import {qcAddQc,qcUpdateQc,qcSelectById} from "@/api/lzjcz/index.js";
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import GdMap from "@/components/GdMap/index.vue";
import emitter from "@/utils/eventBus.js";
import {
ref,
defineExpose,
reactive,
onMounted,
defineEmits,
getCurrentInstance
} from "vue";
const props = defineProps({
dic: Object
});
const { proxy } = getCurrentInstance();
const emit = defineEmits(["updateDate"]);
const dialogForm = ref(false); //弹窗
const xfzy = ref([]);
const listQuery = ref({ qcys: "#409eff" }); //表单
const loading = ref(false);
const elform = ref();
const title = ref("");
const jczVisible = ref(false);
const rules = reactive({
qcmc: [{ required: true, message: "请输入巡防区名称", trigger: "change" }]
});
const mapType = ref(""); //地图绘制对象
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: null,
haveControls:false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageNum: 1
}, //分页
controlsWidth: 210, //操作栏宽度
tableColumn: [
{ label: "所属部门", prop: "ssbm" },
{ label: "检查站名称", prop: "jczmc" },
{ label: "检查站类型", prop: "jczlx", showSolt: true },
{ label: "检查站地址", prop: "xxdz" },
{ label: "经度", prop: "jd" },
{ label: "纬度", prop: "wd" }
]
});
onMounted(() => {
emitter.on("coordString", (res) => {
if (res.type === "polygon") listQuery.value.zbList = res.coord[0];
});
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = row ? "编辑圈层" : "新增圈层";
if (row) getDataById(row);
};
// 根据id查询详情
const getDataById = (row) => {
qcSelectById({ id: row.id }).then( (res) => {
listQuery.value = res;
if (res.jczList) {
listQuery.value.jczidList = res.jczList.map((item) => {
return item.id;
});
listQuery.value.jczList = res.jczList;
}
//如果是自定义绘制的圈层
if (res.zbList && res.zbList.length > 0) {
setTimeout(() => {
let obj = { position: [res.zbList], text: res.xfqMc, id: res.id };
let ys = res.qcys ? choseRbgb(res.qcys, 0.5) : "rgba(29,237,245,0.6)"; //全部按照类型区分颜色 , 二机撒随机颜色
emitter.emit("echoPlane", {
coords: [obj],
color: ys,
linecolor: ys,
flag: "qc",
type: "polygon"
});
emitter.emit("setMapCenter", {
location: res.zbList[0],
zoomLevel: 10
});
}, 500);
}
});
};
// 失去焦點會先
const handleBlur = () => {
if (listQuery.value.zbList && !Array.isArray(listQuery.value.zbList)) {
let att = listQuery.value.zbList.split(",");
let coods = [],
newAtt = [];
att.forEach((iv, idx) => {
newAtt.push(iv);
let index = idx + 1;
if (index % 2 == 0) {
coods.push(newAtt);
newAtt = [];
}
});
listQuery.value.zbList = coods;
let ys = listQuery.value.qcys
? choseRbgb(listQuery.value.qcys, 0.3)
: "rgba(29,237,245,0.3)"; //全部按照类型区分颜色 , 二机撒随机颜色
let obj = { position: [coods], text: "", id: "" };
emitter.emit("echoPlane", {
coords: [obj],
color: ys,
linecolor: ys,
flag: "qc",
type: "polygon"
});
emitter.emit("setMapCenter", { location: coods[0], zoomLevel: 10 });
}
};
//获取经纬度
const chackLat = (type) => {
// emitter.emit("removeEara", "qc");
let ys = choseRbgb(listQuery.value.qcys, 0.5);
let linecolor = listQuery.value.qcys;
emitter.emit("drawShape", {
type: "polygon",
flag: "qc",
color: ys,
linecolor,
isclear: true
});
listQuery.value.zbList = "";
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
let text = title.value == "新增圈层" ? "新增成功" : "编辑成功";
if(title.value=="新增圈层"){
qcAddQc(listQuery.value)
.then(() => {
proxy.$message({ type: "success", message: text });
close();
emit("updateDate");
})
.catch(() => {
loading.value = false;
});
}else{
qcUpdateQc(listQuery.value)
.then(() => {
proxy.$message({ type: "success", message: text });
close();
emit("updateDate");
})
.catch(() => {
loading.value = false;
});
}
});
};
// 关闭
const close = () => {
listQuery.value = { qcys: "#409eff" };
dialogForm.value = false;
loading.value = false;
};
// 选择检查站
const choosedJcz = (arr) => {
console.log(arr);
listQuery.value.jczList = arr;
listQuery.value.jczidList = arr.map((v) => {
return v.id;
});
};
defineExpose({ init });
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.mapBox {
width: 100%;
height: 600px;
}
.latlng {
width: 100%;
display: flex;
justify-content: space-between;
}
</style>

View File

@ -0,0 +1,237 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">防控圈层</div>
<div class="btnBox">
<el-button type="primary" @click="addEditForm('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
<el-button type="primary" @click="deletList(null)" :disabled="ids.length == 0" typeof="danger">
<el-icon>
<CirclePlus />
</el-icon>
<span>批量删除</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
@chooseData="chooseData"
>
<template #qclx="{ row }">
<dict-tag :value="row.qclx" :options="D_BZ_QCLX" :tag="false"/>
</template>
<template #qcjb="{ row }">
<dict-tag :options="D_BZ_QCDJ" :value="row.qcjb" :tag="false" />
</template>
<!-- 操作 -->
<template #controls="{ row }">
<el-button @click="addEditForm('eidt',row)" size="small">编辑</el-button>
<el-button @click="deletList(row.id)" type="danger" size="small">删除</el-button>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{...pageData.pageConfiger,total: pageData.total}" />
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm ref="editInfo" @updateDate="getList" :dic="{D_BZ_QCLX,D_BZ_QCDJ,D_BZ_JCZLX}"></EditAddForm>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import {qcSelectQcList,qcDeleteQc} from "@/api/lzjcz/index.js";
import {
ref,
reactive,
computed,
watch,
nextTick,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const {
D_BZ_QCLX,D_BZ_QCDJ,D_BZ_JCZLX
} = proxy.$dict(
"D_BZ_QCLX","D_BZ_QCDJ","D_BZ_JCZLX"
);
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "qcmc",
placeholder: "请输入圈层名称",
label: "圈层名称",
},
{
showType: "select",
prop: "qclx",
placeholder: "请选择圈层类型",
label: "圈层类型",
options:D_BZ_QCLX
},
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType:'checkBox',
},
total: 0,
pageConfiger: {
pageSize: 10,
pageNum: 1
}, //分页
controlsWidth: 210, //操作栏宽度
tableColumn: [
{ label: "所属部门", prop: "ssbm"},
{ label: "圈层名称", prop: "qcmc"},
{ label: "圈层类型", prop: "qclx", showSolt:true },
{ label: "圈层等级", prop: "qcjb" ,showSolt:true}
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val)=>{
listQuery.value = {...listQuery.value,...val}
if(val.cz) listQuery.value.ssbmdm = '';
delete listQuery.value.cz;
getList()
}
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
qcSelectQcList(params).then(res=>{
pageData.tableData=res.records
pageData.total=res.total
}).finally(()=>{
pageData.tableConfiger.loading=false
})
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
serviceDelete({}, "/mosty-qwzx/tbQwglJz/" + id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
// 多选
const ids=ref([])
const chooseData = (val)=>{
if(!val) return false;
console.log(val);
if(val instanceof Array) ids.value = val.map(v=>{ return v.id })
console.log(ids.value );
}
//批量删除
const deletList = (id) => {
proxy.$confirm("确定要删除", "警告", {type: "warning"}).then(() => {
let IDS = id ? [id] : ids.value
qcDeleteQc(IDS).then(() => {
proxy.$message({ type: "success",message: "删除成功"});
getList()
});
}).catch(() => {
proxy.$message.info("已取消");
});
};
// 新增编辑表单
const editInfo=ref()
const addEditForm = (type,row)=>{
nextTick(()=>{
editInfo.value.init(type,row)
})
}
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,391 @@
<!--
* @Author: your name
* @Date: 2023-05-17 21:33:29
* @LastEditTime: 2023-05-31 09:39:26
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \mosty-qcck-new\src\views\basicsmanage\gudingjianchazhan\component\addGzyZ.vue
-->
<template>
<div>
<div class="searchBox" ref="searchBox">
<el-form :model="listQuery" :inline="true">
<el-form-item label="名称" style="width: 18%">
<el-input v-model="listQuery.gzyzmc" placeholder="名称" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="handleFilter"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
<el-button type="primary" @click="addGzyEvent"> 新增 </el-button>
</el-form-item>
</el-form>
</div>
<div class="tabBox">
<el-table :data="tableData" border row-key="id" style="width: 100%" :key="keyCount" :height="tableHeight" v-loading="loadingTable" element-loading-background="rgba(0,0,0,0.3)" element-loading-text="数据加载中。。">
<!-- <el-table-column align="center" type="selection" width="55" /> -->
<el-table-column type="index" show-overflow-tooltip align="center" width="60px" label="序号">
</el-table-column>
<el-table-column prop="gzyzmc" show-overflow-tooltip label="感知源组名称" width="250px"></el-table-column>
<el-table-column prop="jl" show-overflow-tooltip width="100px" label="距离(米)"></el-table-column>
<el-table-column prop="jd" show-overflow-tooltip width="150px" label="经度"></el-table-column>
<el-table-column prop="wd" show-overflow-tooltip width="150px" label="纬度"></el-table-column>
<el-table-column prop="jczmc" show-overflow-tooltip width="150px" label="所属检查站"></el-table-column>
<el-table-column label="关联感知源">
<template #default="{ row }">
<el-tag v-for="(item, index) in row.sxtList" :key="item" @close="onClickJczClose(index)" style="margin-bottom: 5px">{{ item.sbmc }}</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="200px">
<template #default="{ row }">
<el-button size="small" @click="onClickGzyz(row, 'info')">
详情
</el-button>
<el-button size="small" @click="onClickGzyz(row, 'update')">
编辑
</el-button>
<el-button size="small" type="danger" @click="onClickGzyz(row, 'delete')">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination class="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="listQuery.pageNum" :page-sizes="[2, 5, 10, 20]" :page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
</div>
</div>
<div v-if="dialogFormVisible" class="dialog" style="top: 0; left: 0; right: 0; overflow: hidden">
<div class="head_box" style="margin-bottom: 20px">
<span class="title">感知源组</span>
<div>
<el-button type="primary" :loading="btnLoading" size="small" @click="submit" v-if="isShowBut">保存</el-button>
<el-button size="small" @click="(dialogFormVisible = false), (form = {})">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="form" :rules="rules" :inline="true" label-position="top" class="mosty-from-wrap">
<el-form-item style="width: 48%" prop="gzyzmc" label="名称">
<el-input v-model="form.gzyzmc" placeholder="请输入名称" style="width: 100%" clearable />
</el-form-item>
<el-form-item style="width: 48%" prop="jl" label="距离">
<el-input v-model="form.jl" placeholder="请输入距离(米)" style="width: 100%" clearable />
</el-form-item>
<el-form-item style="width: 100%" prop="jczmc" label="关联感知源" @click="gzyModelValue = true">
<el-input v-model="form.gz" placeholder="请选择感知源" style="width: 100%" clearable suffix-icon="ArrowDown" readonly v-if="gzyList.length <= 0">
</el-input>
<div style="text-align: left" e-else>
<el-tag closable v-for="(item, index) in gzyList" :key="item" @close="onClickJczClose(index)">{{ item.sbmc }}</el-tag>
</div>
</el-form-item>
<el-form-item style="width: 100%" prop="jd" label="坐标位置">
<div class="latlng">
<el-input v-model="form.jd" clearable style="width: 45%; margin-right: 10px" />
<el-input v-model="form.wd" clearable style="width: 45%; margin-right: 10px" />
<el-button @click="seachLat">确定</el-button>
<el-button @click="zdyLat">自定义坐标</el-button>
</div>
</el-form-item>
<el-form-item style="width: 100%">
<div class="map" style="height: 520px">
<GdMap v-if="dialogFormVisible" :isShowDraw="true" />
</div>
</el-form-item>
</el-form>
<GzSource :gzyModelValue="gzyModelValue" @choosedGzy="choosedGzy" @close="gzyModelValue = false" :data="gzyList" />
</div>
</template>
<script setup>
import GzSource from "./index";
import GdMap from "@/components/GdMap/index.vue";
import {gzyzPageList,gzyEditGzyz,gzyZaddGzyz,gzyDeleteGzyz} from '@/api/lzjcz/index.js'
import emitter from "@/utils/eventBus.js";
import { useStore } from "vuex";
import {
ref,
reactive,
onMounted,
onUnmounted,
defineProps,
watch,
getCurrentInstance
} from "vue";
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(null); // 表格高度
const tableHeight1 = ref(); // 表格高度
const tableData = ref([]); //表格数据
const ids = ref([]); //批量删除的ID
const total = ref(0);
const keyCount = ref(0); //tabel组件刷新值
const btnLoading = ref(false); //按钮截流
const loadingTable = ref(false);
const dialogFormVisible = ref(false);
const gzyModelValue = ref(false); //感知源组件弹窗
const isShowBut = ref(true); //是否显示按钮 新增 修改显示
const isUpdate = ref(false); //当前操作是否为修改操作
const store = useStore();
//搜索数据
const props = defineProps({
jczid: String,
dict: Object //字典
});
const listQuery = ref({
pageCurrent: 1,
pageSize: 20,
jczid: props.jczid
});
const gzyList = ref([]);
const form = ref({});
const { proxy } = getCurrentInstance();
onMounted(() => {
form.value = {};
getListData();
tabHeightFn();
window.onresize = function () {
tabHeightFn();
};
emitter.on("coordString", (res) => {
console.log(res, "坐标");
const coords = res.coord
form.value["jd"] = coords[0];
form.value["wd"] = coords[1];
});
emitter.on("drawLngLat", (res) => {
//如果点位存在 删除点位
if (store.getters.points.length > 0) {
for (let i = 0; i < store.getters.points.length; i++) {
const item = store.getters.points[i];
egis.removePlotFeature(item);
}
store.commit("map/setPoints", []);
}
if (res.properties.t == "Point") {
store.commit("map/setPoints", [res.properties.id]);
form.value.jd = res.properties.conteolPoint[0];
form.value.wd = res.properties.conteolPoint[1];
} else {
proxy.$message.warning("请选择绘制点位");
egis.removePlotFeature(res.properties.id);
return;
}
});
});
onUnmounted(() => {
emitter.off("coordString");
emitter.off("drawLngLat");
});
//感知源组操作
const onClickGzyz = (val, type) => {
isShowBut.value = true;
isUpdate.value = false;
switch (type) {
case "info":
case "update":
form.value = val;
if (type == "info") {
isShowBut.value = false;
isUpdate.value = false;
}
if (type == "update") isUpdate.value = true;
gzyList.value = val.sxtList;
dialogFormVisible.value = true;
setTimeout(() => {
emitter.emit("addPointArea", {
coords: [val],
icon: require("@/assets/point/kk.png"),
flag: "gzyz",
isBounds: true
});
}, 1e3);
break;
case "delete":
proxy
.$confirm("确定要删除", "警告", {
type: "warning"
})
.then(() => {
deleteGzyz(val.id);
})
.catch(() => {
proxy.$message.info("已取消");
});
break;
}
};
//删除
const deleteGzyz = (id) => {
gzyDeleteGzyz(id).then((res) => {
proxy.$message.success("成功");
reset();
});
};
// 新增感知源
const addGzyEvent = () => {
dialogFormVisible.value = true;
gzyList.value = [];
};
//保存数据
const submit = () => {
let requestUrl;
form.value.sbbhList = gzyList.value.map((item) => item.id);
form.value.jczid = props.jczid;
if (isUpdate.value) {
//修改地址
gzyEditGzyz(form.value).then((res) => {
proxy.$message.success("成功");
dialogFormVisible.value = false;
form.value = {};
reset();
});
} else {
gzyZaddGzyz(form.value).then((res) => {
proxy.$message.success("成功");
dialogFormVisible.value = false;
form.value = {};
reset();
});
}
};
//批量数据
const handleSelectionChange = (val) => {
ids.value = [];
if (val) {
val.forEach((item) => {
ids.value.push(item.id);
});
}
};
//删除选中的感知源数据
const onClickJczClose = (index) => {
gzyList.value.splice(index, 1);
};
//选择感知源
const choosedGzy = (val) => {
gzyList.value = val;
if (val.length > 0) {
form.value.jd = val[0].jd;
form.value.wd = val[0].wd;
}
};
//搜索
function handleFilter() {
listQuery.value.pageNo = 1;
getListData();
}
//重置
function reset() {
listQuery.value = {
pageCurrent: 1,
pageSize: 20,
jczid: props.jczid
};
getListData();
}
//重置新增表单
function formReset() {
form.value = {};
}
//获取列表数据
function getListData() {
loadingTable.value = true;
gzyzPageList(listQuery.value)
.then((res) => {
if (res) {
tableData.value = res.records.map((item) => {
return {
...item,
btnLoading: false
};
});
total.value = res.total;
loadingTable.value = false;
}
})
.catch(() => {
loadingTable.value = false;
});
}
/**
* size 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageNum = currentPage;
getListData();
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value =
window.innerHeight - 57 - 37 - searchBox.value.offsetHeight - 130;
tableHeight1.value = window.innerHeight - 57 - 20 - 130;
};
// 搜索经纬度
function seachLat() {
emitter.emit("deletePointArea", "gzyz");
if (form.value.jd && form.value.wd) {
let item = {
jd: form.value.jd,
wd: form.value.wd
};
emitter.emit("addPointArea", {
coords: [item],
icon: require("@/assets/point/kk.png"),
flag: "gzyz"
});
} else {
proxy.$message.info("经度,纬度不能未空");
}
}
function zdyLat() {
form.value.jd = "";
form.value.wd = "";
emitter.emit("drawShape", { type: "point", flag: "gzyz", isclear: true });
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.latlng {
display: flex;
}
::v-deep .el-form--inline {
padding: 0.1rem 0 !important;
}
.updata {
&::v-deep .el-form-item__content {
display: flex;
flex-wrap: nowrap !important;
}
}
.twoh {
&::v-deep .el-textarea__inner {
height: 64px;
}
}
.map {
width: 100%;
height: 400px;
}
.ipt {
border: 1px solid rgb(7, 85, 188);
width: 100%;
line-height: 32px;
min-height: 32px;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,343 @@
<template>
<div>
<el-dialog
:title="titleValue"
width="1400px"
:model-value="gzyModelValue"
@close="closed"
>
<el-form :model="listQuery" :inline="true">
<el-form-item label="所属部门">
<MOSTY.Department width="100%" clearable v-model="listQuery.ssbmdm" />
</el-form-item>
<el-form-item label="设备编号">
<el-input
v-model="listQuery.sbbh"
placeholder="请填写设备编号"
></el-input>
</el-form-item>
<el-form-item label="感知源名称">
<el-input
v-model="listQuery.sbmc"
placeholder="请填写感知源名称"
></el-input>
</el-form-item>
<el-form-item label="感知源类型">
<el-select v-model="listQuery.sblx">
<el-option
v-for="item in D_BZ_SBLX"
:key="item"
:label="item.label"
:value="item.value"
>{{ item.label }}</el-option
>
</el-select>
</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" style="margin-top: 0px" v-if="gzyModelValue">
<el-table
ref="multipleUserRef"
@selection-change="handleSelectionChange"
:data="tableData"
border
style="width: 100%"
:row-key="keyid"
height="450"
>
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
v-if="props.multiple"
/>
<el-table-column width="55" #default="{ row }" v-else>
<el-radio v-model="ridioIndex" :label="row.id"></el-radio>
</el-table-column>
<el-table-column
label="序号"
type="index"
align="center"
sortable
width="80"
/>
<el-table-column
prop="sbmc"
show-overflow-tooltip
align="center"
label="感知源名称"
/>
<el-table-column
prop="sbbh"
show-overflow-tooltip
align="center"
label="编号"
/>
<el-table-column
prop="dzmc"
show-overflow-tooltip
align="center"
label="地址"
/>
<el-table-column
prop="sblx"
show-overflow-tooltip
align="center"
label="感知源类型"
width="120px"
>
<template #default="{ row }">
<dict-tag :options="D_BZ_SBLX" :value="row.sblx" :tag="false" />
</template>
</el-table-column>
<el-table-column
prop="sblxdm"
show-overflow-tooltip
align="center"
sortable
label="摄像机类型"
width="120px"
>
<template #default="{ row }">
<dict-tag
:options="D_BZ_GZSBLX"
:value="row.sblxdm"
:tag="false"
/>
</template>
</el-table-column>
<el-table-column
prop="ssbm"
show-overflow-tooltip
align="center"
sortable
label="所属部门"
/>
</el-table>
</div>
<div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.pageNum"
:page-sizes="[2, 5, 10, 20]"
:page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
></el-pagination>
</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>
</div>
</template>
<script setup>
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import {sxtzPageList} from '@/api/lzjcz/index.js'
// import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import {
defineProps,
watch,
ref,
onMounted,
nextTick,
getCurrentInstance
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SBLX, D_BZ_GZSBLX } = proxy.$dict("D_BZ_SBLX", "D_BZ_GZSBLX");
const props = defineProps({
//是否显示
gzyModelValue: {
type: Boolean,
required: true
},
//标题
titleValue: {
type: String,
default: "选择感知源"
},
//是否多选
multiple: {
default: true,
type: Boolean
},
//已经选中得数据回显
data: {
type: Array,
default: []
}
});
const keyid = (row) => {
return row.id;
};
const total = ref(0);
const ridioIndex = ref(null);
const listQuery = ref({
pageNum: 1,
pageSize: 20,
sblx: "",
sbmc: ""
});
const form = ref({});
const tableData = ref([]);
const emits = defineEmits(["close", "choosedGzy"]);
const closed = () => {
emits("close", false);
};
const reset = () => {
listQuery.value = {
pageNum: 1,
pageSize: 20,
sblx: ""
};
getListData();
};
const checkopenList = ref([]);
//确认选中
const onComfirm = () => {
if (props.multiple) {
//多选
const List = multipleSelectionUser.value;
if (List.length === 0) {
proxy.$message.warning("请选择感知源");
return;
}
emits("choosedGzy", [...List, ...checkopenList.value]);
} else {
//单选
if (![ridioIndex.value][0]) {
proxy.$message.warning("请选择感知源");
return;
}
const info = tableData.value.find((item) => {
return item.id === ridioIndex.value;
});
emits("choosedGzy", [info]);
}
closed();
};
onMounted(() => {
getListData();
});
/**
* pageSize 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageNum = currentPage;
getListData();
};
//圈层数据
const getListData = async () => {
sxtzPageList(listQuery.value).then((res) => {
tableData.value = res?.records;
multipleUser(props.data, tableData.value);
total.value = Number(res.total);
});
};
const handleFilter = () => {
listQuery.value.pageNum = 1;
getListData();
};
const multipleUserRef = ref(null); //表单
//多选选中的数据
const multipleSelectionUser = ref([]);
const handleSelectionChange = (val) => {
multipleSelectionUser.value = val;
if (checkopenList.value) {
for (let i = 0; i < multipleSelectionUser.value.length; i++) {
const l = multipleSelectionUser.value[i];
for (let j = 0; j < checkopenList.value.length; j++) {
const z = checkopenList.value[j];
if (l.id == z.id) {
checkopenList.value.splice(j, 1);
}
}
}
}
};
const deweighThree = (arr) => {
let map = new Map();
for (let item of arr) {
if (!map.has(item.id)) {
map.set(item.id, item);
}
}
return [...map.values()];
};
//回显
function multipleUser(row, list) {
if (row) {
row.forEach((item) => {
list.forEach((select) => {
let val = item.id ? item.id : item;
if (val == select.id) {
if (multipleUserRef.value) {
multipleUserRef.value.toggleRowSelection(select, true);
}
}
});
});
}
}
watch(
() => props.gzyModelValue,
(val) => {
if (val === true) {
handleFilter();
}
}
);
watch(
() => props.data,
(val) => {
if (multipleUserRef.value) multipleUser(val, tableData.value);
checkopenList.value = JSON.parse(JSON.stringify(val));
},
{ deep: true, immediate: true }
);
</script>
<style lang="scss" scoped>
@import "@/assets/css/layout.scss";
@import "@/assets/css/element-plus.scss";
::v-deep .el-form--inline {
padding-left: 0 !important;
}
::v-deep .el-radio__label {
display: none;
}
</style>
<style lang="scss" >
// .el-dialog {
// --el-dialog-bg-color: #001238 !important;
// }
.el-dialog__title {
// color: #fff !important;
}
</style>

View File

@ -0,0 +1,344 @@
<template>
<div>
<div class="searchBox" ref="searchBox">
<el-form :model="listQuery" :inline="true">
<el-form-item label="感知源名称" style="width: 18%">
<el-input
v-model="listQuery.sbmc"
placeholder="请填写感知源名称"
></el-input>
</el-form-item>
<el-form-item label="所属部门" style="width: 18%">
<MOSTY.Department width="100%" clearable v-model="listQuery.ssbmdm" />
</el-form-item>
<el-form-item label="设备编号">
<el-input
v-model="listQuery.sbbh"
placeholder="请填写设备编号"
></el-input>
</el-form-item>
<el-form-item prop="sblx" label="感知源类型" style="width: 16%">
<el-select v-model="listQuery.sblx">
<el-option
v-for="item in props.dict.D_BZ_SBLX"
:key="item"
:label="item.label"
:value="item.value"
>{{ item.label }}</el-option
>
</el-select>
</el-form-item>
<el-form-item prop="sblx" label="状态" style="width: 15%">
<el-select v-model="listQuery.sfdy">
<el-option label="已订阅" value="1">已订阅</el-option>
<el-option label="未订阅" value="0">未订阅</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleFilter"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
</div>
<div class="tabBox">
<el-table
@selection-change="handleSelectionChange"
:data="tableData"
border
ref="dataTreeList"
row-key="id"
:tree-props="{ children: 'itemList', hasChildren: true }"
style="width: 100%"
:key="keyCount"
:height="tableHeight"
v-loading="loadingTable"
element-loading-background="rgba(0,0,0,0.3)"
element-loading-text="数据加载中"
>
<el-table-column
type="index"
show-overflow-tooltip
align="center"
width="60px"
label="序号"
>
</el-table-column>
<el-table-column
prop="sbmc"
show-overflow-tooltip
width="250px"
label="感知源名称"
>
<template #default="{ row }">
<div>{{ row.sbmc }}</div>
</template>
</el-table-column>
<el-table-column
prop="sbbh"
show-overflow-tooltip
align="center"
label="编号"
width="250px"
>
<template #default="{ row }">
<div>{{ row.sbbh }}</div>
</template>
</el-table-column>
<el-table-column
prop="dzmc"
show-overflow-tooltip
label="地址"
width="250px"
>
<template #default="{ row }">
<div>{{ row.dzmc }}</div>
</template>
</el-table-column>
<el-table-column
prop="sblx"
show-overflow-tooltip
align="center"
label="感知源类型"
width="120px"
>
<template #default="{ row }">
<dict-tag
:options="props.dict.D_BZ_SBLX"
:value="row.sblx"
:tag="false"
/>
</template>
</el-table-column>
<el-table-column
prop="sblxdm"
show-overflow-tooltip
align="center"
label="订阅类型"
width="120px"
>
<template #default="{ row }">
<span v-if="row.sblx != '07'">远端感知</span>
<span v-else>视频天网</span>
</template>
</el-table-column>
<el-table-column prop="ssbm" show-overflow-tooltip label="所属部门">
<template #default="{ row }">
<div>{{ row.ssbm }}</div>
</template>
</el-table-column>
<el-table-column
prop="dzmc"
show-overflow-tooltip
label="状态"
width="100px"
align="center"
>
<template #default="{ row }">
<el-tag type="success" v-if="row.sfDy">已订阅</el-tag>
<el-tag type="primary" v-else>未订阅</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="150px">
<template #default="{ row }">
<el-button
size="small"
type="warning"
@click="_updateGayStaus(row, '02', '取消订阅成功')"
v-if="row.sfDy"
>
取消订阅
</el-button>
<el-button
size="small"
type="primary"
@click="_updateGayStaus(row, '01', '订阅成功')"
v-else
>
添加订阅
</el-button>
</template>
</el-table-column>
</el-table>
<div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="listQuery.pageNum"
:page-sizes="[2, 5, 10, 20]"
:page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
// import { qcckGet, qcckPost, qcckPut, qcckDelete } from "@/api/qcckApi.js";
import { sxtzPageList,sxtzjczDyGzy } from "@/api/lzjcz/index.js";
import emitter from "@/utils/eventBus.js";
import {
ref,
reactive,
onMounted,
onUnmounted,
defineProps,
watch,
getCurrentInstance
} from "vue";
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(null); // 表格高度
const tableHeight1 = ref(); // 表格高度
const tableData = ref([]); //表格数据
const ids = ref([]); //批量删除的ID
const total = ref(0);
const keyCount = ref(0); //tabel组件刷新值
const btnLoading = ref(false); //按钮截流
const loadingTable = ref(false);
//搜索数据
const props = defineProps({
jczid: String,
dict: Object, //字典
dyLx:String//视频和感知源类型
});
const listQuery = ref({
pageNum: 1,
pageSize: 20,
sbmc: "",
ssbmdm: "",
isChild: "1",
sblx: "",
sfdy: "1",
jczid: props.jczid,
dyLx:props.dyLx
});
const { proxy } = getCurrentInstance();
//批量数据
const handleSelectionChange = (val) => {
ids.value = [];
if (val) {
val.forEach((item) => {
ids.value.push(item.id);
});
}
};
//搜索
function handleFilter() {
listQuery.value.pageNo = 1;
getListData();
}
//重置
function reset() {
listQuery.value = {
pageNum: 1,
pageSize: 20,
sbmc: "",
ssbmdm: "",
isChild: "1",
sblx: "",
sfdy: "1",
jczid: props.jczid,
dyLx:props.dyLx
};
getListData();
}
//更改订阅状态
function _updateGayStaus(item, status, msg) {
let data = {
sxtid: item.id,
lx: status,
jczid: props.jczid,
dyLx:props.dyLx
};
sxtzjczDyGzy(data).then((res) => {
proxy.$message.success(msg);
reset();
});
}
//重置新增表单
function formReset() {
form.value = {};
}
//获取列表数据
function getListData() {
loadingTable.value = true;
sxtzPageList(listQuery.value).then((res) => {
if (res) {
tableData.value = res.records.map((item) => {
return {
...item,
btnLoading: false
};
});
total.value = res.total;
loadingTable.value = false;
}
});
}
/**
* size 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageNum = currentPage;
getListData();
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value =
window.innerHeight - 57 - 37 - searchBox.value.offsetHeight - 150;
tableHeight1.value = window.innerHeight - 57 - 20 - 130;
};
onMounted(() => {
getListData();
tabHeightFn();
window.onresize = function () {
tabHeightFn();
};
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .el-form--inline {
padding: 0.1rem 0 !important;
}
.updata {
&::v-deep .el-form-item__content {
display: flex;
flex-wrap: nowrap !important;
}
}
.twoh {
&::v-deep .el-textarea__inner {
height: 64px;
}
}
.map {
width: 100%;
height: 400px;
}
.ipt {
border: 1px solid rgb(7, 85, 188);
width: 100%;
line-height: 32px;
min-height: 32px;
border-radius: 4px;
}
</style>

View File

@ -0,0 +1,612 @@
<template>
<div>
<div class="titleBox">
<div class="title">检查站管理</div>
<div class="btnBox">
<el-button type="primary" @click="addKfdList()">
<el-icon style="vertical-align: middle">
<CirclePlus />
</el-icon>
<span style="vertical-align: middle">新增</span>
</el-button>
<el-button @click="deletList" :disabled="multipleSelection.length == 0" typeof="danger">
<el-icon style="vertical-align: middle">
<Delete />
</el-icon>
<span style="vertical-align: middle">批量删除</span>
</el-button>
</div>
</div>
<div class="searchBox" ref="searchBox">
<el-form class="mosty-from-wrap" :model="listQuery" :inline="true">
<el-form-item label="所属部门">
<MOSTY.Department width="100%" clearable v-model="listQuery.ssbmdm" />
</el-form-item>
<el-form-item label="检查站名称">
<el-input v-model="listQuery.jczmc" placeholder="请输入检查站名称" clearable />
</el-form-item>
<el-form-item label="执勤类型">
<el-select clearable style="width: 100%" v-model="listQuery.zqlx" placeholder="请选择执勤类型">
<el-option v-for="dict in D_BZ_ZQLX" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="点位类型">
<el-select clearable style="width: 100%" v-model="listQuery.jczlx" placeholder="请选择点位类型">
<el-option v-for="dict in D_BZ_JCZLX" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="所属圈层">
<el-select v-model="qcidList" collapse-tags multiple class="m-2" placeholder="请选择所属圈层">
<el-option v-for="item in ssqcList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleFilter"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
</div>
<div class="tabBox">
<el-table @selection-change="handleSelectionChange" :data="tableData" border row-key="kfdId" style="width: 100%" :height="tableHeight" :key="keyCount" v-loading="loadingTable"
element-loading-background="rgba(0,0,0,0.3)" element-loading-text="数据加载中">
<el-table-column type="selection" align="center" width="55" />
<el-table-column type="index" align="center" width="60px" label="序号" />
<el-table-column prop="ssbm" label="所属部门" show-overflow-tooltip align="center" />
<el-table-column prop="jczmc" show-overflow-tooltip align="center" label="检查站名称" />
<el-table-column show-overflow-tooltip align="center" label="执勤类型">
<template #default="{ row }">
<DictTag :options="D_BZ_ZQLX" :value="row.zqlx" :tag="false" />
</template>
</el-table-column>
<el-table-column show-overflow-tooltip align="center" label="点位类型">
<template #default="{ row }">
<DictTag :options="D_BZ_JCZLX" :value="row.jczlx" :tag="false" />
</template>
</el-table-column>
<el-table-column show-overflow-tooltip align="center" label="所属圈层">
<template #default="{ row }">
<el-tag v-for="item in row.qcList" :key="item.id">{{ item.qcmc }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="xxdz" show-overflow-tooltip align="center" label="检查站地址" />
<el-table-column label="感知源操作" align="center" width="250">
<template #default="{ row }">
<el-button size="small" @click="onClickDygzy(row, 'gzyz')" type="primary">配置感知源</el-button>
<el-button type="success" size="small" @click="onClickDygzy(row, 'sp')">配置现场天网</el-button>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="250">
<template #default="{ row }">
<el-button @click="update(row)" size="small">编辑</el-button>
<el-button @click="delDictItem(row.id)" type="danger" size="small">删除</el-button>
<!-- <el-button @click="commonQC(row)" size="small">同步圈层</el-button> -->
</template>
</el-table-column>
</el-table>
<div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" class="pagination" :current-page="listQuery.pageCurrent" :page-sizes="[2, 5, 10, 20]" :page-size="listQuery.pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
</div>
<!-- 弹窗 -->
<div v-if="dialogFormVisible" class="dialog">
<div class="head_box">
<span class="title">{{ diaTitle }}</span>
<div>
<el-button type="primary" :loading="btnLoading" size="small" @click="submit">保存</el-button>
<el-button size="small" @click="dialogFormVisible = false">关闭</el-button>
</div>
</div>
<el-form ref="elform" :model="form" :rules="rules" :inline="true" label-position="top" class="mosty-from-wrap">
<el-form-item style="width: 31%" prop="ssbmdm" label="所属部门">
<MOSTY.Department :placeholder="form.ssbm" style="width: 100%" ref="cascader" clearable filterable :options="depList" :props="props" v-model="form.ssbmdm" />
</el-form-item>
<el-form-item style="width: 31%" prop="jczmc" label="检查站名称">
<el-input v-model="form.jczmc" placeholder="请输入检查站名称" style="width: 100%" clearable />
</el-form-item>
<el-form-item label="执勤类型" style="width: 31%" prop="zqlx">
<el-select v-model="form.zqlx" placeholder="请选择执勤类型">
<el-option v-for="item in D_BZ_ZQLX" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item style="width: 32%" prop="jczlx" label="点位类型">
<el-select v-model="form.jczlx" placeholder="请选择点位类型">
<el-option v-for="item in D_BZ_JCZLX" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item style="width: 31%" label="站点负责人">
<el-input v-model="form.fzr" placeholder="请输入站点负责人" style="width: 100%" clearable />
</el-form-item>
<el-form-item style="width: 31%" label="联系电话">
<el-input v-model="form.lxdh" placeholder="请输入联系电话" style="width: 100%" clearable />
</el-form-item>
<el-form-item label="道路类型" style="width: 31%" prop="dllx">
<el-select v-model="form.dllx" placeholder="请选择道路类型">
<el-option v-for="item in D_BZ_DLLX" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item style="width: 31%" prop="xxdz" label="检查站地址">
<el-input v-model="form.xxdz" placeholder="请输入检查站地址" style="width: 100%" clearable />
</el-form-item>
<el-form-item @click="showRichOnly = true" style="width: 31%" prop="ssqc" label="所属圈层" required>
<el-input v-model="form.ssqc" placeholder="所属圈层" style="width: 100%" clearable suffix-icon="ArrowDown" v-if="qcList.length === 0" />
<template v-else>
<el-tag v-for="(item, index) in qcList" :key="item.id" closable @close="onCloseQc(index)">{{ item.qcmc }}</el-tag>
</template>
</el-form-item>
<MOSTY.RichOnly width="100%" :data="qcList" v-model="showRichOnly" @close="showRichOnly = false" @choosedQc="choosedQcData" />
<el-form-item label="示意图(最多3张)" prop="fjid" style="width: 48%">
<MOSTY.Upload :isImg="true" width="100%" :limit="3" v-model="form.fjid"></MOSTY.Upload>
</el-form-item>
<el-form-item label="全景图(正面、侧面、俯视共3张)" prop="qjfjid" style="width: 48%">
<MOSTY.Upload width="100%" :isImg="true" :limit="3" v-model="form.qjfjid"></MOSTY.Upload>
</el-form-item>
<el-form-item style="width: 100%" prop="jd" label="坐标位置">
<div class="latlng">
<el-input v-model="form.jd" clearable style="width: 45%" />
<el-input v-model="form.wd" clearable style="width: 45%" />
<el-button @click="seachLat">确定</el-button>
<el-button @click="zdyLat">自定义坐标</el-button>
</div>
</el-form-item>
<el-form-item style="width: 100%">
<div class="map">
<GdMap :isShowDraw="true" />
</div>
</el-form-item>
</el-form>
</div>
<!-- 订阅天网视频 -->
<div v-if="dialogSpVisible" class="dialog">
<div class="head_box">
<span class="title">选择现场视频</span>
<div>
<el-button @click="(dialogSpVisible = false), (formGzy.radius = 2000)">关闭</el-button>
</div>
</div>
<Pzgzy :dyLx="'02'" :jczid="formGzy.jczid" :dict="{ D_BZ_GZSBLX, D_BZ_SBLX, D_BZ_SF }" v-if="formGzy.jczid"/>
</div>
<!-- 添加感知源组 -->
<div v-if="dialogGzyzVisible" class="dialog">
<div class="head_box">
<span class="title">感知源组管理</span>
<div>
<el-button @click="dialogGzyzVisible = false">关闭</el-button>
</div>
</div>
<AddGzyZ :jczid="formGzy.jczid" :dict="{ D_BZ_GZSBLX, D_BZ_SBLX, D_BZ_SF }" :data="gzyList"/>
</div>
</div>
</template>
<script setup>
import { selectDeptPage } from "@/api/user-manage";
import * as MOSTY from "@/components/MyComponents/index";
import GdMap from "@/components/GdMap/index.vue";
import AddGzyZ from "./component/addGzyZ.vue";
import Pzgzy from "./component/pzgzy.vue";
import {
selectQcList,
sysQcck,
} from "@/api/file.js";
import {JczSelectJczList,qcSelectQcList,JczupdateJcz,JczSaveJcz,JczDeletesJcz,} from '@/api/lzjcz/index.js'
import { getItem } from "@/utils/storage.js";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import {
ref,
reactive,
onMounted,
getCurrentInstance,
onUnmounted,
inject,
watch,
nextTick
} from "vue";
const { proxy } = getCurrentInstance();
const userId = getItem("USERID");
import emitter from "@/utils/eventBus.js";
const {
D_BZ_KFDLX,
D_BZ_DLLX,
D_BZ_JCZJB,
D_BZ_JCZLX,
D_BZ_QCLX,
D_BZ_ZQLX,
D_BZ_GZSBLX,
D_BZ_SBLX,
D_BZ_SF
} = proxy.$dict(
"D_BZ_KFDLX",
"D_BZ_DLLX",
"D_BZ_JCZJB",
"D_BZ_JCZLX",
"D_BZ_QCLX",
"D_BZ_ZQLX",
"D_BZ_GZSBLX",
"D_BZ_SBLX",
"D_BZ_SF"
);
const showRichOnly = ref(false);
const chackipt = ref(true);
const cascader = ref(null);
const depList = ref([]); //部门数据
const keyCount = ref(0); //tabel组件刷新值
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(null); // 表格高度
const diaTitle = ref("新增检查站");
const loadingTable = ref(false);
const checkList = ref([]);
const reload = inject("reload");
const isShow = ref(false); //是否是修改
const qcidList = ref([]);
const listQuery = ref({
pageCurrent: 1,
pageSize: 20,
jczmc: "",
ssbmdm: ""
});
//表单数据
const form = ref({
jczmc: "",
ssbmdm: "",
jd: "",
wd: "",
qjfjid: []
});
const gzyTotal = ref(0); //感知源总数
const gzyFunction = ref("01"); //感知源功能选项
const dialogSpVisible = ref(false); //显示视频弹窗
const dialogGzyzVisible = ref(false); //显示感知源组弹窗
const btnLoading = ref(false); //按钮加载
const tableData = ref([]); //表单数据
const total = ref(0); //总数据
const dialogFormVisible = ref(false);
const multipleSelection = ref([]); //批量数据
const mapType = ref(""); //地图绘制对象
const gzyMapList = ref([]); //感知源数据
const selectJcz = ref(); //已选择感知源
const router = useRouter();
const store = useStore();
const handleFilter = () => {
listQuery.value.pageCurrent = 1;
getListData();
};
//表单验证
const rules = reactive({
jczmc: [{ required: true, message: "请输入检查站名称", trigger: "change" }],
ssbmdm: [{ required: true, message: "请选择部门", trigger: "change" }],
jczlx: [{ required: true, message: "请选择点位类型", trigger: "change" }],
zqlx: [{ required: true, message: "请选择执勤类型", trigger: "change" }],
fzr: [{ required: true, message: "请输入站点负责人", trigger: "change" }],
lxdh: [{ required: true, message: "请输入联系电话", trigger: "change" }],
dllx: [{ required: true, message: "请选择道路类型", trigger: "change" }],
xxdz: [{ required: true, message: "请输入检查站地址", trigger: "change" }],
jd: [{ required: true, message: "请选择快返点位置", trigger: "change" }],
ssqc: [{ required: true, message: "请选择所属圈层", trigger: "change blur" }]
});
const elform = ref(null);
const qcList = ref([]); //选中的圈层数据
//级联选择器配置
const props = {
expandTrigger: "children",
children: "childDeptList",
label: "orgName",
value: "id",
checkStrictly: true,
emitPath: false
};
const formGzy = ref({
pageNum: 1,
pageSize: 20,
isChild: 1
});
onMounted(() => {
tabHeightFn();
window.onresize = function () {
tabHeightFn();
};
//获取地图选点坐标
emitter.on("coordString", (res) => {
if (res.type === "point") {
form.value.jd = res.coord[0];
form.value.wd = res.coord[1];
}
});
getListData();
getQCListData();
emitter.on("drawLngLat", (res) => {
//如果点位存在 删除点位
if (store.getters.points.length > 0) {
for (let i = 0; i < store.getters.points.length; i++) {
const item = store.getters.points[i];
egis.removePlotFeature(item);
}
store.commit("map/setPoints", []);
}
if (res.properties.t == "Point") {
store.commit("map/setPoints", [res.properties.id]);
form.value.jd = res.properties.conteolPoint[0];
form.value.wd = res.properties.conteolPoint[1];
} else {
proxy.$message.warning("请选择绘制点位");
egis.removePlotFeature(res.properties.id);
return;
}
});
});
const ssqcList = ref([]);
//圈层数据
const getQCListData =() => {
let params = { pageCurrent: 1, pageSize: 100 };
qcSelectQcList(params).then((res) => {
let arr = res.records || [];
ssqcList.value = arr.map((item, index) => {
return { label: item.qcmc, value: item.id };
});
});
};
// 同步圈层
// const commonQC = (val) => {
// proxy
// .$confirm("确定要同步该数据到检查站", "警告", { type: "warning" })
// .then(() => {
// console.log(val);
// sysQcck(val.id).then((res) => {
// proxy.$message.success(res);
// getListData();
// });
// })
// .catch((err) => {console.log(err);});
// };
onUnmounted(() => {
emitter.off("coordString");
emitter.off("showJczDygzy");
emitter.off("drawLngLat");
});
//选中的圈层数据
const choosedQcData = (val) => {
qcList.value = val;
form.value.ssqc = "111";
};
const onCloseQc = (index) => {
qcList.value.splice(index, 1);
if (qcList.value.length == 0) {
form.value.ssqc = "";
}
};
//显示订阅感知源
function onClickDygzy(row, type) {
switch (type) {
case "gzyz":
dialogGzyzVisible.value = true;
break;
case "sp":
dialogSpVisible.value = true;
break;
}
formGzy.value = {
...formGzy.value,
jczid: row.id
};
}
//获取数据
const getListData = () => {
loadingTable.value = true;
listQuery.value.qcidList = qcidList.value.join(",");
JczSelectJczList(listQuery.value)
.then((res) => {
loadingTable.value = false;
if (res && res.records) {
tableData.value = res.records;
total.value = res.total;
}
})
.catch((err) => {
loadingTable.value = false;
});
};
const reset = () => {
listQuery.value = { pageCurrent: 1, pageSize: 20 };
form.value = { fjid: "", qjfjid: "" };
qcidList.value = [];
getListData();
};
//批量数据
const handleSelectionChange = (val) => {
multipleSelection.value = [];
if (val) {
val.forEach((item) => {
multipleSelection.value.push(item.id);
});
}
};
//新增
function addKfdList() {
qcList.value = [];
diaTitle.value = "新增检查站";
nextTick(() => {
dialogFormVisible.value = true;
});
form.value = {
fjid: "",
qjfjid: ""
};
isShow.value = false;
}
//删除
const delDictItem = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
JczDeletesJcz({ids:[id]}).then(() => {
proxy.$message.success("删除成功");
getListData();
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
//批量删除
const deletList = () => {
proxy
.$confirm("确定要删除", "警告", {
type: "warning"
})
.then(() => {
const ids = multipleSelection.value;
JczDeletesJcz({ids:ids}).then(() => {
proxy.$message.success("删除成功");
getListData();
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
//修改
const update = (row) => {
nextTick(() => {
dialogFormVisible.value = true;
let obj = JSON.parse(JSON.stringify(row));
if (obj.qjfjid) obj.qjfjid = obj.qjfjid.split(",");
if (obj.fjid) obj.fjid = obj.fjid.split(",");
form.value = obj;
isShow.value = true;
diaTitle.value = "修改检查站";
setTimeout(() => {
emitter.emit("addPointArea", {
coords: [row],
icon: require("@/assets/point/jwz.png"),
flag: "zqd",
isBounds: true
});
emitter.emit("setMapCenter", {
location: [row.jd, row.wd],
zoomLevel: 10
});
}, 1e3);
qcList.value = [];
if (row.qcList) {
qcList.value = row.qcList;
form.value.ssqc = "111";
}
});
};
function changeStatus(row) {
let params = { id: row.id, sfqd: row.sfqd };
qcckPost(params, "/mosty-jcgl/jcz/updateJcz").then((res) => {
let text = row.sfqd == 0 ? "关闭成功" : "启动成功";
proxy.$message.success(text);
getListData();
});
}
function zdyLat() {
form.value.jd = "";
form.value.wd = "";
emitter.emit("drawShape", { type: "point", flag: "zqd", isclear: true });
}
// 搜索经纬度
function seachLat() {
emitter.emit("deletePointArea", "zqd");
if (form.value.jd && form.value.wd) {
let item = { jd: form.value.jd, wd: form.value.wd };
emitter.emit("addPointArea", {
coords: [item],
icon: require("@/assets/point/jwz.png"),
flag: "zqd"
});
emitter.emit("setMapCenter", {
location: [form.value.jd, form.value.wd],
zoomLevel: 10
});
} else {
proxy.$message.info("经度,纬度不能未空");
}
}
//提交
function submit() {
elform.value.validate((valid) => {
if (valid) {
form.value.qcidList = qcList.value.map((item) => item.id);
console.log(form.value, "form.value.");
let prams = { ...form.value };
if (prams.fjid && Array.isArray(prams.fjid))
prams.fjid = prams.fjid.join(",");
if (prams.qjfjid && Array.isArray(prams.qjfjid))
prams.qjfjid = prams.qjfjid.join(",");
if (!isShow.value) {
JczSaveJcz(prams).then((res) => {
proxy.$message.success("新增成功");
dialogFormVisible.value = false;
reset();
});
} else {
JczupdateJcz(prams).then((res) => {
proxy.$message.success("编辑成功");
dialogFormVisible.value = false;
reset();
});
}
}
});
}
/**
* size 改变触发
*/
const handleSizeChange = (currentSize) => {
listQuery.value.pageSize = currentSize;
getListData();
};
/**
* 页码改变触发
*/
const handleCurrentChange = (currentPage) => {
listQuery.value.pageCurrent = currentPage;
getListData();
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 238;
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
// @import "~@/assets/css/element-plus.scss";
.map {
width: 100%;
height: 400px;
}
.latlng {
width: 100%;
display: flex;
justify-content: space-between;
}
.dygzy {
padding: 20px;
.function_box {
display: flex;
align-items: center;
}
}
</style>

View File

@ -0,0 +1,295 @@
<template>
<!-- 勤务作息编辑新增 -->
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button type="primary" size="small" @click="onSave" v-if="bcBtn" :loading="btnLoading">保存</el-button>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="mt20">
<el-form ref="formRef" :model="formData" :rules="rules" :inline="true" label-position="top">
<el-form-item prop="qwdj" label="勤务等级" style="width: 25%">
<el-select v-model="formData.qwdj" :disabled="!bcBtn">
<el-option v-for="dict in dic.D_BZ_DJQW" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="qwQzsj" label="勤务起止时间" style="width: 25%">
<el-date-picker style="width: 100%" :disabled="!bcBtn" v-model="formData.qwQzsj" type="datetimerange" range-separator="至" start-placeholder="开始时间" unlink-panels end-placeholder="结束时间"
format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
</el-form-item>
<el-form-item prop="ssbmdm" label="所属部门" style="width: 25%">
<MOSTY.Department width="100%" :disabled="!bcBtn" :placeholder="formData.ssbm" clearable v-model="formData.ssbmdm" />
</el-form-item>
<el-form-item prop="sfxj" label="是否发送到下级" style="width: 25%">
<el-select style="width: 100%" v-model="formData.sfxj" :disabled="!bcBtn">
<el-option v-for="dict in dic.D_BZ_SF" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item prop="jyzqrybl" label="建议执勤人员比例(%" style="width: 25%">
<el-input-number :max="100" :min="0" style="width: 100%" v-model="formData.jyzqrybl" :step="1" :disabled="!bcBtn" />
</el-form-item>
<el-form-item prop="jyzqclbl" label="建议执勤车辆比例(%" style="width: 25%">
<el-input-number style="width: 100%" v-model="formData.jyzqclbl" :step="1" :disabled="!bcBtn" />
</el-form-item>
<el-form-item prop="kdbbs" label="检查站" style="width: 25%">
<div class="inputbox" @click="chooseUserVisible=true">
<el-tag v-for="(item, index) in listData.jczList" :key="index" class="mx-1" closable @close="handleCloseCl(item)">
{{ item.jczmc }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="警务站" style="width: 25%">
<div class="inputbox" @click="JwzLoadVisible=true">
<el-tag v-for="(item, index) in listData.jwzList" :key="index" class="mx-1" closable @close="JwzCloseCl(item)">
{{ item.jwzMc }}
</el-tag>
</div>
</el-form-item>
<!-- <el-form-item prop="kdbbs" label="专家库" style="width: 25%">
<div class="inputbox" @click="ZjkLoadVisible=true">
<el-tag v-for="(item, index) in listData.zjkList" :key="index" class="mx-1" closable @close="ZjkCloseCl(item)">
{{ item.jczmc }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="资源库" style="width: 25%">
<div class="inputbox" @click="ZykLoadVisible=true">
<el-tag v-for="(item, index) in listData.zykList" :key="index" class="mx-1" closable @close="ZykCloseCl(item)">
{{ item.jczmc }}
</el-tag>
</div>
</el-form-item> -->
<el-form-item prop="kdbbs" label="卡点数量" style="width: 25%">
<el-input-number :max="100" :min="0" style="width: 100%" v-model="formData.kdbbs" :step="1" disabled />
</el-form-item>
<el-form-item prop="cysr" label="参与人数" style="width: 25%">
<el-input-number style="width: 100%" v-model="formData.cysr" :step="1" :disabled="!bcBtn" />
</el-form-item>
<el-form-item class="twoh" style="width: 100%" prop="qwyy" label="勤务原因">
<el-input v-model="formData.qwyy" placeholder="请填写勤务原因" show-word-limit type="textarea" :disabled="!bcBtn" />
</el-form-item>
<el-form-item class="twoh" style="width: 100%" prop="qwyq" label="勤务要求">
<el-input v-model="formData.qwyq" placeholder="请填写勤务要求" show-word-limit type="textarea" :disabled="!bcBtn" />
</el-form-item>
<el-form-item style="width: 100%;" label="等级勤务方案">
<MOSTY.FileUpload v-model:modelValue="formData.fjdz" :limit="3" :isEdit="bcBtn" style="height:150px;" @handleChange="changeFile"></MOSTY.FileUpload>
</el-form-item>
<el-form-item label="备注" style="width: 100%">
<el-input v-model="formData.bz" placeholder="请输入关键字" :disabled="!bcBtn" show-word-limit type="textarea" />
</el-form-item>
</el-form>
</div>
<JczLoad v-model="chooseUserVisible" @choosedJcz="choosedJcz" :modelValue='true' :data='listData.jczList' />
<ZjkLoad v-model="ZjkLoadVisible" @choosedJcz="choosedZjk" :modelValue='true' :data='listData.zjkList' />
<JwzLoad v-model="JwzLoadVisible" @choosedJcz="choosedJwz" :modelValue='true' :data='listData.zjkList' />
<ZykLoad v-model="ZykLoadVisible" @choosedJcz="choosedZyk" :modelValue='true' :data='listData.zykList' />
</div>
</template>
<script setup>
import GdMap from "@/components/GdMap/index.vue";
import emitter from "@/utils/eventBus.js";
// src\views\backOfficeSystem\qwManagement\xfpb\xfa\jczLoad.vue
import JczLoad from "@/components/DanLoding/jczLoad.vue";
import ZjkLoad from "@/components/DanLoding/ZjkLoad.vue";
import JwzLoad from "@/components/DanLoding/jwzLoad.vue";
import ZykLoad from "@/components/DanLoding/zykLoad.vue";
import { reactive, ref, getCurrentInstance, defineEmits, onMounted } from "vue";
import{qwjdSava,qwjdPut,qwjdId} from '@/api/lzqwzx/index.js'
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import ChooseUser from "@/components/MyComponents/choosePolice";
const props = defineProps({
dic: Object
});
const configerUser = reactive({
//选择人员配置
chooseUserVisible: false,
titleValue: "人员选择",
PoliceType: "MJ",
chooseUser: []
});
const changeFile = (data) => {
form.value.fjdz = data;
};
const { proxy } = getCurrentInstance();
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
// const formData = ref({});
const formData = ref({
jyzqclbl: 34,
jyzqrybl: 34,
qwQzsj: [],
sfxj: "0"
});
const title = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
// jwzMc: [{ required: true, message: "请输入警务站名称", trigger: "blur" }],
// ssbmdm: [{ required: true, message: "请选择所属部门", trigger: "blur" }],
});
/**部门id对照对象 */
let departmentIdObj = {};
onMounted(() => {
emitter.on("coordString", (res) => {
if (res.type === "point") {
formData.value.jd = res.coord[0];
formData.value.wd = res.coord[1];
}
});
});
const hanlderChoose = (val) => {
formData.value.fzrXm = val[0].xm;
formData.value.fzrSfzh = val[0].sfzh;
};
const bcBtn = ref(true);
/** 初始化数据 */
const init = (type, row) => {
title.value =
type == "add"
? "新增勤务等级"
: type == "edit"
? "编辑勤务等级"
: "编辑勤务详情";
bcBtn.value = type == "xq" ? false : true;
isShowDialog.value = true;
if (row) {
qwjdId(row.id).then((res) => {
formData.value = res;
formData.value.qwQzsj = [res.qwkssj, res.qwjssj];
});
}
};
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 保存
const btnLoading = ref(false);
const onSave = () => {
formRef.value.validate((valid) => {
if (valid) {
btnLoading.value = true;
const data = {
...formData.value,
qwkssj: formData.value.qwQzsj[0],
qwjssj: formData.value.qwQzsj[1],
...listData
};
delete data.qwQzsj;
if (title.value == "新增勤务等级") {
qwjdSava(data)
.then(() => {
proxy.$message({
type: "success",
message: "新增成功"
});
})
.finally(() => {
btnLoading.value = false;
});
} else if (title.value == "编辑勤务等级") {
data.id = formData.value.id;
console.log(formData.value.id);
qwjdPut(data)
.then(() => {
proxy.$message({
type: "success",
message: "修改成功"
});
// dialogFormVisible.value = false;
})
.finally(() => {
btnLoading.value = false;
});
}
closeDialog();
emits("updateList", {});
}
});
formRef.value.validate((valid) => {});
};
const fileEdit = ref(true);
const listData = reactive({
jczList: [],
jwzList: [],
// zjkList: [],
// zykList: [],
// flzyList: []
});
// 选择检查站
const chooseUserVisible = ref(false);
const choosedJcz = (row) => {
listData.jczList = row;
formData.value.kdbbs=row.length
};
const handleCloseCl = (row) => {
listData.jczList.splice(listData.jczList.indexOf(row), 1);
};
//选择检务站
const JwzLoadVisible=ref(false)
const choosedJwz = (row) => {
listData.jwzList = row;
};
const JwzCloseCl = (row) => {
listData.jwzList.splice(listData.jwzList.indexOf(row), 1);
};
//选择专家库
const ZjkLoadVisible = ref(false);
const choosedZjk = (row) => {
listData.zjkList = row;
};
const ZjkCloseCl = (row) => {
listData.zjkList.splice(listData.zjkList.indexOf(row), 1);
};
//选择资源库
const ZykLoadVisible=ref(false)
const choosedZyk = (row) => {
listData.zjkList = row;
};
const ZykCloseCl = (row) => {
listData.zykList.splice(listData.zykList.indexOf(row), 1);
};
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
.map {
width: 100%;
height: 500px;
}
.inputbox {
width: 100%;
min-height: 32px;
border-radius: 5px;
border: 1px solid #d5d2d2;
}
</style>

View File

@ -0,0 +1,304 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">勤务等级</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', null)">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<el-form :model="searchConfiger" :inline="true">
<el-form-item prop="qwdj" label="勤务等级">
<el-select clearable style="width: 100%" v-model="searchConfiger.qwdj">
<el-option v-for="dict in D_BZ_DJQW" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="勤务起止时间">
<el-date-picker v-model="queryTime" unlink-panels type="daterange" range-separator="至" start-placeholder="开始时间" end-placeholder="结束时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item>
<el-button @click="handleFilter"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
</div>
<div class="tabBox">
<MyTable v-loading="loadingTable" :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth">
<template #qwdj="{ row }">
<dict-tag :options="D_BZ_DJQW" :value="row.qwdj" :tag="false"></dict-tag>
</template>
<template #qwkssj="{ row }">
<div>{{ row.qwkssj }} {{ row.qwjssj }}</div>
</template>
<template #jyzqrybl="{ row }">
<div>{{ row.jyzqrybl }}%</div>
</template>
<template #jyzqclbl="{ row }">
<div>{{ row.jyzqclbl }}%</div>
</template>
<template #fbzt="{ row }">
<span v-if="row.fbzt == 0">未发布</span>
<span v-if="row.fbzt == 1">已发布</span>
<span v-if="row.fbzt == 2">已结束</span>
</template>
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-button @click="tableEdit(row)" size="small">警力情况</el-button>
<el-button v-if="row.fbzt == 1" @click="jsQw(row)" size="small">结束勤务</el-button>
<el-button v-if="row.fbzt == 0" :loading="row.btnLoading" @click="fabu(row)" size="small">发布勤务</el-button>
<el-button v-if="row.fbzt == 0" @click="addEdit('edit', row)" size="small">修改</el-button>
<el-button v-if="row.fbzt != 0" @click="addEdit('xq', row)" size="small">详情</el-button>
<el-button v-if="row.fbzt == 0" type="danger" size="small" @click="delDictItem(row)">删除</el-button>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" :dic="{D_BZ_DJQW,D_BZ_SF}" />
<TableEdit ref="tableEditDialog" :tableHeight="tableHeight"/>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import Search from "@/components/aboutTable/Search.vue";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { getqwdj, deleteQwdj, fabuzt, updateQwdj } from "@/api/file.js";
import{qwjdSelectList,qwjdpublish,qwjdPut,qwjdelete} from '@/api/lzqwzx/index.js'
import { ElMessage } from "element-plus";
import EditAddForm from "./editAddForm.vue";
import TableEdit from "./tableEdit.vue";
// const { proxy } = getCurrentInstance();
// const { D_BZ_DJQW, D_BZ_ZXFW,D_BZ_SF } = proxy.$dict("D_BZ_DJQW", "D_BZ_ZXFW","D_BZ_SF");
const { proxy } = getCurrentInstance();
const { D_BZ_JWZLX, D_BZ_DJQW ,D_BZ_SF} = proxy.$dict("D_BZ_JWZLX", "D_BZ_DJQW","D_BZ_SF");
const addEditDialog = ref();
const searchConfiger = reactive({ qwdj: "", qwkssj: "", qwjssj: "" });
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 320, //操作栏宽度
tableColumn: [
{
label: "勤务等级",
prop: "qwdj",
showSolt: true
},
{
label: "勤务起止时间",
prop: "qwkssj",
showSolt: true
},
{
label: "所属部门",
prop: "ssbm"
},
{
label: "建议执勤人员比例",
prop: "jyzqrybl",
showSolt: true
},
{
label: "建议执勤车辆比例",
prop: "jyzqclbl",
showSolt: true
},
{
label: "状态",
prop: "fbzt",
showSolt: true
}
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 新增和修改详情
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
const tableEditDialog=ref()
const tableEdit=(row)=>{
tableEditDialog.value.init(row)
}
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageNo = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 处理删除数据
function delDictItem(row) {
if (row.fbzt === "1") {
proxy.$message({
type: "error",
message: "勤务已经发布,不能删除!!"
});
} else {
proxy
.$confirm("确定删除当前勤务等级?", "警告", { type: "warning" })
.then(() => {
qwjdelete(row.id).then(() => {
proxy.$message({
type: "success",
message: "删除成功"
});
getList();
});
})
.catch(() => {
proxy.$message.info("已取消");
});
}
}
//详情
// function info(row) {
// title.value = "勤务等级详情";
// bcBtn.value = false;
// getQwdjInfo(row.id).then((res) => {
// form.value = res;
// form.value.qwQzsj = [res.qwkssj, res.qwjssj];
// chackAdd.value = false;
// fileEdit.value = false;
// dialogFormVisible.value = true;
// });
// }
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const loadingTable = ref(false);
const queryTime = ref([]);
// 处理勤务数据
const getList=()=> {
loadingTable.value = true;
let params = { ...searchConfiger, ...pageData.pageConfiger };
qwjdSelectList(params)
.then((res) => {
pageData.tableData = res.records.map((item) => {
return {
...item,
};
});
pageData.total = res.total;
loadingTable.value = false;
})
.catch(() => {})
.finally(() => {
loadingTable.value = false;
});
}
const handleFilter = () => {
if (queryTime.value.length > 0) {
searchConfiger.qwkssj = queryTime.value[0];
searchConfiger.qwjssj = queryTime.value[1];
}
getList();
};
//发布
const fabu=(row)=> {
proxy
.$confirm("请确认发布此等级勤务", "警告", {
type: "warning"
})
.then((_) => {
qwjdpublish({
id: row.id
}).then(() => {
proxy.$message({
type: "success",
message: "发布成功"
});
getList();
});
})
.catch((_) => {
proxy.$message.info("已取消");
});
}
function jsQw(row) {
proxy
.$confirm("请确认结束此等级勤务", "警告", {
type: "warning"
})
.then((_) => {
row.fbzt = "2";
qwjdPut(row).then(() => {
proxy.$message({
type: "success",
message: "已结束该等级勤务"
});
getLis();
});
})
.catch((_) => {
proxy.$message.info("已取消");
});
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,152 @@
<template>
<!-- 勤务作息编辑新增 -->
<div v-if="jlqkVisible" class="dialog">
<div class="head_box">
<span class="title">警力情况</span>
<div>
<el-button size="small" @click="jlqkVisible = false">关闭</el-button>
</div>
</div>
<el-table
:data="zqjlData"
border
ref="dataTreeList"
row-key="id"
style="width: 100%"
:height="tableHeight"
v-loading="loadingTable"
element-loading-background="rgba(0,0,0,0.3)"
element-loading-text="数据加载中"
>
<el-table-column
sortable
prop="ssbmmc"
show-overflow-tooltip
align="center"
label="所属部门名称"
/>
<el-table-column
sortable
prop="ksrq"
show-overflow-tooltip
align="center"
label="开始日期"
>
</el-table-column>
<el-table-column
sortable
prop="jsrq"
show-overflow-tooltip
align="center"
label="结束日期"
>
</el-table-column>
<el-table-column
prop="xzsl"
label="街面巡组数"
align="center"
></el-table-column>
<el-table-column
sortable
prop="mjsl"
label="巡防民警数"
align="center"
></el-table-column>
<el-table-column
sortable
prop="fjsl"
show-overflow-tooltip
label="巡防辅警数"
align="center"
>
</el-table-column>
<el-table-column
sortable
prop="clsl"
show-overflow-tooltip
label="巡防车辆数"
align="center"
>
</el-table-column>
<el-table-column
sortable
prop="znzbsl"
show-overflow-tooltip
label="智能装备数"
align="center"
>
</el-table-column>
<el-table-column
sortable
prop="qxsl"
show-overflow-tooltip
label="警用器械数"
align="center"
>
</el-table-column>
</el-table>
<!-- <div class="fenye" :style="{ top: tableHeight + 'px' }">
<el-pagination
class="pagination"
:current-page="listQueryzq.pageCurrent"
:page-sizes="[10, 20, 50]"
:page-size="listQueryzq.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalzq"
>
</el-pagination>
</div> -->
</div>
</template>
<script setup>
import {ref,defineExpose, reactive} from 'vue'
import {qwbbList} from '@/api/file.js'
const props=defineProps({
tableHeight:Number
})
const jlqkVisible=ref(false)
/** 初始化数据 */
const init = ( row) => {
if (row) {
jlqkVisible.value=true
qwbbListData(row.id)
}
};
const totalzq=ref(0)
const loadingTable=ref(false)
const zqjlData= ref();
const qwbbListData=(val)=>{
loadingTable.value=true
qwbbList({id:val}).then(res=>{
zqjlData.value=res
}).finally(()=>{
loadingTable.value=false
})
}
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
}
.dialog .el-form-item--default.form-item {
width: calc(50% - 100px);
margin-bottom: 10px;
}
.map {
width: 100%;
height: 500px;
}
</style>

View File

@ -0,0 +1,188 @@
<template>
<div class="form-item-box" :style="{ width: width }">
<el-cascader
:disabled="disabled"
style="width: 100%"
class="el-cascader-zj"
:show-all-levels="false"
clearable
filterable
:placeholder="modelValue ? placeholder : '请选择部门'"
:options="tableData"
v-model="oldmodelValue"
@change="handleChange"
:props="endProps"
/>
</div>
</template>
<script setup>
import { COMPONENT_WIDTH } from "@/constant";
import { servicePost, serviceGet, qcckFlvGet } from "@/api/serviceApi.js";
import {
ref,
defineProps,
defineEmits,
defineExpose,
computed,
onMounted,
watch
} from "vue";
import { selectDeptPage } from "@/api/user-manage";
const props = defineProps({
//获取组件传值
placeholder: {
default: "请选择",
type: String
},
multiple: {
default: false,
type: Boolean
},
isAll: {
default: 100,
type: Number
},
modelValue: {
type: String ||Array ,
default: ""
},
disabled: {
type: Boolean,
default: false
},
width: {
default: COMPONENT_WIDTH,
type: String
},
// 不使用懒加载
noLazyTree: {
default: false,
type: Boolean
}
});
const modelShow = ref(false);
const oldmodelValue = ref([]);
const listQuery = ref({
deptname: "",
deptcode: "",
parentid: ""
});
const depList = ref([]);
//配置项
let endProps = {
children: "childDeptList",
value: "orgCode",
label: "orgName",
checkStrictly: true,
multiple: props.multiple,
lazy: true,
lazyLoad(node, resolve) {
listQuery.value.parentid = node.data.id;
selectDeptPage(listQuery.value).then((res) => {
depList.value = depList.value.concat(res);
//处理部门是否包含下级
for (let i = 0; i < res.length; i++) {
res[i].leaf = !res[i].hasChildren;
}
resolve(res);
});
}
};
if (props.noLazyTree) {
endProps = {
multiple: props.multiple
};
}
const getChild = (arr) => {
if (!arr.length) return [];
return arr.map((item) => {
const isHadChild = item.childDeptList?.length > 0;
if (isHadChild) item.children = getChild(item.childDeptList);
return {
label: item.orgName,
value: item.orgCode, // orgCode
...item
};
});
};
const tableData = ref([]);
/**获取所有数据,不用懒加载 */
const getAllTreeData = () => {
servicePost({}, "/mosty-base/sysDept/getAllChildDeptList").then((res) => {
tableData.value = getChild(res.childDeptList);
depList.value = tableData.value;
});
};
const getSysMenuTree = async () => {
const res = await selectDeptPage(listQuery.value);
tableData.value = res;
depList.value = res;
};
onMounted(() => {
if (props.noLazyTree) {
console.log("xxxxx");
getAllTreeData();
} else {
getSysMenuTree();
console.log("-------");
}
});
watch(
() => props.modelValue,
(val) => {
oldmodelValue.value = val;
},
{ deep: true, immediate: true }
);
const emits = defineEmits(["update:modelValue", "getDepValue"]);
const handleChange = (e) => {
console.log("e", e);
if (props.multiple === true) {
const data = e.map((item) => {
return item[item.length - 1];
});
emits("update:modelValue", data);
/** 数组转评级对象 key 为orgCode*/
let treeToMapObj = (arr) => {
let codeObj = {};
function setArrChild(arr2) {
arr2.forEach((item) => {
let currCode = item.orgCode; // 关键字设置
if (item.childDeptList?.length > 0) setArrChild(item.childDeptList);
codeObj[currCode] = {
...item,
childDeptList: [],
children: []
};
});
}
setArrChild(arr);
return codeObj;
};
let treeObj = treeToMapObj(depList.value);
let dataRetail = data.map((code) => {
let obj = treeObj[code]; // 对象对应中找
return obj;
});
emits("getDepValue", dataRetail);
} else {
// 仅用于多选先
// const data = e ? e[e.length - 1] : "";
// emits("update:modelValue", data);
// let obj = depList.value.find(item=>{ return item.orgCode == data})
// emits("getDepValue", obj);
}
};
</script>
<style lang="scss" scoped>
.el-cascader-zj {
width: 100%;
}
</style>

View File

@ -0,0 +1,474 @@
<template>
<div class="dialog" v-if="isShowDialog">
<div class="head_box">
<span class="title" v-if="!isDetail">{{ isAdd ? '新增' : '修改' }}</span>
<span class="title" v-else>详情</span>
<div>
<el-button type="primary" size="small" @click="onSave" :loading="buttonLoading" v-if="!isDetail">保存</el-button>
<el-button size="small" @click="closeDialog">关闭</el-button>
</div>
</div>
<div class="form-content">
<el-form ref="formRef" :label-width="140" :model="formData" :rules="rules" inline>
<div class="content">
<el-form-item style="width:48%" class="form-item" prop="faMc" label="方案名称">
<el-input v-model="formData.faMc" :disabled="isDetail" placeholder="请输入方案名称"></el-input>
</el-form-item>
<el-form-item style="width:48%" class="form-item" prop="faBmdj" label="方案部门等级">
<MOSTY.Select :dictEnum="props.dic.D_QW_FA_BMDJ" :disabled="isDetail" placeholder="请选择方案部门等级"
v-model="formData.faBmdj" />
</el-form-item>
<el-form-item style="width:48%" class="form-item" prop="faQwdj" label="方案勤务等级">
<MOSTY.Select :dictEnum="props.dic.D_QW_FA_QWDJ" :disabled="isDetail" placeholder="请选择方案勤务等级"
v-model="formData.faQwdj" />
</el-form-item>
<el-form-item style="width:48%" class="form-item" prop="faSjKsrq" label="方案时间开始日期">
<el-date-picker style="width:100%;" type="date" v-model="formData.faSjKsrq" :disabled="isDetail"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item style="width:48%" class="form-item" prop="faSjJsrq" label="方案时间结束日期">
<el-date-picker style="width:100%;" type="date" v-model="formData.faSjJsrq" :disabled="isDetail"
value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item style="width:48%" class="form-item" prop="bbsl" label="报备数量">
<el-input-number v-model="formData.bbsl" :disabled="isDetail" :min="0" :step="1"></el-input-number>
</el-form-item>
<!-- 这里要改列表 -->
<el-form-item style="width:48%" v-if="!isDetail" class="form-item" prop="bmListVal" label="部门列表">
<!-- <MOSTY.Department width="100%" clearable @getDepValue="modelValue" multiple v-model="formData.bmListVal" :modelValue="formData.bmListVal" :noLazyTree="true" /> -->
<!-- <Department width="100%" clearable @getDepValue="modelValue"
multiple v-model="formData.bmListVal"
:modelValue="formData.bmListVal" noLazyTree /> -->
<MOSTY.Department :multiple="true" width="100%"
clearable noLazyTree @getDepValue="getDepValue"
v-model="formData.bmListVal"
/>
</el-form-item>
<el-form-item prop="kdbbs" label="检查站" style="width: 48%">
<div class="inputbox" @click="chooseUserVisible = true">
<el-tag v-for="(item, index) in listData.jczList" :key="index" class="mx-1" closable
@close="handleCloseCl(item)">
{{ item.jczmc }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="警务站" style="width: 48%">
<div class="inputbox" @click="JwzLoadVisible = true">
<el-tag v-for="(item, index) in listData.jwzList" :key="index" class="mx-1" closable
@close="JwzCloseCl(item)">
{{ item.jwzMc }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="专家库" style="width: 48%">
<div class="inputbox" @click="ZjkLoadVisible = true">
<el-tag v-for="(item, index) in listData.zjkList" :key="index" class="mx-1" closable
@close="ZjkCloseCl(item)">
{{ item.xm }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="资源库" style="width: 48%">
<div class="inputbox" @click="ZykLoadVisible = true">
<el-tag v-for="(item, index) in listData.zykList" :key="index" class="mx-1" closable
@close="ZykCloseCl(item)">
{{ item.zymc }}
</el-tag>
</div>
</el-form-item>
<el-form-item prop="kdbbs" label="法律指引" style="width: 48%">
<div class="inputbox" @click="FlLoadVisible = true">
<el-tag v-for="(item, index) in listData.flzyList" :key="index" class="mx-1" closable
@close="ZykCloseCl(item)">
{{ item.title }}
</el-tag>
</div>
</el-form-item>
<el-form-item style="width:100%" class="form-item" prop="faSm" label="方案说明">
<el-input type="textarea" v-model="formData.faSm" :disabled="isDetail" placeholder="请输入方案说明"></el-input>
</el-form-item>
<el-form-item style="width:100%" class="form-item" prop="faZl" label="方案资料">
<el-input type="textarea" v-model="formData.faZl" :disabled="isDetail" placeholder="请输入方案资料"></el-input>
</el-form-item>
</div>
<div v-if="isDetail" class="department-list">
<h3>部门列表:</h3>
<div class="department-item" v-for="item of formData.bmList" :key="item.id">
{{ item.ssbm }}
</div>
</div>
</el-form>
</div>
</div>
<JczLoad v-model="chooseUserVisible" @choosedJcz="choosedJcz" :modelValue='true' :data='listData.jczList' />
<ZjkLoad v-model="ZjkLoadVisible" @choosedJcz="choosedZjk" :modelValue='true' :data='listData.zjkList' />
<JwzLoad v-model="JwzLoadVisible" @choosedJcz="choosedJwz" :modelValue='true' :data='listData.zjkList' />
<ZykLoad v-model="ZykLoadVisible" @choosedJcz="choosedZyk" :modelValue='true' :data='listData.zykList' />
<FlLoad v-model="FlLoadVisible" @choosedJcz="choosedFl" :modelValue='true' :data='listData.flzyList' />
</template>
<script setup>
import{qwfaUpdate,qwfaSave} from '@/api/lzqwzx/index.js'
import { reactive, ref, getCurrentInstance, defineEmits } from "vue";
import JczLoad from "@/components/DanLoding/jczLoad.vue";
import ZjkLoad from "@/components/DanLoding/ZjkLoad.vue";
import JwzLoad from "@/components/DanLoding/jwzLoad.vue";
import ZykLoad from "@/components/DanLoding/zykLoad.vue";
import FlLoad from "@/components/DanLoding/flLoad.vue";
import * as MOSTY from "@/components/MyComponents/index";
import * as rule from "@/utils/rules.js";
import { qwfatbQwglQwfa } from '@/api/file.js'
import Department from "./department.vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF } = proxy.$dict("D_BZ_SF");
const props = defineProps({
dic: Object
});
const emits = defineEmits(["updateList"]);
const loading = ref(false); // 加载
const formRef = ref(); // 表单验证
const formDataDefault = ref({});
const formData = ref({});
const title = ref("");
let listData = reactive({
jczList: [],
jwzList: [],
zjkList: [],
zykList: [],
flzyList: []
});
formData.value.bmList = [];
/** type {Array} 部门列表 */
const modelValue = (val) => {
console.log("val", val);
if (val?.length > 0) {
formData.value.bmList = val.map((item) => {
const isTrue = D_BZ_SF.value[1]?.dm;
const isFalse = D_BZ_SF.value[0]?.dm;
return {
isChild: isTrue,
ssbm: item.orgName,
ssbmdm: item.orgCode
};
});
} else {
formData.value.bmList = [];
}
};
const isAdd = ref(false); // 是否是新增状态
const isShowDialog = ref(false); //弹窗
const dialogType = ref(0); // add 新增 edit编辑 detail详情
const isDetail = ref(false);
const rules = reactive({
faMc: [{ required: true, message: "请填写方案名称", trigger: "blur" }],
faBmdj: [{ required: true, message: "请选择部门等级", trigger: "blur" }],
faQwdj: [{ required: true, message: "请选择勤务等级", trigger: "blur" }],
faSjKsrq: [
{ required: true, message: "请选择方案时间开始日期", trigger: "blur" }
],
faSjJsrq: [
{ required: true, message: "请选择方案时间结束日期称", trigger: "blur" }
]
});
/**部门id对照对象 */
let departmentIdObj = {};
const init = (type, row) => {
// formDataDefault.value = JSON.parse(JSON.stringify(formData.value));
isShowDialog.value = true; // 显示新增编辑dialog框
isAdd.value = type == "add" ? true : false;
dialogType.value = type;
isDetail.value = type === "detail";
// 是否有填充数据
let data = formDataDefault.value || {};
departmentIdObj = {};
if (row && type == "edit") {
// let {
// id,
// faMc,
// faBmdj,
// faQwdj,
// faSjKsrq,
// faSjJsrq,
// bmList,
// faSm,
// bbsl,
// faZl
// } = row;
/** 初始化-获取需要的部门列表格式 */
const getNeedBmList = (arr) => {
if (!Array.isArray(arr)) return [];
return arr.map((item) => {
let newItem = {
isChild: item?.isChild,
ssbm: item?.ssbm,
ssbmdm: item?.ssbmdm
};
return newItem;
});
};
/**保存一份原来部门列表的id在对象中 */
function getDepartmentIdObj(arr) {
let obj = {};
if (!Array.isArray(arr)) return {};
arr.forEach((item) => {
let code = item.ssbmdm; // 部门代码 ssbmdm
obj[code] = item.id;
});
return obj;
}
// formData.value = {
// id,
// faMc,
// faBmdj,
// faQwdj,
// faSjKsrq,
// faSjJsrq,
// bmList,
// bmListVal,
// faSm,
// bbsl,
// faZl
// };
// 新增
qwfatbQwglQwfa(row.id).then(res => {
formData.value = res
departmentIdObj = getDepartmentIdObj(res.bmList);
formData.value.bmList = getNeedBmList(res.bmList);
formData.value.bmListVal = res.bmList.map((item) => item.ssbmdm);
listData.jczList = res.jczList
listData.jwzList = res.jwzList
listData.zjkList = res.zjkList
listData.zykList = res.zykList
listData.flzyList = res.flzyList
})
} else if (type == "detail") {
qwfatbQwglQwfa(row.id).then(res => {
formData.value = res
listData.jczList = res.jczList
listData.jwzList = res.jwzList
listData.zjkList = res.zjkList
listData.zykList = res.zykList
listData.flzyList = res.flzyList
})
}
};
// 重置表单
const reserForm = () => {
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
// 关闭弹窗
const closeDialog = () => {
isShowDialog.value = false;
loading.value = false;
listData.jczList = []
listData.jwzList = []
listData.zjkList = []
listData.zykList = []
listData.flzyList = []
formData.value = JSON.parse(JSON.stringify(formDataDefault.value));
};
/**获取有id的部门列表(原来有的就赋值上去,否则为空) */
const getBmListWithId = (arr) => {
if (!Array.isArray(arr)) return [];
return arr.map((item) => {
if (departmentIdObj[item.ssbmdm]) item.id = departmentIdObj[item.ssbmdm];
return item;
});
};
// 保持test TODO:
const onSave = () => {
formRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
buttonLoading.value = true;
let params={}
if(formData.value.faMc.slice(-2)=='方案'){
params= { ...formData.value, ...listData};
}else{
params = { ...formData.value, ...listData,faMc:formData.value.faMc+'方案'};
}
let text = isAdd.value ? "新增成功" : "编辑成功";
delete params.bmListVal;
if (isAdd.value) {
delete params.id;
qwfaSave(params) .then((res) => {
closeDialog();
buttonLoading.value = false;
proxy.$message.success(text);
emits("updateList", {});
})
.catch(() => {
loading.value = false;
buttonLoading.value = false;
});
} else {
params.bmList = getBmListWithId(params.bmList);
qwfaUpdate(params) .then((res) => {
closeDialog();
buttonLoading.value = false;
proxy.$message.success(text);
emits("updateList", {});
})
.catch(() => {
loading.value = false;
buttonLoading.value = false;
});
}
// let url = isAdd.value ? "/tbQwglQwfa/save" : "/tbQwglQwfa/update";
if (isAdd.value) {
} else {
}
// servicePost(params, `/mosty-qwzx${url}`)
});
};
const buttonLoading = ref(false);
// 选择检查站
const chooseUserVisible = ref(false);
const choosedJcz = (row) => {
listData.jczList = row;
formData.value.kdbbs = row.length;
};
const handleCloseCl = (row) => {
listData.jczList.splice(listData.jczList.indexOf(row), 1);
};
//选择检务站
const JwzLoadVisible = ref(false);
const choosedJwz = (row) => {
listData.jwzList = row;
};
const JwzCloseCl = (row) => {
listData.jwzList.splice(listData.jwzList.indexOf(row), 1);
};
//选择专家库
const ZjkLoadVisible = ref(false);
const choosedZjk = (row) => {
listData.zjkList = row;
};
const ZjkCloseCl = (row) => {
listData.zjkList.splice(listData.zjkList.indexOf(row), 1);
};
//选择资源库
const ZykLoadVisible = ref(false);
const choosedZyk = (row) => {
listData.zykList = row;
};
const ZykCloseCl = (row) => {
listData.zykList.splice(listData.zykList.indexOf(row), 1);
};
//法律指引
const FlLoadVisible = ref(false);
const FlCloseCl = (row) => {
listData.flzyList.splice(listData.flzyList.indexOf(row), 1);
};
const choosedFl = (row) => {
listData.flzyList = row;
};
const getDepValue = (res) => {
formData.value.bmList = res.map(item => {
return {
...item,
ssbm: item.orgName,
ssbmdm: item.orgCode
}
});
console.log(formData.value.bmList,"xxxxxxxxxxxxxxxxxxxxxxxxxx");
}
defineExpose({ init });
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.form-content {
margin-top: 20px;
}
.bblxItem {
line-height: 40px;
min-height: 40px;
// display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
}
.content {
// display: flex;
// flex-wrap: wrap;
padding: 10px 40px;
}
.dialog {
&::v-deep .el-form--inline {
padding: 0 !important;
}
&::v-deep .el-input__inner {
border: 1px solid #d5d2d2;
}
// width: ;
// overflow-x: hidden;
}
.dialog .el-form-item--default.form-item {
// border: 1px solid rgb(226, 200, 200);
// max-width: 400px;
width: calc(50% - 100px);
margin-bottom: 10px;
}
.department-list {
padding: 10px 20px;
}
.department-item {
color: #000;
margin-left: 20px;
height: 35px;
line-height: 35px;
// border-top: none;
}
.inputbox {
width: 100%;
min-height: 32px;
border-radius: 5px;
border: 1px solid #d5d2d2;
}
</style>

View File

@ -0,0 +1,333 @@
<template>
<!-- <div> 勤务方案</div> -->
<div class="main-box">
<div class="tableCnt">
<div class="titleBox">
<div class="title">勤务方案</div>
<div class="btnBox">
<el-button type="primary" @click="addEdit('add', '')">
<el-icon>
<CirclePlus />
</el-icon>
<span>新增方案</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<el-form class="mosty-from-wrap" :model="listQuery" :inline="true">
<el-form-item label="所属部门">
<MOSTY.Department :multiple="true" width="100%" clearable v-model="list" />
</el-form-item>
<el-form-item label="方案勤务等级">
<el-select v-model="listQuery.faQwdj" class="m-2" placeholder="请选择方案勤务等级">
<el-option v-for="item in D_QW_FA_QWDJ" :label="item.label" :key="item.value" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="方案部门等级">
<el-select v-model="listQuery.faBmdj" class="m-2" placeholder="请选择方案部门等级">
<el-option v-for="item in D_QW_FA_BMDJ" :label="item.label" :key="item.value" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="方案名称">
<el-input v-model="listQuery.faMc" placeholder="请输入方案名称"></el-input>
</el-form-item>
<el-form-item label="方案开始日期">
<el-date-picker v-model="listQuery.faSjKsrq" format="YYYY-MM-DD" value-format="YYYY-MM-DD" type="date" placeholder="请输入方案开始日期" />
</el-form-item>
<el-form-item label="方案结束日期">
<el-date-picker v-model="listQuery.faSjJsrq" format="YYYY-MM-DD" value-format="YYYY-MM-DD" type="date" placeholder="请输入方案结束日期" />
</el-form-item>
<el-form-item label="方案部门等级">
<el-select v-model="listQuery.faZt" class="m-2" placeholder="请选择方案部门等级">
<el-option v-for="item in D_QW_FA_ZT" :label="item.label" :key="item.value" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="onSearch"> 查询 </el-button>
<el-button @click="reset()"> 重置 </el-button>
</el-form-item>
</el-form>
<!-- <Search :searchArr="searchConfiger" @submit="onSearch" /> -->
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<!-- 部门列表 -->
<template #bmList="{ row }">
<!-- {{row}} -->
<div>
<span v-for="item in row.bmList" :key="item.id">{{item.ssbm}};</span>
</div>
</template>
<!-- 控制按钮 -->
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
<span class="linkGapLine">|</span>
<!-- [创建][停止]只能"开启",[开启]只能"停用" -->
<el-link type="primary" @click="switchStatus(row.id,row)">{{row.faZt=='02'?'停止':'开启'}}</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="seeDetail('detail',row)">详情</el-link>
<span class="linkGapLine">|</span>
<!-- <el-link type="primary" @click="preview(row)">方案预览</el-link> -->
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" @updateList="getList" :dic="{D_QW_FA_BMDJ,D_QW_FA_QWDJ}" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import { useRoute, useRouter } from 'vue-router';
import Search from "@/components/aboutTable/Search.vue";
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import {qwfaSelectPage} from "@/api/lzqwzx/index.js"
import { ElMessage } from "element-plus";
import { selectDeptPage, getAllChildDeptList } from "@/api/user-manage";
import EditAddForm from "./editAddForm.vue";
import * as MOSTY from "@/components/MyComponents/index";
const { proxy } = getCurrentInstance();
const { D_QW_FA_QWDJ, D_QW_FA_BMDJ, D_QW_FA_ZT } = proxy.$dict(
"D_QW_FA_QWDJ",
"D_QW_FA_BMDJ",
"D_QW_FA_ZT"
);
const addEditDialog = ref();
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61, // 高度height?
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{ label: "方案名称", prop: "faMc", showOverflowTooltip: true, width: 100 },
{
label: "方案部门等级",
prop: "faBmdjName",
showOverflowTooltip: true,
width: 100
},
{
label: "方案勤务等级",
prop: "faQwdjName",
showOverflowTooltip: true,
width: 100
},
{
label: "报备数量",
prop: "bbsl",
showOverflowTooltip: true,
width: 100
},
{
label: "方案时间开始日期",
prop: "faSjKsrq",
showOverflowTooltip: true,
// noDateDisabled: true,
width: 100
},
{
label: "方案时间结束日期",
prop: "faSjJsrq",
noDateDisabled: true,
showOverflowTooltip: true,
width: 100
},
{
label: "部门列表",
prop: "bmList",
showOverflowTooltip: true,
showSolt: true,
width: 180
},
{ label: "方案说明", prop: "faSm", showOverflowTooltip: true },
{ label: "方案资料", prop: "faZl", showOverflowTooltip: true },
{
label: "方案状态",
prop: "faZtName",
width: 80,
showOverflowTooltip: true
}
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
// const bumen = ref();
const selectDept = () => {
const listQuery = {
deptname: "",
deptcode: "",
parentid: ""
};
// getAllChildDeptList({}).then((res) => {
// bumen.value = res;
// });
};
selectDept();
// mounted
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
const list = ref([]);
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value.list = list.value.toString();
listQuery.value = { ...listQuery.value, ...val };
console.log(listQuery.value);
getList();
};
// 详情借用新增和修改的页面
const seeDetail = (type, row) => {
addEdit(type, row);
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = false;
qwfaSelectPage(params)
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records || [];
pageData.tableData = pageData.tableData.map((item) => {
item.faZtName = D_QW_FA_ZT.value.find(
(item2) => item2.value == item.faZt
)?.label;
item.faQwdjName = D_QW_FA_QWDJ.value.find(
(item2) => item2.value == item.faQwdj
)?.label;
item.faBmdjName = D_QW_FA_BMDJ.value.find(
(item2) => item2.value == item.faBmdj
)?.label;
return item;
});
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
serviceDelete({}, "/mosty-qwzx/tbQwglQwfa/" + id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
const switchStatus = (id, row) => {
proxy
.$confirm("确定要修改状态", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
let isOpen = row.faZt == "02";
let api = isOpen ? "/tbQwglQwfa/shutoff/" : "/tbQwglQwfa/start/";
let txt = isOpen ? "停止" : "开启";
serviceGet({}, `/mosty-qwzx/${api}${id}`).then((res) => {
proxy.$message.success(`${txt}成功`);
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
// 方案预览
// useRoute, useRouter
const router=useRouter()
const preview=(val)=>{
const to = router.resolve({
name: "preview",
path: "/preview",
query: {
id: val.id
}
});
window.open(to.href, "_blank");
}
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,195 @@
<template>
<div class="main-box" >
<div class="tableCnt">
<div class="titleBox">
<div class="title">勤务轨迹</div>
</div>
<div class="flex">
<div >
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bbZt="{ row }">
<dict-tag :options="D_QW_BBZT" :value="row.bbZt" :tag="true"></dict-tag>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="lookGj(row,'gjhf')">轨迹回放</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{ ...pageData.pageConfiger, total: pageData.total}" />
</div>
<div class="mapbox" :style="{ height: tableHeight?tableHeight +90+ 'px':'600px' }">
<MapDialog v-model:modelValue="isShowMap" :lxtype="typeGj" :data="gJDate"/>
</div>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import MapDialog from './mapDialog.vue';
import { timeValidate, weekValidate } from "@/utils/tools.js";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted,
defineEmits,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const { D_QW_BBZL,D_QW_BBZT } = proxy.$dict("D_QW_BBZL","D_QW_BBZT");
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
dic: Object
});
const gJDate = ref({});
const isShowMap = ref(true); //展示地图
const typeGj = ref(''); //轨迹回放类型
const isShowBb = ref(false);
const searchConfiger = reactive([
{
showType: "defaultSlot",
label: "报备类型"
},
{
showType: "input",
prop: "jzMc",
placeholder: "请输入警组名称",
label: "警组名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "警组名称", prop: "jzMc" },
{ label: "报备开始时间", prop: "bbSjKssj" },
{ label: "报备结束时间", prop: "bbSjJssj" },
{ label: "所属部门 ", prop: "ssbm" },
{ label: "报备状态 ", prop: "bbZt", showSolt: true }
]
});
const loading = ref(false);
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const bblx = ref();
const listQuery = ref({});
const baseDate = reactive({
year: timeValidate(null, "ymd"),
week: weekValidate(timeValidate(null, "ymd")),
bbzt: "街面勤务报备",
info: null
});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
val.startTime = val.daterange ? val.daterange[0] + " 00:00:00" : "";
val.endTime = val.daterange ? val.daterange[1] + " 23:59:59" : "";
listQuery.value = { ...listQuery.value, ...val };
delete listQuery.value.daterange;
getList();
};
// 轨迹回放
function lookGj (row,type){
if(type == 'clgj' && row.clList && row.clList.length==0){
return proxy.$message({ type: "info", message: '该数据没有报备车辆' });
}
typeGj.value = type
gJDate.value = row
}
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let params = { ...listQuery.value, ...pageData.pageConfiger };
if (baseDate.bbzt != "值班报备" && baseDate.bbzt != "街面勤务报备") {
let obj = D_QW_BBZL.value.find((it) => {
return it.label == baseDate.bbzt;
});
params.qwBbzl = obj.dm;
}
serviceGet(params, '/mosty-qwzx/tbQwglXfbb/selectPage')
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
if(pageData.pageConfiger.pageCurrent==1) lookGj(res.records[0],'gjhf')
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 250 ;
window.onresize = function () {
tabHeightFn();
};
};
const changeCanlendar = () => {
emits("update:modelValue", true);
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
::v-deep .dialog .el-form--inline {
padding: 0 !important;
}
.mapbox{
// position: relative;
padding: 0 10px;
width: 1000px;
box-sizing: border-box;
z-index: 1;
}
</style>

View File

@ -0,0 +1,354 @@
<template>
<div class="mm-box" v-if="modelValue">
<div class="head_box_ii">
<div class="timeBox">
<div class="time-map">{{ times[0] }}</div>
<el-slider v-model="playTime" id="playtimeSlider" :range="true" :min="sliderMIn" :max="sliderMax" :format-tooltip="playTimeFormat" @change="playTimeChange" :key="videoTndex">
</el-slider>
<div class="time-map" v-if="times[0]">{{ times[1] }}</div>
<div style="display:flex;" v-if="props.lxtype == 'gjhf'">
<el-select v-model="sbId" @change="getGjDare" style="width:150px">
<el-option v-for="item in gpisSbList" :key="item.gpsId" :label="item.gpsMc" :value="item.gpsId" />
</el-select>
<el-button @click="chooseTime">搜索</el-button>
<el-button @click="getGjDare">轨迹回放</el-button>
<el-button v-if="props.data.xffwlx == 1" @click="getXfqData">
巡防区
</el-button>
<el-button size="small" v-else-if="props.data.xffwlx == 2" @click="getKfdData">快反点
</el-button>
</div>
</div>
</div>
<div class="map">
<GdMap :isShowDraw="true"/>
</div>
</div>
</template>
<script setup>
import { spliceArray, spliceString } from "@/utils/auth.js";
import { ElMessage } from "element-plus";
import {
getTbJcglXfqySelectById,
getTpJcglKfdSelectByid
} from "@/api/dpApi/home.js";
import {gjselectLswz} from '@/api/lzjmxf/index.js'
import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import GdMap from "@/components/GdMap/index.vue";
import emitter from "@/utils/eventBus.js";
import { ref, watch, getCurrentInstance } from "vue";
import { timeValidate } from "@/utils/tools.js";
const emits = defineEmits(["update:modelValue"]);
const { proxy } = getCurrentInstance();
const playTime = ref(null); //时间
const detailFiles = ref([]); //时间范围
const sliderMIn = ref(0);
const sliderMax = ref(0);
const videoTndex = ref(1);
const hphm = ref("");
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
data: {
type: Object,
default: {}
},
lxtype: String
});
const sbId = ref();
const isClearn = ref(true);
const times = ref([1, 1]);
const gpisSbList = ref([]);
const bbId=ref()
watch(
() => props.data,
(val) => {
if (val) {
hphm.value = "";
let ks = val.bbSjKssj;
let js = val.bbSjJssj ? val.bbSjJssj : timeValidate(new Date());
times.value = [ks, js];
console.log(val);
bbId.value=val.id
if (val.gpsInfoList) {
gpisSbList.value = val.gpsInfoList;
sbId.value = gpisSbList.value[0].gpsId;
}
let start = new Date(ks).getTime();
let end = new Date(js).getTime();
sliderMIn.value = start;
sliderMax.value = end;
playTime.value = [start, end];
if (props.lxtype == "gjhf" && sbId.value){
getGjDare();
}
// else{
// proxy.$message({ type: "warning", message: `请选择设备` });
// }
}
},
{
immediate: true,
deep: true
}
);
// 滑块提示
function playTimeFormat(val) {
let time = new Date(val);
return timeValidate(time);
}
//选中时间
function playTimeChange(val) {
let kssj = timeValidate(val[0]);
let jssj = timeValidate(val[1]);
times.value = [kssj, jssj];
}
// 根据时间来画轨迹
function chooseTime() {
let params = {
gpsId:sbId.value,
kssj: times.value[0],
jssj: times.value[1]
};
emitter.emit("removeTrajec", "route");
emitter.emit("deletePointArea", "xzlxIcon");
servicePost(params, "/mosty-jmxf/tbWzXfwz/selectSbLswz").then((res) => {
let arr = res || [];
let brr = [];
arr.forEach((item) => {
brr.push([item.jd, item.wd]);
});
if (brr.length > 0) {
emitter.emit("drawLineAnimation", {
coords: brr,
isClear: true,
flag: "route"
});
} else {
proxy.$message({ type: "warning", message: `没有轨迹数据` });
}
});
}
// 获取轨迹
function getGjDare() {
let params = {
kssj: props.data.bbSjKssj,
jssj: props.data.bbSjJssj ? props.data.bbSjJssj : timeValidate(new Date()),
bbId:bbId.value,
gpsId:sbId.value
// kssj: "2024-06-29 00:00:00",
// jssj: "2024-06-29 23:59:59",
// gpsId: "15390385926"
};
emitter.emit("removeTrajec", "route");
emitter.emit("deletePointArea", "xzlxIcon");
gjselectLswz(params).then((res) => {
let arr = res || [];
let brr = [];
arr.forEach((item) => {
brr.push([item.jd, item.wd]);
});
if (brr.length) {
emitter.emit("drawLineAnimation", { coords: brr, isClear: true, flag: "route"});
} else {
proxy.$message({ type: "warning", message: `没有轨迹数据` });
}
});
// servicePost(params, "/mosty-wzzx/tbWzXfwz/selectSbLswz").then((res) => {
// let arr = res || [];
// let brr = [];
// arr.forEach((item) => {
// brr.push([item.jd, item.wd]);
// });
// if (brr.length) {
// emitter.emit("drawLineAnimation", { coords: brr, isClear: true, flag: "route"});
// } else {
// proxy.$message({ type: "warning", message: `没有轨迹数据` });
// }
// });
}
// 获取车辆轨迹
function getClDare() {
emitter.emit("removeTrajec", "route");
emitter.emit("deletePointArea", "xzlxIcon");
if (hphm.value == "")
return proxy.$message({ type: "warning", message: `请选择车辆` });
let list = props.data.clList;
let obj = list.find((item) => {
return item.jdchphm == hphm.value;
});
if (obj && obj.gpsId) {
let params = {
gpsId: obj.gpsId,
kssj: props.data.bbkssj,
jssj: props.data.bbjssj ? props.data.bbjssj : timeValidate(new Date())
};
servicePost(params, "/mosty-jmxf/tbWzXfwz/selectSbLswzMo").then((res) => {
let arr = res || [];
let brr = arr.map((item) => {
return [item.jd, item.wd];
});
if (brr.length > 0) {
emitter.emit("drawLineAnimation", {
coords: brr,
isClear: true,
flag: "route"
});
} else {
proxy.$message({ type: "warning", message: `没有轨迹数据` });
}
});
} else {
proxy.$message({ type: "warning", message: `该车辆暂时没有轨迹` });
}
}
//获取巡防区数据
function getXfqData() {
isClearn.value = !isClearn.value;
if (isClearn.value) {
emitter.emit("deletePointArea", "xfq");
emitter.emit("deletePoint", "kfd");
emitter.emit("deleteText"); //清除巡防区文字
} else {
let ids = props.data.xffwid.split(",");
if (ids.length > 0) {
ids.forEach((el) => {
getTbJcglXfqySelectById({ id: el }).then((res) => {
if (res) {
if (res.jd && res.wd) {
emitter.emit("setMapCenter", {
location: [res.jd, res.wd],
zoomLevel: 14
});
}
if (res.pgis.length > 0) {
let array = spliceString(res.pgis);
getCenterPoint(res.pgis, res.xfqMc);
emitter.emit("polygonFigure", {
coords: [array],
flag: "xfq",
isclear: false
});
}
} else {
ElMessage({ message: "暂无巡防区数据", type: "warning" });
}
});
});
} else {
ElMessage({ message: "暂无巡防区数据", type: "warning" });
}
}
}
// 获取范围中心的
function getCenterPoint(dm, text) {
servicePost(dm, "/mosty-base/other/getZxd").then((res) => {
let points = [res.x, res.y];
emitter.emit("addTEXT", { points, text });
});
}
//获取快反点数据
function getKfdData() {
isClearn.value = !isClearn.value;
if (isClearn.value) {
emitter.emit("deletePoint", "kfd");
emitter.emit("deletePointArea", "kfdArea");
} else {
getTpJcglKfdSelectByid({ id: props.data.xffwid }).then((res) => {
if (res) {
//点位数据
let arr = [];
if (res.jd && res.wd) {
let icon = require("@/assets/point/f.png");
emitter.emit("addPoint", { coords: [res], icon: icon, flag: "kfd" });
emitter.emit("setMapCenter", {
location: [res.jd, res.wd],
zoomLevel: 14
});
}
//一分钟范围
if (res.yfzfw.length > 0) {
let yy = spliceString(res.yfzfw);
emitter.emit("polygonFigure", {
coords: [yy],
flag: "kfdArea",
color: "#ff0000",
opacity: 0.5
});
}
//三分钟范围
if (res.sfzfw.length > 0) {
let ss = spliceString(res.sfzfw);
arr.push(ss);
emitter.emit("polygonFigure", {
coords: [ss],
flag: "kfdArea",
color: "#fdae2e",
opacity: 0.3
});
}
//五分钟范围
if (res.wfzfw.length > 0) {
let ww = spliceString(res.wfzfw);
arr.push(ww);
emitter.emit("polygonFigure", {
coords: [ww],
flag: "kfdArea",
color: "#0066ff",
opacity: 0.1
});
}
} else {
ElMessage({ message: "暂无快反点数据", type: "warning" });
}
});
}
}
</script>
<style lang="scss" scoped>
.mm-box {
width: 100%;
height: 100%;
.head_box_ii {
width: 100%;
display: flex;
height: 60px;
align-items: center;
justify-content: space-between;
.timeBox {
display: flex;
align-items: center;
.time-map {
width: 212px;
margin: 0 10px;
color: #000;
}
}
}
.map {
position: absolute;
width: 100%;
height: 100%;
}
}
.hphmBox {
display: flex;
height: 60px;
align-items: center;
.btn {
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,512 @@
<template>
<div class="canderlarBox">
<div class="leftbox noScollLine">
<div class="categary">
<el-calendar v-model="dateVal" ref="calendar">
<template #header="{ date }">
<div class="dateTime">{{ date }} {{ date.new }}</div>
<div style="font-size: 16px; display: flex; color: #fff">
<span class="changeBtn" @click="selectDate('prev-month')">上一月</span>
<span class="changeBtn" @click="selectDate('today')">今天</span>
<span class="changeBtn" @click="selectDate('next-month')">下一月</span>
<!-- 传入部门开始日期结束日期接口暂不开发先加按钮 -->
<span class="changeBtn">排班报表导出</span>
<span class="changeBtn" @click="changeList">列表切换</span>
</div>
</template>
<template #dateCell="{ data }">
<div class="date ddd" @click="chooseDay(data)">
<!-- 表示是今天 -->
<div v-if="data.day === pageData.todayStr" class="line"></div>
<div class="day">{{ data.day.split("-")[2] }}</div>
<!-- 下面的文字 -->
<template v-for="(item, index) in dateCount" :key="index">
<div class="fontBox" v-if="data.day == item.tjrqStr">
<div class="fontItem mj" v-show="item.mjsl">
<div class="item_left">
<div class="line"></div>
<div>民警</div>
</div>
<div class="num_text">{{item.mjsl}}</div>
</div>
<div class="fontItem fj" v-show="item.fjsl">
<div class="item_left">
<div class="line"></div>
<div>辅警</div>
</div>
<div class="num_text">{{item.fjsl}}</div>
</div>
<div class="fontItem jc" v-show="item.clsl">
<div class="item_left">
<div class="line"></div>
<div>警车</div>
</div>
<div class="num_text">{{item.clsl}}</div>
</div>
</div>
</template>
</div>
</template>
</el-calendar>
</div>
</div>
<div class="rightbox" :style="{ width: isOpen ? '440px' : '0px' }">
<span class="icon" @click="openInfo"></span>
<!-- 头部 -->
<div class="rightbox-top flex just-center align-center">
<div class="calendar_rttop">
<div class="calendar_date flex f15 just-around align-center">
<span>{{ baseDate.year }}</span>
<span class="f16">{{ baseDate.week }}</span>
</div>
<div class="calendar_dateNub f76">{{ baseDate.year.slice(8, 11) }}</div>
</div>
</div>
<div class="rightbox-bottom">
<div class="bbtitle flex">
<span>报备单位</span>
<MOSTY.Department v-model="pageData.ssbmdm" placeholder="请选择部门" @getDepValue="changeDep" />
</div>
<ul class="bbBox">
<li class="bbBoxItem" v-for="(item,idx) in pageData.bbdwList" :key="idx">
<div class="title">{{ item.label }}</div>
<div>民警:{{ item.mjsl }}</div>
<div>辅警:{{ item.fjsl }}</div>
<div>警车:{{ item.clsl }}</div>
<span class="bbBtn" @click="handleBB(item.label)">报备</span>
</li>
</ul>
<div class="kcdBox">
<div class="cdTitle">应急可抽调警力</div>
<div class="count">
<span>民警{{ pageData.yicdList.mjsl }}</span>
<span>协警{{ pageData.yicdList.fjsl }}</span>
<span>警车{{ pageData.yicdList.clsl }}</span>
</div>
<ul class="bbBox">
<li class="bbBoxItem" v-for="(it,idx) in pageData.yicdList.list" :key="idx">
<div class="title">{{ it.label }}</div>
<div>民警:{{ it.mjsl }}</div>
<div>辅警:{{ it.fjsl }}</div>
<div>警车:{{ it.clsl }}</div>
<div class="bbBtn" @click="handleBB(it.label)">报备</div>
</li>
</ul>
<ul class="bbBox">
<li class="bbBoxItem" v-for="(it,idx) in pageData.yicdList.list1" :key="idx">
<div class="title">{{ it.label }}</div>
<div>民警:{{ it.mjsl }}</div>
<div>辅警:{{ it.fjsl }}</div>
<div>警车:{{ it.clsl }}</div>
<div class="bbBtn" @click="handleBB(it.label)">报备</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- 报备信息 -->
<BbInfo v-if="isShowBb" v-model="isShowBb" :dic="props.dic" :data="baseDate" :dep="{bmdm:pageData.ssbmdm,bmmc:pageData.ssbm}" @updateData="getMonth" text="日历" />
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import BbInfo from "./components/bbInfo.vue";
import * as MOSTY from "@/components/MyComponents/index";
import { timeValidate, weekValidate } from "@/utils/tools.js";
import {
ref,
reactive,
onMounted,
getCurrentInstance,
defineEmits,
defineProps
} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
dic: Object
});
const isShowBb = ref(false); //报备弹窗
const baseDate = reactive({
year: "",
week: "",
bbzt: "值班报备",
info: null
});
const isOpen = ref(false);
const dateVal = ref(new Date());
const calendar = ref();
const chooseDate = ref(); //选择的日期
const pageData = reactive({
// 当天日期 字符串
todayStr: timeValidate("", "ymd"),
bbdwList: [
{ label: "值班报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "01" },
{ label: "街面勤务报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "02" }
],
yicdList: {
mjsl: 0,
clsl: 0,
fjsl: 0,
list: [
{ label: "专项任务报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "03" },
{ label: "办公办案报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "04" }
],
list1: [
{ label: "应急处突报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "05" },
{ label: "备勤报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "06" }
]
}
});
const dateCount = ref([]); //日历里面的数据
onMounted(() => {
getMonth(); //获取月份
});
// 获取月份
const getMonth = (val) => {
console.log(val);
let datevalue = Date.parse(calendar.value.modelValue);
let date = val ? new Date(val) : new Date(datevalue);
let year = date.getFullYear();
let month = date.getMonth() + 1;
if (month < 10) month = "0" + month;
let days = getDaysInMonth(year, month);
let ksrq = `${year}-${month}-01`;
let jsrq = `${year}-${month}-${days}`;
let params = { ksrq, jsrq };
serviceGet(params, "/mosty-qwzx/tbQwglCount/selectDateRangeMFCDayCount").then(
(res) => {
dateCount.value = res || [];
}
);
};
// 获取某个月有好多天
const getDaysInMonth = (year, month) => {
return new Date(year, month, 0).getDate();
};
//返回今天、单日统计、月度统计
const selectDate = (val) => {
if (!calendar.value) return;
calendar.value.selectDate(val);
getMonth(Date.parse(dateVal.value));
};
// 选择某一天
const chooseDay = (val) => {
baseDate.year = val.day;
baseDate.week = weekValidate(baseDate.year);
isOpen.value = true;
chooseDate.value = val.day;
lookDeatil(val.day);
};
// 打开弹窗
const openInfo = () => {
baseDate.year = timeValidate(null, "ymd");
baseDate.week = weekValidate(baseDate.year);
isOpen.value = !isOpen.value;
lookDeatil(timeValidate(new Date(), "ymd"));
};
// 切换部门
const changeDep = (val) => {
pageData.ssbm = val ? val.orgName : '';
lookDeatil(chooseDate.value ? chooseDate.value : timeValidate("", "ymd"),'department');
};
// 查看某一天的统计
const lookDeatil = (val,type) => {
let params = { ksrq: val, jsrq: val, tjrq: val, ssbmdm: pageData.ssbmdm };
if(type) params.isChild = 0
serviceGet(params, "/mosty-qwzx/tbQwglCount/selectDayMFCBbzlCount").then(
(res) => {
let list = res || [];
pageData.yicdList.mjsl = 0; //民警总数
pageData.yicdList.clsl = 0; //辅警总数
pageData.yicdList.fjsl = 0; //警车总数
if (list.length == 0) {
(pageData.bbdwList = [
{ label: "值班报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "01" },
{ label: "街面勤务报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "02" }
]),
(pageData.yicdList = {
mjsl: 0,
clsl: 0,
fjsl: 0,
list: [
{ label: "专项任务报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "03" },
{ label: "办公办案报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "04" }
],
list1: [
{ label: "应急处突报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "05" },
{ label: "备勤报备", mjsl: 0, fjsl: 0, clsl: 0, dm: "06" }
]
});
} else {
list.forEach((item) => {
passValue(item, pageData.bbdwList); // 值班报备 - 街面勤务报备
passValue(item, pageData.yicdList.list); // 专项任务报备 - 办公办案报备
passValue(item, pageData.yicdList.list1); // 应急处突报备 - 备勤报备
if (["03", "04", "05", "06"].includes(item.bbzl)) {
pageData.yicdList.mjsl += item.mjsl;
pageData.yicdList.clsl += item.clsl;
pageData.yicdList.fjsl += item.fjsl;
}
});
}
}
);
};
// 赋值
const passValue = (item, arr) => {
arr.forEach((ic) => {
if (item.bbzl == ic.dm) {
ic.mjsl = item.mjsl;
ic.clsl = item.clsl;
ic.fjsl = item.fjsl;
}
});
};
// 报备
const handleBB = (val) => {
baseDate.bbzt = val;
isShowBb.value = true;
};
// 列表切换
const changeList = () => {
emits("update:modelValue", false);
};
</script>
<style lang="scss" scoped>
.canderlarBox {
display: flex;
height: 100%;
margin-top: 10px;
.leftbox {
flex: 1;
height: 100%;
overflow: hidden;
overflow-y: auto;
.categary {
margin-left: 10px;
padding: 4px;
box-sizing: border-box;
.dateTime {
font-size: 20px;
color: #0fc8f6;
}
.changeBtn {
cursor: pointer;
margin-right: 10px;
padding: 1px 10px;
box-sizing: border-box;
border-radius: 4px;
background: #0fc8f6;
}
:deep(.el-calendar__body) {
padding: 0;
}
:deep(.el-calendar-day) {
height: 114px;
padding: 4px;
}
.el-calendar {
--el-calendar-border: 1px solid #0855aa;
}
::v-deep .el-calendar__header {
background: #eeeeee;
border-bottom: 1px solid #ccc;
}
.date {
height: 100%;
position: relative;
.line {
height: 4px;
background-color: orange;
}
.fontBox {
width: 92%;
text-align: center;
white-space: nowrap;
overflow: hidden;
position: absolute;
bottom: 0;
.fontItem {
padding: 1px 4px;
box-sizing: border-box;
border-radius: 4px;
color: #000;
background: #f4f9fd;
margin: 0 2px;
display: flex;
justify-content: space-between;
height: 32px;
align-items: center;
margin-bottom: 3px;
}
.item_left {
display: flex;
align-items: center;
}
.line {
width: 4px;
height: 23px;
margin-right: 4px;
}
.num_text {
color: #7d8592;
}
.mj {
.line {
background: #3f8cff;
}
}
.fj {
.line {
background: #20e0a5;
}
}
.jc {
.line {
background: #6d5dd3;
}
}
}
.day {
text-align: right;
font-size: 16px;
font-weight: 600;
}
}
}
}
.rightbox {
width: 400px;
height: 100%;
position: relative;
transition: all 0.5s;
.rightbox-top {
height: 200px;
background: rgb(75, 151, 217);
overflow: hidden;
.calendar_rttop {
width: 150px;
height: 150px;
color: #030076;
background: #71c8e0;
box-shadow: 1px 1px 5px rgb(0 0 0 / 50%);
border-radius: 5px;
.calendar_date {
height: 60px;
}
.calendar_dateNub {
text-align: center;
color: #fff;
}
}
}
.rightbox-bottom {
height: calc(100% - 200px);
overflow: hidden;
background: #0588d1;
.bbtitle {
border: solid 3px rgba(199, 199, 199, 0.3);
border-radius: 60px;
height: 40px;
line-height: 32px;
width: 310px;
text-align: left;
position: relative;
box-shadow: 1px 1px 5px rgb(103 103 103 / 30%);
padding-left: 10px;
box-sizing: border-box;
margin: 10px auto;
background: #69c1ff;
span {
white-space: nowrap;
color: #fff;
margin-right: 10px;
}
::v-deep .el-input__inner {
border-radius: 18px;
background: rgba(255, 255, 255, 0.6);
color: #000;
}
}
.bbBox {
display: flex;
flex-wrap: wrap;
width: 380px;
margin: 10px auto;
.bbBoxItem {
flex: 1;
background: #c8e0f0;
border: solid 1px #ccd6de;
border-radius: 4px;
box-shadow: 1px 1px 5px rgb(0 0 0 / 50%);
font-size: 14px;
color: #030076;
font-weight: normal;
text-align: center;
.title {
font-size: 16px;
color: #800000;
line-height: 44px;
}
.bbBtn {
display: inline-block;
background-color: #005c9d;
border-color: #29475c;
cursor: pointer;
border-radius: 50px;
padding: 5px 15px;
box-sizing: border-box;
margin: 4px 0;
color: #fff;
}
}
}
.kcdBox {
background: rgba(255, 255, 255, 0.4);
padding: 10px;
box-sizing: border-box;
width: 400px;
margin: 0 auto;
border: solid 1px #f3f3f3;
border-radius: 4px;
box-shadow: 1px 1px 5px rgb(0 0 0 / 50%);
.cdTitle {
text-align: center;
font-size: 16px;
line-height: 50px;
color: #000;
}
.count {
text-align: center;
color: #000;
font-size: 16px;
span {
margin: 16px 10px;
}
}
}
}
}
.icon {
position: absolute;
left: -26px;
top: 50%;
width: 26px;
height: 28px;
background: url("~@/assets/images/up.png");
transform: translateY(-50%);
transform: rotate(-90deg);
}
}
</style>

View File

@ -0,0 +1,166 @@
<template>
<div class="dialog">
<div class="head_box">
<span class="title">报备单位{{ props.dep?.bmmc || deptId[0].deptName }} {{ props.data.year }}</span>
<div>
<span class="btns" @click="lookCount">报备查看</span>
<span class="btns" @click="goBack">返回{{ props.text }}</span>
</div>
</div>
<!-- 报表查看 -->
<div class="infoContent transition" :style="{ height: isHideen ? '0px' : 'calc(100vh - 190px)' }">
<COUNT :lineData="lineData" :dict="dic.D_QW_BBZL" :tableData="tableData" :bbcxData="bbcxData"/>
</div>
<!-- 报备详情 -->
<div class="infoContent transition" :style="{ height: isHideen ? 'calc(100vh - 190px)' : '0px' }">
<div style="white-space: nowrap;">
<span class="topItem btItem">报备类型</span>
<span @click="changeBtn(item.value)" class="topItem" v-for="item in props.dic.D_QW_BBZL" :key="item"
:class="isActive == item.value ? 'isActive' : ''">{{ item.label }}</span>
</div>
<div class="infoBox">
<!-- 值班报备 -->
<ZBZS v-if="isActive == '01'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 街面勤务报备 -->
<JMQW v-if="isActive == '02'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 专项任务报备 -->
<ZXRW v-if="isActive == '03'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 办公办案报备 -->
<BGBA v-if="isActive == '04'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 应急处突报备 -->
<YJCTBB v-if="isActive == '05'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 备勤报备 -->
<BQBB v-if="isActive == '06'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
<!-- 巡防中心报备 -->
<XFZXBB v-if="isActive == '07'" :dep="props.dep" :isDetail="props.isDetail" :dic="props.dic" :text="props.text"
:bblx="isActive" @updateList="updateList" :data="props.data" />
</div>
</div>
</div>
</template>
<script setup>
import ZBZS from "./zbzs.vue";
import JMQW from "./jmqw.vue";
import ZXRW from "./zxrw.vue";
import BGBA from "./bgba.vue";
import YJCTBB from "./yjct.vue";
import BQBB from "./bqbb.vue";
import XFZXBB from "./xfzxbb.vue";
import COUNT from "./count.vue";
import { selectDayMFCBbzlCount, getXfbbBy24h, qwselectList } from '@/api/file.js'
import { ref, reactive, defineProps, defineEmits, watchEffect, watch, getCurrentInstance } from "vue";
const emits = defineEmits(['update:modelValue', 'updateData']);
const props = defineProps({
data: Object,
modelValue: Boolean,
dic: Object,
text: String,
isDetail: Boolean,
dep: Object
})
const deptId = JSON.parse(localStorage.getItem("deptId"));
const { proxy } = getCurrentInstance();
const { D_QW_BBZL } = proxy.$dict("D_QW_BBZL");
const isHideen = ref(true);
const activeName = ref("");
const isActive = ref('01');//街面勤务报备
watch(() => props.data, (val) => {
let obj = props.dic.D_QW_BBZL.find(item => { return item.label == val.bbzt })
isActive.value = obj ? obj.value : '01'
}, { immediate: true })
// 切换按钮
const changeBtn = (val) => {
if (props.text == '列表') return false;
if (val != '报备类型') isActive.value = val;
};
// 查看报表
const lineData = ref()
const tableData = ref([])
const bbcxData = ref([])
const lookCount = async () => {
isHideen.value = !isHideen.value;
if (!isHideen.value) {
const res = await selectDayMFCBbzlCount({ ksrq: props.data.year, jsrq: props.data.year, tjrq: props.data.year })
const res1 = await qwselectList({ startTime: props.data.year, endTime: props.data.year })
const res2 = await getXfbbBy24h()
bbcxData.value = res1 ? res1 : []
tableData.value = res ? res : []
lineData.value = {
clList: res2.clList,
fjList: res2.fjList,
mjList: res2.mjList,
time: res2.time.map(item => item + '点')
}
}
};
// 返回上一级
const goBack = () => {
emits('update:modelValue', false)
};
const updateList = () => {
emits('updateData')
emits('update:modelValue', false)
};
</script>
<style lang="scss" scoped>
.btns {
border-radius: 50px;
padding: 5px 15px;
margin: 5px 5px 0;
border: 1px solid #e9e9e9;
cursor: pointer;
}
.infoContent {
height: calc(100vh - 190px);
overflow: hidden;
.topItem {
display: inline-block;
text-align: center;
height: 64px;
line-height: 64px;
padding: 0 15px;
background: #8dc6cf;
border-radius: 0;
margin-right: 1px;
border: none;
color: #fff;
cursor: pointer;
}
.btItem {
width: 180px;
color: #649bb9;
background: #e3e8eb;
border-color: #eaeef1;
cursor: text;
}
.isActive {
background: #fd9532;
}
.infoBox {
height: calc(100% - 50px);
overflow: hidden;
overflow-y: auto;
}
}
.transition {
transition: all 0.5s;
}
</style>

View File

@ -0,0 +1,307 @@
<template>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">警组设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{isRadio:true,lx:'jz',width:780,jzlx:props.bblx}" @change="changeJz" :dic="props.dic" />
</el-form-item>
<el-form-item prop="jzMc">
<el-input placeholder="警组名称" readonly v-model="dialogForm.jzMc"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">办公时间</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:600,isRadio:true,lx:'zbbc',bclx:props.bblx}" @change="changeBc" :dic="props.dic" />
</el-form-item>
<el-form-item prop="bcMc">
<el-input placeholder="班次名称" readonly v-model="dialogForm.bcMc" />
</el-form-item>
<el-form-item prop="bcKssj">
<el-time-picker v-model="dialogForm.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss"/>
</el-form-item>
<el-form-item style="width: 20px">
<span class="f16"></span>
</el-form-item>
<el-form-item prop="bcKtsDict" style="width: 90px">
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" placeholder="跨天数" v-model="dialogForm.bcKtsDict" style="width: 100%" />
</el-form-item>
<el-form-item prop="bcJssj">
<el-time-picker v-model="dialogForm.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss"/>
</el-form-item>
<el-form-item v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:800,isRadio:true,lx:'mj',placement:'left'}" @change="changeShr" :dic="props.dic" />
</el-form-item>
<el-form-item prop="shrXm" v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<el-input placeholder="审核人" readonly v-model="dialogForm.shrXm"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">办公办案报备</div>
<div class="info">
<dl class="dl-car">
<dt class="peo">
<span>办公办案报备</span>
</dt>
<dd class="info flex dir-column pt10">
<el-form-item prop="zbmjStr" label="当班民警">
<div class="flex">
<div class="num">{{dialogForm.zbmjStr ? dialogForm.zbmjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbmjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="当班辅警">
<div class="flex">
<div class="num">{{dialogForm.zbfjStr ? dialogForm.zbfjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'fj'}" v-model="dialogForm.zbfjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbfjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</div>
</div>
<div class="bblxItem" v-if="!isDetail">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="saveForm" v-loading="loading">{{props.text=='日历'?'新增报备':'修改报备'}}</el-button>
<el-button @click="resetForm" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import { reactive, ref ,getCurrentInstance,defineProps,defineEmits ,watch} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(['updateList'])
const props = defineProps({
bblx:{
type:String,
default:'01'
},
text:String,
data:Object,
dic:Object,
isDetail:{
type:Boolean,
default:false
},
dep:Object
})
const loading = ref(false)
const editRef = ref();
const dialogForm = ref({
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
});
const rules = reactive({
shrXm: [{ required: true, message: "请选择审核人", trigger: ['change','blur'] }],
bcKssj: [{ required: true, message: "请选择时间", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
jzMc: [{ required: true, message: "请填写警组名称", trigger: "blur" }]
});
// 选择审核人
const changeShr = (val) =>{
dialogForm.value.shrXm = val[0].xm;
dialogForm.value.shrSfzh = val[0].sfzh;
}
// 选择警组
const changeJz = (val) =>{
val.forEach(item => {
dialogForm.value.jzMc = item.jzMc
dialogForm.value.jzId = item.id
dialogForm.value.bcKtsDict = item.bcKtsDict
dialogForm.value.bcMc = item.bcMc
dialogForm.value.bcId = item.glQwbcId
dialogForm.value.bcKssj = item.bcKssj
dialogForm.value.bcJssj =item.bcJssj
dialogForm.value.zbmjStr = item.zbmjStr ? JSON.parse(item.zbmjStr):[];
dialogForm.value.zbfjStr = item.zbfjStr ? JSON.parse(item.zbfjStr):[];
});
}
// 选择班次
const changeBc = (val) =>{
dialogForm.value.bcMc = val ? val[0].bcMc :''
dialogForm.value.bcId = val ? val[0].id :''
dialogForm.value.bcKssj = val ? val[0].bcKssj :''
dialogForm.value.bcJssj = val ? val[0].bcJssj :''
dialogForm.value.bcKtsDict = val ? val[0].bcKtsDict :''
}
// 处理数据
const handleRylist = (arr,text)=>{
let list = arr.map(it=>{
return {xfllId:it.id, ryId:it.id, ryJzlx:it.lx, ryMfjlb:it.fl, rySfzh:it.sfzh, ryXm:it.xm,ryXfbbzw: handleDic(text)}
})
return list;
}
// 处理字典
const handleDic = (val) =>{
let obj = props.dic.D_BZ_RYXFBBZW.find(v=>{return v.label == val});
return obj ? obj.dm :''
}
// 提交
const saveForm = ()=>{
editRef.value.validate((valid) => {
if (!valid) return;
let params = {...dialogForm.value}
params.bbSjBbrq = props.data.year;
let zbmj = handleRylist(dialogForm.value.zbmjStr,'当班民警')
let zbfj = handleRylist(dialogForm.value.zbfjStr,'同行辅警')
params.ryList = []
params.ryList = params.ryList.concat(zbmj,zbfj)
params.qwBbzl = props.bblx;
let url = props.text == '日历' ? '/mosty-qwzx/tbQwglBb/save' :'/mosty-qwzx/tbQwglBb/update'
let message = props.text == '日历' ? '新增成功' :'修改成功'
loading.value = true;
servicePost(params, url).then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
}).catch(() => {
loading.value = false;
});
})
};
// 重置表單
const resetForm = () =>{
dialogForm.value = {
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
};
}
// 回显数据
const showData = (val) =>{
dialogForm.value = JSON.parse(JSON.stringify(val));
dialogForm.value.zbmjStr = [] //值班民警 01
dialogForm.value.zbfjStr = [] //值班辅警 02
if(dialogForm.value.ryList && dialogForm.value.ryList.length>0){
dialogForm.value.ryList.forEach(item=>{
let obj = { id:item.ryId, lx:item.ryJzlx, fl:item.ryMfjlb, sfzh:item.rySfzh, xm:item.ryXm}; //editId新增成功后返回的列表数据回有一个自定生成的值
if( item.ryMfjlb == '01' ) dialogForm.value.zbmjStr.push(obj); //值班民警 06
if( item.ryMfjlb == '02' ) dialogForm.value.zbfjStr.push(obj); //值班辅警 07
})
}
}
watch(()=>props.data,(val)=>{
if(val && val.info) showData(val.info)
},{immediate:true})
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
.dl-car {
min-width: 200px;
display: inline-block;
border: solid 1px #66cbff;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
background: #fff;
position: relative;
dt {
display: flex;
justify-content: space-between;
align-items: center;
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 30px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -18px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
}
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 20px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
</style>

View File

@ -0,0 +1,307 @@
<template>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">警组设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{isRadio:true,lx:'jz',width:780,jzlx:props.bblx}" @change="changeJz" :dic="props.dic" />
</el-form-item>
<el-form-item prop="jzMc">
<el-input placeholder="警组名称" readonly v-model="dialogForm.jzMc"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">办公时间</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:600,isRadio:true,lx:'zbbc',bclx:props.bblx}" @change="changeBc" :dic="props.dic" />
</el-form-item>
<el-form-item prop="bcMc">
<el-input placeholder="班次名称" readonly v-model="dialogForm.bcMc" />
</el-form-item>
<el-form-item prop="bcKssj">
<el-time-picker v-model="dialogForm.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss"/>
</el-form-item>
<el-form-item style="width: 20px">
<span class="f16"></span>
</el-form-item>
<el-form-item prop="bcKtsDict" style="width: 90px">
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" placeholder="跨天数" v-model="dialogForm.bcKtsDict" style="width: 100%" />
</el-form-item>
<el-form-item prop="bcJssj">
<el-time-picker v-model="dialogForm.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss"/>
</el-form-item>
<el-form-item v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03'">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:800,isRadio:true,lx:'mj',placement:'left'}" @change="changeShr" :dic="props.dic" />
</el-form-item>
<el-form-item prop="shrXm" v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<el-input placeholder="审核人" readonly v-model="dialogForm.shrXm"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">备勤报备</div>
<div class="info">
<dl class="dl-car">
<dt class="peo">
<span>备勤报备</span>
</dt>
<dd class="info flex dir-column pt10">
<el-form-item prop="zbmjStr" label="当班民警">
<div class="flex">
<div class="num">{{dialogForm.zbmjStr ? dialogForm.zbmjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbmjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="当班辅警">
<div class="flex">
<div class="num">{{dialogForm.zbfjStr ? dialogForm.zbfjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'fj'}" v-model="dialogForm.zbfjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbfjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</div>
</div>
<div class="bblxItem" v-if="!isDetail">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="saveForm" v-loading="loading">{{props.text=='日历'?'新增报备':'修改报备'}}</el-button>
<el-button @click="resetForm" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import { reactive, ref ,getCurrentInstance,defineProps,defineEmits ,watch} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(['updateList'])
const props = defineProps({
bblx:{
type:String,
default:'01'
},
text:String,
data:Object,
dic:Object,
isDetail:{
type:Boolean,
default:false
},
dep:Object
})
const loading = ref(false)
const editRef = ref();
const dialogForm = ref({
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
});
const rules = reactive({
shrXm: [{ required: true, message: "请选择审核人", trigger: ['change','blur'] }],
bcKssj: [{ required: true, message: "请选择时间", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
jzMc: [{ required: true, message: "请填写警组名称", trigger: "blur" }]
});
// 选择审核人
const changeShr = (val) =>{
dialogForm.value.shrXm = val[0].xm;
dialogForm.value.shrSfzh = val[0].sfzh;
}
// 选择警组
const changeJz = (val) =>{
val.forEach(item => {
dialogForm.value.jzMc = item.jzMc
dialogForm.value.jzId = item.id
dialogForm.value.bcKtsDict = item.bcKtsDict
dialogForm.value.bcMc = item.bcMc
dialogForm.value.bcId = item.glQwbcId
dialogForm.value.bcKssj = item.bcKssj
dialogForm.value.bcJssj =item.bcJssj
dialogForm.value.zbmjStr = item.zbmjStr ? JSON.parse(item.zbmjStr):[];
dialogForm.value.zbfjStr = item.zbfjStr ? JSON.parse(item.zbfjStr):[];
});
}
// 选择班次
const changeBc = (val) =>{
dialogForm.value.bcMc = val ? val[0].bcMc :''
dialogForm.value.bcId = val ? val[0].id :''
dialogForm.value.bcKssj = val ? val[0].bcKssj :''
dialogForm.value.bcJssj = val ? val[0].bcJssj :''
dialogForm.value.bcKtsDict = val ? val[0].bcKtsDict :''
}
// 处理数据
const handleRylist = (arr,text)=>{
let list = arr.map(it=>{
return {xfllId:it.id, ryId:it.id, ryJzlx:it.lx, ryMfjlb:it.fl, rySfzh:it.sfzh, ryXm:it.xm,ryXfbbzw: handleDic(text)}
})
return list;
}
// 处理字典
const handleDic = (val) =>{
let obj = props.dic.D_BZ_RYXFBBZW.find(v=>{return v.label == val});
return obj ? obj.dm :''
}
// 提交
const saveForm = ()=>{
editRef.value.validate((valid) => {
if (!valid) return;
let params = {...dialogForm.value}
params.bbSjBbrq = props.data.year;
let zbmj = handleRylist(dialogForm.value.zbmjStr,'当班民警')
let zbfj = handleRylist(dialogForm.value.zbfjStr,'同行辅警')
params.ryList = []
params.ryList = params.ryList.concat(zbmj,zbfj)
params.qwBbzl = props.bblx;
let url = props.text == '日历' ? '/mosty-qwzx/tbQwglBb/save' :'/mosty-qwzx/tbQwglBb/update'
let message = props.text == '日历' ? '新增成功' :'修改成功'
loading.value = true;
servicePost(params, url).then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
}).catch(() => {
loading.value = false;
});
})
};
// 重置表單
const resetForm = () =>{
dialogForm.value = {
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
};
}
// 回显数据
const showData = (val) =>{
dialogForm.value = JSON.parse(JSON.stringify(val));
dialogForm.value.zbmjStr = [] //值班民警 01
dialogForm.value.zbfjStr = [] //值班辅警 02
if(dialogForm.value.ryList && dialogForm.value.ryList.length>0){
dialogForm.value.ryList.forEach(item=>{
let obj = { id:item.ryId, lx:item.ryJzlx, fl:item.ryMfjlb, sfzh:item.rySfzh, xm:item.ryXm}; //editId新增成功后返回的列表数据回有一个自定生成的值
if( item.ryMfjlb == '01' ) dialogForm.value.zbmjStr.push(obj); //值班民警 06
if( item.ryMfjlb == '02' ) dialogForm.value.zbfjStr.push(obj); //值班辅警 07
})
}
}
watch(()=>props.data,(val)=>{
if(val && val.info) showData(val.info)
},{immediate:true})
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
.dl-car {
min-width: 200px;
display: inline-block;
border: solid 1px #66cbff;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
background: #fff;
position: relative;
dt {
display: flex;
justify-content: space-between;
align-items: center;
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 30px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -18px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
}
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 20px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
</style>

View File

@ -0,0 +1,187 @@
<template>
<div class="countBox">
<div class="topBox">
<div class="panel-heading">报表统计</div>
<MyTable :tableData="tableData" :tableColumn="pageData.tableColumn" :tableHeight="pageData.tableHeight"
:key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bbzl="{ row }">
<dict-tag :options="dict" :value="row.bbzl" :tag="false" />
</template>
</MyTable>
</div>
<div class="topBox">
<div class="panel-heading">报表查看(值班值守)</div>
<MyTable :tableData="bbcxData" :tableColumn="pageDataCk.tableColumn" :tableHeight="pageDataCk.tableHeight"
:key="pageDataCk.keyCount" :tableConfiger="pageDataCk.tableConfiger" :controlsWidth="pageDataCk.controlsWidth">
<template #ryList="{ row }">
<span v-for="(item, index) in ryData('01', row.ryList)" :key="index">{{ item.ryXm }}
</span>
</template>
<template #fb="{ row }">
<span v-for="(item, index) in ryData('02', row.ryList)" :key="index">{{ item.ryXm }}</span>
</template>
<template #zhzzb="{ row }">
<span v-for="(item, index) in ryData('03', row.ryList)" :key="index">{{ item.ryXm }}
</span>
</template>
<template #zhzfb="{ row }">
<span v-for="(item, index) in ryData('04', row.ryList)" :key="index">{{ item.ryXm }}</span>
</template>
<template #zbz="{ row }">
<span v-for="(item, index) in ryData('05', row.ryList)" :key="index">{{ item.ryXm }}
</span>
</template>
<template #mj="{ row }">
<span v-for="(item, index) in ryData('06', row.ryList)" :key="index">{{ item.ryXm }}</span>
</template>
<template #fj="{ row }">
<span v-for="(item, index) in ryData('07', row.ryList)" :key="index">{{ item.ryXm }}</span>
</template>
</MyTable>
</div>
<div class="topBox">
<div class="panel-heading">时段警力(值班值守)</div>
<div class="eharsBox">
<barEcharts :data="lineData" />
</div>
</div>
</div>
</template>
<script setup>
import barEcharts from './lineEcharts.vue'
import MyTable from "@/components/aboutTable/MyTable.vue";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted,
} from "vue";
const props = defineProps({
lineData: {},
dict: {},
tableData: [],
bbcxData: []
})
const pageData = reactive({
// tableData:props.tableData? props.tableData:[], //表格数据
keyCount: 0,
tableHeight: 245,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null",
haveControls: false,
showIndex: false,
stripe: true
},
total: 0,
pageConfiger: {
pageSize: 10,
pageNum: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "勤务报备种类", prop: "bbzl", showSolt: true },
{ label: "民警数量", prop: "mjsl" },
{ label: "辅警数量", prop: "fjsl" },
{ label: "车俩数量", prop: "clsl" },
{ label: "统计日期", prop: "tjrqStr" },
]
});
const pageDataCk = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null",
haveControls: false,
showIndex: false,
stripe: true
},
tableHeight: 300,
total: 0,
pageConfiger: {
pageSize: 10,
pageNum: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "班次", prop: "bcMc" },
{ label: "值班领导(主班)", prop: "ryList", showSolt: true },
{ label: "值班领导(副班)", prop: "fb", showSolt: true },
{ label: "指挥长(主班)", prop: "zhzzb", showSolt: true },
{ label: "指挥长(副班)", prop: "zhzfb", showSolt: true },
{ label: "值班长", prop: "zbz", showSolt: true },
{ label: "值班民警", prop: "mj", showSolt: true },
{ label: "值班辅警", prop: "fj", showSolt: true },
{ label: "频道", prop: "zbpdh" },
{ label: "呼号", prop: "zbpdhh" },
{ label: "值班电话", prop: "zbdh" },
{ label: "报备人", prop: "xtCjr" },
]
});
const ryData = (val, data) => {
switch (val) {
case "01":
return data.filter(item => item.ryZbbbzw == val)
case "02":
return data.filter(item => item.ryZbbbzw == val)
case "03":
return data.filter(item => item.ryZbbbzw == val)
case "04":
return data.filter(item => item.ryZbbbzw == val)
case "05":
return data.filter(item => item.ryZbbbzw == val)
case "06":
return data.filter(item => item.ryZbbbzw == val)
case "07":
return data.filter(item => item.ryZbbbzw == val)
}
}
</script>
<style lang="scss" scoped>
.countBox {
width: 100%;
height: 100%;
overflow-y: auto;
padding: 0 10px;
box-sizing: border-box;
.topBox {
margin-bottom: 10px;
.eharsBox {
height: 400px;
}
}
}
.panel-heading {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
padding: 10px 15px;
border-bottom: 1px solid transparent;
}
::v-deep .el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell {
background: #ECF7F7;
}
::v-deep .el-table th.el-table__cell {
background: #ECF7F7;
}
::v-deep .el-table .cell {
color: #000;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
<template>
<div style="width:100%;height:100%" ref="lineEchrats"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted, defineProps, watchEffect, nextTick } from "vue";
const lineEchrats = ref();
const props = defineProps({
data: {
type: Object,
default: {
// label: ["民警", "辅警", "警车"], //类型
// value: [111, 222, 333], //值
// colorList: [
// ["#4285f4", "#4285f4", "#4285f4"],
// ["#34B877", "#34B877", "#34B877"],
// ["#01C2FF", "#01C2FF", "#01C2FF"]
// ]
}
}
});
const barEchrats = ref();
const initEchrats = (obj) => {
const options = {
color: ["#00DFE3", "#00ABFB", "#21F9A3","#F9C521"],
title:{
text:'时段警力统计图'
},
legend:{
data:['民警','辅警','警车']
},
tooltip: {
trigger: "axis",
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
top:'14%',
containLabel: true
},
xAxis: [
{
type: "category",
boundaryGap: false,
show: true,
data: props.data.time,
}
],
yAxis: [
{
axisTick: { show: false },
type: "value",
axisLine: {
lineStyle: {
color: "#000"
}
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(15,36,90,0.4)",
type: "dashed"
}
}
}
],
series: [
{
name:"民警",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
emphasis: {
focus: "series"
},
data: props.data.mjList,
markPoint:{
data:[
{type:'max',name:'Max'},
{type:'min',name:'Min'},
]
}
},
{
name:"辅警",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
emphasis: {
focus: "series"
},
data: props.data.fjList,
markPoint:{
data:[
{type:'max',name:'Max'},
{type:'min',name:'Min'},
]
}
},
{
name:"警车",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
emphasis: {
focus: "series"
},
data: props.data.clList,
markPoint:{
data:[
{type:'max',name:'Max'},
{type:'min',name:'Min'},
]
}
},
]
};
var myChart = echarts.init(lineEchrats.value);
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data) {
nextTick(() => {
initEchrats(props.data); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,391 @@
<template>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">巡防部门</div>
<div class="info">
<el-form-item label="巡防部门" prop="ssbmdm">
<MOSTY.Department width="180px" clearable filterable v-model="dialogForm.ssbmdm"
:placeholder="dialogForm.ssbm ? dialogForm.ssbm : '选择部门'" />
</el-form-item>
<el-form-item label="值班日期" prop="zbrq">
<el-date-picker :disabled="ischooseTime" style="width: 100%" v-model="dialogForm.zbrq" placeholder="请选择"
format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">值班领导</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" @change="handleFzr" :configer="{ lx: 'mj', rowKey: 'id', isRadio: true }"
:dic="props.dic" />
</el-form-item>
<el-form-item prop="zbldXm" label=" ">
<el-input readonly v-model="dialogForm.zbldXm" placeholder="负责人" clearable />
</el-form-item>
<el-form-item prop="zbldDh">
<el-input readonly v-model="dialogForm.zbldDh" placeholder="负责人电话" clearable />
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">值班人员</div>
<div class="info flex dir-column">
<el-form-item label="值班指挥长" :label-width="140" prop="zbzhzXm">
<div class="num">{{ dialogForm.zbzhzXm ? dialogForm.zbzhzXm.length : 0 }}</div>
<ChooseTable :deptment="props.dep" :configer="{ lx: 'mj', rowKey: 'id', isRadio: true }" v-model="dialogForm.zbzhzXm"
:dic="props.dic" />
<el-tag type="primary" v-for="(item, idx) in dialogForm.zbzhzXm" :key="idx">{{ item.xm }}</el-tag>
</el-form-item>
<el-form-item :deptment="props.dep" label="专职指挥长" :label-width="140" prop="zzzhzXm">
<div class="num">{{ dialogForm.zzzhzXm ? dialogForm.zzzhzXm.length : 0 }}</div>
<ChooseTable :deptment="props.dep" :configer="{ lx: 'mj', rowKey: 'id', isRadio: true }" v-model="dialogForm.zzzhzXm"
:dic="props.dic" />
<el-tag type="primary" v-for="(item, idx) in dialogForm.zzzhzXm" :key="idx">{{ item.xm }}</el-tag>
</el-form-item>
<el-form-item label="法制值班" :label-width="140" prop="fzzbXm">
<div class="num">{{ dialogForm.fzzbXm ? dialogForm.fzzbXm.length : 0 }}</div>
<ChooseTable :deptment="props.dep" :configer="{ lx: 'mj', rowKey: 'id', isRadio: true }" v-model="dialogForm.fzzbXm"
:dic="props.dic" />
<el-tag type="primary" v-for="(item, idx) in dialogForm.fzzbXm" :key="idx">{{ item.xm }}</el-tag>
</el-form-item>
<el-form-item label="值班民警" :label-width="140" prop="mjList">
<div class="num">{{ dialogForm.mjList ? dialogForm.mjList.length : 0 }}</div>
<ChooseTable :deptment="props.dep" :configer="{ lx: 'mj' }" v-model="dialogForm.mjList" :dic="props.dic" />
<el-tag type="primary" v-for="it in dialogForm.mjList" :key="it.id">{{ it.xm }}</el-tag>
</el-form-item>
<el-form-item label="值班辅警" :label-width="140" prop="fjList">
<div class="num">{{ dialogForm.fjList ? dialogForm.fjList.length : 0 }}</div>
<ChooseTable :deptment="props.dep" :configer="{ lx: 'fj' }" v-model="dialogForm.fjList" :dic="props.dic" />
<el-tag type="primary" v-for="it in dialogForm.fjList" :key="it.id">{{ it.xm }}</el-tag>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">班次设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" :configer="{ width: 616, isRadio: true, lx: 'zbbc', bclx: props.bblx }"
@change="changeBc" :dic="props.dic" />
</el-form-item>
<el-form-item prop="bcMc">
<el-input placeholder="班次名称" readonly v-model="dialogForm.bcMc" />
</el-form-item>
<el-form-item>
<span class="f16">(</span>
</el-form-item>
<el-form-item prop="kssj">
<el-time-picker v-model="dialogForm.kssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<el-form-item style="width: 20px">
<span class="f16"></span>
</el-form-item>
<el-form-item prop="kts" style="width: 90px">
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" placeholder="跨天数" v-model="dialogForm.kts"
style="width: 100%" />
</el-form-item>
<el-form-item prop="jssj">
<el-time-picker v-model="dialogForm.jssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<el-form-item>
<span class="f16">)</span>
</el-form-item>
<!-- <el-form-item prop="kssj" label="值班时长">
<el-input v-model="dialogForm.zbsc" />
</el-form-item> -->
</div>
</div>
<div class="bblxItem">
<div class="btItem">呼号</div>
<div class="info">
<el-form-item>
<el-input v-model="dialogForm.hh" placeholder="请输入呼号" />
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">备注</div>
<div class="info">
<el-form-item style="width: 100%">
<el-input v-model="dialogForm.bz" placeholder="请输入关键字" show-word-limit type="textarea" />
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="saveForm" v-loading="loading">报备</el-button>
<el-button @click="dialogForm.value.xffwlx = '1'" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
</template>
<script setup>
import { servicePost, servicePut } from "@/api/serviceApi.js";
import { ElMessage } from "element-plus";
import * as MOSTY from "@/components/MyComponents/index";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import emitter from "@/utils/eventBus.js";
import CheckBox from "@/components/checkBox/index";
import { reactive, ref, getCurrentInstance, defineProps, watch, defineEmits } from "vue";
const { proxy } = getCurrentInstance();
const props = defineProps({
bblx: {
type: String,
default: "01"
},
text: String,
data: Object,
dic: Object,
isDetail: {
type: Boolean,
default: false
},
dep: Object
});
const emits = defineEmits(["updateList", "update:modelValue"]);
const editRef = ref();
const loading = ref(false);
const dialogForm = ref({
xffwlx: '1',
});
const rules = reactive({
lx: [{ required: true, message: "请选择类型", trigger: ["change"] }],
ssbmdm: [{ required: true, message: "请选择巡防部门", trigger: ["change"] }],
zbrq: [{ required: true, message: "请选择值班日期", trigger: ["change"] }],
zbldXm: [{ required: true, message: "请选择值班领导", trigger: ["change"] }],
zbzhzXm: [{ required: true, message: "请选择值班指挥长", trigger: ["blur"] }],
zzzhzXm: [{ required: true, message: "请选择专职指挥长", trigger: ["blur"] }],
fzzbXm: [{ required: true, message: "请选择法制值班", trigger: ["change"] }],
// mjList: [{ required: true, message: "请选择值班民警", trigger: ["blur"] }],
// fjList: [{ required: true, message: "请选择值班辅警", trigger: ["blur"] }],
});
// 选择班次
const changeBc = (val) => {
dialogForm.value.bcMc = val ? val[0].bcMc : "";
dialogForm.value.kssj = val ? val[0].bcKssj : "";
dialogForm.value.jssj = val ? val[0].bcJssj : "";
dialogForm.value.kts = val ? val[0].bcKtsDict : "";
};
// 处理负责人
const handleFzr = (val) => {
dialogForm.value.zbldXm = val.length > 0 ? val[0].xm : ''
dialogForm.value.zbldDh = val.length > 0 ? val[0].lxdh : ''
}
// 提交
const saveForm = () => {
editRef.value.validate((valid) => {
if (!valid) return;
let params = { ...dialogForm.value };
if(!dialogForm.value.mjList||dialogForm.value.mjList.length==0||!dialogForm.value.mjList||dialogForm.value.mjList.length==0){
proxy.$message.warning("请选择民警和辅警");
return
}
// 值班指挥长
params.zbzhzDh = params.zbzhzXm[0].lxdh;
params.zbzhzId = params.zbzhzXm[0].id
params.zbzhzSfzh = params.zbzhzXm[0].sfzh
params.zbzhzXm = params.zbzhzXm[0].xm
// 法制值班
params.fzzbDh = params.fzzbXm[0].lxdh;
params.fzzbId = params.fzzbXm[0].id
params.fzzbSfzh = params.fzzbXm[0].sfzh
params.fzzbXm = params.fzzbXm[0].xm
// 专职指挥长
params.zzzhzDh = params.zzzhzXm[0].lxdh
params.zzzhzId = params.zzzhzXm[0].id
params.zzzhzSfzh = params.zzzhzXm[0].sfzh
params.zzzhzXm = params.zzzhzXm[0].xm
// 民警
params.mjList = params.mjList.map(item => {
return {
jlId: item.id,
jllx: "01",
jlxm: item.xm,
sfzh: item.sfzh,
xbdm: item.xbdm,
lxdh: item.lxdh
};
})
// 辅警
params.fjList = params.fjList.map(item => {
return {
jlId: item.id,
jllx: "02",
jlxm: item.xm,
sfzh: item.sfzh,
xbdm: item.xbdm,
lxdh: item.lxdh
};
})
params.jlList = params.fjList.concat(params.mjList);
loading.value = true;
let message = props.text == "日历" ? "新增成功" : "修改成功";
if (props.text == "日历") {
servicePost(params, '/mosty-qwzx/tbQwZbbb').then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
}).catch(() => { loading.value = false; });
} else {
delete params.zbmj;
delete params.zbfj;
servicePut(params, '/mosty-qwzx/tbQwZbbb').then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
}).catch(() => { loading.value = false; });
}
});
};
// 回显数据
const showData = (data) => {
let val = JSON.parse(JSON.stringify(data));
val.ssbmid = val.ssbmdm;
val.zbzhzXm = [{ lxdh: val.zbzhzDh, id: val.zbzhzId, sfzh: val.zbzhzSfzh, xm: val.zbzhzXm }];
val.fzzbXm = [{ lxdh: val.fzzbDh, id: val.fzzbId, sfzh: val.fzzbSfzh, xm: val.fzzbXm }];
val.zzzhzXm = [{ lxdh: val.zzzhzDh, id: val.zzzhzId, sfzh: val.zzzhzSfzh, xm: val.zzzhzXm }];
val.mjList = val.zbmj.map(item => {
return { id: item.jlId, xm: item.jlxm, sfzh: item.sfzh, xbdm: item.xbdm, lxdh: item.lxdh }
})
val.fjList = val.zbfj.map(item => {
return { id: item.jlId, xm: item.jlxm, sfzh: item.sfzh, xbdm: item.xbdm, lxdh: item.lxdh }
})
dialogForm.value = val;
};
watch(() => props.data, (val) => {
if (val && val.info) showData(val.info);
}, { immediate: true });
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
.gapline {
height: 1px;
border-top: 1px dashed #e2e2e2;
margin: 4px 0;
}
.dl-car {
min-width: 200px;
display: inline-block;
border: solid 1px #66cbff;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
position: relative;
dt {
display: flex;
justify-content: space-between;
align-items: center;
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 30px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -18px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 18px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 20px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
.deBtn {
padding: 0px 10px;
background: rgb(35, 176, 241);
border-radius: 18px;
color: #fff;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,402 @@
<template>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">警组设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{isRadio:true,lx:'jz',width:780,jzlx:props.bblx}" @change="changeJz" :dic="props.dic" />
</el-form-item>
<el-form-item prop="jzMc">
<el-input placeholder="警组名称" readonly v-model="dialogForm.jzMc"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">办公时间</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:600,isRadio:true,lx:'zbbc',bclx:props.bblx}" @change="changeBc" :dic="props.dic" />
</el-form-item>
<el-form-item prop="bcMc">
<el-input placeholder="班次名称" readonly v-model="dialogForm.bcMc" />
</el-form-item>
<el-form-item prop="bcKssj">
<el-time-picker v-model="dialogForm.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<el-form-item style="width: 20px">
<span class="f16"></span>
</el-form-item>
<el-form-item prop="bcKtsDict" style="width: 90px">
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" placeholder="跨天数" v-model="dialogForm.bcKtsDict" style="width: 100%" />
</el-form-item>
<el-form-item prop="bcJssj">
<el-time-picker v-model="dialogForm.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss" />
</el-form-item>
<el-form-item v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03'">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:800,isRadio:true,lx:'mj',placement:'left'}" @change="changeShr" :dic="props.dic" />
</el-form-item>
<el-form-item prop="shrXm" v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<el-input placeholder="审核人" readonly v-model="dialogForm.shrXm"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">器械列表</div>
<div class="info">
<el-form-item :label="item.zdmc" :label-width="120" v-for="(item,index) in dialogForm.qxList" :key="index">
<el-input-number v-model="item.qxsl" :min="0" :max="1000"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">巡逻方式</div>
<div class="info">
<!-- 车辆 -->
<div>
<ChooseTable style="background-color: red;" class="dinw" :deptment="props.dep" v-if="!isDetail" v-model="dialogForm.clList" :configer="{lx:'cl',selectName:'选择车辆'}" @change="changeCl" :dic="props.dic" />
</div>
<div v-if=" dialogForm.clList">
<dl class="dl-car" v-for="item in dialogForm.clList" :key="item.cid">
<dt class="flex just-between align-center">
<div>{{item.cph}}</div>
<div @click="closeCl(item)">
<el-icon>
<Close />
</el-icon>
</div>
</dt>
<!-- <dd class="flex dir-column pr20 pt10">
<el-form-item v-for="it in item.tcryListStr" :label="it.label" :key="it.vlaue">
<div class="flex">
<div class="num">{{it.list ? it.list.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx: it.label == '同行辅警'?'fj':'mj',placement:'top-start'}" v-model="it.list" :key="it" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="itchid in it.list" :key="itchid">{{itchid.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd> -->
</dl>
</div>
</div>
</div>
<div class="bblxItem">
<div class="btItem">应急处突报备</div>
<div class="info">
<dl class="dl-car">
<dt class="peo">
<span>应急处突报备</span>
</dt>
<dd class="info flex dir-column pt10">
<el-form-item prop="zbmjStr" label="当班民警">
<div class="flex">
<div class="num">{{dialogForm.zbmjStr ? dialogForm.zbmjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbmjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbmjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
<el-form-item prop="zbfjStr" label="当班辅警">
<div class="flex">
<div class="num">{{dialogForm.zbfjStr ? dialogForm.zbfjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'fj'}" v-model="dialogForm.zbfjStr" :dic="props.dic" />
<div class="peolist">
<el-tag type="primary" v-for="item in dialogForm.zbfjStr" :key="item">{{item.xm}}</el-tag>
</div>
</div>
</el-form-item>
</dd>
</dl>
</div>
</div>
<div class="bblxItem" v-if="!isDetail">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="saveForm" v-loading="loading">{{props.text=='日历'?'新增报备':'修改报备'}}</el-button>
<el-button @click="resetForm" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import {
reactive,
ref,
getCurrentInstance,
defineProps,
defineEmits,
watch,
onMounted
} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(["updateList"]);
const props = defineProps({
bblx: {
type: String,
default: "01"
},
text: String,
data: Object,
dic: Object,
isDetail: {
type: Boolean,
default: false
},
dep: Object
});
const loading = ref(false);
const editRef = ref();
const dialogForm = ref({
bcKtsDict: "01",
bcKssj: "00:00:00",
bcJssj: "00:00:00"
});
const rules = reactive({
shrXm: [
{ required: true, message: "请选择审核人", trigger: ["change", "blur"] }
],
bcKssj: [{ required: true, message: "请选择时间", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
jzMc: [{ required: true, message: "请填写警组名称", trigger: "blur" }]
});
// 选择审核人
const changeShr = (val) => {
dialogForm.value.shrXm = val[0].xm;
dialogForm.value.shrSfzh = val[0].sfzh;
};
// 选择警组
const changeJz = (val) => {
val.forEach((item) => {
dialogForm.value.jzMc = item.jzMc;
dialogForm.value.jzId = item.id;
dialogForm.value.bcKtsDict = item.bcKtsDict;
dialogForm.value.bcMc = item.bcMc;
dialogForm.value.bcId = item.glQwbcId;
dialogForm.value.bcKssj = item.bcKssj;
dialogForm.value.bcJssj = item.bcJssj;
dialogForm.value.zbmjStr = item.zbmjStr ? JSON.parse(item.zbmjStr) : [];
dialogForm.value.zbfjStr = item.zbfjStr ? JSON.parse(item.zbfjStr) : [];
});
};
// 选择班次
const changeBc = (val) => {
dialogForm.value.bcMc = val ? val[0].bcMc : "";
dialogForm.value.bcId = val ? val[0].id : "";
dialogForm.value.bcKssj = val ? val[0].bcKssj : "";
dialogForm.value.bcJssj = val ? val[0].bcJssj : "";
dialogForm.value.bcKtsDict = val ? val[0].bcKtsDict : "";
};
// 处理数据
const handleRylist = (arr, text) => {
let list = arr.map((it) => {
return {
xfllId: it.id,
ryId: it.id,
ryJzlx: it.lx,
ryMfjlb: it.fl,
rySfzh: it.sfzh,
ryXm: it.xm,
ryXfbbzw: handleDic(text)
};
});
return list;
};
// 处理字典
const handleDic = (val) => {
let obj = props.dic.D_BZ_RYXFBBZW.find((v) => {
return v.label == val;
});
return obj ? obj.dm : "";
};
// 提交
const saveForm = () => {
editRef.value.validate((valid) => {
if (!valid) return;
let params = { ...dialogForm.value };
params.bbSjBbrq = props.data.year;
let zbmj = handleRylist(dialogForm.value.zbmjStr, "当班民警");
let zbfj = handleRylist(dialogForm.value.zbfjStr, "同行辅警");
params.ryList = [];
params.ryList = params.ryList.concat(zbmj, zbfj);
params.qwBbzl = props.bblx;
let url =
props.text == "日历"
? "/mosty-qwzx/tbQwglBb/save"
: "/mosty-qwzx/tbQwglBb/update";
let message = props.text == "日历" ? "新增成功" : "修改成功";
loading.value = true;
servicePost(params, url)
.then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
})
.catch(() => {
loading.value = false;
});
});
};
// 重置表單
const resetForm = () => {
dialogForm.value = {
bcKtsDict: "01",
bcKssj: "00:00:00",
bcJssj: "00:00:00"
};
};
// 回显数据
const showData = (val) => {
dialogForm.value = JSON.parse(JSON.stringify(val));
dialogForm.value.zbmjStr = []; //值班民警 01
dialogForm.value.zbfjStr = []; //值班辅警 02
if (dialogForm.value.ryList && dialogForm.value.ryList.length > 0) {
dialogForm.value.ryList.forEach((item) => {
let obj = {
id: item.ryId,
lx: item.ryJzlx,
fl: item.ryMfjlb,
sfzh: item.rySfzh,
xm: item.ryXm
}; //editId新增成功后返回的列表数据回有一个自定生成的值
if (item.ryMfjlb == "01") dialogForm.value.zbmjStr.push(obj); //值班民警 06
if (item.ryMfjlb == "02") dialogForm.value.zbfjStr.push(obj); //值班辅警 07
});
}
};
watch(
() => props.data,
(val) => {
if (val && val.info) showData(val.info);
},
{ immediate: true }
);
// 删除车辆
const closeCl = (item) => {
dialogForm.value.clList = dialogForm.value.clList.filter((el) => {
return el.cid != item.cid;
});
};
onMounted(() => {
dialogForm.value.qxList = props.dic.D_JCGL_JYQX_QXLX.map((item) => {
return {
...item,
qxsl: 0
};
});
});
//车辆选择
const changeCl = (val) => {
val.forEach((item) => {
item.tcryListStr = props.dic.D_BZ_RYXFBBZW;
});
dialogForm.value.clList = dialogForm.value.clList.concat(val);
dialogForm.value.clList = Array.from(new Set(dialogForm.value.clList.map(JSON.stringify))).map(JSON.parse);
};
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
.dl-car {
min-width: 200px;
display: inline-block;
border: solid 1px #66cbff;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
background: #fff;
position: relative;
dt {
display: flex;
justify-content: space-between;
align-items: center;
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 30px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -18px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
}
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 20px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
</style>

View File

@ -0,0 +1,332 @@
<template>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">警组设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{isRadio:true,lx:'jz',width:780,jzlx:props.bblx}" @change="changeJz" :dic="props.dic" />
</el-form-item>
<el-form-item prop="jzMc" label=" ">
<el-input readonly placeholder="警组名称" v-model="dialogForm.jzMc" />
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">班次设置</div>
<div class="info">
<el-form-item>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:600,isRadio:true,lx:'zbbc',bclx:props.bblx}" @change="changeBc" :dic="props.dic" />
</el-form-item>
<el-form-item prop="bcMc" label=" ">
<el-input placeholder="班次名称" v-model="dialogForm.bcMc"></el-input>
</el-form-item>
<el-form-item>
<span class="f16">(</span>
</el-form-item>
<el-form-item prop="bcKssj">
<el-time-picker v-model="dialogForm.bcKssj" format="HH:mm:ss" value-format="HH:mm:ss"></el-time-picker>
</el-form-item>
<el-form-item style="width: 20px">
<span class="f16"></span>
</el-form-item>
<el-form-item prop="bcKtsDict" style="width: 90px" >
<MOSTY.Select :dictEnum="props.dic.D_QW_BC_KTS" v-model="dialogForm.bcKtsDict" style="width: 100%" />
</el-form-item>
<el-form-item prop="bcJssj" >
<el-time-picker v-model="dialogForm.bcJssj" format="HH:mm:ss" value-format="HH:mm:ss"/>
</el-form-item>
<el-form-item>
<span class="f16">)</span>
</el-form-item>
<el-form-item v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:800,isRadio:true,lx:'mj',placement:'left'}" @change="changeShr" :dic="props.dic" />
</el-form-item>
<el-form-item prop="shrXm" v-if="dialogForm.bcKtsDict != '01' && dialogForm.bcKtsDict != '02' && dialogForm.bcKtsDict != '03' ">
<el-input placeholder="审核人" readonly v-model="dialogForm.shrXm"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">值班人员</div>
<div class="info flex dir-column">
<el-form-item label="值班领导(主班)" :label-width="140">
<div class="num">{{dialogForm.zbldZbStr ? dialogForm.zbldZbStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbldZbStr" :dic="props.dic" />
<el-tag type="primary" v-for="(item,idx) in dialogForm.zbldZbStr" :key="idx">{{item.xm}}</el-tag>
</el-form-item>
<el-form-item :deptment="props.dep" label="值班领导(副班)" :label-width="140">
<div class="num">{{dialogForm.zbldFbStr ? dialogForm.zbldFbStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbldFbStr" :dic="props.dic" />
<el-tag type="primary" v-for="(item,idx) in dialogForm.zbldFbStr" :key="idx">{{item.xm}}</el-tag>
</el-form-item>
<el-form-item label="指挥长(主班)" :label-width="140">
<div class="num">{{dialogForm.zhzZbStr ? dialogForm.zhzZbStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zhzZbStr" :dic="props.dic" />
<el-tag type="primary" v-for="(item,idx) in dialogForm.zhzZbStr" :key="idx">{{item.xm}}</el-tag>
</el-form-item>
<el-form-item v-if="!isDetail" label="指挥长(副班)" :label-width="140">
<div class="num">{{dialogForm.zhzFbStr ? dialogForm.zhzFbStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zhzFbStr" :dic="props.dic" />
<el-tag type="primary" v-for="(item,idx) in dialogForm.zhzFbStr" :key="idx">{{item.xm}}</el-tag>
</el-form-item>
<el-form-item label="值班长" :label-width="140">
<div class="num">{{dialogForm.zbzStr ? dialogForm.zbzStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbzStr" :dic="props.dic"/>
<el-tag type="primary" v-for="(item,idx) in dialogForm.zbzStr" :key="idx">{{item.xm}}</el-tag>
</el-form-item>
<el-form-item label="值班民警" :label-width="140">
<div class="num">{{dialogForm.zbmjStr ? dialogForm.zbmjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'mj'}" v-model="dialogForm.zbmjStr" :dic="props.dic" />
<el-tag type="primary" v-for="it in dialogForm.zbmjStr" :key="it.id">{{it.xm}}</el-tag>
</el-form-item>
<el-form-item label="值班辅警" :label-width="140">
<div class="num">{{dialogForm.zbfjStr ? dialogForm.zbfjStr.length : 0}}</div>
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{lx:'fj'}" v-model="dialogForm.zbfjStr" :dic="props.dic" />
<el-tag type="primary" v-for="it in dialogForm.zbfjStr" :key="it.id">{{it.xm}}</el-tag>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">值班电话</div>
<div class="info">
<el-form-item label="频道号">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{isRadio:true,lx:'pdh',width:800}" @change="changePdh" :dic="props.dic" />
<el-input readonly placeholder="请选择频道号" v-model="dialogForm.zbpdmc" style="width: 150px"></el-input>
</el-form-item>
<el-form-item prop="zbpdhh" label="呼号">
<el-input v-model="dialogForm.zbpdhh" placeholder="请输入呼号"></el-input>
</el-form-item>
<el-form-item prop="zbdh" label="值班电话">
<el-input v-model="dialogForm.zbdh" style="width: 250px" placeholder="请选择值班电话"></el-input>
<span style="color: rgb(144 144 144)">值班电话手机号码13912345678</span>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="!isDetail">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="onSave" v-loading="loading">{{props.text == '日历'?'新增报备':'修改报备'}}</el-button>
<el-button @click="resetForm" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import * as rule from "@/utils/rules.js";
import { reactive, ref,getCurrentInstance, onMounted, watch } from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(['updateList','update:modelValue'])
const props = defineProps({
data:Object,
text:String,
dic:Object,
bblx:{
type:String,
default:'01'
},
isDetail:{
type:Boolean,
default:false
},
dep:Object
})
const editRef = ref();
const loading = ref(false);
const dialogFormDefault = ref({})
const dialogForm = ref({
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
});
const rules = reactive({
bcMc: [{ required: true, message: "请填写班次名称", trigger: ['change','blur'] }],
shrXm: [{ required: true, message: "请选择审核人", trigger: ['change','blur'] }],
bcKtsDict: [{ required: true, message: "请选择跨天数", trigger: "change" }],
bcKssj: [{ required: true, message: "请选择开始时间", trigger: "change" }],
bcJssj: [{ required: true, message: "请选择结束时间", trigger: "change" }],
zbpdhh: [{ required: true, message: "请输入呼号", trigger: ['change','blur'] }],
jzMc: [{ required: true, message: "请填写警组名称", trigger: ['change','blur'] }],
...rule.phoneRule({ validator: true, require: true }, "zbdh") //邮箱
});
// 回显数据
const showData = (val) =>{
dialogForm.value = JSON.parse(JSON.stringify(val));
dialogForm.value.zbldZbStr = [] //值班领导主班01
dialogForm.value.zbldFbStr =[] //'值班领导副班02
dialogForm.value.zhzZbStr = [] //'指挥长主班03
dialogForm.value.zhzFbStr = [] //'指挥长副班04
dialogForm.value.zbzStr = [] //值班长 05
dialogForm.value.zbmjStr = [] //值班民警 06
dialogForm.value.zbfjStr = [] //值班辅警 07
let rylist = val.ryList ? val.ryList : [];
rylist.forEach(item=>{
let obj = { id:item.ryId, lx:item.ryJzlx, fl:item.ryMfjlb, sfzh:item.rySfzh, xm:item.ryXm };
if( item.ryZbbbzw == '01' ) dialogForm.value.zbldZbStr.push(obj); //值班领导主班01
if( item.ryZbbbzw == '02' ) dialogForm.value.zbldFbStr.push(obj); //'值班领导副班02
if( item.ryZbbbzw == '03' ) dialogForm.value.zhzZbStr.push(obj); //'指挥长主班03
if( item.ryZbbbzw == '04' ) dialogForm.value.zhzFbStr.push(obj); //'指挥长副班04
if( item.ryZbbbzw == '05' ) dialogForm.value.zbzStr.push(obj); //值班长 05
if( item.ryZbbbzw == '06' ) dialogForm.value.zbmjStr.push(obj); //值班民警 06
if( item.ryZbbbzw == '07' ) dialogForm.value.zbfjStr.push(obj); //值班辅警 07
})
}
// 选择班次
const changeBc = (val) =>{
dialogForm.value.bcMc = val ? val[0].bcMc :''
dialogForm.value.bcId = val ? val[0].id :''
dialogForm.value.bcKssj = val ? val[0].bcKssj :''
dialogForm.value.bcJssj = val ? val[0].bcJssj :''
dialogForm.value.bcKtsDict = val ? val[0].bcKtsDict :''
}
// 选择审核人
const changeShr = (val) =>{
dialogForm.value.shrXm = val[0].xm;
dialogForm.value.shrSfzh = val[0].sfzh;
}
// 选择警组
const changeJz = (val) =>{
console.log(val,'val');
val.forEach(item => {
dialogForm.value.jzMc = item.jzMc ;
dialogForm.value.jzId = item.id ;
dialogForm.value.zbpdh = item.zbpdh ;
dialogForm.value.zbpdmc = item.zbpdmc ;
dialogForm.value.zbpdhh = item.zbpdhh ;
dialogForm.value.zbdh=item.zbdh;
dialogForm.value.bcMc = item.bcMc
dialogForm.value.bcId = item.glQwbcId
dialogForm.value.bcKssj = item.bcKssj
dialogForm.value.bcJssj = item.bcJssj
dialogForm.value.bcKtsDict = item.bcKtsDict
dialogForm.value.zbldFbStr = item.zbldFbStr ? JSON.parse(item.zbldFbStr) :[]
dialogForm.value.zbldZbStr = item.zbldZbStr ? JSON.parse(item.zbldZbStr) :[]
dialogForm.value.zhzZbStr = item.zhzZbStr ? JSON.parse(item.zhzZbStr) :[]
dialogForm.value.zbzStr = item.zbzStr ? JSON.parse(item.zbzStr) :[]
dialogForm.value.zhzFbStr = item.zhzFbStr ? JSON.parse(item.zhzFbStr) :[]
dialogForm.value.zbmjStr = item.zbmjStr ? JSON.parse(item.zbmjStr) :[]
dialogForm.value.zbfjStr = item.zbfjStr ? JSON.parse(item.zbfjStr) :[]
});
}
// 改变频道号
const changePdh = (val) =>{
dialogForm.value.zbpdh = val ? val[0].pdh :''
dialogForm.value.zbpdmc = val ? val[0].pdmc :''
};
// 处理字典
const handleDic = (val) =>{
let obj = props.dic.D_BZ_RYZBBBZW.find(v=> v.label == val);
return obj ? obj.value :''
}
// 处理数据
const handleRylist = (arr,text)=>{
let list = arr.map(it=>{
return { xfllId:it.id, ryId:it.id, ryJzlx:it.lx, ryMfjlb:it.fl, rySfzh:it.sfzh, ryXm:it.xm, ryZbbbzw: handleDic(text)}
})
return list;
}
// 保存数据
const onSave = () => {
editRef.value.validate((valid) => {
if (!valid) return;
loading.value = true;
let params = { ...dialogForm.value };
params.ryList = []
let zbldZb = handleRylist(dialogForm.value.zbldZbStr,'值班领导(主班)')
let zbldFb = handleRylist(dialogForm.value.zbldFbStr,'值班领导(副班)')
let zhzZb = handleRylist(dialogForm.value.zhzZbStr,'指挥长(主班)')
let zhzFb = handleRylist(dialogForm.value.zhzFbStr,'指挥长(副班)')
let zbz = handleRylist(dialogForm.value.zbzStr,'值班长')
let zbmj = handleRylist(dialogForm.value.zbmjStr,'值班民警')
let zbfj = handleRylist(dialogForm.value.zbfjStr,'值班辅警')
params.ryList = params.ryList.concat(zbldZb,zbldFb,zhzZb,zhzFb,zbz,zbmj,zbfj)
params.bbSjBbrq = props.data.year
let url = props.text == '日历' ? '/mosty-qwzx/tbQwglZbbb/save' :'/mosty-qwzx/tbQwglZbbb/update'
let message = props.text == '日历' ? '新增' :'修改'
servicePost(params, url).then((res) => {
loading.value = false;
proxy.$message.success(`${message}成功`);
emits("updateList");
}).catch(() => {
loading.value = false;
});
});
};
// 重置
const resetForm = () =>{
dialogForm.value = {
bcKtsDict: '01',
bcKssj: "00:00:00",
bcJssj: "00:00:00"
};
};
watch(()=>props.data,(val)=>{
if(val && val.info) showData(val.info)
},{immediate:true})
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 10px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
</style>

View File

@ -0,0 +1,768 @@
<template>
<div>
<el-form ref="editRef" class="info" :model="dialogForm" :inline="true" :rules="rules">
<div class="bblxItem">
<div class="btItem">基本信息</div>
<div class="info">
<el-form-item label="安保类型:" prop="abbbLx">
<el-radio-group v-model="dialogForm.abbbLx" @change="onChange" :disabled="props.text=='日历'?false:true">
<el-radio :label="item.dm" :value="item.dm" v-for="item in props.dic.D_QW_ABBB_LX" :key="item">
{{ item.zdmc }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="类别:" prop="cgabLb" v-if="dialogForm.abbbLx=='01'">
<el-select v-model="dialogForm.cgabLb">
<el-option :label="item.zdmc" :value="item.dm" v-for="item in props.dic.D_QW_ABBB_CGABLB" :key="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="活动主题:" prop="jrhdZt" v-else-if="dialogForm.abbbLx=='02'">
<el-select v-model="dialogForm.jrhdZt">
<el-option :label="item.zdmc" :value="item.dm" v-for="item in props.dic.D_QW_ABBB_JRHDZT" :key="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="活动名称:" prop="hdmc">
<el-input placeholder="活动名称" v-model="dialogForm.hdmc"></el-input>
</el-form-item>
<el-form-item label="活动市州:" prop="hdsz">
<el-select v-model="dialogForm.hdsz">
<el-option :label="item.zdmc" :value="item.dm" v-for="item in props.dic.D_BZ_DSZ" :key="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="举办地址:" prop="hdjbd">
<el-input placeholder="举办地址" v-model="dialogForm.hdjbd"></el-input>
</el-form-item>
<el-form-item label="拟投入警力:" prop="ntrjl">
<el-input-number v-model="dialogForm.ntrjl" placeholder="拟投入警力" :min="0"></el-input-number>
</el-form-item>
<el-form-item label="经度:" prop="dqjd">
<el-input placeholder="经度" v-model="dialogForm.dqjd"></el-input>
</el-form-item>
<el-form-item label="纬度:" prop="dqwd">
<el-input placeholder="纬度" v-model="dialogForm.dqwd"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="openDialog">获取经纬度</el-button>
</el-form-item>
<el-form-item label="响应机制:" prop="abbbXyjz">
<el-radio-group v-model="dialogForm.abbbXyjz">
<el-radio :label="item.dm" :value="item.dm" v-for="item in props.dic.D_QW_ABBB_XYJZ" :key="item">
{{ item.zdmc }}
</el-radio>
</el-radio-group>
</el-form-item>
<div v-if="dialogForm.abbbLx=='02'">
<el-form-item label="人数规模/场" prop="jrhdRsgmMc">
<el-select v-model="dialogForm.jrhdRsgmMc">
<el-option :label="item.zdmc" :value="item.dm" v-for="item in props.dic.D_QW_ABBB_JRHDRSGM" :key="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="预计观众人数:" prop="jrhdRsgmYjgzrs">
<el-input-number v-model="dialogForm.jrhdRsgmYjgzrs" placeholder="预计观众人数" :min="0"></el-input-number>
</el-form-item>
</div>
<el-form-item label="活动日期:" prop="hdrq">
<el-date-picker style="width: 100%" @change="hdrqChange" v-model="dialogForm.hdrq" type="daterange" format="YYYY-MM-DD" value-format="YYYY-MM-DD"></el-date-picker>
</el-form-item>
<el-form-item label="每日活动时段:" prop="hdsj">
<el-time-picker style="width: 100%" is-range @change="hdsjChange" v-model="dialogForm.hdsj" range-separator="TO" format="HH:MM:ss" value-format="HH:MM:ss"></el-time-picker>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">防控圈配置</div>
<div class="info">
<el-form-item label="防控圈内圈层半径:" prop="fkqnqbj">
<el-input-number v-model="dialogForm.fkqnqbj" :min="10" />
</el-form-item>
<el-form-item label="防控圈外圈层半径:" prop="fkqwqbj">
<el-input-number v-model="dialogForm.fkqwqbj" :min="10" />
</el-form-item>
<el-form-item>
<el-checkbox v-model="checked1">自适应感知源</el-checkbox>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">点位负责人</div>
<div class="info">
<el-form-item label="负责人" prop="dwfzrXm">
<div class="flex">
<ChooseTable :deptment="props.dep" v-if="!isDetail" :configer="{width:900,isRadio:true,lx:'mj',placement:'right'}" @change="changeShr" :dic="props.dic" />
<el-input placeholder="负责人" readonly v-model="dialogForm.dwfzrXm"></el-input>
</div>
</el-form-item>
<el-form-item label="联系电话" prop="dwfzrLxdh">
<el-input placeholder="联系电话" v-model="dialogForm.dwfzrLxdh"></el-input>
</el-form-item>
<el-form-item label="职务" prop="dwfzrZw">
<el-input placeholder="职务" v-model="dialogForm.dwfzrZw"></el-input>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">警力配置</div>
<div class="info">
<el-form-item label="辅警数" prop="jlpzFjsl">
<el-input-number v-model="dialogForm.jlpzFjsl" :min="0"></el-input-number>
</el-form-item>
<el-form-item label="车辆类型" prop="jlpzFjsl">
<el-select v-model="dialogForm.qwclCx">
<el-option :label="item.zdmc" :value="item.dm" v-for="item in props.dic.D_BZ_CLLX" :key="item">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="勤务车辆数量" prop="qwclSl">
<el-input-number v-model="dialogForm.qwclSl" :min="0"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem"> 车载装备</div>
<div class="info">
<el-form-item :label="item.zdmc" :label-width="120" v-for="(item,index) in dialogForm.pbmxCzzb" :key="index">
<el-input-number v-model="item.qxsl" :min="0" :max="1000"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">个人防护装备</div>
<div class="info">
<el-form-item :label="item.zdmc" :label-width="120" v-for="(item,index) in dialogForm.pbmxGrfhzb" :key="index">
<el-input-number v-model="item.qxsl" :min="0" :max="1000"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem">
<div class="btItem">应急装备</div>
<div class="info">
<el-form-item :label="item.zdmc" :label-width="120" v-for="(item,index) in dialogForm.pbmxYjzb" :key="index">
<el-input-number v-model="item.qxsl" :min="0" :max="1000"></el-input-number>
</el-form-item>
</div>
</div>
<div class="bblxItem" v-if="!isDetail">
<div class="btItem"></div>
<div class="info subBtn">
<el-button @click="saveForm" v-loading="loading">{{props.text=='日历'?'新增报备':'修改报备'}}</el-button>
<el-button @click="resetForm" v-if="props.text == '日历'">重置</el-button>
</div>
</div>
</el-form>
<el-dialog v-model="dialogShow" title="选择坐标系" width="1200px" custom-class="dialog_box" :show-close="true" :before-close="handleClose">
<div style="width:100%">
<div class="latlng">
<el-button v-for="btn in props.dic.D_QW_ABBB_DTBD_LX" :key="btn" @click="chackLat(btn)" v-show="btn.dm!='09'">{{btn.zdmc}}</el-button>
<div style="margin-top:10px;">
<el-input @change="jwdChange" v-model="dialogForm.dqjd" clearable style="width: 45%" />
<el-input @change="jwdChange" v-model="dialogForm.dqwd" clearable style="width: 45%" />
<el-button @click="chackLat({dm:'00'})">选取坐标</el-button>
</div>
</div>
<el-form class="info">
<el-form-item style="width: 100%">
<div class="map">
<GdMap v-if="dialogNum" />
</div>
</el-form-item>
</el-form>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="resetMap">重置</el-button>
<el-button type="primary" @click="onComfirm">确认</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { servicePost, serviceGet } from "@/api/serviceApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import emitter from "@/utils/eventBus.js";
import ChooseTable from "@/components/chooseList/chooseTable.vue";
import GdMap from "@/components/GdMap/index.vue";
import {
reactive,
ref,
getCurrentInstance,
defineProps,
defineEmits,
watch,
onMounted,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(["updateList"]);
const props = defineProps({
bblx: {
type: String,
default: "01"
},
text: String,
data: Object,
dep: Object,
dic: {
type: Object,
default: {
D_QW_ABBB_LX: [],
D_QW_ABBB_CGABLB: [],
D_QW_ABBB_XYJZ: [],
D_QW_ABBB_JRHDZT: [],
D_BZ_DSZ: [],
D_QW_ABBB_DTBD_LX: []
}
},
isDetail: {
type: Boolean,
default: false
}
});
const checked1 = ref(true);
const loading = ref(false);
const editRef = ref();
const dialogShow = ref(false);
const ablxoptions = ref([
{ text: "常规安保", value: "01" },
{ text: "节日安保", value: "02" }
]);
const dialogForm = ref({
abbbLx: "01",
dtbdList: [],
abbbXyjz: "01"
});
const dialogNum = ref(false);
const rules = reactive({
abbbLx: [
{ required: true, message: "请选择安保类型", trigger: ["change", "blur"] }
],
cgabLb: [{ required: true, message: "请选择类别", trigger: "change" }],
dwfzrXm: [{ required: true, message: "请选择负责人", trigger: "change" }],
jrhdZt: [{ required: true, message: "请选择活动主题", trigger: "change" }],
hdsz: [{ required: true, message: "请选择活动市州", trigger: "change" }],
abbbXyjz: [{ required: true, message: "请选择响应机制", trigger: "change" }],
hdmc: [{ required: true, message: "请输入活动名称", trigger: "change" }],
hdjbd: [{ required: true, message: "请输入举办地址", trigger: "change" }],
ntrjl: [{ required: true, message: "请输入拟投入警力", trigger: "change" }],
fkqnqbj: [
{ required: true, message: "请输入防控圈内圈层半径", trigger: "change" }
],
fkqwqbj: [
{ required: true, message: "请输入防控圈外圈层半径", trigger: "change" }
],
dwfzrLxdh: [
{ required: true, message: "请输入负责人联系电话", trigger: "change" }
],
jrhdRsgmMc: [
{ required: true, message: "请选择人数规模/场", trigger: "change" }
],
jrhdRsgmYjgzrs: [
{ required: true, message: "请输入预计观众人数", trigger: "change" }
],
hdrq: [{ required: true, message: "请选择活动日期", trigger: "change" }],
hdsj: [{ required: true, message: "请选择每日活动时段", trigger: "change" }],
dwfzrZw: [{ required: true, message: "请输入职务", trigger: "blur" }]
});
// 选择审核人
const changeShr = (val) => {
dialogForm.value.dwfzrXm = val[0].xm;
dialogForm.value.dwfzrLxdh = val[0].lxdh;
dialogForm.value.dwfzrLxdh = val[0].lxdh;
};
//获取经纬度 - 圈层范围清空
function chackLat(type) {
//type 00为选择经纬度01为中心点
switch (type.dm) {
case "00":
dialogForm.value.dqjd = "";
dialogForm.value.dqwd = "";
emitter.emit("drawShape", {
type: "point",
flag: "qw_jwd",
isclear: true
});
break;
case "01":
emitter.emit("deletePointArea", "qw_zxd");
emitter.emit("drawShape", {
type: "point",
flag: "qw_zxd",
isclear: true
});
break;
case "02":
emitter.emit("drawShape", {
type: "circle",
flag: "qw_hxq",
isclear: true
});
break;
case "03":
emitter.emit("drawShape", {
type: "line",
flag: "qw_jbx",
isclear: true
});
break;
case "04":
emitter.emit("deletePointArea", "qw_tzsb");
emitter.emit("drawShape", {
type: "point",
flag: "qw_tzsb",
isclear: true
});
break;
case "05":
emitter.emit("deletePointArea", "qw_ddyy");
emitter.emit("drawShape", {
type: "point",
flag: "qw_ddyy",
isclear: true
});
break;
case "06":
emitter.emit("deletePointArea", "qw_jl");
emitter.emit("drawShape", {
type: "point",
flag: "qw_jl",
isclear: true
});
break;
case "07":
emitter.emit("drawShape", { type: "line", flag: "qw_td", isclear: true });
break;
case "08":
emitter.emit("drawShape", { type: "line", flag: "qw_xl", isclear: true });
break;
}
}
// 重置地图
const resetMap = () => {
emitter.emit("deletePointArea", "qw_zxd");
emitter.emit("deletePointArea", "qw_tzsb");
emitter.emit("deletePointArea", "qw_ddyy");
emitter.emit("deletePointArea", "qw_jl");
emitter.emit("deletePointArea", "qw_jwd");
emitter.emit("removeEara", "qw_td");
emitter.emit("removeEara", "qw_xl");
emitter.emit("removeEara", "qw_jbx");
emitter.emit("removePlot", "qw_hxq");
emitter.emit("removePlot", "qw_jwd");
emitter.emit("removePlot", "qw_zxd");
emitter.emit("removePlot", "qw_ddyy");
emitter.emit("removePlot", "qw_tzsb");
dialogForm.value.dtbdList = [];
};
// 选择班次
const changeBc = (val) => {
dialogForm.value.bcMc = val ? val[0].bcMc : "";
dialogForm.value.bcId = val ? val[0].id : "";
dialogForm.value.bcKssj = val ? val[0].bcKssj : "";
dialogForm.value.bcJssj = val ? val[0].bcJssj : "";
dialogForm.value.bcKtsDict = val ? val[0].bcKtsDict : "";
};
const openDialog = () => {
dialogShow.value = true;
setTimeout(() => {
dialogNum.value = true;
getDtBdData(dialogForm.value.id);
}, 200);
};
// 处理数据
const handleRylist = (arr, text) => {
let list = arr.map((it) => {
return {
xfllId: it.id,
ryId: it.id,
ryJzlx: it.lx,
ryMfjlb: it.fl,
rySfzh: it.sfzh,
ryXm: it.xm,
ryXfbbzw: handleDic(text)
};
});
return list;
};
const onComfirm = () => {
dialogShow.value = false;
};
// 处理字典
const handleDic = (val) => {
let obj = props.dic.D_BZ_RYXFBBZW.find((v) => {
return v.label == val;
});
return obj ? obj.dm : "";
};
const hdrqChange = (e) => {
dialogForm.value.jrhdSjKsrq = e[0];
dialogForm.value.jrhdSjJsrq = e[1];
};
const hdsjChange = (e) => {
dialogForm.value.jrhdSjMrkssj = e[0];
dialogForm.value.jrhdSjMrjssj = e[1];
};
// 提交
const saveForm = () => {
editRef.value.validate((valid) => {
if (!valid) return;
dialogForm.value.pbmxCzzb = JSON.stringify(dialogForm.value.pbmxCzzb);
dialogForm.value.pbmxGrfhzb = JSON.stringify(dialogForm.value.pbmxGrfhzb);
dialogForm.value.pbmxYjzb = JSON.stringify(dialogForm.value.pbmxYjzb);
let params = { ...dialogForm.value };
let url =
props.text == "日历"
? "/mosty-qwzx/tbQwglAbbb/save"
: "/mosty-qwzx/tbQwglAbbb/update";
let message = props.text == "日历" ? "新增成功" : "修改成功";
loading.value = true;
console.log(dialogForm.value);
servicePost(params, url)
.then((res) => {
loading.value = false;
proxy.$message.success(message);
emits("updateList");
})
.catch(() => {
loading.value = false;
});
qixie();
});
};
// 重置表單
const resetForm = () => {
dialogForm.value = {
bcKtsDict: "01",
bcKssj: "00:00:00",
bcJssj: "00:00:00"
};
};
const onChange = (e) => {
dialogForm.value.cgabLb = "";
dialogForm.value.jrhdZt = "";
};
// 回显数据
const showData = (val) => {
dialogForm.value = JSON.parse(JSON.stringify(val));
dialogForm.value.dtbdList = [];
dialogForm.value.hdrq = [
dialogForm.value.jrhdSjKsrq,
dialogForm.value.jrhdSjJsrq
]; //值班民警 01
dialogForm.value.hdsj = [
dialogForm.value.jrhdSjMrkssj,
dialogForm.value.jrhdSjMrjssj
]; //值班辅警 02
if (dialogForm.value.ryList && dialogForm.value.ryList.length > 0) {
dialogForm.value.ryList.forEach((item) => {
let obj = {
id: item.ryId,
lx: item.ryJzlx,
fl: item.ryMfjlb,
sfzh: item.rySfzh,
xm: item.ryXm
}; //editId新增成功后返回的列表数据回有一个自定生成的值
if (item.ryMfjlb == "01") dialogForm.value.zbmjStr.push(obj); //值班民警 06
if (item.ryMfjlb == "02") dialogForm.value.zbfjStr.push(obj); //值班辅警 07
});
}
};
// 获取地图标点数据
const getDtBdData = (abbbId) => {
serviceGet(
{},
`/mosty-qwzx/tbQwglAbbb/selectDtbdListByAbbbId/${abbbId}`
).then((res) => {
let zbData = [];
let icon;
let flag;
let coods;
res.forEach((el) => {
switch (el.dtbdLx) {
case "01":
zbData = JSON.parse(el.dtbdZb);
icon = require(`@/assets/point/${el.dtbdTb}`);
flag = "qw_zxd";
break;
case "02":
let params = {
coords: JSON.parse(el.dtbdZb),
type: "circle",
radius: el.dtbdTbXzjd,
flag: "qw_hxq",
color: "rgba(29,237,245,0.3)",
linecolor: "#ffa500",
isclear: true
};
emitter.emit("echoPlane", params);
break;
case "03":
coods = { coords: [JSON.parse(el.dtbdZb)], text: "" };
flag = "qw_jbx";
break;
case "04":
zbData = JSON.parse(el.dtbdZb);
icon = require(`@/assets/point/${el.dtbdTb}`);
flag = "qw_tzsb";
break;
case "05":
zbData = JSON.parse(el.dtbdZb);
icon = require(`@/assets/point/${el.dtbdTb}`);
flag = "qw_ddyy";
break;
case "06":
zbData = JSON.parse(el.dtbdZb);
icon = require(`@/assets/point/${el.dtbdTb}`);
flag = "qw_jl";
break;
case "07":
coods = { coords: [JSON.parse(el.dtbdZb)], text: "" };
flag = "qw_td";
break;
case "08":
coods = { coords: [JSON.parse(el.dtbdZb)], text: "" };
flag = "qw_xl";
break;
}
if (
el.dtbdLx == "01" ||
el.dtbdLx == "04" ||
el.dtbdLx == "05" ||
el.dtbdLx == "06"
) {
emitter.emit("addPointArea", {
flag,
icon,
scale: true,
coords: [{ jd: zbData[0], wd: zbData[1] }]
});
}
if (el.dtbdLx == "03" || el.dtbdLx == "07" || el.dtbdLx == "08") {
emitter.emit("echoLine", {
coords: [coods],
flag,
type: "solid",
width: 6,
isclear: true,
color: "rgba(255,0,0,1)"
});
}
emitter.emit("addPointArea", {
flag: "qw_jwd",
icon: require("@/assets/point/zsdw.png"),
scale: true,
coords: [{ jd: dialogForm.value.dqjd, wd: dialogForm.value.dqwd }]
});
dialogForm.value.dtbdList = res;
});
});
};
watch(
() => props.data,
(val) => {
if (val && val.info) showData(val.info);
},
{ immediate: true }
);
onMounted(() => {
emitter.on("coordString", (res) => {
let icon;
let objStr = {
dtbdBznr: "", //标注内容
dtbdLx: "", //地图标点类型 D_QW_ABBB_DTBD_LX
dtbdTb: "", //地图标点图标
dtbdTbXzjd: "", //地图标点图标旋转角度
dtbdZb: "" //地图标点坐标
};
objStr.dtbdZb = JSON.stringify(res.coord);
switch (res.flag) {
case "qw_jwd":
dialogForm.value.dqjd = res.coord[0];
dialogForm.value.dqwd = res.coord[1];
icon = require("@/assets/point/zsdw.png");
break;
case "qw_hxq":
objStr.dtbdLx = "02";
objStr.dtbdZb = JSON.stringify(res.data.centerPoint);
objStr.dtbdTbXzjd = String(res.data.radius);
break;
case "qw_jbx":
objStr.dtbdLx = "03";
break;
case "qw_td":
objStr.dtbdLx = "07";
break;
case "qw_xl":
objStr.dtbdLx = "08";
break;
case "qw_zxd":
icon = require("@/assets/point/zxd.png");
objStr.dtbdLx = "01";
objStr.dtbdTb = "zxd.png";
break;
case "qw_tzsb":
icon = require("@/assets/point/yj.png");
objStr.dtbdLx = "04";
objStr.dtbdTb = "yj.png";
break;
case "qw_ddyy":
icon = require("@/assets/point/hospital.png");
objStr.dtbdLx = "05";
objStr.dtbdTb = "hospital.png";
break;
case "qw_jl":
icon = require("@/assets/point/jl.png");
objStr.dtbdLx = "06";
objStr.dtbdTb = "jl.png";
break;
}
if (objStr.dtbdLx) {
dialogForm.value.dtbdList.push(objStr);
}
if (res.type == "point") {
emitter.emit("addPointArea", {
flag: res.flag,
icon,
scale: true,
coords: [{ jd: res.coord[0], wd: res.coord[1] }]
});
}
});
});
onUnmounted(() => {
emitter.off("coordString");
});
// const qixieList=ref()
// 器械
const qixie = () => {
dialogForm.value.pbmxCzzb = dialogForm.value.pbmxCzzb
? JSON.parse(dialogForm.value.pbmxCzzb)
: props.dic.D_JCGL_JYQX_QXLX.map((item) => {
return { ...item, qxsl: 0 };
});
dialogForm.value.pbmxGrfhzb = dialogForm.value.pbmxGrfhzb
? JSON.parse(dialogForm.value.pbmxGrfhzb)
: props.dic.D_JCGL_JYQX_QXLX.map((item) => {
return { ...item, qxsl: 0 };
});
dialogForm.value.pbmxYjzb = dialogForm.value.pbmxYjzb
? JSON.parse(dialogForm.value.pbmxYjzb)
: props.dic.D_JCGL_JYQX_QXLX.map((item) => {
return { ...item, qxsl: 0 };
});
};
qixie();
</script>
<style lang="scss" scoped>
.bblxItem {
width: 100%;
line-height: 40px;
min-height: 40px;
display: flex;
.btItem {
width: 180px;
padding: 7px 0;
background: #e9e9e9;
color: #000;
margin-top: 1px;
text-align: center;
}
.info {
flex: 1;
background: #f2f2f2;
margin-top: 1px;
padding: 10px;
box-sizing: border-box;
.dl-car {
min-width: 200px;
display: inline-block;
border: solid 1px #66cbff;
margin: 20px 30px 0 0;
padding: 0;
border-radius: 5px;
background: #fff;
position: relative;
dt {
display: flex;
justify-content: space-between;
align-items: center;
color: #0380c0;
padding: 0 10px 0 40px;
box-sizing: border-box;
font-weight: 600;
box-sizing: border-box;
border-bottom: solid 1px #66cbff;
background: #e3f5ff;
height: 30px;
border-radius: 5px 5px 0 0;
}
.peo {
border-bottom: solid 1px #01d608;
background: #dbf3cf;
color: #339d00;
}
}
.dl-car::before {
position: absolute;
content: "";
top: -18px;
left: -18px;
width: 52px;
height: 49px;
background: url("~@/assets/images/peo.png");
}
}
}
.num {
width: 50px;
height: 30px;
line-height: 30px;
text-align: center;
border: 1px solid #d2d2d2;
background-color: #e7e7e7;
border-radius: 4px;
margin-right: 10px;
}
.subBtn {
padding-left: 100px;
box-sizing: border-box;
}
::v-deep .el-form-item--default {
margin-bottom: 0;
}
::v-deep .el-form-item {
margin-bottom: 10px;
}
::v-deep .el-form--inline .el-form-item {
margin-right: 20px;
margin-top: 10px;
}
::v-deep .el-input__inner {
border: 1px solid #d2d2d2;
background-color: #f9f9f9;
}
.map {
width: 98%;
height: 500px;
}
.latlng {
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,75 @@
<template>
<Calendar v-if="isShowCalendar" v-model="isShowCalendar" :dic="{D_BZ_JWZLX,D_QW_BBZT,D_ZDY_XFFWLX, D_BZ_PDDTLX, D_BZ_RYMFJLB, D_BZ_RYJZLB, D_QW_BC_KTS, D_BZ_RYZBBBZW, D_QW_BBZL, D_BZ_SF, D_QW_XQLB, D_QW_XQLX, D_JCGL_ZDSB_SBLB, D_JCGL_ZDSB_SBLX, D_JCGL_JYCL_JYJTGJLB, D_JCGL_JYCL_JYJTFWLB, D_BZ_RYXFBBZW, D_BZ_CLLX,D_BZ_XLFS, D_BZ_WZLX, D_BZ_ZZLX, D_JCGL_JYQX_QXLX,D_QW_ABBB_LX,D_QW_ABBB_CGABLB,D_QW_ABBB_XYJZ,D_QW_ABBB_JRHDZT,D_QW_ABBB_JRHDRSGM,D_BZ_DSZ,D_QW_ABBB_DTBD_LX}" />
<Tablelist v-if="!isShowCalendar" v-model="isShowCalendar" :dic="{D_BZ_JWZLX,D_QW_BBZT, D_ZDY_XFFWLX,D_BZ_PDDTLX, D_BZ_RYMFJLB, D_BZ_RYJZLB, D_QW_BC_KTS, D_BZ_RYZBBBZW, D_QW_BBZL, D_BZ_SF, D_QW_XQLB, D_QW_XQLX, D_JCGL_ZDSB_SBLB, D_JCGL_ZDSB_SBLX, D_JCGL_JYCL_JYJTGJLB, D_JCGL_JYCL_JYJTFWLB, D_BZ_RYXFBBZW, D_BZ_CLLX,D_BZ_XLFS, D_BZ_WZLX, D_BZ_ZZLX, D_JCGL_JYQX_QXLX,D_QW_ABBB_LX,D_QW_ABBB_CGABLB,D_QW_ABBB_XYJZ,D_QW_ABBB_JRHDZT,D_QW_ABBB_JRHDRSGM,D_BZ_DSZ,D_QW_ABBB_DTBD_LX}" />
</template>
<script setup>
import Calendar from './calendar.vue'
import Tablelist from './tablelist.vue'
import { ref ,getCurrentInstance} from 'vue';
const { proxy } = getCurrentInstance();
const {
D_BZ_JWZLX,
D_QW_BBZT,
D_BZ_PDDTLX,
D_BZ_RYMFJLB,
D_BZ_RYJZLB,
D_QW_BC_KTS,
D_BZ_RYZBBBZW,
D_QW_BBZL,
D_BZ_SF,
D_QW_XQLB,
D_QW_XQLX,
D_JCGL_ZDSB_SBLB,
D_JCGL_ZDSB_SBLX,
D_JCGL_JYCL_JYJTGJLB,
D_JCGL_JYCL_JYJTFWLB,
D_BZ_RYXFBBZW,
D_BZ_XLFS,
D_BZ_WZLX,
D_BZ_ZZLX,
D_JCGL_JYQX_QXLX,
D_QW_ABBB_LX,
D_QW_ABBB_XYJZ,
D_QW_ABBB_CGABLB,
D_BZ_DSZ,
D_QW_ABBB_JRHDRSGM,
D_QW_ABBB_JRHDZT,
D_QW_ABBB_DTBD_LX,
D_ZDY_XFFWLX,D_BZ_CLLX
} = proxy.$dict(
"D_BZ_JWZLX",
"D_QW_BBZT",
"D_BZ_PDDTLX",
"D_BZ_RYMFJLB",
"D_BZ_RYJZLB",
'D_QW_BC_KTS',
"D_BZ_RYZBBBZW",
"D_QW_BBZL",
"D_BZ_SF",
"D_QW_XQLB",
"D_QW_XQLX",
"D_JCGL_ZDSB_SBLB",
"D_JCGL_JYCL_JYJTGJLB",
"D_JCGL_JYCL_JYJTFWLB",
"D_BZ_RYXFBBZW",
"D_BZ_XLFS",
"D_BZ_WZLX",
"D_BZ_ZZLX",
"D_JCGL_JYQX_QXLX",
"D_QW_ABBB_LX",
"D_QW_ABBB_XYJZ",
"D_QW_ABBB_CGABLB",
"D_BZ_DSZ",
"D_QW_ABBB_JRHDRSGM",
"D_QW_ABBB_JRHDZT",
"D_QW_ABBB_DTBD_LX",
"D_JCGL_ZDSB_SBLX",
'D_ZDY_XFFWLX',"D_BZ_CLLX"
)
const isShowCalendar = ref(true);
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,307 @@
<template>
<div class="main-box">
<div class="tableCnt">
<div class="titleBox" v-if="headerShow">
<div class="title">勤务列表</div>
<div class="btnBox">
<el-button type="primary" @click="changeCanlendar">
<span>返回日历</span>
</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch">
<template #defaultSlot>
<el-select v-model="baseDate.bbzt" @change="changeType">
<el-option v-for="item in props.dic.D_QW_BBZL" :key="item.label" :label="item.label" :value="item.label" />
</el-select>
</template>
</Search>
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth">
<template #bbZt="{ row }">
<dict-tag :options="props.dic.D_QW_BBZT" :value="row.bbZt" :tag="true"></dict-tag>
</template>
<template #abbbLx="{ row }">
<dict-tag :options="props.dic.D_QW_ABBB_LX" :value="row.abbbLx" :tag="true"></dict-tag>
</template>
<template #jrhdZt="{ row }">
<dict-tag :options="props.dic.D_QW_ABBB_JRHDZT" :value="row.jrhdZt" :tag="true"></dict-tag>
</template>
<template #cgabLb="{ row }">
<dict-tag :options="props.dic.D_QW_ABBB_CGABLB" :value="row.cgabLb" :tag="true"></dict-tag>
</template>
<template #zbmj="{ row }">
<el-tag v-for="item in row.zbmj" :key="item.id" >{{ item.jlxm }}</el-tag>
</template>
<template #zbfj="{ row }">
<el-tag v-for="item in row.zbfj" :key="item.id" >{{ item.jlxm }}</el-tag>
</template>
<template #zbrq="{ row }">
{{ row.zbrq ? row.zbrq.substring(0, 10) : row.zbrq }}
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit(row)">修改</el-link>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="handleDelete(row.id)">删除</el-link>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{ ...pageData.pageConfiger, total: pageData.total}" />
</div>
</div>
<!-- 新增编辑 -->
<BbInfo v-if="isShowBb" v-model="isShowBb" :dic="props.dic" :data="baseDate" @updateData="getList" text="列表" />
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import BbInfo from "./components/bbInfo.vue";
import { timeValidate, weekValidate } from "@/utils/tools.js";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted,
defineEmits,
defineProps,
watchEffect
} from "vue";
const { proxy } = getCurrentInstance();
const emits = defineEmits(["update:modelValue"]);
const props = defineProps({
dic: Object,
headerShow: {
//是否显示操作和顶部
type: Boolean,
default: true
},
serachConfig:{
type:Object,
default:{}
}
});
const obj = reactive({
ssbmdm:'',
ssbm:''
})
const addEditForm = ref();
const isShowBb = ref(false);
const searchConfiger = reactive([
{
showType: "defaultSlot",
label: "报备类型"
},
{
showType: "input",
prop: "jzMc",
placeholder: "请输入警组名称",
label: "警组名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null",
haveControls: props.headerShow
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "警组名称", prop: "jzMc" },
{ label: "报备开始时间", prop: "bbSjKssj" },
{ label: "报备结束时间", prop: "bbSjJssj" },
{ label: "所属部门 ", prop: "ssbm" },
{ label: "报备状态 ", prop: "bbZt", showSolt: true }
]
});
const loading = ref(false);
const searchBox = ref(null); // 搜索盒子
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const bblx = ref();
const listQuery = ref({});
const baseDate = reactive({
year: timeValidate(null, "ymd"),
week: weekValidate(timeValidate(null, "ymd")),
bbzt: "值班报备",
info: null
});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
pageData.keyCount = data;
});
});
// 类型判断
const changeType = (val) => {
getList();
}
// 获取巡防中心报备数据
const getBblist = () =>{
}
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
val.startTime = val.daterange ? val.daterange[0] + " 00:00:00" : "";
val.endTime = val.daterange ? val.daterange[1] + " 23:59:59" : "";
listQuery.value = { ...listQuery.value, ...val };
delete listQuery.value.daterange;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let params = { ...listQuery.value, ...pageData.pageConfiger };
let url = "";
if (baseDate.bbzt == "值班报备") url = "/mosty-qwzx/tbQwglZbbb/selectPage";
else if (baseDate.bbzt == "街面勤务报备") url = "/mosty-qwzx/tbQwglXfbb/selectPage";
else if (baseDate.bbzt == "巡防中心报备") url = "/mosty-qwzx/tbQwZbbb";
else if (baseDate.bbzt == "专项任务报备") url = "/mosty-qwzx/tbQwglAbbb/selectPage";
else url = "/mosty-qwzx/tbQwglBb/selectPage";
if (baseDate.bbzt == "专项任务报备") {
pageData.tableColumn = [
{ label: "安保类型", prop: "abbbLx", showSolt: true },
{ label: "活动名称", prop: "hdmc" },
{ label: "安保类别", prop: "cgabLb", showSolt: true },
{ label: "活动主题", prop: "jrhdZt", showSolt: true },
{ label: "负责人姓名 ", prop: "dwfzrXm" },
{ label: "点位负责人联系电话 ", prop: "dwfzrLxdh" },
];
}else if(baseDate.bbzt == "巡防中心报备"){
pageData.tableColumn = [
{ label: "值班部门", prop: "ssbm" },
{ label: "值班日期", prop: "zbrq",showSolt: true },
{ label: "开始时间", prop: "kssj" },
{ label: "结束时间 ", prop: "jssj" },
{ label: "值班领导 ", prop: "zbldXm"},
{ label: "民警 ", prop: "zbmj",showSolt: true},
{ label: "辅警 ", prop: "zbfj",showSolt: true},
];
}else {
pageData.tableColumn = [
{ label: "警组名称", prop: "jzMc" },
{ label: "报备开始时间", prop: "bbSjKssj" },
{ label: "报备结束时间", prop: "bbSjJssj" },
{ label: "所属部门 ", prop: "ssbm" },
{ label: "报备状态 ", prop: "bbZt", showSolt: true }
];
}
if (baseDate.bbzt != "值班报备" && baseDate.bbzt != "街面勤务报备") {
let obj = props.dic.D_QW_BBZL.find((it) => {
return it.label == baseDate.bbzt;
});
params.qwBbzl = obj.dm;
}
serviceGet(params, url).then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
if (baseDate.bbzt == "巡防中心报备"){
pageData.tableData.forEach((item) => {
item.zbmj = JSON.parse(item.zbmj);
item.zbfj = JSON.parse(item.zbfj);
});
}
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy.$confirm("确定要删除", "警告", { type: "warning" }).then(() => {
let url = "";
if (baseDate.bbzt == "巡防中心报备"){
serviceDelete({}, '/mosty-qwzx/tbQwZbbb/batch?ids=' + id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
}else{
if (baseDate.bbzt == "值班报备") url = "/mosty-qwzx/tbQwglZbbb/";
else if (baseDate.bbzt == "街面勤务报备") url = "/mosty-qwzx/tbQwglXfbb/";
else if (baseDate.bbzt == "专项任务报备") url = "/mosty-qwzx/tbQwglAbbb/";
else url = "/mosty-qwzx/tbQwglBb/";
serviceDelete({}, url + id).then((res) => {
proxy.$message.success("删除成功");
getList({});
});
}
})
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = props.headerShow ? window.innerHeight - searchBox.value.offsetHeight - 250 : window.innerHeight - searchBox.value.offsetHeight - 580;
window.onresize = function () {
tabHeightFn();
};
};
// 修改数据
const addEdit = (row) => {
baseDate.info = JSON.parse(JSON.stringify(row));
isShowBb.value = true;
};
const changeCanlendar = () => {
emits("update:modelValue", true);
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
watchEffect(()=>{
console.log(props.serachConfig,'serachConfig');
pageData.pageConfiger={...pageData.pageConfiger,...props.serachConfig}
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
::v-deep .dialog .el-form--inline {
padding: 0 !important;
}
</style>

View File

@ -0,0 +1,305 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="false"
v-model="listQuery.ssbmdm"
/>
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="flex align-center" style="width: 40%">
<div>是否包含下级:</div>
<el-select
style="flex: 1"
v-model="listQuery.isChild"
placeholder="请选择是否包含"
@change="changeSfbhFn"
>
<el-option
v-for="item in D_BZ_SF"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<!-- <ul class="itemBox">
<li class="item">
<div class="ItemTitle">统计图</div>
<div class="echartsCnt">
<BarEcharts v-if="EchartsData.length>0" :data='EchartsData' :Xdata='Xdata' />
</div>
</li>
</ul> -->
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="tableHeight"
:pageConfiger="{ ...pageData.pageConfiger, total: pageData.total }"
/>
</div>
</div>
</div>
</template>
<script setup>
import { getItem } from "@/utils/storage";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/components/barEcharts.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import {getPageBbtx} from "@/api/lzqwzx/index.js";
import Search from "@/components/aboutTable/Search.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import { timeValidate } from "@/utils/tools.js";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_QWDBZT, D_BZ_QWZT, D_QW_BBZL, D_QW_BBZT, D_BZ_SF } = proxy.$dict(
"D_BZ_QWDBZT",
"D_BZ_QWZT",
"D_QW_BBZL",
"D_QW_BBZT",
"D_BZ_SF"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const tableDialog = ref();
const searchConfiger = reactive([
{
showType: "input",
prop: "fzrXm",
placeholder: "请输入负责人名称",
label: "负责人名称"
}
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
haveControls: false,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 30,
pageCurrent: 1
}, //分页
controlsWidth: 250, //操作栏宽度
tableColumn: [
{ label: "负责人姓名", prop: "fzrXm" },
{ label: "警组名称", prop: "jzMc" },
{ label: "所属部门", prop: "ssbm" },
{ label: "状态提醒", prop: "text" },
{ label: "提醒时间", prop: "tzsj" }
]
});
const Xdata = ref([]);
const EchartsData = ref([]);
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: "四川省林芝市公安局",
gldwdm: "511600000000"
});
const listQuery = ref({
isChild: "",
// tjrq: "2024-08-13", //单日统计
tjrq: timeValidate(new Date(), "ymd"), //单日统计
dateType: "03",
ssbmdm: ""
});
onMounted(() => {
tabHeightFn();
getTjFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgJc;
getList();
getTjFn();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
getPageBbtx(params)
.then((res) => {
console.log(res);
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.finally((err) => {
pageData.tableConfiger.loading = false;
});
// serviceGet(params, "/mosty-base/sysUserExtend/selectXfllQwVOPage")
// .then((res) => {
// pageData.tableConfiger.loading = false;
// pageData.tableData = res.records;
// pageData.total = res.total;
// })
// .catch(() => {
// pageData.tableConfiger.loading = false;
// });
};
const getTjFn = () => {
serviceGet(listQuery.value, "/mosty-qwzx/tbQwglCount/selectBmjcCount").then(
(res) => {
console.log(res, "res");
let jzscArr = [];
let xlyjcsArr = [];
Xdata.value = [res.ssbm];
jzscArr = [res.jzsc];
xlyjcsArr = [res.xlyjcs];
EchartsData.value = [
{ name: "久坐时长", data: jzscArr, type: "bar", barWidth: 10 },
{ name: " 巡逻越界次数", data: xlyjcsArr, type: "bar", barWidth: 10 }
];
}
);
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 确定启动督办
const handleConfirm = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/startQwDbzt").then((res) => {
proxy.$message.success("启动成功");
getList({});
});
};
// 确定启动督办
const handleConfirmJs = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/finishQwDbzt").then((res) => {
proxy.$message.success("关闭成功");
getList({});
});
};
// 打开表格弹窗
const openTable = (row, type) => {
tableDialog.value.init(row.sfzh, type);
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 400;
window.onresize = function () {
tabHeightFn();
};
};
const getJrjqYj = () => {
const promes = { pageCurrent: 1, pageSize: 20 };
getPageBbtx(promes).then((res) => {
console.log(res);
});
};
getJrjqYj();
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: 200px;
}
</style>

View File

@ -0,0 +1,300 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="false"
v-model="listQuery.ssbmdm"
/>
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="flex align-center" style="width: 40%">
<div>是否包含下级:</div>
<el-select
style="flex: 1"
v-model="listQuery.isChild"
placeholder="请选择是否包含"
@change="changeSfbhFn"
>
<el-option
v-for="item in D_BZ_SF"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<ul class="itemBox">
<li class="item">
<div class="ItemTitle">统计图</div>
<div class="echartsCnt">
<BarEcharts
v-if="EchartsData.length > 0"
:data="EchartsData"
:Xdata="Xdata"
/>
</div>
</li>
</ul>
<!-- <div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div> -->
<div class="tabBox">
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #qwZt="{ row }">
<dict-tag :options="D_BZ_QWZT" :value="row.qwZt" :tag="false" />
</template>
<template #qwDbzt="{ row }">
<dict-tag :options="D_BZ_QWDBZT" :value="row.qwDbzt" :tag="false" />
<span v-if="row.qwDbzt == null">未督办</span>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="tableHeight"
:pageConfiger="{ ...pageData.pageConfiger, total: pageData.total }"
/>
</div>
</div>
</div>
</template>
<script setup>
import { getItem } from "@/utils/storage";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/components/barEcharts.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import { timeValidate } from "@/utils/tools.js";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_QWDBZT, D_BZ_QWZT, D_QW_BBZL, D_QW_BBZT, D_BZ_SF } = proxy.$dict(
"D_BZ_QWDBZT",
"D_BZ_QWZT",
"D_QW_BBZL",
"D_QW_BBZT",
"D_BZ_SF"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const tableDialog = ref();
const searchConfiger = reactive([
// {
// showType: "daterange",
// prop: "daterange",
// placeholder: "请选择日期",
// label: "日期"
// }
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
haveControls: false,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 250, //操作栏宽度
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "勤务状态", prop: "qwZt", showSolt: true },
{ label: "督办状态", prop: "qwDbzt", showSolt: true },
{ label: "勤务时长", prop: "qwsc" },
{ label: "久坐时长", prop: "jzsc" },
{ label: "巡逻越界次数", prop: "xlyjcs" }
]
});
const Xdata = ref([]);
const EchartsData = ref([]);
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: "四川省林芝市公安局",
gldwdm: "511600000000"
});
const listQuery = ref({
isChild: "",
// tjrq: "2024-08-13", //单日统计
tjrq: timeValidate(new Date(), "ymd"), //单日统计
dateType: "03",
ssbmdm: ""
});
onMounted(() => {
tabHeightFn();
getTjFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgJc;
getList();
getTjFn();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
serviceGet(params, "/mosty-base/sysUserExtend/selectXfllQwVOPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
const getTjFn = () => {
serviceGet(listQuery.value, "/mosty-qwzx/tbQwglCount/selectBmjcCount").then(
(res) => {
console.log(res, "res");
let jzscArr = [];
let xlyjcsArr = [];
Xdata.value = [res.ssbm];
jzscArr = [res.jzsc];
xlyjcsArr = [res.xlyjcs];
EchartsData.value = [
{ name: "久坐时长", data: jzscArr, type: "bar", barWidth: 10 },
{ name: " 巡逻越界次数", data: xlyjcsArr, type: "bar", barWidth: 10 }
];
}
);
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 确定启动督办
const handleConfirm = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/startQwDbzt").then((res) => {
proxy.$message.success("启动成功");
getList({});
});
};
// 确定启动督办
const handleConfirmJs = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/finishQwDbzt").then((res) => {
proxy.$message.success("关闭成功");
getList({});
});
};
// 打开表格弹窗
const openTable = (row, type) => {
tableDialog.value.init(row.sfzh, type);
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 480;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: 200px;
}
</style>

View File

@ -0,0 +1,289 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="false"
v-model="listQuery.ssbmdm"
/>
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
<div class="flex align-center" style="width: 40%">
<div>是否包含下级:</div>
<el-select
style="flex: 1"
v-model="listQuery.isChild"
placeholder="请选择是否包含"
@change="changeSfbhFn"
>
<el-option
v-for="item in D_BZ_SF"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<ul class="itemBox">
<li class="item">
<div class="ItemTitle">统计图</div>
<div class="echartsCnt">
<BarEcharts
v-if="EchartsData.length > 0"
:data="EchartsData"
:Xdata="Xdata"
/>
</div>
</li>
</ul>
<!-- <div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div> -->
<div class="tabBox">
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #qwZt="{ row }">
<dict-tag :options="D_BZ_QWZT" :value="row.qwZt" :tag="false" />
</template>
<template #qwDbzt="{ row }">
<dict-tag :options="D_BZ_QWDBZT" :value="row.qwDbzt" :tag="false" />
<span v-if="row.qwDbzt == null">未督办</span>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="tableHeight"
:pageConfiger="{ ...pageData.pageConfiger, total: pageData.total }"
/>
</div>
</div>
</div>
</template>
<script setup>
import { getItem } from "@/utils/storage";
import BarEcharts from "@/views/backOfficeSystem/qwManagement/components/barEcharts.vue";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import {getPageBbtx} from "@/api/lzqwzx/index.js";
import Search from "@/components/aboutTable/Search.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import { qwjcSelectBmjcCount } from "@/api/lzqwzx/index.js";
import { qwjcSelectXfllQwVOPage } from "@/api/lzbase/index.js";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import { timeValidate } from "@/utils/tools.js";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_QWDBZT, D_BZ_QWZT, D_QW_BBZL, D_QW_BBZT, D_BZ_SF } = proxy.$dict(
"D_BZ_QWDBZT",
"D_BZ_QWZT",
"D_QW_BBZL",
"D_QW_BBZT",
"D_BZ_SF"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const tableDialog = ref();
const searchConfiger = reactive([
// {
// showType: "daterange",
// prop: "daterange",
// placeholder: "请选择日期",
// label: "日期"
// }
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
haveControls: false,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 250, //操作栏宽度
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "勤务状态", prop: "qwZt", showSolt: true },
{ label: "督办状态", prop: "qwDbzt", showSolt: true },
{ label: "勤务时长", prop: "qwsc" },
{ label: "久坐时长", prop: "jzsc" },
{ label: "巡逻越界次数", prop: "xlyjcs" }
]
});
const Xdata = ref([]);
const EchartsData = ref([]);
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: "四川省林芝市公安局",
gldwdm: "511600000000"
});
const listQuery = ref({
isChild: "",
// tjrq: "2024-08-13", //单日统计
tjrq: timeValidate(new Date(), "ymd"), //单日统计
dateType: "03",
ssbmdm: ""
});
onMounted(() => {
tabHeightFn();
getTjFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.gldwdm = val.orgCode;
baseInfo.value.orgName = val.orgJc;
getList();
getTjFn();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
qwjcSelectXfllQwVOPage(params).then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
const getTjFn = () => {
qwjcSelectBmjcCount(listQuery.value, "/mosty-qwzx/tbQwglCount/selectBmjcCount").then(
(res) => {
console.log(res, "res");
let jzscArr = [];
let xlyjcsArr = [];
Xdata.value = [res.ssbm];
jzscArr = [res.jzsc];
xlyjcsArr = [res.xlyjcs];
EchartsData.value = [
{ name: "久坐时长", data: jzscArr, type: "bar", barWidth: 10 },
{ name: " 巡逻越界次数", data: xlyjcsArr, type: "bar", barWidth: 10 }
];
}
);
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 480;
window.onresize = function () {
tabHeightFn();
};
};
const getJrjqYj = () => {
const promes = { pageCurrent: 1, pageSize: 20 };
getPageBbtx(promes).then((res) => {
console.log(res);
});
};
getJrjqYj();
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: 200px;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<div style="width:100%;height:100%" ref="barEchrats"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted ,defineProps,watchEffect,nextTick} from "vue";
const props = defineProps({
data: {
type: Array,
default: []
},
colorList: {
type: Array,
default: [
["#4285f4", "#4285f4", "#4285f4"],
["#34B877", "#34B877", "#34B877"],
["#01C2FF", "#01C2FF", "#01C2FF"]
]
}
});
const barEchrats = ref();
const initEchrats = (data) => {
const options = {
grid: {
top: "15%",
left: "10%",
bottom: "10%",
right: "10%",
containLabel: true
},
xAxis: [
{
axisLine: {
show: true,
lineStyle: {
type: "solid",
width: "1"
}
},
axisTick: {
show: false
},
axisLabel: {
color: "#000"
},
data: ["民警", "辅警", "警车"]
}
],
yAxis: [
{
nameTextStyle: {
fontSize: 13 // y轴name的样式调整
},
splitLine: {
show: true, // 不显示网格线
lineStyle: {
color: "rgba(15,36,90,0.4)",
type: "dashed"
}
},
axisLabel: {
color: "#000"
},
type: "value"
}
],
series: [
{
name: "数量",
type: "bar",
showBackground: false,
barWidth: 24, // 柱子宽度
itemStyle: {
barBorderRadius: [5, 5, 0, 0],
normal: {
label: {
show: true,
position: "top"
},
color: function (params) {
if (props.colorList && props.colorList.length>0) {
var colorList = props.colorList;
let colorItem = colorList[params.dataIndex];
let colors = {
type: "linear",x: 0,y: 1,x2: 0, y2: 0,
colorStops: [
{ offset: 0, color: colorItem[0] },
{ offset: 0.5, color: colorItem[1] },
{ offset: 1, color: colorItem[2] }
]
};
return colors;
} else {
return {
colorStops: [
{ offset: 0, color: "#4285f4" },
{ offset: 1, color: "#3afbc2" }
]
};
}
}
}
},
data: data
}
]
};
var myChart = echarts.init(barEchrats.value);
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data) {
nextTick(() => {
initEchrats(props.data); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,245 @@
<template>
<div style="width:100%;height:100%" ref="echratsDc"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { on } from "element-plus/es/utils";
import { onMounted, ref, defineProps, watchEffect, nextTick } from "vue";
const props = defineProps({
data: {
type: Array,
default: []
},
colorList: {
type: Array,
default: [
["#4285f4", "#4285f4", "#4285f4"],
["#34B877", "#34B877", "#34B877"],
["#01C2FF", "#01C2FF", "#01C2FF"]
]
}
});
const echratsDc = ref();
const max = ref(0);
onMounted(() => {});
const callMax = (arr) => {
let max = 0;
arr.forEach((el) => {
el.forEach((el1) => {
if (!(el1 === undefined || el1 === "")) {
if (max < Number(el1)) max = Number(el1);
}
});
});
let maxInt = Math.ceil(max / 9.5);
// 不让最高的值超过最上面的刻度
let maxval = maxInt * 10;
return maxval;
};
const initEcharts = (data, getmydzd) => {
var myChart = echarts.init(echratsDc.value);
let options = {
backgroundColor: "rgba(0,0,0,0)", //背景颜色
grid: {
left: "3%",
top: "10%",
right: "10%",
bottom: "10%",
containLabel: true
},
tooltip: {
formatter: (params) => {
if (params.name !== "")
return params.name + ":" + data[params.dataIndex];
},
textStyle: {
align: "left"
}
},
xAxis: [
{
type: "value",
axisLabel: {
margin: 5,
color: "#000", //x轴文字颜色
formatter: function (val) {
return val + "";
},
textStyle: { fontSize: "13" }
},
min: 0,
max: max.value, // 计算最大值
interval: max.value / 5, // 平均分成5份
splitNumber: 5,
splitLine: { show: false },
axisLine: { show: true },
axisTick: { show: false }
},
{
type: "value",
axisLabel: { show: true },
min: 0,
max: max.value, // 计算最大值
interval: max.value / 10, // 平均分成10份
splitNumber: 10,
splitLine: { show: false },
axisTick: { show: false }
}
],
yAxis: [
{
type: "category",
inverse: true,
axisLabel: {
formatter: (value, index) => {
if (value.length >= 12) {
value = value.slice(0, 12) + "\n" + value.slice(12);
}
if (value.length >= 26) {
value = value.slice(0, 26) + "\n" + value.slice(26);
}
return value;
},
textStyle: {
color: "#000", //y轴文字颜色
fontSize: "12",
align: "right",
lineHeight: 18
}
},
splitLine: { show: false },
axisTick: { show: false },
axisLine: {
lineStyle: {
color: "#000",
width: 1,
opacity: 0.3
}
},
data: ["民警", "辅警", "警车"]
}
],
dataZoom: [
{
type: "inside",
show: true,
height: 15,
start: 1,
end: 100,
orient: "vertical",
zlevel: 66
}
],
series: [
{
name: "值",
type: "bar",
xAxisIndex: 0,
itemStyle: {
normal: {
color: function (params) {
if (props.colorList && props.colorList.length > 0) {
var colorList = props.colorList;
let colorItem = colorList[params.dataIndex];
let colors = {
type: "linear",
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [
{ offset: 0, color: colorItem[0] },
{ offset: 0.5, color: colorItem[1] },
{ offset: 1, color: colorItem[2] }
]
};
return colors;
} else {
return {
colorStops: [
{ offset: 0, color: "#40cbe8" },
{ offset: 1, color: "#3afbc2" }
]
};
}
}
}
},
barWidth: 15,
data: data,
z: 0
},
{
type: "pictorialBar",
itemStyle: {
normal: {
color: "#fff" //分割的显色
}
},
symbolRepeat: "fixed",
// symbolMargin: 3, //每一节的宽度
symbol: "rect",
symbolClip: true,
symbolSize: [4, 18],
symbolPosition: "start",
symbolOffset: [0, -1],
// data: getmydzd,
// z: 66,
// animationEasing: "elasticOut"
}, //分隔
{
type: "pictorialBar",
symbol: "rect",
itemStyle: {
normal: {
color: "none"
}
},
label: {
normal: {
formatter: (patams) => {
var text = "{f| " + patams.data + "}";
return text;
},
rich: {
f: { color: "#000" }
},
position: "right",
show: true
}
},
data: data,
z: 77,
animationEasing: "elasticOut"
} //外边框
]
};
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data) {
var getmydzd = [],
big = 0;
let arr = props.data;
max.value = Math.ceil(callMax([arr]) / 10) * 10;
arr.forEach((el) => {
if (!(el === undefined || el === "")) {
if (big < Number(el)) big = Number(el);
}
});
for (let index = 0; index < arr.length; index++) {
getmydzd.push(big * 4);
}
nextTick(() => {
initEcharts(arr, getmydzd); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,210 @@
<template>
<div style="width:100%;height:100%" ref="lineEchrats"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted, defineProps, watchEffect, nextTick } from "vue";
const lineEchrats = ref();
const props = defineProps({
data: {
type: Object,
default: {
label: ["民警", "辅警", "警车"], //类型
value: [111, 222, 333], //值
colorList: [
["#4285f4", "#4285f4", "#4285f4"],
["#34B877", "#34B877", "#34B877"],
["#01C2FF", "#01C2FF", "#01C2FF"]
]
}
}
});
const barEchrats = ref();
const initEchrats = (obj) => {
const options = {
color: ["#00DFE3", "#00ABFB", "#21F9A3","#F9C521"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985"
}
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
top:'10%',
containLabel: true
},
xAxis: [
{
type: "category",
boundaryGap: false,
show: true,
data: ["0点","1点","2点","3点","4点","5点","6点","7点","8点","9点","10点","11点","12点","13点","14点","15点","16点","17点","18点","19点","20点","21点","22点","23点"],
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: "#000"
}
},
lineStyle: {
color: "#000"
}
}
],
yAxis: [
{
axisTick: {
show: false
},
type: "value",
axisLine: {
lineStyle: {
color: "#000"
}
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(15,36,90,0.4)",
type: "dashed"
}
}
}
],
series: [
{
name:"民警",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: {
opacity: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(66,133,244,0)"
},
{
offset: 0.5,
color: "rgba(66,133,244,0.5)"
},
{
offset: 1,
color: "rgba(66,133,244,1)"
}
],
global: false
}
},
emphasis: {
focus: "series"
},
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
},
{
name:"辅警",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: {
opacity: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(52,184,119,0)"
},
{
offset: 0.5,
color: "rgba(52,184,119,0.3)"
},
{
offset: 1,
color: "rgba(52,184,119,1)"
}
],
global: false
}
},
emphasis: {
focus: "series"
},
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
},
{
name:"警车",
type: "line",
stack: "Total",
smooth: true,
lineStyle: {
width: 2
},
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: {
opacity: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(0,233,227,0)"
},
{
offset: 0.5,
color: "rgba(0,233,227,0.5)"
},
{
offset: 1,
color: "rgba(0,233,227,1)"
}
],
global: false
}
},
emphasis: {
focus: "series"
},
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]
},
]
};
var myChart = echarts.init(lineEchrats.value);
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data) {
nextTick(() => {
initEchrats(props.data); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,148 @@
<template>
<div style="width:100%;height:100%" ref="lineEchrats"></div>
</template>
<script setup>
import * as echarts from "echarts";
import { ref, onMounted, defineProps, watchEffect, nextTick, watch } from "vue";
const lineEchrats = ref();
const props = defineProps({
data: {
type: [],
default: []
}
});
const barEchrats = ref();
const childData = ref([]);
const initEchrats = (data) => {
console.log(data, "data");
const options = {
color: ["#00DFE3", "#00ABFB", "#21F9A3", "#F9C521"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "cross",
label: {
backgroundColor: "#6a7985"
}
}
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
top: "10%",
containLabel: true
},
xAxis: [
{
type: "category",
boundaryGap: false,
show: true,
data: [
"0点",
"1点",
"2点",
"3点",
"4点",
"5点",
"6点",
"7点",
"8点",
"9点",
"10点",
"11点",
"12点",
"13点",
"14点",
"15点",
"16点",
"17点",
"18点",
"19点",
"20点",
"21点",
"22点",
"23点"
],
splitLine: {
show: false
},
axisLine: {
lineStyle: {
color: "#000"
}
},
lineStyle: {
color: "#000"
}
}
],
yAxis: [
{
axisTick: {
show: false
},
type: "value",
axisLine: {
lineStyle: {
color: "#000"
}
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(15,36,90,0.4)",
type: "dashed"
}
}
}
],
series: data
};
var myChart = echarts.init(lineEchrats.value);
myChart.setOption(options);
window.addEventListener("resize", () => {
myChart.resize();
});
};
watchEffect(() => {
if (props.data) {
childData.value = props.data.map((item) => {
return {
lineStyle: { width: 2 },
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: {
opacity: 0.8,
colorStops: [
{
offset: 0,
color: "rgba(66,133,244,0)"
},
{
offset: 0.5,
color: "rgba(66,133,244,0.5)"
},
{
offset: 1,
color: "rgba(66,133,244,1)"
}
],
global: false
}
},
emphasis: { focus: "series" },
...item
};
});
nextTick(() => {
initEchrats(childData.value); //初始化统计图
});
}
});
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,476 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree width="300px" placeholder="管理部门ID" @changeSsbm='changeSsbm' clearable filterable :isBmId="true" v-model="listQuery.ssbmdm" />
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构{{ssbmmc}}</div>
<div class="flex align-center" style="width:40%">
<div>是否包含下级:</div>
<el-select style="flex:1" v-model="listQuery.isChild" placeholder="请选择是否包含">
<el-option v-for="item in D_BZ_SF" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-date-picker v-model="listQuery.tjrq" type="date" value-format="YYYY-MM-DD" />
<el-button type='primary' @click="searchFn">搜索</el-button>
</div>
</div>
<div class="echartsBox">
<!-- 第一模块 -->
<ul class="itemBox">
<li class="item" v-for="item in date.oneList" :key="item.label">
<div class="ItemTitle">{{item.label}}</div>
<div class="echartsCnt">
<BatteryEharts v-if="item.value.length>0" :data='item.value' />
</div>
</li>
</ul>
<!-- 第2模块 -->
<ul class="itemBoxSmall">
<li class="item" v-for="item in date.twoList" :key="item.label">
<div class="ItemTitle">{{item.label}}</div>
<ul class="itemCnt">
<li class="itemCntChild" v-for="(it,idx) in item.list" :key="idx">
<span class="icon"><img :src="it.icon" alt="" :style="{width:idx==2?'26px':'30px'}"></span>
<span class="title">{{it.title}} :</span>
<span class="num">{{it.num}} {{it.dw}}</span>
</li>
</ul>
</li>
</ul>
<!-- 第3模块 -->
<ul class="itemBox">
<li class="item" v-for="(item,idx) in date.threeList" :key="idx" :style="{flex:idx==0 ? 1:2}">
<div class="ItemTitle">{{item.label}}</div>
<div class="echartsCnt">
<BarEcharts v-if="item.label =='在岗警力数量统计'" :data="item.value" />
<LineEcharts v-if="item.label =='在岗警力时段统计' && item.value" :data="item.value" />
</div>
</li>
</ul>
<!-- 第4模块 -->
<ul class="itemBox">
<li class="item" v-for="(item,idx) in date.fourList" :key="idx" :style="{flex:idx==0 ? 1:2}">
<div class="ItemTitle">
<span>{{item.label}}</span>
<!-- <span class="btn">
<el-icon>
<Download />
</el-icon> 导出EXCEL
</span> -->
</div>
<div class="echartsCnt">
<ul v-if="item.label == '在岗警力统计报表'">
<li>
<div class="head">统计类型</div>
<div class="head">数量</div>
</li>
<li v-for="it in item.list" :key="it.label">
<div class="num num1">{{it.label}}</div>
<div class="num">{{it.value}}</div>
</li>
</ul>
<ul v-if="item.label == '在岗警力时段统计报表'">
<li v-for="(it,itix) in item.list" :key="it.label">
<div class="numlabel" :class="itix==0 ? 'topNum':''">{{it.label}}</div>
<div class="numValue">
<span :class="itix==0 ? 'topSpan':''" v-for="(id,ix) in it.lx" :key="ix">{{id}}</span>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import BatteryEharts from "./components/batteryEharts.vue";
import BarEcharts from "./components/barEcharts.vue";
import { timeValidate } from "@/utils/tools.js";
import { serviceGet, servicePost } from "@/api/serviceApi.js";
import LineEcharts from "./components/lineEcharts.vue";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const deptId=JSON.parse(localStorage.getItem('deptId'))
const { proxy } = getCurrentInstance();
const { D_BZ_SF } = proxy.$dict("D_BZ_SF");
const listQuery = ref({
// tjrq: "2024-08-13", //单日统计
tjrq:timeValidate(new Date(),'ymd'),//单日统计
dateType: "03",
ssbmdm: deptId[0].deptCode
});
const ssbmmc=ref(deptId[0].deptName);
const date = reactive({
oneList: [
{ label: "街面警力", value: [] },
{ label: "可抽调警力", value: [] },
{ label: "报备警力", value: [] },
{ label: "报备总量", value: [] }
],
twoList: [
{
label: "当日当前时刻",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
},
{
label: "峰值00:00:00 ~ 235959",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
},
{
label: "报备总量",
list: [
{
icon: require("@/assets/images/mj.png"),
title: "在岗民警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/fj.png"),
title: "在岗辅警",
num: 110,
dw: "人"
},
{
icon: require("@/assets/images/jc.png"),
title: "在岗警车",
num: 110,
dw: "辆"
}
]
}
],
threeList: [
{ label: "在岗警力数量统计", value: [] },
{
label: "在岗警力时段统计",
value: [
{
data: [0, 0, 0],
name: "民警",
smooth: true,
stack: "Total",
type: "line"
},
{
data: [0, 0, 0],
name: "辅警",
stack: "Total",
smooth: true,
type: "line"
},
{
data: [0, 0, 0],
name: "车辆",
stack: "Total",
smooth: true,
type: "line"
}
]
}
],
fourList: [
{
label: "在岗警力统计报表",
list: [
{ label: "民警", value: 3 },
{ label: "辅警", value: 3 },
{ label: "警车", value: 3 }
]
},
{
label: "在岗警力时段统计报表",
list: [
{
label: "统计类型",
lx: [
"0时",
"1时",
"2时",
"3时",
"4时",
"5时",
"6时",
"7时",
"8时",
"9时",
"10时",
"11时",
"12时",
"13时",
"14时",
"15时",
"16时",
"17时",
"18时",
"19时",
"20时",
"21时",
"22时",
"23时"
]
},
{
label: "民警",
lx: []
},
{
label: "辅警",
lx: []
},
{
label: "警车",
lx: []
}
]
}
]
});
// 获取上面柱状图的数据
const handleJlData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDateJYBMFCCount"
).then((res) => {
date.oneList[0].value = [res.jmjlMjsl, res.jmjlFjsl, res.jmjlClsl];
date.oneList[1].value = [res.yjkcdjlMjsl, res.yjkcdjlFjsl, res.yjkcdjlClsl];
date.oneList[2].value = [res.bbjlMjsl, res.bbjlFjsl, res.bbjlClsl];
date.oneList[3].value = [res.bbzlMjsl, res.bbzlFjsl, res.bbzlClsl];
});
};
const searchFn=()=>{
handleJlData();
handleFzData();
}
// 获取中间柱状图的数据
const handleFzData = () => {
serviceGet(
listQuery.value,
"/mosty-qwzx/tbQwglCount/selectDateMFCPartCount"
).then((res) => {
date.twoList[0].list[0].num = res.dqskMjsl;
date.twoList[0].list[1].num = res.dqskFjsl;
date.twoList[0].list[2].num = res.dqskClsl;
date.twoList[1].list[0].num = res.fzMjsl;
date.twoList[1].list[1].num = res.fzFjsl;
date.twoList[1].list[2].num = res.fzClsl;
date.twoList[2].list[0].num = res.gzMjsl;
date.twoList[2].list[1].num = res.gzFjsl;
date.twoList[2].list[2].num = res.gzClsl;
date.threeList[0].value = [res.zsMjsl, res.zsFjsl, res.zsClsl];
date.threeList[1].value[0].data = res.partMjslList;
date.threeList[1].value[1].data = res.partFjslList;
date.threeList[1].value[2].data = res.partClslList;
date.fourList[0].list[0].value = res.zsMjsl;
date.fourList[0].list[1].value = res.zsFjsl;
date.fourList[0].list[2].value = res.zsClsl;
date.fourList[1].list[1].lx = res.partMjslList;
date.fourList[1].list[2].lx = res.partFjslList;
date.fourList[1].list[3].lx = res.partClslList;
});
};
const changeSsbm = (val) => {
ssbmmc.value=val.orgName;
listQuery.value.ssbmdm = val.orgCode;
handleJlData();
handleFzData();
};
onMounted(() => {
handleJlData();
handleFzData();
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
font-size: 16px;
.tableCnt {
flex: 1;
margin-left: 10px;
.echartsBox {
height: calc(100% - 50px);
display: flex;
flex-direction: column;
.itemBox {
flex: 1;
display: flex;
height: 100%;
margin: 2px 0;
}
.itemBoxSmall {
height: 110px;
display: flex;
margin: 2px 0;
}
.ItemTitle {
display: flex;
justify-content: space-between;
align-items: center;
height: 30px;
background: #f4f4f4;
padding: 0 14px;
box-sizing: border-box;
.btn {
padding: 2px 6px;
color: #fff;
background: #01c2ff;
border-radius: 4px;
font-size: 14px;
cursor: pointer;
}
}
.echartsCnt {
height: calc(100% - 30px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
li {
display: flex;
.head {
width: 50%;
background: #f0f0f0;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
font-size: 16px;
line-height: 30px;
}
.num {
width: 50%;
line-height: 30px;
text-align: center;
padding: 4px 0;
box-sizing: border-box;
border: 1px solid #f0f0f0;
border-top: 0;
}
.num1 {
border-right: 0;
}
}
.numlabel {
width: 80px;
text-align: center;
font-size: 14px;
white-space: nowrap;
border: 1px solid #cac8c8;
background: #f0f0f0;
line-height: 38px;
border-top: 0;
}
.topNum {
border-top: 1px solid #cac8c8;
}
.numValue {
width: calc(100% - 80px);
line-height: 38px;
span {
border: 1px solid #cac8c8;
font-size: 14px;
display: inline-block;
width: calc(100% / 24);
text-align: center;
border-top: 0;
border-left: 0;
white-space: nowrap;
}
.topSpan {
border-top: 1px solid #cac8c8;
}
}
}
.itemCnt {
width: 100%;
display: flex;
flex-wrap: wrap;
overflow: hidden;
.itemCntChild {
width: 50%;
padding: 5px 20px;
box-sizing: border-box;
display: flex;
align-items: center;
overflow: hidden;
.icon {
display: inline-block;
text-align: center;
width: 30px;
}
.title {
color: #000;
font-size: 14px;
margin: 0 12px;
white-space: nowrap;
}
.num {
color: #142232;
font-size: 16px;
white-space: nowrap;
}
}
}
.item {
flex: 1;
height: 100%;
margin: 0 2px;
}
}
}
}
</style>

View File

@ -0,0 +1,152 @@
<template>
<div class="dialog" v-if="dialogVisble">
<div class="head_box">
<span class="title">{{title}}</span>
<div class="btnBox">
<el-button size="small" @click="dialogVisble = false">关闭</el-button>
</div>
</div>
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" >
<template #defaultSlot>
<el-select v-model="baseDate.bbzt" @change="getList">
<el-option v-for="item in props.dic.D_QW_BBZL" :key="item.label" :label="item.label" :value="item.label" />
</el-select>
</template>
</Search>
</div>
<div class="tabBox">
<MyTable
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #bbZt="{ row }">
<dict-tag :options="props.dic.D_QW_BBZT" :value="row.bbZt" :tag="true"></dict-tag>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{ ...pageData.pageConfiger, total: pageData.total}" />
</div>
</div>
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import { timeValidate, weekValidate } from "@/utils/tools.js";
import { ref, reactive, defineExpose,getCurrentInstance,defineProps } from "vue";
const props = defineProps({
dic:Object
})
const listQuery = ref({})
const tableHeight = ref(600)
const { proxy } = getCurrentInstance();
const baseDate = reactive({
year:timeValidate(null, "ymd"),
week:weekValidate(timeValidate(null, "ymd")),
bbzt: "值班报备",
});
const dialogVisble = ref(false)
const searchConfiger = reactive([
{
showType: "defaultSlot",
label: "报备类型",
},
{
showType: "input",
prop: "jzMc",
placeholder: "请输入警组名称",
label: "警组名称"
},
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "null",
haveControls:false
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 120, //操作栏宽度
tableColumn: [
{ label: "警组名称", prop: "jzMc" },
{ label: "报备开始时间", prop: "bbSjKssj" },
{ label: "报备结束时间", prop: "bbSjJssj" },
{ label: "所属部门 ", prop: "ssbm"},
{ label: "报备状态 ", prop: "bbZt",showSolt: true },
]
});
const idEntityCard = ref('')
const title = ref('')
// 初始化
const init = (sfzh,type) =>{
title.value = type;
idEntityCard.value = sfzh
dialogVisble.value = true;
getList()
}
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
val.startTime = val.daterange ? val.daterange[0]+' 00:00:00' : ''
val.endTime = val.daterange ? val.daterange[1]+' 23:59:59' : ''
listQuery.value = { ...listQuery.value, ...val };
delete listQuery.value.daterange;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let params = { ...listQuery.value, ...pageData.pageConfiger };
let url = ''
if(baseDate.bbzt == '值班报备') url='/mosty-qwzx/tbQwglZbbb/selectPage'
else if(baseDate.bbzt == '街面勤务报备') url='/mosty-qwzx/tbQwglXfbb/selectPage'
else url='/mosty-qwzx/tbQwglBb/selectPage'
if(baseDate.bbzt != '值班报备' && baseDate.bbzt !='街面勤务报备'){
let obj = props.dic.D_QW_BBZL.find(it=>{return it.label == baseDate.bbzt})
params.qwBbzl = obj.dm
}
params.sfzh = idEntityCard.value;
if(title.value == '勤务跟踪') params.bbZt = '03'
serviceGet(params, url).then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
}).catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
defineExpose({init})
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,123 @@
<template>
<div class="dialog" v-if="dialogForm">
<div class="head_box">
<span class="title">{{ title }}</span>
<div>
<el-button
type="primary"
size="small"
:loading="loading"
@click="submit"
v-show="!disabledFoem"
>保存</el-button
>
<el-button size="small" @click="close">关闭</el-button>
</div>
</div>
<div class="formCnt">
<el-form ref="elform" :model="formData" label-width="110px" :rules="rules" :inline="true">
<div class="infoItem">
<el-form-item label="姓名" prop="xm" style="width:46%;">
<el-input v-model="formData.xm" :disabled="true" placeholder="请输入姓名" style="width: 100%" />
</el-form-item>
<el-form-item label="勤务状态" prop="qwZt" style="width:46%;">
<MOSTY.Select :dictEnum="props.dic.D_BZ_QWZT" placeholder="请选择勤务状态" v-model="formData.qwZt" style="width: 100%" />
</el-form-item>
<el-form-item label="督办状态" prop="qwDbzt" style="width:46%;">
<MOSTY.Select :disabled="true" :dictEnum="props.dic.D_BZ_QWDBZT" placeholder="请选择勤务状态" v-model="formData.qwDbzt" style="width: 100%" />
</el-form-item>
<el-form-item label="勤务时长" prop="qwsc" style="width:46%;" >
<el-input-number :disabled="true" v-model="formData.qwsc" placeholder="请输入勤务时长" style="width:100%;" />
</el-form-item>
<el-form-item label="久坐时长" prop="jzsc" style="width:46%;" >
<el-input-number :disabled="true" v-model="formData.jzsc" placeholder="请输入久坐时长" style="width:100%;" />
</el-form-item>
<el-form-item label="巡逻越界次数" prop="xlyjcs" style="width:46%;" >
<el-input-number :disabled="true" v-model="formData.xlyjcs" placeholder="请输入巡逻越界次数" style="width:100%;" />
</el-form-item>
</div>
</el-form>
</div>
</div>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { serviceGet, servicePost, servicePut } from "@/api/serviceApi.js";
import { getDifferTime } from "@/utils/tools.js";
import * as rule from "@/utils/rules.js";
import { ref, defineExpose, reactive, getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_SF, D_JC_XFJY_JYLX } = proxy.$dict("D_BZ_SF", "D_JC_XFJY_JYLX");
const emits = defineEmits(["updateDate"]);
const props = defineProps({
dic: { type: Object, default: {} }
});
const title = ref("新增");
const elform = ref();
const disabledFoem = ref(false); //表单禁用
const dialogForm = ref(false); //弹窗显示隐藏
const loading = ref(false);
const formData = ref({});
const rules = reactive({
qwZt: [{ required: true, message: "请选择勤务状态", trigger: "change" }],
});
// 初始化数据
const init = (type, row) => {
dialogForm.value = true;
title.value = row ? "修改" : "新增";
if (row) formData.value = JSON.parse(JSON.stringify(row)); //根据id查询详情
};
const getDepValue = (val) => {
formData.value.gldwmc = val ? val.orgJc : "";
};
const getDepValue1 = (val) => {
formData.value.sydwmc = val ? val.orgJc : "";
};
// 关闭
const close = () => {
formData.value = {};
dialogForm.value = false;
loading.value = false;
};
// 提交
const submit = () => {
elform.value.validate((valid) => {
if (!valid) return false;
loading.value = true;
let params = { ...formData.value }
params.xfllId =formData.value.id;
params.idEntityCard =formData.value.sfzh;
servicePost(params, `/mosty-base/sysUserExtend/saveOrUpdateQwZt`).then((res) => {
proxy.$message({ type: "success", message: `${title}成功` });
close();
emits("updateDate");
}).catch(() => { loading.value = false; });
});
};
defineExpose({ init });
</script>
<style lang='scss' scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.formCnt {
height: calc(100% - 60px);
padding: 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.label {
font-weight: 600;
margin-bottom: 10px;
width: 100%;
}
.infoItem {
width: 100%;
}
.el-form--inline .el-form-item {
width: 47%;
}
}
</style>

View File

@ -0,0 +1,283 @@
<template>
<div class="main-box">
<div class="treeBox">
<MOSTY.DepartmentTree
@changeSsbm="changeSsbm"
width="300px"
placeholder="管理部门ID"
clearable
filterable
:isBmId="false"
v-model="listQuery.ssbmdm"
/>
</div>
<div class="tableCnt">
<div class="titleBox">
<div class="title">已选机构 - {{ baseInfo.orgName }}</div>
</div>
<!-- <div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div> -->
<div class="tabBox">
<MyTable
@chooseData="chooseData"
:tableData="pageData.tableData"
:tableColumn="pageData.tableColumn"
:tableHeight="tableHeight"
:key="pageData.keyCount"
:tableConfiger="pageData.tableConfiger"
:controlsWidth="pageData.controlsWidth"
>
<template #qwZt="{ row }">
<dict-tag :options="D_BZ_QWZT" :value="row.qwZt" :tag="false" />
</template>
<template #qwDbzt="{ row }">
<dict-tag :options="D_BZ_QWDBZT" :value="row.qwDbzt" :tag="false" />
<span v-if="row.qwDbzt == null">未督办</span>
</template>
<template #controls="{ row }">
<el-link type="primary" @click="addEdit('edit', row)"
>修改勤务状态</el-link
>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="openTable(row, '勤务工作')"
>勤务工作</el-link
>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="openTable(row, '勤务执行')"
>勤务执行</el-link
>
<span class="linkGapLine">|</span>
<el-link type="primary" @click="openTable(row, '勤务跟踪')"
>勤务跟踪</el-link
>
<span class="linkGapLine">|</span>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
title="是否确认启动勤务督办?"
@confirm="handleConfirm(row)"
>
<template #reference>
<el-link
type="primary"
v-if="row.qwDbzt == null || row.qwDbzt == '01'"
>勤务督办</el-link
>
</template>
</el-popconfirm>
<span class="linkGapLine">|</span>
<el-popconfirm
confirm-button-text="确定"
cancel-button-text="取消"
title="是否确认关闭督办?"
@confirm="handleConfirmJs(row)"
>
<template #reference>
<el-link type="primary" v-if="row.qwDbzt == '02'"
>结束督办</el-link
>
</template>
</el-popconfirm>
</template>
</MyTable>
<Pages
@changeNo="changeNo"
@changeSize="changeSize"
:tableHeight="tableHeight"
:pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}"
/>
</div>
</div>
</div>
<!-- 新增 -->
<EditAddForm
ref="addEditDialog"
:dic="{ D_BZ_QWDBZT, D_BZ_QWZT }"
@updateDate="getList"
/>
<!-- 表格 -->
<DialogTable ref="tableDialog" :dic="{ D_QW_BBZL, D_QW_BBZT }" />
</template>
<script setup>
import { getItem } from "@/utils/storage";
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import Search from "@/components/aboutTable/Search.vue";
import EditAddForm from "./editAddForm.vue";
import DialogTable from "./dialogTable.vue";
import { servicePost, serviceGet, serviceDelete } from "@/api/serviceApi.js";
import * as rule from "@/utils/rules.js";
import * as MOSTY from "@/components/MyComponents/index";
import { ElMessage } from "element-plus";
import {
ref,
reactive,
computed,
watch,
onMounted,
getCurrentInstance,
onUnmounted
} from "vue";
const { proxy } = getCurrentInstance();
const { D_BZ_QWDBZT, D_BZ_QWZT, D_QW_BBZL, D_QW_BBZT } = proxy.$dict(
"D_BZ_QWDBZT",
"D_BZ_QWZT",
"D_QW_BBZL",
"D_QW_BBZT"
);
const addEditDialog = ref();
const multipleTable = ref([]);
const tableDialog = ref();
const searchConfiger = reactive([
// {
// showType: "daterange",
// prop: "daterange",
// placeholder: "请选择日期",
// label: "日期"
// },
]);
const pageData = reactive({
tableData: [], //表格数据
keyCount: 0,
tableConfiger: {
loading: false,
rowHieght: 61,
showSelectType: "checkBox"
},
total: 0,
pageConfiger: {
pageSize: 10,
pageCurrent: 1
}, //分页
controlsWidth: 250, //操作栏宽度
tableColumn: [
{ label: "姓名", prop: "xm" },
{ label: "勤务状态", prop: "qwZt", showSolt: true },
{ label: "督办状态", prop: "qwDbzt", showSolt: true },
{ label: "勤务时长", prop: "qwsc" },
{ label: "久坐时长", prop: "jzsc" },
{ label: "巡逻越界次数", prop: "xlyjcs" }
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const baseInfo = ref({
orgName: "四川省林芝市公安局",
gldwdm: "51160000000"
});
const listQuery = ref({});
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
// 搜索
const onSearch = (val) => {
pageData.pageConfiger.pageCurrent = 1;
listQuery.value.startTime = val.daterange[0];
listQuery.value.endTime = val.daterange[1];
delete val.daterange;
listQuery.value = { ...listQuery.value, ...val };
getList();
};
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 切换部门
const changeSsbm = (val) => {
baseInfo.value.orgName = val.orgJc;
getList();
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
let params = { ...listQuery.value, ...pageData.pageConfiger };
pageData.tableConfiger.loading = true;
serviceGet(params, "/mosty-base/sysUserExtend/selectXfllQwVOPage")
.then((res) => {
pageData.tableConfiger.loading = false;
pageData.tableData = res.records;
pageData.total = res.total;
})
.catch(() => {
pageData.tableConfiger.loading = false;
});
};
// 列表多选
const chooseData = (val) => {
if (Array.isArray(val))
multipleTable.value = val.map((v) => {
return v.id;
});
};
// 确定启动督办
const handleConfirm = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/startQwDbzt").then((res) => {
proxy.$message.success("启动成功");
getList({});
});
};
// 确定启动督办
const handleConfirmJs = (row) => {
let data = { xfllId: row.id, idEntityCard: row.sfzh };
servicePost(data, "/mosty-base/sysUserExtend/finishQwDbzt").then((res) => {
proxy.$message.success("关闭成功");
getList({});
});
};
// 打开表格弹窗
const openTable = (row, type) => {
tableDialog.value.init(row.sfzh, type);
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
onUnmounted(() => {
proxy.mittBus.off("mittFn");
});
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,248 @@
<template>
<!-- 日历组件 -->
<div class="calender">
<div class="date-header">
<!-- 切换日期按钮 -->
<div class="btn-month">
<div>
<!-- <button @click="handleYear(-1)">&lt;&lt;</button> -->
<el-button size="small" @click="handlePrev">
<ArrowLeftBold style="width: 12px; height: 12px" />
</el-button>
</div>
<div class="show-date">{{ year }}{{ month }}</div>
<div>
<el-button size="small" @click="handleNext">
<ArrowRightBold style="width: 12px; height: 12px" />
</el-button>
<!-- <button @click="handleYear(1)">&gt;&gt;</button> -->
</div>
</div>
</div>
<div class="date-content">
<div class="week-header">
<div
v-for="item in [
'周日',
'周一',
'周二',
'周三',
'周四',
'周五',
'周六'
]"
:key="item"
>
{{ item }}
</div>
</div>
<div class="week-day">
<div v-for="item in 42" :key="item + 'day'">
<!-- 当月 -->
<div
:class="getDay(item - beginDay()) ? 'active' : ''"
v-if="item - beginDay() > 0 && item - beginDay() <= prevDays(0)"
@click="chack(item - beginDay())"
>
<span class="day">{{ item - beginDay() }}日</span>
<div
class="btn_day"
v-for="(c, i) in data.filter(
(evn) => evn.day * 1 == item - beginDay()
)"
:key="c * i"
>
<div class="tit" :style="{ backgroundColor: c.color }">
{{ c.title }}
</div>
<div class="time">{{ c.time }}</div>
</div>
</div>
<!-- 上月 -->
<div
class="other-day"
v-else-if="item - beginDay() <= 0"
@click="handlePrev"
>
<span class="day">{{ item - beginDay() + prevDays(1) }}日</span>
</div>
<!-- 下月 -->
<div class="other-day" v-else @click="handleNext">
<span class="day">{{ item - beginDay() - prevDays(0) }}日</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, defineProps, watch, defineEmits } from "vue";
const emit = defineEmits(["calClick"]);
const props = defineProps({
//数据
list: Array
});
watch(
() => props.list,
() => {
data.value = [...props.list];
},
{ deep: true }
);
const arr = ref([1]);
const active = ref(null);
const year = ref(null);
const month = ref(null);
const day = ref(null);
const curDate = ref(null);
const nextDay = ref(null);
const data = ref([]);
function getInitDate() {
const date = new Date();
year.value = date.getFullYear();
month.value = date.getUTCMonth() + 1;
day.value = date.getDate();
curDate.value = `${year.value}-${month.value}-${day.value}`;
}
// 獲取當天日期
function getDay(e) {
const date = new Date();
const dqTime =
date.getFullYear() + "-" + (date.getMonth() + 1) + date.getDate();
return dqTime === year.value + "-" + month.value + e;
}
//获取1号开始位置
function beginDay() {
return new Date(year.value, month.value - 1, 1).getDay();
}
// 获取某月天数
function prevDays(e) {
return new Date(year.value, month.value - e, 0).getDate();
}
function handlePrev() {
active.value = null;
data.value = [];
if (month.value == 1) {
month.value = 12;
year.value--;
} else {
month.value--;
}
emit("calClick", year.value + "-" + month.value);
}
function handleNext() {
active.value = null;
data.value = [];
if (month.value == 12) {
month.value = 1;
year.value++;
} else {
month.value++;
}
emit("calClick", year.value + "-" + month.value);
}
function handleYear(e) {
active.value = null;
year.value += e;
}
function chack(e) {}
onMounted(() => {
getInitDate();
data.value = props.list;
});
</script>
<style lang="scss" scoped>
.calender {
height: calc(100% - 80px);
// overflow-y: scroll;
.date-header {
padding: 12px 0;
}
.btn-month {
display: flex;
justify-content: center;
.show-date {
font-size: 18px;
margin: 0 24px;
}
}
.date-content {
.week-header {
display: flex;
justify-content: center;
> div {
width: 13%;
text-align: center;
padding: 10px 0;
border-left: 1px solid #266ff8;
border-top: 1px solid #266ff8;
}
> div:nth-child(7) {
border-right: 1px solid #266ff8;
}
}
.week-day {
display: flex;
justify-content: center;
flex-wrap: wrap;
> div:nth-child(7n) {
border-right: 1px solid #266ff8;
}
> div:nth-child(36),
> div:nth-child(37),
> div:nth-child(38),
> div:nth-child(39),
> div:nth-child(40),
> div:nth-child(41),
> div:nth-child(42) {
border-bottom: 1px solid #266ff8;
}
> div {
border-left: 1px solid #266ff8;
border-top: 1px solid #266ff8;
width: 13%;
min-height: 10vh;
.btn_day {
text-align: center;
.tit {
font-size: 16px;
margin: 0 50px;
line-height: 2em;
padding: 0 16px;
border-radius: 4px;
}
.time {
line-height: 2em;
}
}
}
.other-day,
.other-day {
color: #858585;
// height: 11vh;
}
.day {
display: block;
padding: 4px;
text-align: right;
}
.active {
position: relative;
}
.active::after {
content: "当天";
position: absolute;
top: 0;
left: 0;
background: rgb(63, 128, 248);
padding: 4px;
border-radius: 0 0 8px 0;
}
}
}
}
</style>

View File

@ -0,0 +1,75 @@
<!-- 全县值班 -->
<template>
<div class="qxzbrl">
<div class="titleBox">
<div class="title">我的巡防排班</div>
<el-button style="margin-top: 12px" @click="active = !active">
{{ active ? "列表模式" : "日历模式" }}
</el-button>
</div>
<ZbCalendar @calClick='getListData' :list="list" v-if="active" />
<List v-else />
</div>
</template>
<script setup>
import List from "./list";
import { getPbbbByMonth } from "@/api/service/watchmanSchedulingPbjl.js";
import { ref, onMounted } from "vue";
import ZbCalendar from "./Calendar";
//状态字典
const ztDict = [
{
label: "未执勤",
value: "01",
color: "#7b7b7b",
},
{
label: "执勤中",
value: "02",
color: "#51fb06",
},
{
label: "执勤",
value: "03",
color: "#0084ff",
},
{
label: "请假",
value: "04",
color: "#f00",
},
];
const active = ref(true);
//日历组件key
//日历数据
const list = ref([]);
function getListData(e){
list.value = []
getPbbbByMonth({time:e}).then(res=>{
res.forEach(v=>{
v.list.forEach(item=>{
list.value.push({
title:ztDict.filter(evn=>evn.value===item.zt)[0].label,
day:v.day,
start:e+'-'+v.day,
end:e+'-'+v.day,
time:item.time,
color:ztDict.filter(evn=>evn.value===item.zt)[0].color
})
})
})
})
}
onMounted(() => {
var time = new Date()
getListData(time.getFullYear()+'-'+(time.getMonth()+1))
});
</script>
<style lang="scss" scoped>
.qxzbrl {
height: calc(100vh - 110px);
}
</style>

View File

@ -0,0 +1,308 @@
<template>
<!-- <div> 勤务方案</div> -->
<div class="main-box">
<div class="tableCnt">
<div ref="searchBox">
<Search :searchArr="searchConfiger" @submit="onSearch" />
</div>
<div class="tabBox">
<MyTable :tableData="pageData.tableData" :tableColumn="pageData.tableColumn" :tableHeight="tableHeight" :key="pageData.keyCount" :tableConfiger="pageData.tableConfiger" :controlsWidth="pageData.controlsWidth"
@chooseData="chooseData">
<template #controls="{ row }">
<el-button @click="batchAddFn('',row)" size="small">详情</el-button>
</template>
</MyTable>
<Pages @changeNo="changeNo" @changeSize="changeSize" :tableHeight="tableHeight" :pageConfiger="{
...pageData.pageConfiger,
total: pageData.total
}" />
</div>
</div>
</div>
<!-- 新增-编辑 -->
<EditAddForm ref="addEditDialog" :disabledFoem="true" :dic="{D_BZ_WZLX,D_BZ_ZZLX}" @updateDate="getList" />
</template>
<script setup>
import MyTable from "@/components/aboutTable/MyTable.vue";
import Pages from "@/components/aboutTable/Pages.vue";
import { ref, reactive, onMounted, getCurrentInstance } from "vue";
import EditAddForm from '../xfa/editAddForm.vue'
import Search from "@/components/aboutTable/Search.vue";
// import { serviceGet, serviceDelete, servicePost } from "@/api/serviceApi.js";
import { getXfbbList, deleteXfpb, getJqNum } from "@/api/file.js";
import { ElMessage } from "element-plus";
const { proxy } = getCurrentInstance();
const {
D_BZ_WZLX,
D_BZ_ZZLX
} = proxy.$dict(
"D_BZ_WZLX",
"D_BZ_ZZLX"
);
const addEditDialog = ref();
const searchConfiger = reactive([
{
showType: "daterange",
prop: "QzrqS",
placeholder: "请选择开始日期",
label: "起止日期"
}
]);
const pageData = reactive({
tableData: [], // 表格数据
keyCount: 0,
tableConfiger: {
showSelectType: "checkBox",
loading: false,
rowHieght: 61 // 高度height?
},
total: 0,
pageConfiger: {
pageSize: 20,
pageCurrent: 1
}, //分页
controlsWidth: 160, //操作栏宽度
tableColumn: [
{ label: "巡防部门", prop: "ssbm", showOverflowTooltip: true },
{
label: "排班名称",
prop: "pbmc",
showOverflowTooltip: true
},
{
label: "排班开始日期",
prop: "pbksrq",
showOverflowTooltip: true
},
{
label: "排班结束日期",
prop: "pbjsrq",
showOverflowTooltip: true
},
{
label: "每日排班数量",
prop: "mrbc",
noDateDisabled: true,
showOverflowTooltip: true
}
]
});
const searchBox = ref(null); // 搜索盒子
const keyCount = ref(0); //tabel组件刷新值
const tableHeight = ref(); // 表格高度
const treeHeight = ref(""); // 树高度
const listQuery = ref({});
function batchDelete() {
proxy
.$confirm("确定要删除", "警告", {
type: "warning"
})
.then(() => {
deleteXfpb(chegList.value).then(() => {
proxy.$message({
type: "success",
message: "删除成功"
});
getList();
});
})
.catch(() => {
proxy.$message.info("已取消");
});
}
// mounted
onMounted(() => {
tabHeightFn();
getList();
proxy.mittBus.on("mittFn", (data) => {
keyCount.value = data;
});
});
const onSearch = (val) => {
console.log(val);
let praem;
if (val.QzrqS) {
praem = { ...listQuery.value, pbksrq: val.QzrqS[0], pbjsrq: val.QzrqS[1] };
} else {
praem = { ...listQuery.value, pbksrq: "", pbjsrq: ""};
}
console.log(praem);
pageData.pageConfiger.pageCurrent = 1;
listQuery.value = praem
getList();
};
// 详情借用新增和修改的页面
// const seeDetail = (type, row) => {
// addEdit(type, row);
// };
// 新增和修改
const addEdit = (type, row) => {
addEditDialog.value.init(type, row);
};
// 改变分页
const changeNo = (val) => {
pageData.pageConfiger.pageCurrent = val;
getList();
};
// 页数
const changeSize = (val) => {
pageData.pageConfiger.pageSize = val;
getList();
};
// 获取列表
const getList = () => {
pageData.tableConfiger.loading = true;
let params = { ...listQuery.value, ...pageData.pageConfiger };
getXfbbList(params)
.then((res) => {
pageData.tableData = res.records;
console.log(res);
})
.finally(() => {
pageData.tableConfiger.loading = false;
});
};
// 处理删除数据
const handleDelete = (id) => {
proxy
.$confirm("确定要删除", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
deleteXfpb(id).then((res) => {
proxy.$message.success("删除成功");
getList();
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
const switchStatus = (id, row) => {
proxy
.$confirm("确定要修改状态", "警告", { type: "warning" })
.then(() => {
// tbQwglQwfa
let isOpen = row.faZt == "02";
let api = isOpen ? "/tbQwglQwfa/shutoff/" : "/tbQwglQwfa/start/";
let txt = isOpen ? "停止" : "开启";
serviceGet({}, `/mosty-qwzx/${api}${id}`).then((res) => {
proxy.$message.success(`${txt}成功`);
getList({});
});
})
.catch(() => {
proxy.$message.info("已取消");
});
};
// 表格高度计算
const tabHeightFn = () => {
tableHeight.value = window.innerHeight - searchBox.value.offsetHeight - 250;
window.onresize = function () {
tabHeightFn();
};
};
const batchAddFn = (type, row) => {
if (type) {
const time = new Date().getTime() - 24 * 60 * 60 * 1000;
const date = new Date(time);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const dates = date.getDate();
const times = year + "/" + month + "/" + dates;
const params = {
startTime: times,
endTime: times
};
const bacthForm = ref();
getJqNum(params).then((res) => {
proxy
.$confirm(`昨日产生警情${res}条,请合理安排排班`, "警告", {
type: "warning"
})
.then(() => {
bacthForm.value = {
mrbc: 1,
xhzq: 1,
jsrqlx: "0",
pbms: "",
pbmc: "",
zqList: [
{
jlList: [],
jyqxList: [],
znzbList: [],
clList: [],
wzlx: "1",
zzlx: "1"
}
]
};
console.log("xxxx");
addEditDialog.value.init(type, bacthForm.value);
})
.catch((err) => {
console.log(err);
});
});
} else {
addEditDialog.value.init(type, row);
}
};
const chegList = ref();
const show = ref(false);
const doenLits = ref();
const chooseData = (val) => {
doenLits.value = val;
chegList.value = val.map((item) => item.id);
if (chegList.value.length == 0) {
show.value = false;
} else {
show.value = true;
}
};
const Activedown = ref(false);
const tabOption = ref([
{ label: "巡防部门", prop: "ssbm" },
{ label: "排班开始日期", prop: "pbksrq" },
{ label: "排班结束日期", prop: "pbjsrq" },
{ label: "每日班次数量", prop: "mrbc" }
// { label: "排班类型", prop: "xhlx", dict: xhlxDict }
]);
function exportExcel() {
Activedown.value = true;
}
const tables = ref();
const moeth = () => {
tables.value.init();
};
</script>
<style lang="scss" scoped>
@import "~@/assets/css/layout.scss";
@import "~@/assets/css/element-plus.scss";
.main-box {
display: flex;
.tableCnt {
flex: 1;
margin-left: 10px;
}
}
.tag {
padding: 2px 6px;
margin: 0 1px;
border: 1px solid rgb(111, 180, 225);
border-radius: 4px;
white-space: nowrap;
background: #ecf5ff;
color: #409eff;
font-size: 12px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More