Commit a971b3cf by huangqy

提交

parent 222a1281
......@@ -15,6 +15,7 @@
"element-ui": "^2.15.6",
"file-saver": "^2.0.5",
"nprogress": "^0.2.0",
"ol": "^7.1.0",
"script-loader": "^0.7.2",
"swiper": "^6.3.5",
"timetables": "^1.1.0",
......
import Vue from 'vue'
import { Button, Descriptions, Empty, Icon, Statistic, Tree, TreeSelect, Modal ,Table, Input, FormModel } from 'ant-design-vue'
import { Button, Descriptions, Empty, Icon, Statistic, Tree, TreeSelect, Modal ,Table, Input, FormModel, Upload } from 'ant-design-vue'
Vue.use(Statistic)
Vue.use(Empty)
Vue.use(Tree)
......@@ -11,3 +11,4 @@ Vue.use(Modal)
Vue.use(Table)
Vue.use(Input)
Vue.use(FormModel)
Vue.use(Upload)
......@@ -10,5 +10,10 @@ const report = [
name: '/report/kqtj',
component: () => import(/* webpackChunkName: "index/statistics/stock" */ '@/report/kqtj')
},
{
path: prefix +'/workQueue/moveCar',
name: '/workQueue/moveCar',
component: () => import(/* webpackChunkName: "index/statistics/stock" */ '@/workQueue/moveCar')
},
]
export default report
\ No newline at end of file
......@@ -40,15 +40,20 @@
<template slot-scope="scope">
<a-button type="primary" icon="play-circle" size="small" ghost @click="startClick(scope.row)" v-if="scope.row.id && scope.row.upStatus === 2">开启打卡</a-button>
<a-button type="danger" icon="pause-circle" style="margin-left: 6px;" ghost size="small" @click="endClick(scope.row)" v-if="scope.row.id && scope.row.upStatus === 1">关闭打卡</a-button>
<a-button type="primary" icon="play-circle" size="small" style="margin-left: 6px;" ghost @click="showClick(scope.row)">详情</a-button>
<!-- <a-button type="primary" icon="play-circle" size="small" style="margin-left: 6px;" ghost @click="showClick(scope.row)">详情</a-button> -->
</template>
</el-table-column>
</el-table>
<el-dialog :append-to-body="true" title="学员打卡记录" :visible.sync="dialogVisible" width="800px" :close-on-click-modal="false" @close="dialogClose()">
<el-dialog :append-to-body="true" title="打卡中" :visible.sync="dialogVisible" width="800px" :close-on-click-modal="false" @close="dialogClose()">
<el-form :model="formData" ref="formData" label-position="right" style="border: 2px solid rgb(67, 167, 71);padding:20px;">
<el-table :data="recordList" size="medium" highlight-current-row height="500">
<el-steps :active="2" simple>
<el-step :title="'应到人数: '+ planAmount + '人'"></el-step>
<el-step :title="'实到人数: '+ amount+ '人'"></el-step>
<el-step :title="'缺勤人数: '+ (planAmount - amount) + '人'"></el-step>
</el-steps>
<el-table :data="recordList" size="medium" height="500" style="margin-top: 20px;" :row-class-name="tableRowClassName">
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="studentNo" label="学号" align="center" />
<el-table-column prop="studentName" label="姓名" align="center" />
......@@ -56,9 +61,9 @@
</el-table>
</el-form>
<span slot="footer" class="dialog-footer">
<!-- <span slot="footer" class="dialog-footer">
<a-button @click="dialogVisible = false" type="primary" ghost>关 闭</a-button>
</span>
</span> -->
</el-dialog>
......@@ -85,6 +90,8 @@ export default {
},
// 总条数
total: 0,
planAmount: 0,
amount: 0,
timer: null,
recordList: []
}
......@@ -102,6 +109,14 @@ export default {
},
methods: {
tableRowClassName({row, rowIndex}) {
if (!row.recodeDate) {
return 'warning-row'
} else {
return 'success-row'
}
return ''
},
async initClass() {
const { data: res } = await this.$axios.post('/class/getPage', {pageNo: 1, pageSize: 999})
if (res.code !== 99200) return this.$message(res.message)
......@@ -139,17 +154,29 @@ export default {
this.initData()
},
async startClick(row) {
const that = this
const { data: res } = await this.$axios.post('/clockIn/open', { classCode: row.classCode, classTime: row.classTime,id: row.id, upStatus: 1})
if (res.code !== 99200) return this.$message.error(res.message)
this.planAmount = row.planAmount
this.$message.success('开启打卡')
this.initData()
this.timer = setInterval(() => that.showDetail(row), 1000)
this.dialogVisible = true
},
async endClick(row) {
const { data: res } = await this.$axios.post('/clockIn/close', { classCode: row.classCode, classTime: row.classTime,id: row.id, upStatus: 2})
if (res.code !== 99200) return this.$message.error(res.message)
this.$message.success('结束打卡')
clearInterval(this.timer)
this.initData()
},
async showDetail(row) {
const { data: res } = await this.$axios.post('/clockIn/getAttndetailed', row)
if (res.code !== 99200) return this.$message(res.message)
this.title = row.className + '班级考勤详情'
this.recordList = res.data.records
this.amount = this.recordList.filter(i => i.recodeDate).length
},
async showClick(row) {
const that = this
if (row.upStatus === 2) {
......@@ -159,12 +186,6 @@ export default {
}
this.dialogVisible = true
},
async showDetail(row) {
console.log('刷新')
const { data: res } = await this.$axios.post('/clockIn/getClockInRecord', { classCode: row.classCode, courseCode: row.courseCode, classTime: row.classTime, lessonId: row.lessonId, pageSize: 999 })
if (res.code !== 99200) return this.$message.error(res.message)
this.recordList = res.data.records
},
dialogClose() {
clearInterval(this.timer)
}
......@@ -177,6 +198,11 @@ export default {
}
</script>
<style scoped lang='less'>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
......@@ -58,14 +58,32 @@
</el-row>
</el-form>
<el-table :data="data" style="width: 100%;overflow: auto;" size="medium" highlight-current-row>
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="className" label="班级名称" align="center" />
<el-table-column prop="studentName" label="学生姓名" align="center" />
<el-table-column prop="courseName" label="课程名称" align="center" />
<el-table-column prop="lessonId" label="课时编号" align="center" />
<el-table-column prop="recordDate" label="考勤打卡日期" align="center" />
</el-table>
<el-table :data="data" style="width: 100%;overflow: auto;" size="medium" highlight-current-row>
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="className" label="班级名称" align="center" :show-overflow-tooltip="true"/>
<el-table-column prop="courseName" label="课程名称" align="center" />
<el-table-column prop="classTime" label="上课日期" align="center">
<template slot-scope="scope">
{{parseTimes(scope.row.classTime)}}
</template>
</el-table-column>
<el-table-column prop="lessonName" label="课时名称" align="center" />
<el-table-column prop="planAmount" label="应到人数" align="center">
<template slot-scope="scope">
{{scope.row.planAmount}}
</template>
</el-table-column>
<el-table-column prop="amount" label="实到人数" align="center">
<template slot-scope="scope">
{{scope.row.amount}}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<a-button type="primary" size="small" ghost @click="showClick(scope.row)">详情</a-button>
</template>
</el-table-column>
</el-table>
<el-pagination
......@@ -79,6 +97,22 @@
:total="total"
/>
<el-dialog :append-to-body="true" :title="title" :visible.sync="dialogVisible" width="800px" :close-on-click-modal="false" @close="dialogClose()">
<el-form :model="formData" ref="formData" label-position="right" style="border: 2px solid rgb(67, 167, 71);padding:20px;">
<el-table :data="recordList" size="medium" height="500" :row-class-name="tableRowClassName">
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="studentNo" label="学号" align="center"/>
<el-table-column prop="studentName" label="姓名" align="center"/>
<!-- <el-table-column prop="className" label="班级" align="center" /> -->
<el-table-column prop="recodeDate" label="打卡时间" align="center" />
</el-table>
</el-form>
<span slot="footer" class="dialog-footer">
<a-button @click="dialogVisible = false" type="primary" ghost>关 闭</a-button>
</span>
</el-dialog>
</el-card>
</div>
</div>
......@@ -103,6 +137,7 @@ export default {
timeData: [],
classList: [],
studentList: [],
recordList: [],
pickerOptions: {
shortcuts: [{
text: '最近一日',
......@@ -155,6 +190,36 @@ export default {
},
methods: {
tableRowClassName({row, rowIndex}) {
if (!row.recodeDate) {
return 'warning-row'
} else {
return 'success-row'
}
return ''
},
parseTimes(time) {
if (time != '0001-01-01 00:00') {
var date = new Date(time)
var year = date.getFullYear()
/* 在日期格式中,月份是从0开始的,因此要加0
* 使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
* */
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
// 拼接
return year + '-' + month + '-' + day
} else {
return ''
}
},
async showClick(row) {
this.dialogVisible = true
const { data: res } = await this.$axios.post('/clockIn/getAttndetailed', row)
if (res.code !== 99200) return this.$message(res.message)
this.title = row.className + '班级考勤详情'
this.recordList = res.data.records
},
async initClass() {
const { data: res } = await this.$axios.post('/class/getPage', {pageNo: 1, pageSize: 999})
if (res.code !== 99200) return this.$message(res.message)
......@@ -178,58 +243,10 @@ export default {
}
this.initData()
},
addClick() {
this.title = '新增'
this.initCollege()
this.dialogVisible = true
},
editClick(row) {
this.title = '编辑'
this.initCollege()
const obj = JSON.parse(JSON.stringify(row))
this.dialogVisible = true
this.formData = obj
},
dateChange (date) {
this.searchData.startTime = date ? date[0] : ''
this.searchData.endTime = date ? date[1] : ''
},
deleteClick (row) {
const url = '/major/remove'
const params = {
id: row.id
}
this.delete(url, params)
},
delete (url, params) {
this.$confirm('此操作将永久删除该数据, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const { data: res } = await this.$axios.delete(url, {params})
if (res.code === 99200) {
this.$message.success(res.message)
this.initData()
} else {
this.$message.error(res.message)
}
})
},
subFormData () {
this.$refs.fromRef.validate(async falg => {
if (!falg) return;
let url = '/major/save'
if (this.formData.id) {
url = '/major/update'
}
const { data: res } = await this.$axios.post(url, this.formData)
if (!res.data) return this.$message.error(res.message)
this.$message.success(res.message)
this.dialogVisible = false
this.initData()
})
},
dialogClose() {
this.formData = {}
this.$refs.fromRef.resetFields()
......@@ -254,6 +271,11 @@ export default {
}
</script>
<style scoped lang='less'>
<style>
.el-table .warning-row {
background: oldlace;
}
.el-table .success-row {
background: #f0f9eb;
}
</style>
......@@ -318,7 +318,7 @@ export default {
// logo点击跳转
goHome () {
this.$router.push('/index')
// this.$router.push('/index')
this.show = false
this.edActiveOnePath(`/${this.$route.path.split('/')[1]}`)
this.edActiveLine(`/${this.$route.path.split('/')[1]}`)
......
......@@ -7,10 +7,10 @@
<el-form :inline="true" :model="searchData" size="medium" label-position="left" >
<el-row type="flex" justify="space-between" align="middle">
<el-col>
<el-form-item label="学院名称 :">
<el-form-item label="系别名称 :">
<el-input
clearable
placeholder="请输入学院名称"
placeholder="请输入系别名称"
v-model="searchData.collegeName"
/>
</el-form-item>
......
......@@ -28,13 +28,24 @@
<el-form-item>
<a-button type="primary" ghost @click="resClick()" icon="reload">重置</a-button>
</el-form-item>
</el-col>
<el-form-item>
<el-form-item>
<a-button type="primary" ghost icon="plus" @click="addClick()">
新增
</a-button>
</el-form-item>
</el-col>
<el-form-item>
<a-upload
name="file"
:multiple="false"
:showUploadList="false"
action="http://192.168.3.123:10026/JX/student/readExcel"
@change="handleUpload"
>
<a-button type="primary" icon="upload" ghost round> 导入 </a-button>
</a-upload>
</el-form-item>
</el-row>
</el-form>
......@@ -42,13 +53,19 @@
<el-table :data="data" style="width: 100%;overflow: auto;" size="medium" highlight-current-row>
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="classCode" label="班级编号" align="center" />
<el-table-column prop="className" label="班级名称" align="center" />
<el-table-column prop="className" label="班级名称" align="center" :show-overflow-tooltip="true"/>
<el-table-column prop="totalNumber" label="班级人数" align="center">
<template slot-scope="scope">
{{ scope.row.totalNumber }}
</template>
</el-table-column>
<el-table-column prop="majorName" label="专业名称" align="center" />
<el-table-column prop="collegeName" label="所属学院" align="center" />
<el-table-column label="操作" align="center" width="180">
<el-table-column prop="collegeName" label="所属系别" align="center" />
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<a-button type="primary" icon="edit" size="small" ghost @click="editClick(scope.row)">编辑</a-button>
<a-button type="danger" icon="delete" style="margin-left: 6px;" ghost size="small" @click="deleteClick(scope.row)">删除</a-button>
<a-button type="primary" icon="download" style="margin-left: 6px;" size="small" ghost @click="download(scope.row)">模板</a-button>
</template>
</el-table-column>
</el-table>
......@@ -100,6 +117,21 @@
</el-form-item>
</el-col>
</el-row>
<el-row type="flex" justify="space-between">
<el-col :span="11">
<el-form-item label="班级人数 :">
<el-input-number
clearable
style="width: 100%"
:min="1"
:precision="0"
placeholder="请输入班级人数"
v-model="formData.totalNumber"
/>
</el-form-item>
</el-col>
</el-row>
</el-card>
</el-form>
<span slot="footer" class="dialog-footer">
......@@ -226,6 +258,20 @@ export default {
this.searchData.pageNo = val
this.initData()
},
download(row) {
const url = '/student/createExcel?classCode='+ row.classCode
window.location.href = `${this.$axios.defaults.baseURL}${url}`
},
handleUpload(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
this.$message.success(`${info.file.name} 导入成功`);
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} 导入失败.`);
}
}
},
computed: {
......
......@@ -7,10 +7,10 @@
<el-form :inline="true" :model="searchData" size="medium" label-position="left" >
<el-row type="flex" justify="space-between" align="middle">
<el-col>
<el-form-item label="学院名称 :">
<el-form-item label="系别名称 :">
<el-input
clearable
placeholder="请输入学院名称"
placeholder="请输入系别名称"
v-model="searchData.collegeName"
/>
</el-form-item>
......@@ -34,9 +34,9 @@
<el-table :data="data" style="width: 100%;overflow: auto;" size="medium" highlight-current-row>
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="collegeName" label="学院名称" align="center" />
<el-table-column prop="collegeName" label="系别名称" align="center" />
<el-table-column prop="leaderName" label="领导姓名" align="center" />
<el-table-column prop="remark" label="学院备注" align="center" />
<el-table-column prop="remark" label="系别备注" align="center" />
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<a-button type="primary" icon="edit" size="small" ghost @click="editClick(scope.row)">编辑</a-button>
......@@ -70,10 +70,10 @@
<el-card>
<el-row type="flex" justify="space-between">
<el-col :span="11">
<el-form-item label="学院名称 :">
<el-form-item label="系别名称 :">
<el-input
clearable
placeholder="请输入学院名称"
placeholder="请输入系别名称"
v-model="formData.collegeName"
/>
</el-form-item>
......
......@@ -34,9 +34,9 @@
<el-table :data="data" style="width: 100%;overflow: auto;" size="medium" highlight-current-row>
<el-table-column type="index" width="60" label="序号" align="center" />
<el-table-column prop="majorCode" label="专业代码" align="center" />
<el-table-column prop="majorName" label="专业名称" align="center" />
<el-table-column prop="college" label="所属学院" align="center" />
<el-table-column prop="majorCode" label="专业代码" align="center" sortable/>
<el-table-column prop="majorName" label="专业名称" align="center" sortable/>
<el-table-column prop="collegeName" label="所属系别" align="center" sortable/>
<el-table-column label="操作" align="center" width="180">
<template slot-scope="scope">
<a-button type="primary" icon="edit" size="small" ghost @click="editClick(scope.row)">编辑</a-button>
......@@ -79,11 +79,11 @@
</el-form-item>
</el-col>
<el-col :span="11">
<el-form-item label="所属学院 :">
<el-form-item label="所属系别 :">
<el-select
clearable
filterable
placeholder="请选择所属学院"
placeholder="请选择所属系别"
v-model="formData.college"
style="width: 100%"
>
......
......@@ -7,21 +7,25 @@
<el-form :inline="true" :model="searchData" size="medium" label-position="left" >
<el-row type="flex" justify="space-between" align="middle">
<el-col>
<el-form-item label="班级编号 :">
<el-form-item class="mgl15" label="学员姓名 :" >
<el-input
clearable
placeholder="请输入班级编号"
v-model="searchData.classCode"
placeholder="请输入学员姓名"
v-model="searchData.studentName"
/>
</el-form-item>
<el-form-item class="mgl15" label="班级名称 :" >
<el-input
<el-form-item label="班级名称 :">
<el-select
filterable
clearable
placeholder="请输入班级名称"
v-model="searchData.className"
/>
placeholder="请选择班级名称"
v-model="searchData.classCode"
@change="initData"
>
<el-option v-for="item in classList" :key="item.id" :label="item.className +'(' + item.classCode +')'" :value="item.classCode"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<a-button type="primary" class="mgl15" ghost icon="search" @click="initData()">查询</a-button>
</el-form-item>
......@@ -48,13 +52,14 @@
{{ scope.row.sex == '1' ? '男' : '女'}}
</template>
</el-table-column>
<el-table-column prop="className" label="所属班级" align="center" :show-overflow-tooltip="true"/>
<el-table-column prop="majorName" label="专业名称" align="center" />
<el-table-column prop="collegeName" label="学院名称" align="center"/>
<el-table-column prop="classCode" label="所属班级编号" align="center" />
<el-table-column label="操作" align="center" width="180">
<el-table-column prop="collegeName" label="系别名称" align="center"/>
<el-table-column label="操作" align="center" width="240">
<template slot-scope="scope">
<a-button type="primary" icon="edit" size="small" ghost @click="editClick(scope.row)">编辑</a-button>
<a-button type="danger" icon="delete" style="margin-left: 6px;" ghost size="small" @click="deleteClick(scope.row)">删除</a-button>
<a-button type="primary" icon="laptop" style="margin-left: 6px;" ghost size="small" @click="makeCard(scope.row)">制卡</a-button>
</template>
</el-table-column>
</el-table>
......@@ -108,11 +113,11 @@
</el-row>
<el-row type="flex" justify="space-between">
<el-col :span="11">
<el-form-item label="班级编号 :">
<el-form-item label="所属班级 :">
<el-select
clearable
filterable
placeholder="请选择班级编号"
placeholder="请选择所属班级"
v-model="formData.classCode"
style="width: 100%"
>
......@@ -151,11 +156,14 @@ export default {
},
// 总条数
total: 0,
websock: null,
}
},
created () {
this.initData()
this.initClass()
this.initWbSocket()
},
mounted() {
......@@ -164,8 +172,16 @@ export default {
that.height = document.documentElement.clientHeight - 176
}
},
beforeDestroy() {
this.websock.close()
},
methods: {
async initClass() {
const { data: res } = await this.$axios.post('/class/getPage', {pageNo: 1, pageSize: 999})
if (res.code !== 99200) return this.$message(res.message)
this.classList = res.data.records
},
async initData () {
const { data: res } = await this.$axios.post('/jxUser/getPage', this.searchData)
if (res.code !== 99200) return this.$message(res.message)
......@@ -248,6 +264,42 @@ export default {
this.searchData.pageNo = val
this.initData()
},
makeCard(row) {
this.selectRow = row
this.websock.send(JSON.stringify( {CmdType: 4,Content: JSON.stringify( { epc: row.studentNo, len: 4, offset: 1, password: '00000000' }) }))
},
async saveCard() {
this.selectRow.epc = this.selectRow.studentNo
const { data: res } = await this.$axios.post('/jxStudentCard/makeCard', this.selectRow)
if (!res.data) return this.$message.error(res.message)
this.$message.success('写入成功')
},
initWbSocket() {
this.websock = new WebSocket('ws://127.0.0.1:8081');
this.websock.onopen = this.websocketOnopen;
this.websock.onerror = this.websocketOnerror;
this.websock.onmessage = this.websocketOnmessage;
this.websock.onclose = this.websocketOnclose;
},
websocketOnopen(e) {
console.log('WebSocket连接建立');
},
websocketOnerror: function (e) {
this.$message.warning('写入服务连接发生错误')
console.log("WebSocket连接发生错误");
},
websocketOnmessage: function (e) {
var backMessObj = JSON.parse(e.data);
console.log(backMessObj)
if(backMessObj.CmdType == 4) {
this.saveCard()
} else if(![0,1,2,5].includes(backMessObj.CmdType)) {
this.$message.error(backMessObj.Content)
}
},
websocketOnclose: function (e) {
console.log("connection closed (" + e + ")");
},
},
computed: {
......
<template>
<div class="body" :style="'height:' + height + 'px'">
<div style="border: 2px solid #43A747;">
<!-- 主体区域 - 卡片视图 -->
<el-card :style="'height:' + (height - 60) + 'px;overflow-y: auto;position:relative;'">
<div id="map" ref="map"></div>
</el-card>
</div>
</div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import XYZ from 'ol/source/XYZ';
export default {
data () {
return {
height: document.documentElement.clientHeight - 176,
data: [],
map: null,
dialogVisible: false,
title: '',
formData: {},
classList: [],
// 筛选数据
searchData: {
pageNo: 1,
pageSize: 10,
},
// 总条数
total: 0,
websock: null,
}
},
created () {
this.initMap()
},
mounted() {
const that = this
window.onresize = function temp() {
that.height = document.documentElement.clientHeight - 176
}
},
methods: {
initMap() {
this.$refs.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
projection: "EPSG:4326", // 使用这个坐标系
center: [114.064839, 22.548857], // 深圳
zoom: 12
})
});
}
},
computed: {
}
}
</script>
<style scoped lang='less'>
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论