parent
b42f4ca2e5
commit
c9202a7602
@ -0,0 +1,153 @@
|
||||
|
||||
var throttle = function throttle(func, wait, options) {
|
||||
var context = void 0;
|
||||
var args = void 0;
|
||||
var result = void 0;
|
||||
var timeout = null;
|
||||
var previous = 0;
|
||||
if (!options) options = {};
|
||||
var later = function later() {
|
||||
previous = options.leading === false ? 0 : Date.now();
|
||||
timeout = null;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
};
|
||||
return function () {
|
||||
var now = Date.now();
|
||||
if (!previous && options.leading === false) previous = now;
|
||||
var remaining = wait - (now - previous);
|
||||
context = this;
|
||||
args = arguments;
|
||||
if (remaining <= 0 || remaining > wait) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
previous = now;
|
||||
result = func.apply(context, args);
|
||||
if (!timeout) context = args = null;
|
||||
} else if (!timeout && options.trailing !== false) {
|
||||
timeout = setTimeout(later, remaining);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
Component({
|
||||
options: {
|
||||
addGlobalClass: true,
|
||||
pureDataPattern: /^_/
|
||||
},
|
||||
properties: {
|
||||
list: {
|
||||
type: Array,
|
||||
value: [],
|
||||
observer: function observer(newVal) {
|
||||
var _this = this;
|
||||
|
||||
if (newVal.length === 0) return;
|
||||
var data = this.data;
|
||||
var alphabet = data.list.map(function (item) {
|
||||
return item.letter;
|
||||
});
|
||||
alphabet.unshift("↑");
|
||||
this.setData({
|
||||
alphabet: alphabet,
|
||||
current: alphabet[0]
|
||||
}, function () {
|
||||
_this.computedSize();
|
||||
});
|
||||
}
|
||||
},
|
||||
ext:{
|
||||
type:Object
|
||||
},
|
||||
vibrated: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
}
|
||||
},
|
||||
data: {
|
||||
current: 'A',
|
||||
intoView: '',
|
||||
touching: false,
|
||||
alphabet: [],
|
||||
_tops: [],
|
||||
_anchorItemH: 0,
|
||||
_anchorTop: 0
|
||||
},
|
||||
lifetimes: {
|
||||
created: function created() {},
|
||||
attached: function attached() {
|
||||
this.__scrollTo = throttle(this._scrollTo, 100, {});
|
||||
this.__onScroll = throttle(this._onScroll, 100, {});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
choose: function choose(e) {
|
||||
console.log("choose",e);
|
||||
var item = e.target.dataset.item;
|
||||
this.triggerEvent('choose', { item: item });
|
||||
},
|
||||
scrollTo: function scrollTo(e) {
|
||||
this.__scrollTo(e);
|
||||
},
|
||||
_scrollTo: function _scrollTo(e) {
|
||||
var data = this.data;
|
||||
var clientY = e.changedTouches[0].clientY;
|
||||
console.log(clientY);
|
||||
var index = Math.floor((clientY - data._anchorTop) / data._anchorItemH);
|
||||
if(index<0||index>=data.alphabet.length)
|
||||
return;
|
||||
var current = data.alphabet[index];
|
||||
if(current=='↑')
|
||||
this.setData({current, scrollTop:0, touching:true});
|
||||
else
|
||||
this.setData({ current: current, intoView: current=='#'?'hash':current, touching: true });
|
||||
if (data.vibrated) wx.vibrateShort();
|
||||
},
|
||||
computedSize: function computedSize() {
|
||||
var data = this.data;
|
||||
var query = this.createSelectorQuery();
|
||||
query.selectAll('.index_list_item').boundingClientRect();
|
||||
query.select(".top-view").boundingClientRect();
|
||||
query.select('.anchor-list').boundingClientRect(function (rect) {
|
||||
data._anchorItemH = rect.height / data.alphabet.length;
|
||||
data._anchorTop = rect.top;
|
||||
//console.log("select anchor list");
|
||||
});
|
||||
query.exec(res=>{
|
||||
data._tops = res[0].map(function (item) {
|
||||
return item.top-res[1].top;
|
||||
});
|
||||
//console.log(res);
|
||||
});
|
||||
},
|
||||
removeTouching: function removeTouching() {
|
||||
var _this2 = this;
|
||||
|
||||
setTimeout(function () {
|
||||
_this2.setData({ touching: false });
|
||||
}, 150);
|
||||
},
|
||||
onScroll: function onScroll(e) {
|
||||
this.__onScroll(e);
|
||||
},
|
||||
_onScroll: function _onScroll(e) {
|
||||
var data = this.data;
|
||||
var _tops = data._tops,
|
||||
alphabet = data.alphabet;
|
||||
//console.log("scroll", e.detail, this.data);
|
||||
var pageTop = e.detail.scrollTop;
|
||||
var current = '';
|
||||
if (pageTop < _tops[0]) {
|
||||
current = alphabet[0];
|
||||
} else {
|
||||
for (var i = 0, len = _tops.length; i < len - 1; i++) {
|
||||
if (pageTop >= _tops[i] && pageTop < _tops[i + 1]) {
|
||||
current = alphabet[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!current) current = alphabet[alphabet.length - 1];
|
||||
this.setData({ current: current });
|
||||
}
|
||||
}
|
||||
});
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {},
|
||||
"componentGenerics": {
|
||||
"item": true
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<scroll-view
|
||||
class="page page-select-index"
|
||||
enable-back-to-top
|
||||
scroll-into-view="{{intoView}}"
|
||||
scroll-top="{{scrollTop}}"
|
||||
scroll-y
|
||||
bindscroll="onScroll"
|
||||
>
|
||||
<view class="top-view">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="index_list_item" wx:for="{{list}}" wx:key="alpha" id="{{item.letter=='#'?'hash':item.letter}}">
|
||||
<view class="index-group__title">{{item.letter}}</view>
|
||||
<view class="index-group__list">
|
||||
<view wx:for="{{item.items}}" wx:key="name"
|
||||
class="index-group__item"
|
||||
data-item="{{item}}"
|
||||
bindtap="choose">
|
||||
<item data="{{item}}" ext="{{ext}}"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view
|
||||
class="anchor-bar__wrp wx-flex"
|
||||
catchtouchstart='scrollTo'
|
||||
catchtouchmove='scrollTo'
|
||||
catchtouchend='removeTouching'
|
||||
>
|
||||
<view class="anchor-bar wx-flex__item">
|
||||
<view class="anchor-list">
|
||||
<block wx:for="{{alphabet}}" wx:key="*this" wx:for-item="alpha">
|
||||
<view class="anchor-item {{current == alpha ? ( touching ? 'selected tapped' : 'selected' ): ''}}" data-alpha="{{alpha}}">
|
||||
<view class="anchor-item__inner">{{alpha}}</view>
|
||||
<view class="anchor-item__pop">{{alpha}}</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
@ -0,0 +1,81 @@
|
||||
.page-select-index{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wx-flex {
|
||||
display: flex;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.wx-flex__item {
|
||||
flex: 1
|
||||
}
|
||||
|
||||
|
||||
.index-group__title {
|
||||
padding: 12rpx 24rpx;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.anchor-bar__wrp {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
width: 60rpx;
|
||||
z-index: 999;
|
||||
top:50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.anchor-item {
|
||||
font-size: 0;
|
||||
text-align: center;
|
||||
position: relative
|
||||
}
|
||||
|
||||
.anchor-item__inner {
|
||||
line-height: 28rpx;
|
||||
height: 28rpx;
|
||||
width: 28rpx;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
font-size: 20rpx;
|
||||
margin: 2rpx 0;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.tapped .anchor-item__pop {
|
||||
display: block
|
||||
}
|
||||
|
||||
.anchor-item__pop {
|
||||
position: absolute;
|
||||
font-size: 64rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
color: #fff;
|
||||
background-color: #C9C9C9;
|
||||
border-radius: 50%;
|
||||
right: 80rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: none
|
||||
}
|
||||
|
||||
.anchor-item__pop:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
left: 80rpx;
|
||||
border: 40rpx solid;
|
||||
border-color: transparent transparent transparent #C9C9C9;
|
||||
top: 50%;
|
||||
transform: translateY(-50%)
|
||||
}
|
||||
|
||||
.anchor-item.selected .anchor-item__inner {
|
||||
color: #fff;
|
||||
background-color: #00b0f0
|
||||
}
|
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,43 @@
|
||||
const app = getApp();
|
||||
Component({
|
||||
properties: {
|
||||
data:Object,
|
||||
ext:Object
|
||||
},
|
||||
|
||||
data: {
|
||||
eduImgDir: global.config.eduImgDir,
|
||||
buttons:[{text:"删除", type:"warn"}]
|
||||
},
|
||||
|
||||
methods: {
|
||||
delete(){
|
||||
let {course_id} = this.data.ext;
|
||||
let {course_member_id} = this.data.data;
|
||||
//console.log(course_id, course_member_id);
|
||||
let students = [{course_member_id}];
|
||||
app.api("courses.delete_from_course")({course_id,students})
|
||||
.then(res=>{
|
||||
this.triggerEvent("delete",{},{bubbles:true,composed:true});
|
||||
//console.log(res);
|
||||
//res.message='删除成功';
|
||||
app.showMsg(res);
|
||||
}).catch(e=>{
|
||||
app.showError(e);
|
||||
})
|
||||
},
|
||||
onButtonTap(e){
|
||||
//console.log(e,this.data);
|
||||
wx.showModal({
|
||||
title:"提示",
|
||||
content:"确认删除所选学生吗?",
|
||||
success:res=>{
|
||||
if(res.confirm){
|
||||
this.delete();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"mp-slideview": "/weui-miniprogram/slideview/slideview"
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<mp-slideview disable="{{!ext.course_identity||ext.course_identity==5}}" buttons="{{buttons}}" bindbuttontap="onButtonTap">
|
||||
<view class="student thin-border-bottom">
|
||||
<image class="avatar" src="{{eduImgDir}}{{data.image_url}}"></image>
|
||||
<view class="detail">
|
||||
<view class="name">{{data.name}}</view>
|
||||
<view class="student-id" wx:if="{{data.student_id}}">学号:{{data.student_id}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</mp-slideview>
|
@ -0,0 +1,40 @@
|
||||
.student{
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
background: white;
|
||||
}
|
||||
.thin-border-bottom {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.thin-border-bottom::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
color: #e5e5e5;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transform: scaleY(.5);
|
||||
transform: scaleY(.5);
|
||||
z-index: 2
|
||||
}
|
||||
|
||||
.student.thin-border-bottom::after{
|
||||
left: 60px;
|
||||
}
|
||||
.detail{
|
||||
margin-left: 12px;
|
||||
}
|
||||
.avatar{
|
||||
border-radius: 50%;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
.student-id{
|
||||
color: dimgray;
|
||||
font-size: 14px;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
const app = getApp();
|
||||
Component({
|
||||
properties: {
|
||||
course_id: Number,
|
||||
id_: Number,
|
||||
course_identity:Number,
|
||||
refresh: {
|
||||
type: Number,
|
||||
observer: function (r) {
|
||||
if (r) {
|
||||
console.log("observer refresh")
|
||||
this.refresh();
|
||||
this.setData({ refresh: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
|
||||
},
|
||||
attached(){
|
||||
let {course_id, course_identity} = this.data;
|
||||
let ext = {course_id, course_identity};
|
||||
this.setData({ext});
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChoose(e){
|
||||
console.log(e);
|
||||
},
|
||||
refresh(){
|
||||
let {course_id} = this.data;
|
||||
app.api("weapps.courses.students")({course_id,limit:1000}).then(res=>{
|
||||
console.log(res);
|
||||
let {students,students_count} = res;
|
||||
this.setData({students,students_count});
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"mp-index-list":"../../components/index-list/index-list",
|
||||
"student-item":"./student-item/student-item"
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<mp-index-list binddelete="refresh" list="{{students}}" ext="{{ext}}" vibrated="{{false}}" generic:item="student-item" bindchoose="onChoose">
|
||||
<view class="header">
|
||||
<view class="student-count">
|
||||
<text>学生人数:</text>
|
||||
<text class="count">{{students_count}}</text>
|
||||
</view>
|
||||
<navigator wx:if="{{course_identity<5}}" class='invite' hover-class="none" url="/course/pages/course_invite/course_invite?course_id={{course_id}}"><button class="invite-button" size="mini" type="main">邀请学生</button></navigator>
|
||||
</view>
|
||||
</mp-index-list>
|
||||
|
||||
|
||||
|
@ -0,0 +1,14 @@
|
||||
.student-list-wrap{
|
||||
flex:auto;
|
||||
}
|
||||
|
||||
.header{
|
||||
background: white;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.invite-button{
|
||||
margin: 0;
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
const app = getApp();
|
||||
Component({
|
||||
properties: {
|
||||
data:Object,
|
||||
ext:Object
|
||||
},
|
||||
|
||||
data: {
|
||||
eduImgDir: global.config.eduImgDir,
|
||||
buttons:[{text:"删除", type:"warn"}]
|
||||
},
|
||||
|
||||
methods: {
|
||||
delete(e){
|
||||
console.log(e,this.data);
|
||||
let {course_id} = this.data.ext;
|
||||
let {course_member_id} = this.data.data;
|
||||
console.log(course_id, course_member_id);
|
||||
let students = [{course_member_id}];
|
||||
app.api("courses.delete_from_course")({course_id,students})
|
||||
.then(res=>{
|
||||
this.triggerEvent("delete",{},{bubbles:true,composed:true});
|
||||
//console.log(res);
|
||||
//res.message='删除成功';
|
||||
app.showMsg(res);
|
||||
}).catch(e=>{
|
||||
app.showError(e);
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<view class="teacher thin-border-bottom">
|
||||
<image class="avatar" src="{{eduImgDir}}{{data.image_url}}"></image>
|
||||
<view class="detail">
|
||||
<view class="name">{{data.name}}</view>
|
||||
<view class="school">{{data.school}}</view>
|
||||
</view>
|
||||
</view>
|
@ -0,0 +1,40 @@
|
||||
.teacher{
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
background: white;
|
||||
}
|
||||
.thin-border-bottom {
|
||||
position: relative
|
||||
}
|
||||
|
||||
.thin-border-bottom::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #EAEAEA;
|
||||
color: #e5e5e5;
|
||||
-webkit-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
-webkit-transform: scaleY(.5);
|
||||
transform: scaleY(.5);
|
||||
z-index: 2
|
||||
}
|
||||
|
||||
.teacher.thin-border-bottom::after{
|
||||
left: 60px;
|
||||
}
|
||||
.detail{
|
||||
margin-left: 12px;
|
||||
}
|
||||
.avatar{
|
||||
border-radius: 50%;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
.school{
|
||||
color: dimgray;
|
||||
font-size: 14px;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
const app = getApp();
|
||||
Component({
|
||||
properties: {
|
||||
course_id: Number,
|
||||
id_: Number,
|
||||
course_identity:Number,
|
||||
refresh: {
|
||||
type: Number,
|
||||
observer: function (r) {
|
||||
if (r) {
|
||||
console.log("observer refresh")
|
||||
this.refresh();
|
||||
this.setData({ refresh: false });
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
data: {
|
||||
|
||||
},
|
||||
attached(){
|
||||
let {course_id, course_identity} = this.data;
|
||||
let ext = {course_id, course_identity};
|
||||
this.setData({ext});
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChoose(e){
|
||||
console.log(e);
|
||||
},
|
||||
refresh(){
|
||||
let {course_id} = this.data;
|
||||
app.api("weapps.courses.teachers")({course_id,limit:1000}).then(res=>{
|
||||
console.log(res);
|
||||
let {teacher_list:teachers,teacher_list_size:teachers_count} = res;
|
||||
this.setData({teachers,teachers_count});
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
"mp-index-list":"../../components/index-list/index-list",
|
||||
"teacher-item":"./teacher-item/teacher-item"
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<mp-index-list binddelete="refresh" list="{{teachers}}" ext="{{ext}}" vibrated="{{false}}" generic:item="teacher-item" bindchoose="onChoose">
|
||||
<view class="header">
|
||||
<view class="student-count">
|
||||
<text>教师人数:</text>
|
||||
<text class="count">{{teachers_count}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</mp-index-list>
|
||||
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
.teacher-list-wrap{
|
||||
flex:auto;
|
||||
}
|
||||
|
||||
.header{
|
||||
background: white;
|
||||
padding: 12px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
Loading…
Reference in new issue