suyanyan 2 месяцев назад
Родитель
Сommit
cd4005903f
5 измененных файлов: 162 добавлений и 136 удалений
  1. +1
    -1
      SafeCampus.WEB/src/components/Selectors/OrgSelector/index.vue
  2. +2
    -2
      SafeCampus.WEB/src/routers/modules/staticRouter.ts
  3. +21
    -38
      SafeCampus.WEB/src/views/attendance/roolcall/components/form/index.vue
  4. +128
    -72
      SafeCampus.WEB/src/views/attendance/roolcall/detail.vue
  5. +10
    -23
      SafeCampus.WEB/src/views/attendance/roolcall/index.vue

+ 1
- 1
SafeCampus.WEB/src/components/Selectors/OrgSelector/index.vue Просмотреть файл

@@ -82,7 +82,7 @@ function getOrgTree() {
function changeOrg(value: number | string) {
valueOrg.value = value; //更新当前选中的组织名称
emit("update:orgValue", value); //更新父组件数据
emit("change", treeRef.value.getCurrentNode().path); //触发change事件
emit("change", treeRef.value.getCurrentNode().path, treeRef.value.getCurrentNode()); //触发change事件
}
</script>



+ 2
- 2
SafeCampus.WEB/src/routers/modules/staticRouter.ts Просмотреть файл

@@ -40,9 +40,9 @@ export const staticRouter: RouteRecordRaw[] = [
children: [
{
meta: {
title: "任务人员列表"
title: "学生点名详情"
},
name: "任务人员列表",
name: "学生点名详情",
path: "/roolcall/detail",
component: () => import("@/views/attendance/roolcall/detail.vue")
}


+ 21
- 38
SafeCampus.WEB/src/views/attendance/roolcall/components/form/index.vue Просмотреть файл

@@ -19,12 +19,16 @@
<el-row :gutter="16">
<el-col :span="12">
<s-form-item label="摄像头分组" prop="cameraGroudId">
<org-selector v-model:org-value="sysUserProps.record.cameraGroudId" :org-tree-api="monitorLIVEApi.groupList" :show-all="false"
<org-selector
@change="handleChange"
v-model:org-value="sysUserProps.record.cameraGroudId"
:org-tree-api="monitorLIVEApi.groupList"
:show-all="false"
/></s-form-item>
</el-col>
<el-col :span="12">
<s-form-item label="摄像头" prop="cameraId">
<s-input v-model="sysUserProps.record.cameraId"></s-input>
<s-select v-model="sysUserProps.record.cameraId" :options="CameraList" label="sensorName" value="sensorId"></s-select>
</s-form-item>
</el-col>
</el-row>
@@ -63,28 +67,23 @@
</template>

<script setup lang="ts" name="SysUserPersonnelForm">
import { SysUserPersonnel, userManagePersonnelApi, monitorLIVEApi } from "@/api";
import { SysDictEnum } from "@/enums";
import { attendanceRoolcallApi, userManagePersonnelApi, monitorLIVEApi } from "@/api";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import { useDictStore } from "@/stores/modules";
const visible = ref(false); //是否显示表单
const formatTooltip = (val: number) => {
return val / 80;
};
/** 表单操作类型枚举 */
enum FormOptEnums {
/** 发起 */
INITIATE = "发起"
}
// 表单参数
const sysUserProps = reactive<FormProps.Base<SysUserPersonnel.SysUserPerInfo>>({
const sysUserProps = reactive<FormProps.Base<any>>({
opt: FormOptEnums.INITIATE,
record: {},
treeAllData: [],
disabled: false
});
const CameraList = ref([]);
/** 表单操作类型枚举 */
enum FormOptEnums {
/** 发起 */
INITIATE = "发起"
}
const CameraList = ref<any>([]);

// 表单验证规则
const rules = reactive({
@@ -99,7 +98,7 @@ const rules = reactive({
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<SysUserPersonnel.SysUserPerInfo>) {
function onOpen(props: FormProps.Base<any>) {
Object.assign(sysUserProps, props); //合并参数
if (props.opt == FormOptEnums.INITIATE) {
//如果是新增,设置默认值
@@ -108,28 +107,15 @@ function onOpen(props: FormProps.Base<SysUserPersonnel.SysUserPerInfo>) {
visible.value = true; //显示表单
if (props.record.personId) {
//如果传了id,就去请求api获取record
userManagePersonnelApi.detail({ id: props.record.personId }).then(res => {
userManagePersonnelApi.detail({ id: props.record.personId }).then((res: any) => {
sysUserProps.record = res.data;
});
}
}
watch(
sysUserProps.record.cameraGroudId,
(newVal, oldVal) => {
console.log(newVal, "..........");
},
{
deep: true,
immediate: true
}
);

const handleChange = (val: any) => {
console.log(val);

// monitorLIVEApi.list({ groupId: val }).then(res => {
// CameraList.value = res.data;
// });
const handleChange = async (val: any, data: any) => {
let res = await monitorLIVEApi.list({ pageNum: 1, pageSize: 1000, groupId: data.id });
CameraList.value = res.data.list;
};
// 提交数据(新增/编辑)
const sysUserFormRef = ref<FormInstance>();
@@ -138,11 +124,8 @@ async function handleSubmit() {
sysUserFormRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
//提交表单
if (sysUserProps.record.faces.length === 0) {
return ElMessage.error("请上传人脸图片");
}
if (sysUserProps.record.personId) {
await userManagePersonnelApi
await attendanceRoolcallApi
.update(sysUserProps.record)
.then(() => {
sysUserProps.successful!(); //调用父组件的successful方法
@@ -151,7 +134,7 @@ async function handleSubmit() {
onClose();
});
} else {
await userManagePersonnelApi
await attendanceRoolcallApi
.add(sysUserProps.record)
.then(() => {
sysUserProps.successful!(); //调用父组件的successful方法


+ 128
- 72
SafeCampus.WEB/src/views/attendance/roolcall/detail.vue Просмотреть файл

@@ -1,87 +1,129 @@
<template>
<div class="roolcallDetail">
<el-row>
<el-col :xl="4" :lg="4" :md="6" :sm="12" v-for="(item, index) in listData" :key="index"
><div class="grid-content">
<div class="imgBox">
<img
src="http://deepvision.oss-cn-zhangjiakou.aliyuncs.com/dfield-cruising/online/person-set/quanjiang/DEMO00001/8746a847ecd64c1696b37f4cdf617a18/5dc35e4c7af84b3fb5aab70156574873.jpg?Expires=1721376415&OSSAccessKeyId=STS.NUSm6539EVcLhtZCZEHnhRF8t&Signature=2Kmz3s%2FXjUBLfMfXi0GcuV998WY%3D&security-token=CAIS0wN1q6Ft5B2yfSjIr5bmJoyB3uZk4aGnalLrp1oQROFEvYOTljz2IHFMf3huCeodsv8%2BlGxS5%2FgelrpqVpZDR03Na8RHwrly1lv5O9KY42JpORrg0s%2FLI3OaLjKm9hi7AYygPgK0GJqEb1TDiVUto9%2FTfimjWFqIKICAjYUdAP0cQgi%2Fa0gwZrJRPRAwh8IGEnHTOP2xUHvtmXGCNFd0nQB%2BhGhjk7TdpPeR8R3Dllb35%2FYIroDqWPieYtJrIY10XqWBvqx%2FfbGT1zVLuVoYtvV6gaFc5zbcv9abRFVf4hiCP6%2Ff6MBuNw5%2Fae94efZNp%2BOukuZj6K6B1db7xhtVI%2BBOUiPZA4mr2IzdBeqvNNcwc7m8F1no9YjXbsGs9EEGGStLaVgVI4F8dyAhWEd9FWjgR%2FX5qAyQUGCKULOY1aw6651xwmjz8MCCT1r1GOTBindGasVnMxh5Z0JMjDK9aNkKfgFUbVJ8BrGTCIh%2FYx0bsq7yowDIEyp71TRMo%2Bbu%2FDBhIifKpO4VN7AxMup1DPwu2wNCxATp3htf%2FAxd8uAx9DyyfH1x3TObqd7jjqzaKs3NYdtswV4BUlvK5CGWEjhzQEO8mJtNIDT39awuolxWrfsIeBqAAVOd5Y2r6RQD6ZRZFrkepn9XGhIi2MZGgFU5h4wAMv9fpXFA%2FgTSJhbBoKXkAOvkYLObuS4FAaKYBll7eEMnCpOf%2BVGjABIbd%2BhpQaD8MIuUBVw1SOyjTVaLxMbb7guH7nLPyeZMcRqmZw3WH0leI4eeyeTPTT0DfJMgIezHEGctIAA%3D"
alt=""
/>
</div>
<div class="info">
<div class="desc">
<span class="label">姓名:</span>
{{ item.name }}
</div>
<div class="desc">
<span class="label">所属分组:</span>
{{ item.group }}
</div>
</div>
<div class="btn">
<el-button type="text" :icon="Edit">编辑</el-button>
<el-button type="danger" text :icon="Delete">删除</el-button>
</div>
</div></el-col
<div class="header">
<el-row>
<el-col :span="18">
<el-row>
<el-col :span="6"><el-text class="mx-1" type="primary" size="large">应到:8人</el-text></el-col>
<el-col :span="6"><el-text class="mx-1" type="success" size="large">实到:4</el-text> </el-col>
<el-col :span="6"> <el-text class="mx-1" type="warning" size="large">趴桌子:2</el-text></el-col>
<el-col :span="6">
<el-text class="mx-1" type="info" size="large">未识别:{{ UnrecognizedD.length }}</el-text></el-col
>
</el-row>
</el-col>
</el-row>
</div>
<el-row :gutter="20">
<el-col :span="18"
><el-row class="rowbg">
<el-col :xl="4" :lg="4" :md="6" :sm="8" :xs="12" v-for="(item, index) in listData" :key="index"
><div class="grid-content">
<div class="imgBox" :class="{ active: item.status === 1 ? true : false }">
<img :src="item.faces[0].faceUrl" alt="" />
</div>
<div class="info">
<div class="desc">
<span class="label">姓名:</span>
{{ item.name }}
</div>
<div class="desc">
<span class="label">所属分组:</span>
{{ item.personSets[0].personSetName }}
</div>
</div>
</div></el-col
>
</el-row></el-col
>
<el-col :span="6">
<div class="unrecognized">
<div class="title">未识别人员</div>
<div class="imgBox" v-for="(item, index) in UnrecognizedD" :key="index">
<img :src="item.faceUrl" alt="" />
</div>
</div>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts" name="SysUserPersonnel">
import { Delete, Edit } from "@element-plus/icons-vue";
const listData = ref([
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
},
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
},
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
},
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
},
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
},
{
name: "zhangsan ",
group: "所属fenzu ",
status: "正常",
phone: "1234567890",
email: "1234567890@qq.com"
}
]);
import { userManagePersonnelApi, attendanceRoolcallApi } from "@/api";
const route = useRoute();
const listData = ref<any>([]); //人员列表
const HighlightData = ref<any>([]); //点名人员列表
const UnrecognizedD = ref<any>([]); //未识别数据
const getList = () => {
userManagePersonnelApi
.page({
pageNum: 1,
pageSize: 1000,
personSetId: route.query.personSetId
})
.then((res: any) => {
listData.value = res.data.list;
Highlight();
});
};
const Highlight = () => {
attendanceRoolcallApi
.page({
pageNum: 1,
pageSize: 1000,
taskId: route.query.taskId
})
.then((res: any) => {
HighlightData.value = res.data.list;
listData.value
.map((item: any) => {
item.status = 0;
return item;
})
.forEach((item: any) => {
HighlightData.value.forEach((item1: any) => {
if (item.personId === item1.personId) {
item.status = 1;
}
});
});
// 未识别人员摘取
UnrecognizedD.value = [];
JSON.parse(JSON.stringify(HighlightData.value)).map((item: any) => {
if (!item.personId) {
UnrecognizedD.value.push(item);
}
});
console.log(UnrecognizedD.value);
});
};
onMounted(() => {
getList();
console.log(route.query);
});
</script>
<style lang="scss" scoped>
.roolcallDetail {
.el-row {
width: 100%;
}
.header {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
height: 80px;
padding: 0 20px;
background: #ffffff;
.el-col {
text-align: center;
}
}
.rowbg {
width: 100%;
.el-col {
box-sizing: border-box;
height: 310px;
height: 190px;
margin-bottom: 20px;
.grid-content {
box-sizing: border-box;
@@ -94,8 +136,13 @@ const listData = ref([
align-items: center;
justify-content: center;
width: 100%;
height: 150px;
height: 100px;
background: #f2f2f2;
opacity: 0.5;
&.active {
background: #79bbff45;
opacity: 1;
}
img {
max-height: 100%;
object-fit: cover;
@@ -111,7 +158,7 @@ const listData = ref([
}
.desc {
max-width: 100%;
margin-top: 15px;
margin-top: 10px;
overflow: hidden;
font-size: 14px;
color: #41465f;
@@ -131,5 +178,14 @@ const listData = ref([
}
}
}
.unrecognized {
.title {
font-size: 18px;
font-weight: bold;
line-height: 50px;
color: #41465f;
text-align: center;
}
}
}
</style>

+ 10
- 23
SafeCampus.WEB/src/views/attendance/roolcall/index.vue Просмотреть файл

@@ -22,8 +22,7 @@
</template>
</TreeFilter>
<div class="table-box">
<!-- :request-api="attendanceRoolcallApi.page" -->
<ProTable ref="proTable" title="任务列表" :columns="columns" rowKey="personId" :data="tableData">
<ProTable ref="proTable" title="任务列表" :columns="columns" rowKey="id" :request-api="attendanceRoolcallApi.getTaskPageList">
<!-- 表格 header 按钮 -->
<template #tableHeader="scope">
<s-button :opt="FormOptEnums.INITIATE" @click="onOpen(FormOptEnums.INITIATE, { personSetId: personSetId }, treeFilter.treeAllData)" />
@@ -54,7 +53,6 @@ import { attendanceRoolcallApi,userManagePersonnelApi,userManageClassManageApi}
import { useHandleData } from "@/hooks/useHandleData";
import { FormOptEnum } from "@/enums";
import Form from "./components/form/index.vue";
import { ArrowDown,More } from "@element-plus/icons-vue";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import TreeFilter from "@/components/TreeFilter/index.vue";
import { useRouter } from "vue-router";
@@ -73,20 +71,7 @@ enum FormOptEnums {
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const visible = ref(false); //是否显示人员表单
const proTable = ref<ProTableInstance>();
const treeFilter = ref<InstanceType<typeof TreeFilter> | null>(null);

const tableData = ref([
{
cameraName: "摄像头1",
continueTime: "20",
similarity: "0.7",
},
{
cameraName: "摄像头2",
continueTime: "30",
similarity: "0.45",
}
])
const treeFilter = ref<any>();
// 表格配置项
const columns: ColumnProps[] = [
{ type: "selection", fixed: "left", width: 50 },
@@ -104,12 +89,14 @@ const columns: ColumnProps[] = [
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
const handleClose = () => {
visible.value = false;
};

const onView = (row: any) => {
router.push('/roolcall/detail');
router.push( {
path:'/roolcall/detail',
query: {
taskId: row.taskId,
personSetId:row.personSetId
}
});
};
// 发起任务表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);
@@ -119,7 +106,7 @@ const formRef = ref<InstanceType<typeof Form> | null>(null);
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnum, record: {},treeAllData:any) {
function onOpen(opt: FormOptEnums, record: {},treeAllData:any) {
formRef.value?.onOpen({ opt: opt, record: record,treeAllData:treeAllData, successful: RefreshTable });
}



Загрузка…
Отмена
Сохранить