使用APICloud AVM多端框架开发课程表功能
Posted 海阔凭鱼跃_api
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用APICloud AVM多端框架开发课程表功能相关的知识,希望对你有一定的参考价值。
一、效果展示
二、功能实现的思路
本项目基于APICloud的AVM多端框架编写,因此需要想办法去构造特定数据、然后再改变数据,本项目核心业务就是课程数据的处理,难点就是课表的添加。
项目主要针对大学课表进行设计,课程很多地方存在不确定性,如课程周次数可能连续也可能不连续、上课时间可能1-2节也可能一整天、上课教室也可能不一样,因此课程的数据结构如下图。
后端需要提供当前周、当前周课程数据、添加课程等接口,当然课程数据查询是比较复杂的,这里就不讲。前端主要是将课表信息显示在指定位置,数据比较简单。
1、课程列表页面
(1)当前周课程原始数据结构
这个数据需要再重组,因为需要将课程摆放到指定位置,必须知道距离顶部距离以及自身高度。可以通过上课时间jie这个参数获取height,top。
let data = [
name: 大数据可视化技术,
room: 机房C414,
weekday: 3,
bg: 2,
jie: 3-4,
top: 140px,
height: 140px
]
横向分为8份,每份宽度12.5%,高度70px,默认可以显示13节课。课程背景默认有7种样式,星期对应的是left参数也有7种样式,上课节次对应top参数有12种样式具体css如下:
.bg-1 background: linear-gradient(#facea8, #fe8979)
.bg-2 background: linear-gradient(#dfc3fe, #90c5fb)
.bg-3 background: linear-gradient(#9deef5, #68e1b5)
.bg-4 background: linear-gradient(#eeba93, #dd65c7)
.bg-5 background: linear-gradient(#e6f6c9, #68e1b5)
.bg-6 background: linear-gradient(#dfc3fe, #dd65c7)
.bg-7 background: linear-gradient(#c8e65f, #7abafb)
.week-1 left: 12.5%;
.week-2 left: 25%;
.week-3 left: 37.5%;
.week-4 left: 50%;
.week-5 left: 62.5%;
.week-6 left: 75%;
.week-0 left: 87.5%;
每一门课程都是用绝对定位,宽度相同,根据上课时间决定高度、位置代码表示如下
<view class="course_list">
<view v-for="(rs,key) in course_data" :key="key" :class="course week-+rs.weekday+
bg-+rs.bg" :style="height:+rs.height+;top:+rs.top">
<text class=" course-name">rs.name</text>
<text class="course-room">rs.room</text>
</view>
</view>
(2)当前周星期数据结构
获取当前周的时间代码如下
this.setDate(new Date());
setDate(date)
let arr = [];
let week = date.getDay() - 1;
date = this.addDate(date, week * -1);
this.currentFirstDate = new Date(date);
for (var i = 0; i < 7; i++)
arr[i] = this.formatDate(i == 0 ? date : this.addDate(date, 1))
this.week_data = arr
this.currentWeek()
,
addDate(date, n)
date.setDate(date.getDate() + n);
return date;
,
formatDate(date)
let year = date.getFullYear();
let month = (date.getMonth() + 1);
let day = date.getDate();
let week = [周日, 周一, 周二, 周三, 周四, 周五, 周六][date.getDay()];
this.currentMonth = month;
if (month < 10) month = 0 + month;
if (day < 10) day = 0 + day;
return "week": week, "date": month + / + day, "active": false ;
,
//当前星期
currentWeek()
let date = new Date();
let weekday = date.getDay();
if (weekday == 1)
this.week_data[0].active = true
else if (weekday == 2)
this.week_data[1].active = true
else if (weekday == 3)
this.week_data[2].active = true
else if (weekday == 4)
this.week_data[3].active = true
else if (weekday == 5)
this.week_data[4].active = true
else if (weekday == 6)
this.week_data[5].active = true
else if (weekday == 0)
this.week_data[6].active = true
上一周以及下一周相应代码
last()
if (this.week > 1)
this.week = this.week - 1
this.setDate(this.addDate(this.currentFirstDate, -7));
,
next()
if (this.week < 20)
this.week = this.week + 1
this.setDate(this.addDate(this.currentFirstDate, 7));
,
2、课程添加页面
本项目主要针对大学课程进行设计,由于上课时间地点可能不规律,因此需要考虑周次、节次、星期、上课地点几个因素。为了方便用户快速添加课程,同一门课程可支持添加多个上课时间。页面业务逻辑只有周次选择、时间选择两个地方有点复杂因此将其拆分为两个组件<class-week></class-week> <class-time></class-time>
课程的主要字段如下
name: 大学计算机, //课程名称
room: 机房C411, //上课教室
teacher: 李国海, //任课教师
weekday: 0, //星期
weeks: 1-9,11-20, //上课周数
jie: 5-9, //上课节次
bg:1, //课程颜色,系统提供7种颜色
大学的课程上课时间可能不规律上课周数也不一定是20周,周数大致分为单双周以及其他,周数的格式如下:
不规律的周次格式:1-9,11,13,15-20
1-20周单周的格式:1,3,5,7,9,11,13,15,17,19
1-20周双周的格式:2,4,6,8,10,12,14,16,18,20
1-20周的格式:1-20
但是这种数据格式对后端数据查询很不友好。
页面初始数据,默认1-24周全部选中。
(1)单周choose(1),双周choose(2),全选choose(0)具体业务处理源代码如下:
choose(n)
for (let i in this.weeks)
this.weeks[i].on = false
if (n == 1)
if (this.choose == 1)
this.choose = 3
else
this.choose = 1
for (let i = 0; i < this.weeks.length; i++)
if (this.weeks[i].week % 2 != 0)
this.weeks[i].on = true
else if (n == 2)
if (this.choose == 2)
this.choose = 3
else
this.choose = 2
for (let i = 0; i < this.weeks.length; i++)
if (this.weeks[i].week % 2 == 0)
this.weeks[i].on = true
else if (n == 0)
if (this.choose == 0)
this.choose = 3
else
this.choose = 0
for (let i in this.weeks)
this.weeks[i].on = true
(2)选择某一周的函数set_week(i) 源代码如下
set_week(i)
if (this.weeks[i].on == true)
this.weeks[i].on = false
else
this.weeks[i].on = true
(3)确定按钮get_weeks()源代码如下
get_weeks()
this.mask = false //影藏组件
let arr = [];
for (let i = 0; i < this.weeks.length; i++)
let on = this.weeks[i].on;
if (on == true)
arr.push(this.weeks[i].week);
let result = [];
let tmp;
while (tmp = arr.shift())
if (result.length == 0)
result.push([tmp]);
continue;
let e = result[result.length - 1];
if (tmp == e[e.length - 1] + 1)
e.push(tmp);
else
result.push([tmp]);
for (let i = 0; i < result.length; i++)
let res = result[i];
if (res.length > 1)
result[i] = res[0] + - + res[res.length - 1];
else
result[i] = res[0] +
for (let i = 0; i < result.length; i++)
if (result[i].indexOf("-") != -1)
result[i] = result[i]
this.fire(GetWeek, weeks: result.join(,) );//格式为1-9,11,13,15-20
上课时间组件<class-time></class-time> 里面包含星期、上课节次数(注意上课节次数必须是连续的否则需要单独添加另一个上课时间),主要难点在于判断上课节次数是否连续。
页面初始数据,默认最大上课节次13节。
weekdays: [
name: 星期一, on: false ,
name: 星期二, on: false ,
name: 星期三, on: false ,
name: 星期四, on: false ,
name: 星期五, on: false ,
name: 星期六, on: false ,
name: 星期日, on: false
],
times: base.class_time(),
num_arr: [],
mask: false,
jie: ,
weekday: 0
class_time()
let data = [
jie: 1节, time: 08:30-09:15 ,
jie: 2节, time: 09:25-10:10 ,
jie: 3节, time: 10:25-11:10 ,
jie: 4节, time: 11:20-12:05 ,
jie: 5节, time: 14:00-14:45 ,
jie: 6节, time: 14:55-15:40 ,
jie: 7节, time: 15:55-16:40 ,
jie: 8节, time: 16:50-17:35 ,
jie: 9节, time: 17:45-18:30 ,
jie: 10节, time: 18:30-19:00 ,
jie: 11节, time: 19:00-19:45 ,
jie: 12节, time: 19:50-20:35 ,
jie: 13节, time: 20:45-21:30
]
return data;
选择上课节次数(如5-9 这里需要判断单击后选中的数据是否为连续的数字)函数set_time(index)源代码如下
set_time(index)
let jie = (index + 1);
//判断是否已添加
if (this.isInArray(this.num_arr, jie))
this.delArrItem(this.num_arr, jie);
this.num_arr.sort(function (x, y)
return x - y;
);
//console.log(删除 + jie)
if (this.isContinuityNum(this.num_arr))
this.times[index].td1 = false
else
//console.log(删除后不连续)
this.times[index].td1 = true
this.num_arr.push(jie);
this.num_arr.sort(function (x, y)
return x - y;
);
api.toast(
msg: 上课时间必须连续
);
else
this.num_arr.push(jie);
this.num_arr.sort(function (x, y)
return x - y;
);
if (this.isContinuityNum(this.num_arr))
this.times[index].td1 = true
else
//console.log(增加后不连续)
this.delArrItem(this.num_arr, jie);
this.num_arr.sort(function (x, y)
return x - y;
);
this.times[index].td1 = false
api.toast(
msg: 上课时间必须连续
);
this.jie =this.num_arr[0]+ -+this.num_arr[(this.num_arr.length -1)];//格式1-2
//删除数组元素
delArrItem(arr, item)
for (var i = 0; i < arr.length; i++)
if (arr[i] === item)
if (arr[i + 1] === item)
arr.splice(i, 1);
i--;
continue;
arr.splice(i, 1);
return arr;
,
//判断是否是连续的数字
isContinuityNum(array)
if (!array)
//数组为null
return false;
if (array.length == 0)
//数组为[]
return true;
var len = array.length;
var n0 = array[0];
var sortDirection = 1;//默认升序
if (array[0] > array[len - 1])
//降序
sortDirection = -1;
if ((n0 * 1 + (len - 1) * sortDirection) !== array[len - 1])
//筛除[3,4,5,6,7,8]
return false;
var isContinuation = true;
for (var i = 0; i < len; i++)
if (array[i] !== (i + n0 * sortDirection))
isContinuation = false;
break;
return isContinuation;
,
//判断元素是否在数组里面
isInArray(arr, value)
for (var i = 0; i < arr.length; i++)
if (value == arr[i])
return true;
return false;
最终前端需要提交给后端的数据格式如下:
yearId: 200, //学年id,这里是指那一学期的课程
name: 大学计算机, //课程名称
teacher: 李国海, //任课教师
bg: 1, //课程颜色,系统提供7种颜色
class_time: [
weeks: 1-20, room: 一教A307, weekday: 1, jie: 1-2 ,
weeks: 1-20, room: 机房C405, weekday: 3, jie: 3-4
]
以上是关于使用APICloud AVM多端框架开发课程表功能的主要内容,如果未能解决你的问题,请参考以下文章
使用APICloud AVM多端组件快速实现app中的搜索功能
APICloud AVM框架列表组件list-view的使用flex布局教程