diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/MyTools.js b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/MyTools.js new file mode 100644 index 000000000..ba836a603 --- /dev/null +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/MyTools.js @@ -0,0 +1,260 @@ +/** + * 唯一的随机字符串,用来区分每条数据 + * @returns {string} + */ +export function getUid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0; + const v = c === 'x' ? r : (r & 0x3) | 0x8; + return v.toString(16); + }); +} + +/** + * 计算时间差 + * @param beginTime:2022-01-13 + * @param endTime:2022-01-13 + * @returns {{hours: number, seconds: number, minutes: number, day: number}} + */ +export function dealTime(beginTime, endTime) { + var dateBegin = new Date(beginTime); + var dateEnd = new Date(endTime); + var dateDiff = dateEnd.getTime() - dateBegin.getTime(); //时间差的毫秒数 + var day = Math.floor(dateDiff / (24 * 3600 * 1000)); //计算出相差天数 + var leave1 = dateDiff % (24 * 3600 * 1000); //计算天数后剩余的毫秒数 + var hours = Math.floor(leave1 / (3600 * 1000)); //计算出小时数 + //计算相差分钟数 + var leave2 = leave1 % (3600 * 1000); //计算小时数后剩余的毫秒数 + var minutes = Math.floor(leave2 / (60 * 1000)); //计算相差分钟数 + + //计算相差秒数 + var leave3 = leave2 % (60 * 1000); //计算分钟数后剩余的毫秒数 + var seconds = Math.round(leave3 / 1000); + return { + day, + hours, + minutes, + seconds + } +} + +/** + * 获取当天时间 + * @returns {string} + */ +export function getCurDay() { + var datetime = new Date(); + var year = datetime.getFullYear(); + var month = datetime.getMonth() + 1 < 10 ? "0" + (datetime.getMonth() + 1) : datetime.getMonth() + 1; + var date = datetime.getDate() < 10 ? "0" + datetime.getDate() : datetime.getDate(); + return `${year}-${month}-${date}` +} + +// 日期格式处理 +export function formatDate(date) { + var year = date.getFullYear(); + var months = date.getMonth() + 1; + var month = (months < 10 ? '0' + months : months).toString(); + var day = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()).toString(); + return { + year: year.toString(), + month, + day + } +} + +/** + * 数组中,某个属性相同的数据放在一块,如把某个日期相同的相连一起 + * @param list 传入的数组 + * @param prop 那个属性相同的数据 + * @returns {*[]} + */ +export function margePropData(list = [], prop) { + let arr = [], tempArr = {}; + list.forEach(item => { + if (!tempArr[item[prop]]) { + tempArr[item[prop]] = [item] + } else { + tempArr[item[prop]].push(item) + } + }) + for (const tempArrKey in tempArr) { + arr = [...arr, ...tempArr[tempArrKey]] + } + return arr +} + +/** + * 合并行 + * @param list + * @param prop + */ +export function mergeRows(list = [], prop) { + list.forEach(ele => { + ele.rowspan = 1 + }) + const len = list.length + for (let i = 0; i < len; i++) { + for (let j = i + 1; j < len; j++) { + if (list[i][prop] === list[j][prop]) { + list[i].rowspan++ + list[j].rowspan-- + } + } + // 这里跳过已经重复的数据 + i = i + list[i].rowspan - 1 + } + return list +} + +/** + * 根据当前数据的位置,在数组中插入数据 + * 如数组【1,2,4,5】想要在2后面插入3, + *1:首先获取到2的下标, + *2:然后获取要插入之前的数据,获取要插入之后的数据,中间就是插入的位置 + *3:最后把这三个按顺序合并就得到在想要的位置插入数据 + * @param list + * @param index + * @param target + */ +export function insertArrPositionOfIndex(list = [], index = 0, target = {}) { + //根据index 找出小于index的数据放在左边 + const leftList = list.filter((t, i) => i < index); + //根据index 找出大于index的数据放在右边 + const rightList = list.filter((t, i) => i >= index); + // 最终合并数据 + return [...leftList, target, ...rightList] +} + +/** + * 校验规则 + */ +export function verifyRules(list = [], require = []) { + let message = null + for (const key of require) { + const isEmpty = list.every(it => !it[key.prop]) + if (isEmpty) { + message = key.message + break; + } + } + return message +} + +/** + * 获取元素下标 + * @param dir 为 1:得到正序遍历方法;为 -1: 得到逆序遍历方法。 + * @returns {(function(*, *, *=): (number|number|number))|*} + */ +export function findArrIndex(dir = 1) { + return function (array, cb, context) { + let length = array.length; + // 控制初始 index,0 或者 length-1 + let index = dir >= 0 ? 0 : length - 1; + + // 条件: 在数组范围内; + // 递增或递减:递加 1 或者 -1; 妙啊~ + for (; index >= 0 && index <= length - 1; index += dir) { + if (cb.call(context, array[index], index)) return index + } + return -1 + } +} + +/** + * map转换成数组 + * @param target + * @returns {*[]} + * @constructor + */ +export function MapConvertArr(target = {}) { + let list = []; + for (let key in target) { + list.push(target[key]); + } + return list; +} + +/** + * 对象数组去重 + * @param arr 数组 + * @param prop 根据什么字段去重 + * @returns {any[]} + */ +export function arrayDeduplication(arr, prop) { + let map = new Map(); + return arr.filter(item => !map.has(item[prop]) && map.set(item[prop], 1)); +} + +/** + * 获取当前天时间 + * @param param 【Y:年;M:月;D:日;h:小时;m:分钟;s:秒;】 默认精确到秒 + * @returns {*} + */ +export function getCurrentDate(param = 's') { + var now = new Date(); + var year = now.getFullYear(); //得到年份 + var month = now.getMonth();//得到月份 + var date = now.getDate();//得到日期 + var day = now.getDay();//得到周几 + var hour = now.getHours();//得到小时 + var minu = now.getMinutes();//得到分钟 + var sec = now.getSeconds();//得到秒 + month = month + 1; + if (month < 10) month = "0" + month; + if (date < 10) date = "0" + date; + if (hour < 10) hour = "0" + hour; + if (minu < 10) minu = "0" + minu; + if (sec < 10) sec = "0" + sec; + + const arr = { + 'Y': year, + 'M': year + "-" + month, + 'D': year + "-" + month + "-" + date, + 'h': year + "-" + month + "-" + date + " " + hour, + 'm': year + "-" + month + "-" + date + " " + hour + ":" + minu, + 's': year + "-" + month + "-" + date + " " + hour + ":" + minu + ":" + sec + } + return arr[param]; +} + +/** + * 获取当天时间前后七天时间 + * @param day day>0 当天时间的后几天 day<0 当天时间前几天 + * @returns {string} + */ +export function getRecentDate(day) { + var date1 = new Date(), + time1 = date1.getFullYear() + "-" + (date1.getMonth() + 1) + "-" + date1.getDate();//time1表示当前时间 + var date2 = new Date(date1); + date2.setDate(date1.getDate() + day); + const y = date2.getFullYear(); + const m = (date2.getMonth() + 1) > 9 ? (date2.getMonth() + 1) : '0' + (date2.getMonth() + 1) + const d = date2.getDate() > 9 ? date2.getDate() : '0' + date2.getDate() + return y + "-" + m + "-" + d; +} + +export function MyDebounce(fn, duration = 100) { + let timer = null + return (...args) => { + clearTimeout(timer) + timer = setTimeout(() => { + fn(...args); + }, duration) + + } +} + +export function MyThrottle(fn, duration = 100) { + let target = true; + return (...arg) => { + if (!target) { + return false; + } + target = false; + setTimeout(() => { + fn(...arg); + target = true + }, duration) + } +} diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/monthSchedule.vue b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/monthSchedule.vue new file mode 100644 index 000000000..546a462c6 --- /dev/null +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/components/monthSchedule/monthSchedule.vue @@ -0,0 +1,502 @@ + + + + \ No newline at end of file diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json index 0285f046f..c1e39cd19 100644 --- a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages.json @@ -400,7 +400,7 @@ "navigationBarTitleText": "考勤记录" } }, - // 考勤打卡 + // 教师考勤打卡 { "path": "pages/AttendanceCard/list", "style": { diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/ADRRecord/list.vue b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/ADRRecord/list.vue index e8fb783d6..a65c8fdc9 100644 --- a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/ADRRecord/list.vue +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/ADRRecord/list.vue @@ -1,79 +1,45 @@ @@ -100,8 +66,16 @@ import get from 'lodash/get' import set from 'lodash/set' import pickBy from 'lodash/pickBy' import mapValues from 'lodash/mapValues' + +import monthSchedule from '@/components/monthSchedule/monthSchedule.vue' +import { forEach, forIn } from 'lodash' +import uploadImage from '@/components/uploadImage.vue' export default { + components:{ + monthSchedule, + uploadImage + }, data() { return { // 数据项的数据类型、结构 @@ -136,7 +110,38 @@ export default { // 列表与分页信息 page: 1, total: 2, - list: [] + list: [] , + UserNo:'', + + // 打卡数据 + record:{}, + status:{ + // 1: { + // title: '缺勤', + // color: '#F56C6C' + // }, + // 2: { + // title: '正常', + // color: '#67C23A' + // }, + // 3: { + // title: '迟到早退', + // color: '#E6A23C' + // }, + // 4: { + // title: '未开始', + // color: '#9CADADB7' + // }, + }, + chooseDay:{}, + ClockStatus:{ + 1:'正常', + 2:'迟到', + 3:'早退', + 4:'上班补签', + 5:'下半补签', + 6:'缺勤' + } } }, @@ -172,7 +177,7 @@ export default { this.searchData.UserNo=userInfo.account; const result = await this.HTTP_GET( - 'learun/adms/attendance/getrecordpagelist', + 'learun/adms/attendance/GetTeacherRecord', { // 这里 sidx 表示排序字段,sord 表示排序方式(DESC=降序,ASC=升序) // 代码生成器生成时默认按照主键排序,您可以修改成按创建时间的字段降序 @@ -183,13 +188,16 @@ export default { ) if (!result) { return } - - this.total = result.total - this.page = result.page + 1 - this.list = isConcat?this.list.concat(result.rows):result.rows - - this.tips = `已加载 ${Math.min(result.page, result.total)} / ${result.total} 页,共 ${result.records} 项` - this.loadState = result.page >= result.total ? '已加载所有项目' : '向下翻以加载更多' + + this.list = result.data.map(e=>{ + // e.date = [e.ADYear,e.ADMonth,e.ADDay].join('-') + e.date = e.ADTime.substring(0,10) + e.color = e.ClockStatus == '1'?'#409EFF':'#E6A23C' + this.record[e.date]?this.record[e.date].push(e):this.record[e.date] = [e] + return e + }) + this.status = {} + console.log(this.list,this.record) }, // 刷新清空列表 @@ -326,7 +334,50 @@ export default { } return type; - } + }, + async uploadCo(val){ + if (!val) { + return [] + } + const uidList = val; + const fileList = [] + const wxlist = await this.FETCH_FILEList(uidList); + for (const wxfile of wxlist) { + const fileInfo = await this.FETCH_FILEINFO(wxfile.F_Id) + if (!fileInfo) { + continue + } + + const fileType = fileInfo.F_FileType + const fileSize = fileInfo.F_FileSize + const fileName = fileInfo.F_FileName + + const path = this.API + '/learun/adms/annexes/wxdown?' + this.URL_QUERY(wxfile.F_Id, true) + fileList.push({ + path, + type: fileType, + uid:wxfile.F_Id, + folderId:wxfile.F_FolderId, + size: fileSize, + name: fileName + }) + } + return fileList + }, + + async chooseEntireCard(e){ + this.chooseDay.isActive = false + e.isActive = true + for (let s in this.record[e.date]) { + let e1 = this.record[e.date] + for (let s1 in e1) { + if(e1[s1].ADPhoto) e1[s1].ADPhoto = await this.uploadCo(e1[s1].ADPhoto) + } + + } + this.status = {} + this.chooseDay = e + }, } } @@ -336,4 +387,11 @@ export default { \ No newline at end of file diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCard/list.vue b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCard/list.vue index 7224ffb71..f488bdc87 100644 --- a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCard/list.vue +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCard/list.vue @@ -114,6 +114,10 @@ if ([5].includes(this.info.AttendanceType)) { return } + if(!this.postData.ClockPlace){ + this.TOAST('获取定位失败,无法打卡') + return + } if ([4].includes(this.info.AttendanceType)) { this.NAV_TO(`./single`, this.postData,true) return @@ -164,8 +168,14 @@ this.map = new BMapGL.Map('container'); await this.isFieldPersonnel() + if(!this.postData.ClockPlace){ + return true + } this.timer1 = setInterval(async ()=>{ if(this.isGetingLocal)return + if(!this.postData.ClockPlace){ + clearInterval(this.timer1) + } this.isGetingLocal = true await this.isFieldPersonnel() // console.log(this.postData) diff --git a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue index 12a2e5bab..aaf9d8eb5 100644 --- a/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue +++ b/Learun.Framework.Ultimate V7/LearunApp-2.2.0/pages/AttendanceCardStudent/list.vue @@ -128,6 +128,10 @@ if ([5].includes(this.info.AttendanceType)) { return } + if(!this.postData.ClockPlace){ + this.TOAST('获取定位失败,无法打卡') + return + } if ([4].includes(this.info.AttendanceType)) { this.NAV_TO(`./single`, this.postData,true) return @@ -183,8 +187,14 @@ this.map = new BMapGL.Map('container'); await this.isFieldPersonnel() + if(!this.postData.ClockPlace){ + return true + } this.timer1 = setInterval(async ()=>{ if(this.isGetingLocal)return + if(!this.postData.ClockPlace){ + clearInterval(this.timer1) + } this.isGetingLocal = true await this.isFieldPersonnel() // console.log(this.postData)