Explorar el Código

考勤点名模块

master
yxq hace 7 meses
padre
commit
b8fd7e8693
Se han modificado 20 ficheros con 884 adiciones y 2 borrados
  1. +5
    -2
      SafeCampus.WEB/public/static/rtsPlayer.html
  2. +15
    -0
      SafeCampus.WEB/src/api/interface/sys/attendance/index.ts
  3. +31
    -0
      SafeCampus.WEB/src/api/interface/sys/attendance/passenger.ts
  4. +1
    -0
      SafeCampus.WEB/src/api/interface/sys/index.ts
  5. +43
    -0
      SafeCampus.WEB/src/api/modules/attendance/behaviorTrace.ts
  6. +19
    -0
      SafeCampus.WEB/src/api/modules/attendance/index.ts
  7. +50
    -0
      SafeCampus.WEB/src/api/modules/attendance/passenger.ts
  8. +43
    -0
      SafeCampus.WEB/src/api/modules/attendance/roolcall.ts
  9. +43
    -0
      SafeCampus.WEB/src/api/modules/attendance/studentsReturn.ts
  10. +1
    -0
      SafeCampus.WEB/src/api/modules/index.ts
  11. +16
    -0
      SafeCampus.WEB/src/utils/index.ts
  12. +34
    -0
      SafeCampus.WEB/src/views/attendance/behaviorTrace/index.vue
  13. +47
    -0
      SafeCampus.WEB/src/views/attendance/passenger/components/detailForm/form_detail.vue
  14. +63
    -0
      SafeCampus.WEB/src/views/attendance/passenger/components/detailForm/index.vue
  15. +91
    -0
      SafeCampus.WEB/src/views/attendance/passenger/components/form/form_basic.vue
  16. +135
    -0
      SafeCampus.WEB/src/views/attendance/passenger/components/form/index.vue
  17. +110
    -0
      SafeCampus.WEB/src/views/attendance/passenger/index.vue
  18. +33
    -0
      SafeCampus.WEB/src/views/attendance/roolcall/components/nofaceTable/index.vue
  19. +70
    -0
      SafeCampus.WEB/src/views/attendance/roolcall/index.vue
  20. +34
    -0
      SafeCampus.WEB/src/views/attendance/studentsReturn/index.vue

+ 5
- 2
SafeCampus.WEB/public/static/rtsPlayer.html Ver fichero

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html>
<html style="overflow: hidden;">

<head>
<meta charset="utf-8">
@@ -27,12 +27,13 @@

// 更多播放器配置请参考 https://player.alicdn.com/aliplayer/index.html
let rtsUrl = getUrlParams(location.href)['rtsUrl'] || ''
let height = getUrlParams(location.href)['height'] || "500px"
var options = {
"id": "player-con",
"source": rtsUrl,
"rtsFallbackSource": "降级地址,如HLS",
"width": "100%",
"height": "500px",
"height": height,
"autoplay": true,
"isLive": true,
"playsinline": true,
@@ -65,6 +66,8 @@
// 当RTS拉流成功时触发,通过订阅该事件,可以获取到RTS TraceId
player.on('rtsTraceId', function (data) {
console.log('[EVENT]rtsTraceId', data.paramData);
let fullscreenBtn = document.querySelector('.prism-controlbar .prism-fullscreen-btn')
if(fullscreenBtn)fullscreenBtn.style.display = 'none'
// event.paramData.traceId 拉流的TraceId
// event.paramData.source 当前RTS流的播放地址
})


+ 15
- 0
SafeCampus.WEB/src/api/interface/sys/attendance/index.ts Ver fichero

@@ -0,0 +1,15 @@
/**
* @description
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
export * from "./passenger";

+ 31
- 0
SafeCampus.WEB/src/api/interface/sys/attendance/passenger.ts Ver fichero

@@ -0,0 +1,31 @@
/**
* @description 用户管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
*/

import { ReqPage } from "@/api";
/**
* @Description: 客流查询接口
* @Author: yxq
* @Date: 2023-12-17 15:34:54
*/

export namespace AttendancePassenger {
export interface Page extends ReqPage {}

/** 客流查询表单 */
export interface PassengerInfo {
fenpianleixing:String,
shijianduan:any,
shexiangtou:any,
}
}

+ 1
- 0
SafeCampus.WEB/src/api/interface/sys/index.ts Ver fichero

@@ -21,3 +21,4 @@ export * from "./organization";
export * from "./auth";
export * from "./warn";
export * from "./usermanage";
export * from "./attendance";

+ 43
- 0
SafeCampus.WEB/src/api/modules/attendance/behaviorTrace.ts Ver fichero

@@ -0,0 +1,43 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, SysUserPersonnel } from "@/api/interface";
const http = moduleRequest("/business/dfieldApi/");

/**
* @Description: 单页管理
* @Author: SYY
* @Date: 2023-12-15 15:34:54
*/
const attendanceBehaviorTrace = {
/** 查询底库列表 */
page(params: SysUserPersonnel.ClassPage) {
return http.get("page", params);
},
/** 删除底库 */
delete(params: ReqId) {
return http.delete("deleteDfieldD", params);
},
/** 创建底库 */
add(params: SysUserPersonnel.ClassPage) {
return http.post("createDfieldA", params);
},
/** 更新底库 */
update(params: SysUserPersonnel.ClassPage) {
return http.put("updateDfieldU", params);
}
};

export { attendanceBehaviorTrace };

+ 19
- 0
SafeCampus.WEB/src/api/modules/attendance/index.ts Ver fichero

@@ -0,0 +1,19 @@
/**
* @description
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
export * from "./behaviorTrace";
export * from "./passenger";
export * from "./roolcall";
export * from "./studentsReturn";


+ 50
- 0
SafeCampus.WEB/src/api/modules/attendance/passenger.ts Ver fichero

@@ -0,0 +1,50 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, AttendancePassenger } from "@/api/interface";
const http = moduleRequest("/business/dfieldApi/");

/**
* @Description: 单页管理
* @Author: SYY
* @Date: 2023-12-15 15:34:54
*/
const attendancePassenger = {
/** 查询列表 */
page(params: AttendancePassenger.PassengerInfo) {
return http.get("test", params);
},
/** 删除 */
delete(params: ReqId) {
return http.delete("test", params);
},
/** 创建 */
add(params: AttendancePassenger.PassengerInfo) {
return http.post("test", params);
},
/** 详情 */
detail(params: ReqId) {
return http.post("test", params);
},
};

const attendancePassengerBtnCode = {
/** 新增 */
add: "attendancePassengerBtnCodeAdd",
/** 删除 */
delete: "attendancePassengerBtnCodeDel"
};

export { attendancePassenger,attendancePassengerBtnCode };

+ 43
- 0
SafeCampus.WEB/src/api/modules/attendance/roolcall.ts Ver fichero

@@ -0,0 +1,43 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, SysUserPersonnel } from "@/api/interface";
const http = moduleRequest("/business/dfieldApi/");

/**
* @Description: 单页管理
* @Author: SYY
* @Date: 2023-12-15 15:34:54
*/
const attendanceRoolcall = {
/** 查询底库列表 */
page(params: SysUserPersonnel.ClassPage) {
return http.get("page", params);
},
/** 删除底库 */
delete(params: ReqId) {
return http.delete("deleteDfieldD", params);
},
/** 创建底库 */
add(params: SysUserPersonnel.ClassPage) {
return http.post("createDfieldA", params);
},
/** 更新底库 */
update(params: SysUserPersonnel.ClassPage) {
return http.put("updateDfieldU", params);
}
};

export { attendanceRoolcall };

+ 43
- 0
SafeCampus.WEB/src/api/modules/attendance/studentsReturn.ts Ver fichero

@@ -0,0 +1,43 @@
/**
* @description 单页管理接口
* @license Apache License Version 2.0
* @Copyright (c) 2022-Now 少林寺驻北固山办事处大神父王喇嘛
* @remarks
* SimpleAdmin 基于 Apache License Version 2.0 协议发布,可用于商业项目,但必须遵守以下补充条款:
* 1.请不要删除和修改根目录下的LICENSE文件。
* 2.请不要删除和修改SimpleAdmin源码头部的版权声明。
* 3.分发源码时候,请注明软件出处 https://gitee.com/dotnetmoyu/SimpleAdmin
* 4.基于本软件的作品,只能使用 SimpleAdmin 作为后台服务,除外情况不可商用且不允许二次分发或开源。
* 5.请不得将本软件应用于危害国家安全、荣誉和利益的行为,不能以任何形式用于非法为目的的行为不要删除和修改作者声明。
* 6.任何基于本软件而产生的一切法律纠纷和责任,均于我司无关
* @see https://gitee.com/dotnetmoyu/SimpleAdmin
*/
import { moduleRequest } from "@/api/request";
import { ReqId, SysUserPersonnel } from "@/api/interface";
const http = moduleRequest("/business/dfieldApi/");

/**
* @Description: 单页管理
* @Author: SYY
* @Date: 2023-12-15 15:34:54
*/
const attendanceStudentsReturn = {
/** 查询底库列表 */
page(params: SysUserPersonnel.ClassPage) {
return http.get("page", params);
},
/** 删除底库 */
delete(params: ReqId) {
return http.delete("deleteDfieldD", params);
},
/** 创建底库 */
add(params: SysUserPersonnel.ClassPage) {
return http.post("createDfieldA", params);
},
/** 更新底库 */
update(params: SysUserPersonnel.ClassPage) {
return http.put("updateDfieldU", params);
}
};

export { attendanceStudentsReturn };

+ 1
- 0
SafeCampus.WEB/src/api/modules/index.ts Ver fichero

@@ -20,3 +20,4 @@ export * from "./monitor";
export * from "./sysconfig";
export * from "./statistion";
export * from "./usermanage";
export * from "./attendance";

+ 16
- 0
SafeCampus.WEB/src/utils/index.ts Ver fichero

@@ -323,3 +323,19 @@ export function findItemNested(enumData: any, callValue: any, value: string, chi
if (current[children]) return findItemNested(current[children], callValue, value, children);
}, null);
}

/**
* @description 时间戳转化为日期
* */
export function formatDate(timestamp:number) {
let date = new Date(timestamp);
let year = date.getFullYear();
let month = "0" + (date.getMonth() + 1); // getMonth返回的月份是从0开始的
let day = "0" + date.getDate();
let hours = "0" + date.getHours();
let minutes = "0" + date.getMinutes();
let seconds = "0" + date.getSeconds();

return year + "-" + month.substr(-2) + "-" + day.substr(-2)
+ " " + hours.substr(-2) + ":" + minutes.substr(-2) + ":" + seconds.substr(-2);
}

+ 34
- 0
SafeCampus.WEB/src/views/attendance/behaviorTrace/index.vue Ver fichero

@@ -0,0 +1,34 @@
<!--
* @Description: 班级管理
* @Author: yxq
* @Date: 2024-7-16
-->
<template>
<div class="table-box">
<ProTable ref="proTable" title="班级管理" :columns="columns" :request-api="userManageClassManageApi.page"> </ProTable>
</div>
</template>
<script setup lang="ts">
import { userManageClassManageApi } from "@/api";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
// 表格配置项
const columns: ColumnProps[] = [
{
prop: "personSetName",
label: "班级名称"
},
{
prop: "personSetId",
label: "班级ID"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
</style>

+ 47
- 0
SafeCampus.WEB/src/views/attendance/passenger/components/detailForm/form_detail.vue Ver fichero

@@ -0,0 +1,47 @@
<!--
* @Description: 客流查询
* @Author: yxq
* @Date: 2023-12-17 15:45:50
-->
<template>
<div>
<div>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="分片时间" prop="shijianduan">
<s-input v-model="formInfo.fenpianshijian" disabled></s-input>
</s-form-item>
<s-form-item label="分片数量" prop="shijianduan">
<s-input v-model="formInfo.fenpianshuliang" disabled></s-input>
</s-form-item>
</el-col>
</el-row>
</div>
</div>
</template>

<script setup lang="ts">
import { AttendancePassenger, monitorLIVEApi } from "@/api";
// props
interface FormProps {
modelValue: Partial<AttendancePassenger.PassengerInfo>;
}
const emit = defineEmits(["update:modelValue"]); //定义emit
const props = defineProps<FormProps>(); //定义props
// 客流查询表单
const formInfo = computed({
get: () => props.modelValue,
set: val => emit("update:modelValue", val)
});
console.log(props.modelValue);

onMounted(() => {
// 初始化
});
</script>

<style lang="scss" scoped>
:deep(.el-input__wrapper) {
width: 100% !important;
}
</style>

+ 63
- 0
SafeCampus.WEB/src/views/attendance/passenger/components/detailForm/index.vue Ver fichero

@@ -0,0 +1,63 @@
<!--
* @Description: 表单
* @Author: syy
* @Date: 2023-12-15 15:45:59
-->
<template>
<div>
<form-container v-model="visible" :title="`分片详情`" form-size="600px" @close="onClose">
<el-form
ref="formRef"
:disabled="formProps.disabled"
:model="formProps.record"
:hide-required-asterisk="formProps.disabled"
label-width="auto"
label-suffix=" :"
>
<el-tabs v-model="activeName">
<Detail v-model="formProps.record"></Detail>
</el-tabs>
</el-form>
<template #footer>
<el-button type="primary" @click="onClose"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts">
import { AttendancePassenger, attendancePassenger } from "@/api";
import { FormOptEnum } from "@/enums";
import Detail from "./form_detail.vue";

const visible = ref(false); //是否显示表单
const activeName = ref("detail");
// 表单参数
const formProps = reactive<FormProps.Base<AttendancePassenger.PassengerInfo>>({
opt: FormOptEnum.ADD,
record: {},
disabled: false
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<AttendancePassenger.PassengerInfo>) {
Object.assign(formProps, props); //合并参数
visible.value = true; //显示表单
}

/** 关闭表单*/
function onClose() {
visible.value = false;
activeName.value = "detail";
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped></style>

+ 91
- 0
SafeCampus.WEB/src/views/attendance/passenger/components/form/form_basic.vue Ver fichero

@@ -0,0 +1,91 @@
<!--
* @Description: 客流查询
* @Author: yxq
* @Date: 2023-12-17 15:45:50
-->
<template>
<div>
<div>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="查询时间段" prop="shijianduan">
<el-date-picker
v-model="formInfo.shijianduan"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
>
</el-date-picker>
</s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="摄像头" prop="shexiangtou">
<el-select v-model="formInfo.shexiangtou" multiple placeholder="摄像头">
<el-option v-for="item in shexiangtouOptions" :key="item.value" :label="item.label" :value="item.value"> </el-option>
</el-select>
</s-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="24">
<s-form-item label="分片类型(天/小时)" prop="fenpianleixing">
<s-radio-group v-model="formInfo.fenpianleixing" :options="fenpianleixingOptions" button />
</s-form-item>
</el-col>
</el-row>
</div>
</div>
</template>

<script setup lang="ts">
import { AttendancePassenger, monitorLIVEApi } from "@/api";
// props
interface FormProps {
modelValue: Partial<AttendancePassenger.PassengerInfo>;
}
const emit = defineEmits(["update:modelValue"]); //定义emit
const props = defineProps<FormProps>(); //定义props
// 客流查询表单
const formInfo = computed({
get: () => props.modelValue,
set: val => emit("update:modelValue", val)
});
console.log(props.modelValue);
// 分片类型
const fenpianleixingOptions = ref([
{
label: "天",
value: "0"
},
{
label: "小时",
value: "1"
}
]);
// 摄像头
let shexiangtouOptions = ref([]);
monitorLIVEApi.page({ pageSize: 100, pageNum: 1 }).then(res => {
if (res.code == 200) {
shexiangtouOptions.value = res.data.list.map(e => {
return {
value: e.sensorId,
label: e.sensorName
};
});
}
});

onMounted(() => {
// 初始化
formInfo.value.fenpianleixing = formInfo.value.fenpianleixing ? formInfo.value.fenpianleixing : fenpianleixingOptions.value[0].value;
});
</script>

<style lang="scss" scoped>
:deep(.el-input__wrapper) {
width: 100% !important;
}
</style>

+ 135
- 0
SafeCampus.WEB/src/views/attendance/passenger/components/form/index.vue Ver fichero

@@ -0,0 +1,135 @@
<!--
* @Description: 表单
* @Author: syy
* @Date: 2023-12-15 15:45:59
-->
<template>
<div>
<form-container v-model="visible" :title="`${formProps.opt}查询`" form-size="600px" @close="onClose">
<el-form
ref="formRef"
:rules="rules"
:disabled="formProps.disabled"
:model="formProps.record"
:hide-required-asterisk="formProps.disabled"
label-width="auto"
label-suffix=" :"
>
<el-tabs v-model="activeName">
<Basic v-model="formProps.record"></Basic>
</el-tabs>
</el-form>
<template #footer>
<el-button @click="onClose"> 取消 </el-button>
<el-button v-show="!formProps.disabled" type="primary" @click="handleSubmit"> 确定 </el-button>
</template>
</form-container>
</div>
</template>

<script setup lang="ts">
import { AttendancePassenger, attendancePassenger } from "@/api";
import { FormOptEnum } from "@/enums";
import { required } from "@/utils/formRules";
import { FormInstance } from "element-plus";
import Basic from "./form_basic.vue";
import { formatDate } from "@/utils";

const visible = ref(false); //是否显示表单
const activeName = ref("basic");
// 表单参数
const formProps = reactive<FormProps.Base<AttendancePassenger.PassengerInfo>>({
opt: FormOptEnum.ADD,
record: {},
disabled: false
});

// 表单验证规则
const rules = reactive({
shijianduan: [
required("请选择查询时间段"),
{
validator: (rule, value, callback) => {
value = value.map(e => e.valueOf());
if (86400000 * 7 < value[1] - value[0]) {
callback(new Error("时间跨度不能大于七天"));
} else {
callback();
}
},
trigger: "change"
}
],
shexiangtou: [required("请选择摄像头")]
});

/**
* 打开表单
* @param props 表单参数
*/
function onOpen(props: FormProps.Base<AttendancePassenger.PassengerInfo>) {
Object.assign(formProps, props); //合并参数
if (props.opt == FormOptEnum.ADD) {
//如果是新增,设置默认值
formProps.record.shijianduan = [];
formProps.record.shexiangtou = [];
}
visible.value = true; //显示表单
if (props.record.id) {
//如果传了id,就去请求api获取record
attendancePassenger.detail({ id: props.record.id }).then(res => {
formProps.record = res.data;
});
}
}

// 提交数据(新增/编辑)
const formRef = ref<FormInstance>();
/** 提交表单 */
async function handleSubmit() {
formRef.value?.validate(async valid => {
if (!valid) return; //表单验证失败
// shijianduan时间段
formProps.record.startTime = formatDate(formProps.record.shijianduan[0]);
formProps.record.endTime = formatDate(formProps.record.shijianduan[1]);
delete formProps.record.shijianduan;
// shexiangtou摄像头
formProps.record.shexiangtou = formProps.record.shexiangtou.toString();
//提交表单
console.log(formProps);
if (formProps.record.id) {
await attendancePassenger
.update(formProps.record)
.then(() => {
formProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
} else {
console.log(formProps.record);
await attendancePassenger
.add(formProps.record)
.then(() => {
formProps.successful!(); //调用父组件的successful方法
})
.finally(() => {
onClose();
});
}
});
}

/** 关闭表单*/
function onClose() {
visible.value = false;
activeName.value = "basic";
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>

<style lang="scss" scoped></style>

+ 110
- 0
SafeCampus.WEB/src/views/attendance/passenger/index.vue Ver fichero

@@ -0,0 +1,110 @@
<!--
* @Description: 客流查询
* @Author: yxq
* @Date: 2024-7-17
-->
<template>
<div class="table-box">
<ProTable ref="proTable" title="查询管理" :columns="columns" :data="data" :request-api="attendancePassenger.page">
<!-- 表格 header 按钮 -->
<template #tableHeader>
<s-button v-auth="attendancePassengerBtnCode.add" type="primary" suffix="查询" @click="onOpen(FormOptEnum.ADD)" />
</template>
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link :opt="FormOptEnum.VIEW" prefix="分片" suffix="详情" @click="onOpen(FormOptEnum.VIEW, scope.row)" />
</el-space>
</template>
</ProTable>
<Form ref="formRef" />
<DetailForm ref="detailFormRef"></DetailForm>
</div>
</template>
<script setup lang="ts" name="AttendancePassenger">
import { attendancePassenger, attendancePassengerBtnCode, AttendancePassenger } from "@/api";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import Form from "./components/form/index.vue";
import DetailForm from "./components/detailForm/index.vue";
import { FormOptEnum } from "@/enums";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
const data = ref([
{
chaxunshijian: "2024-07-18 14:20:12",
kaishishijian: "2024-07-16 18:20:12",
jieshushijian: "2024-07-17 16:20:12",
shexiangtou: "大厅(魔豆)",
fenpianleiixng: "天",
tongjirenshu: "100",
fenpianshijian: "2024-07-17 16:20:12",
fenpianshuliang: "100"
},
{
chaxunshijian: "2024-06-19 14:20:12",
kaishishijian: "2024-05-16 18:20:12",
jieshushijian: "2024-05-17 16:20:12",
shexiangtou: "教室(海康)",
fenpianleiixng: "天",
tongjirenshu: "66",
fenpianshijian: "2024-07-17 16:20:12",
fenpianshuliang: "60"
}
]);
// 表格配置项
const columns: ColumnProps<any>[] = [
{
prop: "chaxunshijian",
label: "查询时间"
},
{
prop: "kaishishijian",
label: "开始时间"
},
{
prop: "jieshushijian",
label: "结束时间"
},
{
prop: "shexiangtou",
label: "摄像头"
},
{
prop: "fenpianleiixng",
label: "分片类型"
},
{
prop: "tongjirenshu",
label: "统计后的总人数"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
// 表单引用
const formRef = ref<InstanceType<typeof Form> | null>(null);
const detailFormRef = ref<InstanceType<typeof DetailForm> | null>(null);
/**
* 打开表单
* @param opt 操作类型
* @param record 记录
*/
function onOpen(opt: FormOptEnum, record: {} | AttendancePassenger.PassengerInfo = {}) {
switch (opt) {
case FormOptEnum.ADD:
formRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
break;
case FormOptEnum.VIEW:
detailFormRef.value?.onOpen({ opt: opt, record: record, successful: RefreshTable });
}
}
// 刷新表格
const RefreshTable = () => {
proTable.value?.refresh();
};
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
</style>

+ 33
- 0
SafeCampus.WEB/src/views/attendance/roolcall/components/nofaceTable/index.vue Ver fichero

@@ -0,0 +1,33 @@
<!--
* @Description: 人脸识别失败表格
* @Author: yxq
* @Date: 2023-12-15 15:45:59
-->
<template>
<div>
<ProTable ref="proTable" title="教师点名" :columns="columns" :data="data" :request-api="userManageClassManageApi.page">
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link prefix="人工" :opt="FormOptEnum.EDIT" suffix="确认" @click="onOpen(FormOptEnum.VIEW, scope.row)" />
</el-space>
</template>
</ProTable>
</div>
</template>
<script setup lang="ts">
/** 关闭表单*/
function onClose() {
visible.value = false;
activeName.value = "basic";
}

// 暴露给父组件的方法
defineExpose({
onOpen
});
</script>
<style lang="scss" scoped></style>

+ 70
- 0
SafeCampus.WEB/src/views/attendance/roolcall/index.vue Ver fichero

@@ -0,0 +1,70 @@
<!--
* @Description: 教师点名
* @Author: yxq
* @Date: 2024-7-16
-->
<template>
<div class="table-box">
<ProTable ref="proTable" title="教师点名" :columns="columns" :data="data" :request-api="userManageClassManageApi.page">
<!-- 表格操作栏 -->
<template #operation="scope">
<el-space>
<s-button link prefix="人工" :opt="FormOptEnum.EDIT" suffix="确认" @click="onOpen(FormOptEnum.VIEW, scope.row)" />
</el-space>
</template>
</ProTable>
</div>
</template>
<script setup lang="ts">
import { userManageClassManageApi } from "@/api";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
import { FormOptEnum } from "@/enums";
const data = ref([
{
classname: "XXXXX班级",
classId: "544165",
studentNum: "43",
guiqinNum: "38",
noFaceNum: "5"
},
{
classname: "XX班级",
classId: "555333",
studentNum: "42",
guiqinNum: "37",
noFaceNum: "4"
}
]);
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
// 表格配置项
const columns: ColumnProps[] = [
{
prop: "classname",
label: "班级名称"
},
{
prop: "classId",
label: "班级ID"
},
{
prop: "studentNum",
label: "学生人数"
},
{
prop: "guiqinNum",
label: "归寝人数"
},
{
prop: "noFaceNum",
label: "人脸无法识别人数"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
</style>

+ 34
- 0
SafeCampus.WEB/src/views/attendance/studentsReturn/index.vue Ver fichero

@@ -0,0 +1,34 @@
<!--
* @Description: 班级管理
* @Author: yxq
* @Date: 2024-7-16
-->
<template>
<div class="table-box">
<ProTable ref="proTable" title="班级管理" :columns="columns" :request-api="userManageClassManageApi.page"> </ProTable>
</div>
</template>
<script setup lang="ts">
import { userManageClassManageApi } from "@/api";
import { ColumnProps, ProTableInstance } from "@/components/ProTable/interface";
// 获取 ProTable 元素,调用其获取刷新数据方法(还能获取到当前查询参数,方便导出携带参数)
const proTable = ref<ProTableInstance>();
// 表格配置项
const columns: ColumnProps[] = [
{
prop: "personSetName",
label: "班级名称"
},
{
prop: "personSetId",
label: "班级ID"
},
{ prop: "operation", label: "操作", width: 250, fixed: "right" }
];
</script>
<style scoped lang="scss">
.table-box {
width: 100%;
height: 100%;
}
</style>

Cargando…
Cancelar
Guardar