A 发现界面

master
educoder_weapp 5 years ago
parent bfd7f13a58
commit 82569ce5a0

@ -3,4 +3,4 @@ educoder微信小程序帮助使用[educoder平台](https://www.educoder.net)
## 小程序码
![小程序码](/images/weacode.jpg)
![小程序码](/images/wxacode.jpg)

@ -1,3 +1,7 @@
## v0.16.0
* A 探索界面
* A 我的实践课程模块
## v0.15.1
* A 教师加入课堂审批
* A 熬夜睡觉提醒

@ -40,7 +40,8 @@ Page({
})
},
login_test(){
var data = {login:"educoder_weapp@126.com",save_password:1, password:"abcdefgh"};
var data = global.accountManager.testAccount;
data.save_password = 1;
this.setData(data);
this.login(data);
// this.setStorage({...data,save_password:1});

@ -58,7 +58,7 @@
</view>
<view class="form-item" wx:if="{{school_id}}">
<text class="key">{{identity_index<0?'院系/部门':identity_index==2?'部门':'院系'}}</text>
<picker wx:if="{{departments.length>0}}" class="value" id="department" range="{{departments}}" range-key="name" bindchange="onDepartmentChange" value="{{department_index}}">{{departments[department_index].name||department_name||'请选择'}}</picker>
<picker wx:if="{{departments.length>0}}" class="value" id="department" range="{{departments}}" range-key="name" bindchange="onDepartmentChange" value="{{department_index}}">{{departments[department_index].name||'请选择'}}</picker>
<view wx:else class="value none" bindtap="addDepartment">暂无子单位,点击申请新增</view>
<input hidden="1" disabled="1" name="department_id" type="number" value="{{departments[department_index].id}}"></input>
</view>

@ -18,12 +18,21 @@ App({
success&&success(res.result);
}, fail, complete});
},
realTimeLog:global.realTimeLog,
api(name, config) { return client.api(name, config) },
callApi(options) { return client.callApi(options) },
user() { return client.user },
syncUser(options) { return client.syncUser(options) },
updateUserInfo(info){return client.updateUserInfo(info)},
onLaunch: function (options) {
if(options.scene==1129){
this.api("accounts.login")(global.accountManager.testAccount)
.then(res=>{
let account = { ...res, ...global.accountManager.testAccount};
global.accountManager.setCurrentAccount(account);
});
wx.reportMonitor('1', 1);
}
const db = wx.cloud.database();
if (options.referrerInfo && options.referrerInfo.appId) {
let { appId, extraData } = options.referrerInfo;
@ -55,14 +64,7 @@ App({
})
}
}).catch(e=>{});
wx.getSystemInfo({
complete: (res) => {
let {SDKVersion} = res;
wx.reportAnalytics('lib_version', {
sdkversion: SDKVersion
});
},
})
},
onShow() {
if (client.user_id && client.user_id != 2)

@ -6,6 +6,9 @@
"navigationBarTitleText": "EduCoder",
"backgroundColor": "#f5f5f5"
},
"usingComponents":{
"require-login":"/components/require-login/require-login"
},
"pages": [
"pages/main/main",
"pages/findmore/findmore",
@ -94,6 +97,14 @@
}
],
"preloadRule": {
"pages/findmore/findmore":{
"network":"all",
"packages":[
"shixun",
"search",
"path"
]
},
"pages/home/home": {
"network": "all",
"packages": [
@ -107,7 +118,7 @@
"course",
"account",
"shixun",
"search"
"path"
]
},
"course/pages/course/course": {
@ -134,6 +145,12 @@
"iconPath": "images/tab_study_default.png",
"selectedIconPath": "images/tab_study_pressed.png"
},
{
"pagePath": "pages/findmore/findmore",
"text": "探索",
"iconPath": "images/tab_findmore_default.png",
"selectedIconPath": "images/tab_findmore_pressed.png"
},
{
"pagePath": "pages/tidings/tidings",
"text": "消息",
@ -151,9 +168,7 @@
"useExtendedLib": {
"weui": true
},
"navigateToMiniProgramAppIdList": [
"wx2402d86a6b534f77"
],
"sitemapLocation": "sitemap.json",
"themeLocation":"theme.json",
"style": "v2"
}

@ -0,0 +1,23 @@
Component({
properties: {
image:{
type:String,
value:global.config.attachDir + "908959"
},
show:{
type:Boolean,
value:false
},
title:{
type:String,
value:"没有相关内容呢"
},
desc:String
},
data: {
},
methods: {
}
})

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -0,0 +1,5 @@
<view class="empty" wx:if="{{show}}">
<image class="image" mode="aspectFit" src="{{image}}"/>
<view class="message">{{title}}</view>
<view class="desc">{{desc}}</view>
</view>

@ -0,0 +1,15 @@
.empty{
display: flex;
flex-direction: column;
align-items: center;
padding-top: 40px;
}
.image{
width: 30vw;
height: 30vw;
padding-bottom: 20px;
}
.desc{
font-size: 12px;
color: dimgray;
}

@ -52,7 +52,7 @@ Component({
this.setData({invite_code: res.result});
else if(res.scanType=="WX_CODE"&&res.path){
var match = res.path.match(/course_invite\?(.*)$/)
console.log("match",match);
//console.log("match",match);
if(match){
var options = {}
match[1].split("&").map(i=>{
@ -60,7 +60,7 @@ Component({
var k = i.slice(0, index);
var v = i.slice(index + 1);
options[k]=v})
console.log("options",options);
//console.log("options",options);
if(options.scene){
var scene = {};
for (var i of decodeURIComponent(options.scene).split("&")) {
@ -120,6 +120,7 @@ Component({
app.api("courses.apply_to_join_course")({ invite_code, assistant_professor, professor, student,complete: res=>{this.disabled=false}})
.then(res => {
app.showMsg(res,800);
wx.reportAnalytics('join_course', {});
if (res.course_id&&this.data.auto_navigate&&res.message.indexOf("助教申请")==-1){
setTimeout(()=>{
app[this.data.opentype]({

@ -27,6 +27,7 @@ Component({
type:Number,
observer: function(cur){
this.setData({cur});
console.log("observer current", cur);
this.trigger({source:""});
this.scroll();
}

@ -1,5 +1,5 @@
<scroll-view wx:if="{{list.length>1}}" scroll-x="1" class="navbar {{type}} bar-class" scroll-left="{{scrollLeft}}rpx" scroll-with-animation="1" style="width:{{width}}rpx;background:{{bg}}">
<view wx:for="{{list}}" wx:key="index" class="view common {{type}} item-class {{cur == index ?'active':''}}" data-current="{{index}}" bindtap="switchNav" style="margin-right:{{mg}}rpx;{{_itemWidth>0?'width:'+_itemWidth+'rpx':''}} ">
<view wx:for="{{list}}" wx:key="index" class="view common {{type}} item-class {{cur == index ?'active':''}}" data-current="{{index}}" bindtap="switchNav" style="margin:0 {{mg}}rpx;{{_itemWidth>0?'width:'+_itemWidth+'rpx':''}} ">
<text class="text common {{type}} item-class {{cur == index ?'active':''}}">{{item.text}}</text>
</view>
</scroll-view>

@ -21,6 +21,7 @@
.view.nav.active{
color: #0080f0;
font-size: 15px;
font-weight: bold;
border-bottom: 2px solid #0080f0;
}
.view.plain{
@ -33,7 +34,7 @@
}
.view.cap{
border-radius: 36px;
background: #dddddd;
background: #dfdfdf;
padding: 0 14px;
height: 28px;
line-height: 28px;
@ -54,7 +55,8 @@
}
.text.line.active{
font-size: 15px;
color: #0080f0;
color: #00b0f0;
font-weight: bold;
}
.text.line::after{
transition: all 0.26s ease;

@ -0,0 +1,23 @@
// components/page-status/page-status.js
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -0,0 +1,2 @@
<!--components/page-status/page-status.wxml-->
<text>components/page-status/page-status.wxml</text>

@ -0,0 +1 @@
/* components/page-status/page-status.wxss */

@ -3,7 +3,8 @@ const app = getApp();
Component({
properties: {
user_id:{
type:Number
type:Number,
value:-1
},
message:{
type:"String",
@ -21,7 +22,11 @@ Component({
show:function(){
app.syncUser()
.then(res=>{
this.setData({user_id: res.user.user_id});
if(this.data.user_id!=res.user.user_id){
if(this.data.user_id!=-1)
this.triggerEvent("change",{});
this.setData({user_id: res.user.user_id});
}
})
}
}

@ -55,8 +55,16 @@ Component({
var key = "RICHMDKEY";
//console.log(_data);
let {tag, attr} = _data;
if(tag=='navigator'&&attr.href)
navigateToUrl({url: attr.href});
if(tag=='navigator'&&attr.href){
if(!navigateToUrl({url: attr.href}))
wx.setClipboardData({
data: attr.href,success:res=>{
wx.showToast({
title: '链接已复制'
})
}
});
}
//this.triggerEvent('click',{},{bubbles:true});
if(data&&data._e.tag=="code")
data={attr:{class:"h2w__pre"},child:[data],tag:"view",type:"tag",_e:{type:"tag",attr:{},tag:"pre", child:[data]}}
@ -83,9 +91,7 @@ Component({
let {type, nodes} = this.data;
//console.log(type);
if(!type){
if (nodes.match(/<img .*src=.*>/))
type = "html"
else if (nodes.match(/^\s*<.+>.*<\/.+>/s))
if (nodes.match(/^\s*<.+>.*<\/.+>/s))
type = "rich-text";
else if(nodes.match(/##+|\*.+\*|- |`|\$|\[.*\]\(.+\)|\|.+\|/))
type = "markdown";

@ -1,6 +0,0 @@
<view class="shixun" bindtap="onTap">
<image class="shixun-img" mode="aspectFill" src="{{eduUrl}}/{{shixun.image_url}}"></image>
<view class="detail">
{{shixun.name}}
</view>
</view>

@ -1,20 +0,0 @@
.shixun{
background: white;
padding: 10px 8px;
overflow: hidden;
word-wrap: break-word;
display: flex;
}
.shixun-img{
flex:none;
width: 250rpx;
height: 170rpx;
border-radius: 4px;
}
.detail{
padding-top: 10px;
text-align: center;
flex: auto;
width: 1px;
}

@ -5,10 +5,9 @@ const developUrl = "https://test-newweb.educoder.net";
const trialUrl = "https://pre-newweb.educoder.net";
const releaseUrl = "https://www.educoder.net";
let _version = "0.15.2";
let _version = "0.16.0";
var eduUrl = releaseUrl;
/**
* A 试卷倒计时
*/
export function switchEnv(env) {
@ -46,7 +45,7 @@ const config = global.config = {
]
};
envVersion="release";
switchEnv(envVersion=="develop"?"trial":"release");
switchEnv("release");
//switchEnv(envVersion=="develop"?"trial":"release");
module.exports = config;

@ -29,9 +29,6 @@ Component({
},
methods: {
pull_files: function () {
wx.showLoading({
title: '加载中',
})
app.callApi({ name: "files", data: { course_id: this.data.course_id }, complete: () => { wx.hideLoading(); this.setData({ loading: false }) } })
.then(res => {
console.log("pull_files");

@ -28,13 +28,42 @@ Component({
onChoose(e){
console.log(e);
},
onChange(e){
console.log(e);
let {detail:{value}} = e;
this.sort_type = value?'id':'';
this.refresh();
},
refresh(){
let {course_id, course_identity} = 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});
});
let {sort_type=''} = this;
if(sort_type!='id')
app.api("weapps.courses.students")({course_id, limit:1000}).then(res=>{
console.log(res);
var {students,students_count} = res;
this.setData({students,students_count});
if(!this.imageMap)
this.imageMap = new Map();
for(var item of students){
for(var stu of item.items){
this.imageMap.set(stu.user_id, stu.image_url);
}
}
});
else
app.api("courses.students")({course_id, limit:10000})
.then(res=>{
console.log(res);
var students;
if(this.imageMap)
students = res.students.map(i=>{
i.image_url = this.imageMap.get(i.user_id);
return i;
})
students = [{letter:"#", items:res.students}];
var {students_count} = res;
this.setData({ students, students_count});
})
let ext = {course_id, course_identity};
this.setData({ext});
}

@ -4,6 +4,9 @@
<text>学生人数:</text>
<text class="count">{{students_count}}</text>
</view>
<view class="switch-wrp">
<switch color="#00b0f0" bindchange="onChange">按学号排序</switch>
</view>
<navigator wx:if="{{course_identity&&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>

@ -11,4 +11,7 @@
}
.invite-button{
margin: 0;
}
.switch-wrp{
transform: scale(0.6);
}

@ -307,7 +307,7 @@ Component({
});
},
onShow: function () {
if (this.data.status != 200 && this.data.status != 0 || this.data.status != 0) {
if (this.data.status != 200 && this.data.status != 0) {
this.refresh();
}
},

@ -5,7 +5,8 @@ Page({
* 页面的初始数据
*/
data: {
scrollTop:0,
re:false
},
onScanCode(e){
console.log(e);

@ -1,2 +1,3 @@
<textarea></textarea>
<editor/>
<scroll-view class="scroll" scroll-top="scrollTop" refresher-triggered="{{re}}" refresher-enabled="1">
<button>撒</button>
</scroll-view>

@ -1,4 +1,8 @@
#cam{
width: 100%;
height: 40vh;
}
.scroll{
background: red;
height: 72vh;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@ -0,0 +1,14 @@
<view class="navigation">
<view style="height:{{statusBarHeight}}px"></view>
<view class="navigation-bar">
<view class="navigation-left">
<icon wx:if="{{showSearch}}" class="search" type="search" size="25" color="white" bindtap="enterSearch" />
<text class="title">{{title}}</text>
</view>
<view class="navbar" bindtap="switchNav">
<view class="navitem {{current==index?'active':''}}" wx:for="{{list}}" data-current="{{index}}">
{{item.text}}
</view>
</view>
</view>
</view>

@ -0,0 +1,47 @@
.navigation{
background: #00b0f0;
flex: none;
}
.navigation-bar{
height: 44px;
padding-right: 105px;
display: flex;
align-items: center;
}
.navigation-left{
width: 105px;
display: flex;
align-items: center;
color: white;
}
.search{
padding: 5px 0 5px 7px;
}
.title{
flex: auto;
text-align: center;
white-space: pre;
font-size: 14px;
}
.navbar{
flex: 1 1 1px;
width: 1px;
font-size: 15px;
border-radius: 7px;
display: flex;
text-align: center;
white-space: nowrap;
overflow-x: scroll;
}
.navitem{
flex: auto;
background: #00d0f0;
color: white;
padding: 6px 1px;
transition: all ease 0.6s;
}
.navitem.active{
color: #00b0f0;
background: white;
}

@ -17,7 +17,9 @@ accounts:{
add_department_applies:{config, query, form:{school_id:null, name:null, remarks:void 0},disp:"新增子单位"},
attachments:{url:{_:1,DELETE:'*/{attachment_id}',uploadFile:"*"},query,form:{_:1,uploadFile:{file:null},DELETE:{}},config:{method:"uploadFile", name:"file"}},
collections:{config, query, form:{container_id: null, container_type: null},
cancel:{query, config:{method:"DELETE", form:{container_id: null, container_type: null}}},
},
courses:{ url:{_:"*", DELETE:"*/{course_id}",PUT:"*/{course_id}"},query, form:{_:1,GET:{search:"",limit:20, page:1, order:"all"}, POST:{course_list_name:null,name:null,school: null,end_date: null,class_period:null,credit:null,course_module_types:["shixun_homework","common_homework","group_homework","exercise","attachment","course_group"],authentication:null,professional_certification:null},PUT:{course_list_name:null,name:null,school: null,end_date: null,class_period:null,credit:null,course_module_types:["shixun_homework","common_homework","group_homework","exercise","attachment","course_group"],authentication:null,professional_certification:null}},
act_score:{url:"{course_id}/*", query},
all_course_groups:{url:"{course_id}/*", query},
@ -68,7 +70,7 @@ exercises:{url:"{exercise_id}",query,form:{exercise_name:null, exercise_descript
},
disciplines:{
query, form:{source:null}
},
files:{query, form:{course_id:null, page_size:15, page:1,search:"",sort:0, sort_type:"created_on"},
@ -99,7 +101,9 @@ myshixuns:{
repository: {url:"{identifier}/*",query,form:{path:null},config},
update_file:{url:"{identifier}/*",query,form:{path:null, content: null, evaluate:null, game_id:null},config}
},
paths:{url:""},
paths:{url:"*/{subject_id}",query,
right_banner:{url:"{subject_id}/*",query}
},
schools:{
school_list:{query, form:{search:null}},
@ -117,7 +121,7 @@ shixuns:{url:"*/{identifier}", query, res:{tpm_modified:"代码库是否有更
show_right:{url:""},
shixun_exec:{url:"{identifier}/*", query},
},
stages:{},
stages:{form:{subject_id:null},query},
student_works:{url:"*/{work_id}", query, form:{_:1, PUT:{description:null,attachment_ids:null},GET:{}},config:{method:"PUT"},disp:"提交作业",
comment_list:{url:"{work_id}/*",query},
@ -147,7 +151,8 @@ users:{
courses:{url:"{login}/*", query, form:{page:1, sort_by:"updated_at",sort_direction:"desc", per_page:10, category:void 0, status:void 0},category:["study","manage"],status:["processing","end"]},
get_user_info:{query,form:{school:1}},
homepage_info:{url:"{login}/*",query},
shixuns: { url: "{login}/*", query, form: {sort_by:"updated_at" ,page:1, sort_direction:"desc",per_page:16}},
shixuns: { url: "{login}/*", query, form: {sort_by:"updated_at",category:void 0, page:1, sort_direction:"desc",per_page:16}},
subjects:{url:"{login}/*", query, form:{sort_by:"update_at", category:void 0, page:1, sort_direction:"desc"}},
system_update:{query:query},
/*{"system_update":true,"system_score":"为了给大家提供更优质的体验平台将于2020年3月24日13:20开始对系统进行升级。升级期间系统响应会有一定的延迟。系统拟于2020年3月24日13:30恢复正常。\r\n请大家知悉并提前做好教学安排。带来不便敬请谅解。","subject":" educoder升级服务通知","start_time":"2020-03-24T13:20:00.000+08:00","end_time":"2020-03-24T13:30:00.000+08:00"}*/
tidings: {query, form:{type:void 0,page:1,per_page:10}, data:"type:course,project,interaction,apply,notice"},
@ -167,6 +172,7 @@ weapps:{
delete_course_teachers:{url:"{course_id}/*",query, form:{course_member_ids:null},config:{method:"DELETE"}},
students: {url:"{course_id}/*", query, form:{page:1, limit: void 0}},
teachers: {url:"{course_id}/*", query, form:{page:1, limit: void 0}},
},
course_member_attendances:{query, form:{_:1, GET:{page:1, limit: 10},POST:{attendance_id:null, attendance_mode:null, code:void 0}}, config, disp:"课堂成员签到",
update_status:{query, config, form:{attendance_id:null, attendance_status:null, course_id:null, user_id:null}}
@ -176,7 +182,7 @@ weapps:{
},
code_session: { query, form: {code: null, encrypted_data: null, iv: null }, config },
home: { query,form: { page: 1, limit: 15, category: "study"} },
paths: {},
paths:{query, form:{order:"myshixuns_count", sort:"desc", page:1, limit:10, discipline_id: void 0,sub_discipline_id: void 0}},
register:{query,form:{login:null,password:null, code:null}, config},
session: {query,form:{login:null, password:null},config},
course_stickies:{query, form:{course_id:null, category:null},config,

@ -38,6 +38,7 @@ export default class Client{
this.on("before", "users.accounts", getId);
this.on("before", "users.accounts.password", getLogin);
this.on("before","users.courses", getLogin);
this.on("before","users.subjects", getLogin);
this.on("before","users.homepage_info", getLogin);
this.on("before","users.accounts.avatar",getLogin);
this.on("before","users.unread_message_info", getLogin);
@ -70,25 +71,33 @@ export default class Client{
})
}
getTidingInfo({login}={}){
let index = 2;
this.tidingGet = 1;
const handler = {
fail: res=>{this.tidingGet=0}
};
return this.api("users.unread_message_info")({login}).then(res => {
if (res.unread_message_count)
wx.setTabBarBadge({ index: 1, text: res.unread_message_count.toString(),...handler});
wx.setTabBarBadge({ index, text: res.unread_message_count.toString(),...handler});
else if (res.unread_tiding_count)
wx.showTabBarRedDot({index: 1,...handler});
wx.showTabBarRedDot({index,...handler});
else{
wx.removeTabBarBadge({index:1});
wx.hideTabBarRedDot({index:1});
wx.removeTabBarBadge({index});
wx.hideTabBarRedDot({index});
}
}).catch(e => {
console.error("getTidingInfo", e);
});
}
async syncUser({ refresh = 0 } = {}) {
syncUser({refresh=0}={}){
if(!this.synching||!this.tmp_promise||!this.synch||refresh){
this.synching = 1;
this.tmp_promise = this._syncUser({refresh});
}
return this.tmp_promise;
}
async _syncUser({ refresh = 0 }) {
let old_id = this.user.user_id;
if(!this.synch||refresh){
let info = await this.callApi({name:"users.get_user_info"});
@ -110,6 +119,7 @@ export default class Client{
}
}
this.synching = 0;
return {synch:this.synch,changed, user:this.user};
}
updateUserInfo(info){

@ -105,6 +105,9 @@ class AccountManager{
this.accounts = []; //保存的账号信息
this.loadStorage();
}
get testAccount(){
return {login:"educoder_weapp@126.com", password:"abcdefgh"};
}
addAccount(account, sync=1){
if(!this.updateAccount(account))
this.accounts.push(account);
@ -237,7 +240,7 @@ export function navigateToUrl({url,open_type='navigateTo'}){
return false;
}
export function throttle(func, wait, options) {
export function throttle(func, wait, options) {
var context = void 0;
var args = void 0;
var result = void 0;
@ -267,4 +270,37 @@ export function throttle(func, wait, options) {
}
return result;
};
};
};
export function RealTimeLogManager(){
const log = wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : null;
return {
debug() {
if (!log) return
log.debug.apply(log, arguments)
},
info() {
if (!log) return
log.info.apply(log, arguments)
},
warn() {
if (!log) return
log.warn.apply(log, arguments)
},
error() {
if (!log) return
log.error.apply(log, arguments)
},
setFilterMsg(msg) { // 从基础库2.7.3开始支持
if (!log || !log.setFilterMsg) return
if (typeof msg !== 'string') return
log.setFilterMsg(msg)
},
addFilterMsg(msg) { // 从基础库2.8.1开始支持
if (!log || !log.addFilterMsg) return
if (typeof msg !== 'string') return
log.addFilterMsg(msg)
}
}
}
global.realTimeLog = RealTimeLogManager();

@ -1,13 +1,21 @@
const app = getApp();
const titleMap = ["实训项目", "实践课程","教学课堂"]
const typeMap = {
shixun:0,
path:1,
course:2
}
Page({
data: {
statusBarHeight: 20,
current: 0,
show: [1],
showSearch:1,
title:"实训项目",
list: [
{ text: "实训" ,type:"shixun"},
{ text: "课堂" , type:"course"},
//{text:"课程"}
{ text: "实训", type:"shixun"},
{ text: "课程", type:"path"},
//{ text: "课堂", type:"course"}
]
},
enterSearch() {
@ -22,18 +30,23 @@ Page({
},
})
},
switch({current}){
let title = titleMap[current];
this.setData({ ['show[' + current + ']']: 1,current, title});
},
switchNav({ target: { dataset: { current } } }) {
this.setData({ current });
this.setData({ ['show[' + current + ']']: 1 })
this.switch({current});
},
switchTab({ detail: { current, source, value } }) {
console.log(current, source, value);
//console.log(current, source, value);
if (source == "touch") {
this.setData({ current });
this.setData({ ['show[' + current + ']']: 1 })
this.switch({current});
}
},
onShareAppMessage: function () {
let {list, current} = this.data;
return app.shareApp({
path:"/"+this.route+"?type="+list[current].type
})
}
})

@ -1,5 +1,10 @@
{
"usingComponents": {},
"usingComponents": {
"paths":"./paths/paths",
"shixuns":"./shixuns/shixuns"
},
"navigationBarTitleText": "发现",
"navigationStyle": "custom"
"navigationBarTextStyle": "white",
"navigationStyle": "custom",
"navigationBarBackgroundColor": "#00b0f0"
}

@ -1,22 +1,9 @@
<view class="navigation">
<view style="height:{{statusBarHeight}}px"></view>
<view class="navigation-bar">
<view class="navigation-left">
<icon class="search" type="search" size="26" color="white" bindtap="enterSearch"/>
<text class="title">发现</text>
</view>
<view class="navbar" bindtap="switchNav">
<view class="navitem {{current==index?'active':''}}" wx:for="{{list}}" data-current="{{index}}">
{{item.text}}
</view>
</view>
</view>
</view>
<include src="../../includes/navigation-bar/navigaation-bar.wxml"/>
<swiper class="body" current="{{current}}" bindchange="switchTab" circular="1">
<swiper-item>
<courses wx:if="{{show[0]}}"/>
<shixuns wx:if="{{show[0]}}"/>
</swiper-item>
<swiper-item>
<shixuns wx:if="{{show[1]}}"/>
<paths wx:if="{{show[1]}}"/>
</swiper-item>
</swiper>

@ -1,48 +1,9 @@
@import "../../includes/navigation-bar/navigation-bar.wxss";
page{
display: flex;
flex-direction: column;
height: 100%;
}
.navigation{
background: #00b0f0;
flex: none;
}
.navigation-bar{
height: 44px;
padding-right: 100px;
display: flex;
align-items: center;
}
.navigation-left{
width: 100px;
display: flex;
align-items: center;
color: white;
}
.search{
padding:0 8px;
}
.navbar{
flex: 1 1 1px;
width: 1px;
border-radius: 7px;
display: flex;
text-align: center;
white-space: nowrap;
overflow-x: scroll;
}
.navitem{
flex: auto;
background: #00d0f0;
color: white;
padding: 5px 1px;
transition: all ease 0.6s;
}
.navitem.active{
color: #00b0f0;
background: white;
}
.body{
flex: 1 1 1px;
height: 1px;

@ -0,0 +1,13 @@
const app = getApp();
Component({
properties: {
data:Object
},
data: {
eduUrl: global.config.eduUrl
},
methods: {
}
})

@ -0,0 +1,6 @@
<navigator class="path-item" url="/path/pages/path/path?subject_id={{data.id}}">
<image class="image" src="{{eduUrl}}/{{data.image_url}}"></image>
<view class="detail">
<view class="name">{{data.name}}</view>
</view>
</navigator>

@ -0,0 +1,15 @@
.path-item{
padding: 12px;
display: flex;
background: white;
}
.image{
flex: none;
width: 250rpx;
height: 170rpx;
border-radius: 4px;
background: #221f53;
}
.detail{
padding-left: 8px;
}

@ -0,0 +1,101 @@
const app = getApp();
Component({
properties: {
},
data: {
list: [],
subList:[],
subjects:[],
subCurrent:-1
},
pageLifetimes:{
show(){
if(!this.disciplines)
this.pullDisciplines();
}
},
attached(){
this.options = {page:1, limit:10};
this.pullDisciplines();
this.pullSubjects({refresh:1});
},
methods: {
pullSubjects({refresh=0}={}){
if(refresh){
if(refresh==1){
this.options.page = 1;
var { options } = this;
}else if(refresh==2){
var {page, per_page} = this.options;
var options = {...this.options,page:1, per_page: page*per_page};
}
}else{
this.options.page++;
var {options} = this;
}
return app.api("weapps.paths")(options).then(({subjects})=>{
let length = subjects.length;
if (!refresh){
subjects = this.data.subjects.concat(subjects);
var status = length>0?200:204;
}else{
var status = length>0?200:205;
}
this.setData({ subjects, status});
}).catch(e=>{
this.setData({subjects:[], status:e.code});
})
},
onPullDownRefresh(){
this.pullSubjects({refresh:2});
},
onReachBottom(){
if(this.data.status==200)
this.pullSubjects();
},
pullDisciplines(){
this.disciplines = [];
app.api("disciplines")({source:"subject"})
.then(res=>{
console.log(res);
this.disciplines = res.disciplines;
this.disciplines.unshift({id:"",name:"全部", sub_disciplines:[]});
this.setNavList({disciplines: this.disciplines, key:"list"});
//this.setNavList({disciplines: this.disciplines[0].sub_disciplines, key:"subList"});
}).catch(e=>{
this.disciplines = null;
})
},
setNavList({disciplines, key}){
let list = disciplines.map(i=>{
return {text: i.name, id: i.id};
})
this.setData({[key]: list});
},
onCateChange({detail}){
console.log(detail);
let {current, value} = detail;
this.options.discipline_id = value.id;
this.setNavList({disciplines: this.disciplines[current].sub_disciplines, key:"subList"});
this.setData({subCurrent:-1});
delete this.options.sub_discipline_id;
this.pullSubjects({refresh:1});
},
onSubCateChange({detail}){
console.log(detail);
let {current, value, source} = detail;
if(source!="touch")
return;
if(value.id)
this.options.sub_discipline_id = value.id;
else
delete this.options.sub_discipline_id;
this.pullSubjects({refresh:1});
}
}
})

@ -0,0 +1,8 @@
{
"component": true,
"usingComponents": {
"nav-bar":"/components/nav-bar/nav-bar",
"empty-page":"/components/empty-page/empty-page",
"path-item":"./path-item/path-item"
}
}

@ -0,0 +1,17 @@
<scroll-view scroll-y="1" class="path-body" refresher-enabled="1"
bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom"
lower-threshold="200" bindrefresh="onPullDownRefresh">
<view>
<view class="nav-wrp">
<nav-bar list="{{list}}" type="line" itemWidth="0" mg="20" bindchange="onCateChange"/>
<nav-bar list="{{subList}}" cancellable="1" current="{{subCurrent}}"
type="cap" itemWidth="0" mg="12" bindchange="onSubCateChange"/>
</view>
<view class="subjects-list">
<view class="path-wrp" wx:for="{{subjects}}">
<path-item data="{{item}}"/>
</view>
<empty-page show="{{status==205}}" title="更多数据请访问EduCoder官网"/>
</view>
</view>
</scroll-view>

@ -0,0 +1,10 @@
.path-body{
height: 100%;
}
.nav-wrp{
position: sticky;
top: 0;
}
.path-wrp{
margin-bottom: 2px;
}

@ -0,0 +1,14 @@
Component({
properties: {
data:Object
},
data: {
eduUrl: global.config.eduUrl
},
methods: {
}
})

@ -0,0 +1,7 @@
<navigator class="shixun-item" url="/shixun/pages/shixun/shixun?identifier={{data.identifier}}">
<image class="image" src="{{eduUrl}}/{{data.pic}}"></image>
<view class="detail">
<view class="name"><rich-text nodes="{{data.title}}"/></view>
<view class="level">初级</view>
</view>
</navigator>

@ -0,0 +1,24 @@
.shixun-item{
padding: 12px;
display: flex;
background: white;
}
.image{
flex: none;
width: 250rpx;
height: 170rpx;
border-radius: 4px;
background: #221f53;
}
.detail{
padding:0 0 4px 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.level{
font-size: 12px;
}
.highlight{
color: #00b0f0;
}

@ -1,23 +1,73 @@
// pages/findmore/shixuns/shixuns.js
const app = getApp();
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
shixun_list:[]
},
attached(){
this.options = {page:1, limit: 10};
this.pullShixuns({refresh:1});
},
/**
* 组件的方法列表
*/
methods: {
clear(){
this.setData({keyword:"", showClear:0});
this.options.keyword = "";
this.pullShixuns({refresh:1});
},
onInput(e){
let {detail:{value}} = e;
if(this.data.showClear&&!value){
this.clear();
}else if(!this.data.showClear&&value){
this.setData({showClear:1});
}
},
onSubmit(e){
console.log(e)
let {detail:{value}} = e;
if(this.options.keyword!=value){
this.options.keyword = value;
this.pullShixuns({refresh:1});
}
},
onPullDownRefresh(){
this.pullShixuns({refresh:1});
},
onReachBottom(){
if(this.data.status==200)
this.pullShixuns();
},
pullShixuns({refresh=0}={}){
if(refresh){
if(refresh==1){
this.options.page = 1;
var { options } = this;
}else if(refresh==2){
var {page, per_page} = this.options;
var options = {...this.options,page:1, per_page: page*per_page};
}
}else{
this.options.page++;
var {options} = this;
}
wx.showNavigationBarLoading();
return app.api("shixun_lists")(options).then(({shixun_list})=>{
let length = shixun_list.length;
if (!refresh){
shixun_list = this.data.shixun_list.concat(shixun_list);
var status = length>0?200:204;
}else{
var status = length>0?200:205;
}
this.setData({ shixun_list, status}, wx.hideNavigationBarLoading);
}).catch(e=>{
this.setData({ shixun_list:[], status:e.code}, wx.hideNavigationBarLoading);
})
}
}
})

@ -1,4 +1,7 @@
{
"component": true,
"usingComponents": {}
"usingComponents": {
"empty-page":"/components/empty-page/empty-page",
"shixun-item":"./shixun-item/shixun-item"
}
}

@ -1,2 +1,17 @@
<!--pages/findmore/shixuns/shixuns.wxml-->
<text>pages/findmore/shixuns/shixuns.wxml</text>
<scroll-view class="shixun-body" scroll-y="1" refresher-enabled="1"
bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom"
lower-threshold="200" bindrefresh="onPullDownRefresh">
<view>
<view class="header">
<view class="input-wrp">
<input class="input" value="{{keyword}}" bindinput="onInput" bindblur="onSubmit" bindconfirm="onSubmit" confirm-type="search" placeholder="输入实训关键词进行搜索"></input>
<icon wx:if="{{showClear}}" class="icon" type="clear" bindtap="clear"></icon>
<icon class="icon" type="search"></icon>
</view>
</view>
<view wx:for="{{shixun_list}}" class="shixun-wrp">
<shixun-item data="{{item}}"/>
</view>
<empty-page show="{{status==205}}" title="暂无相关内容" desc="获取更多请进入EduCoder官网"/>
</view>
</scroll-view>

@ -1 +1,25 @@
/* pages/findmore/shixuns/shixuns.wxss */
.shixun-body{
height: 100%;
}
.header{
top: 0;
position: sticky;
background: white;
padding: 4px 12px;
}
.input-wrp{
display: flex;
padding: 4px 10px;
border-radius: 4px;
border: 1px #00b0f0 solid;
}
.input{
flex: auto;
}
.icon{
flex: none;
}
.shixun-wrp{
margin-bottom: 2px;
}

@ -1,17 +1,34 @@
const app = getApp();
const typeMap = {
course: 0,
shixun: 1,
path: 2,
subject:2
}
const titleMap = {
course:"教学课堂",
shixun:"实训项目",
path:"实践课程"
}
Page({
data:{
statusBarHeight:20,
current:0,
show:[1],
showSearch:0,
title:"我的教学课堂",
list:[
{text:"课堂", type:"course"},
{text:"实训", type:"shixun"},
//{text:"课程"}
{text:"课程", type:"path"}
]
},
onLoad(){
onLoad(options){
if(options.type){
let current = typeMap[options.type]||0;
this.switch({current});
}
wx.getSystemInfo({
success: res=>{
let {statusBarHeight} = res;
@ -23,18 +40,23 @@ Page({
let type = this.data.list[this.data.current].type||'';
app.navigateTo({url:`{search}?type=${type}`});
},
switch({current}){
let title = "我的"+titleMap[this.data.list[current].type];
this.setData({['show['+current+']']:1, current, title})
},
switchNav({target:{dataset:{current}}}){
this.setData({current});
this.setData({['show['+current+']']:1})
this.switch({current});
},
switchTab({detail:{current, source, value}}){
console.log(current, source, value);
//console.log(current, source, value);
if(source=="touch"){
this.setData({ current });
this.setData({ ['show[' + current + ']']: 1 })
this.switch({current});
}
},
onShareAppMessage(){
let {list, current} = this.data;
return app.showApp({
path: "/"+this.route+"?type="+list[current].type
})
}
})

@ -3,7 +3,9 @@
"usingComponents": {
"add-tips": "/components/add-tips/add-tips",
"my-course":"./my_course/my_course",
"my-shixun":"./my_shixun/my_shixun"
"my-shixun":"./my_shixun/my_shixun",
"my-path":"../my_path/my_path"
},
"navigationBarTextStyle": "white"
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00b0f0"
}

@ -1,17 +1,5 @@
<view class="navigation">
<view style="height:{{statusBarHeight}}px"></view>
<view class="navigation-bar">
<view class="navigation-left">
<icon class="search" type="search" size="26" color="white" bindtap="enterSearch"/>
<text class="title">我的</text>
</view>
<view class="navbar" bindtap="switchNav">
<view class="navitem {{current==index?'active':''}}" wx:for="{{list}}" data-current="{{index}}">
{{item.text}}
</view>
</view>
</view>
</view>
<include src="../../includes/navigation-bar/navigaation-bar.wxml"/>
<swiper class="body" current="{{current}}" bindchange="switchTab" circular="1">
<swiper-item>
<my-course wx:if="{{show[0]}}"/>
@ -19,6 +7,9 @@
<swiper-item>
<my-shixun wx:if="{{show[1]}}"/>
</swiper-item>
<swiper-item>
<my-path wx:if="{{show[2]}}"/>
</swiper-item>
</swiper>
<add-tips/>

@ -1,48 +1,9 @@
@import "../../includes//navigation-bar/navigation-bar.wxss";
page{
display: flex;
flex-direction: column;
height: 100%;
}
.navigation{
background: #00b0f0;
flex: none;
}
.navigation-bar{
height: 44px;
padding-right: 100px;
display: flex;
align-items: center;
}
.navigation-left{
width: 100px;
display: flex;
align-items: center;
color: white;
}
.search{
padding:0 8px;
}
.navbar{
flex: 1 1 1px;
width: 1px;
border-radius: 7px;
display: flex;
text-align: center;
white-space: nowrap;
overflow-x: scroll;
}
.navitem{
flex: auto;
background: #00d0f0;
color: white;
padding: 5px 1px;
transition: all ease 0.6s;
}
.navitem.active{
color: #00b0f0;
background: white;
}
.body{
flex: 1 1 1px;
height: 1px;

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"iconfont":"../iconfont/iconfont",
"iconfont":"/components/iconfont/iconfont",
"mp-icon": "/weui-miniprogram/icon/icon"
},
"navigationBarBackgroundColor": "#00b0f0",

@ -2,7 +2,7 @@
background-image: linear-gradient(to bottom right,#FEAC5E, #C779D0,#4BC0C8);/*#FEAC5E, #C779D0,#4BC0C8*/
}
.bg1{
background-image: linear-gradient(to bottom right,#f8cdda, #1d2b64);/*#f8cdda, #1d2b64*/
background-image: linear-gradient(to bottom right, #716da3, #ae5b84, #d76d77);/*#f8cdda, #1d2b64*/
}
.bg2{
background-image: linear-gradient(to bottom right, #43cea2, #185a9d);/*#43cea2, #185a9d*/
@ -14,7 +14,7 @@
background-image: linear-gradient(to bottom right, #b92b27, #1565c0);/*#b92b27, #1565c0*/
}
.bg5{
background-image: linear-gradient(to bottom right,#5fc3e4, #e55d87);/*#5fc3e4, #e55d87*/
background-image: linear-gradient(to bottom right,#4f2f54,#505587, #755d97);/*#5fc3e4, #e55d87*/
}
.bg6{
background-image: linear-gradient(to bottom right, #3a1c71, #d76d77, #ffaf7b);/*#3a1c71, #d76d77, #ffaf7b*/

@ -4,7 +4,7 @@
"join-course-modal": "/components/modal/join-course/join-course",
"require-login": "/components/require-login/require-login",
"nav-bar": "/components/nav-bar/nav-bar",
"course-item": "/components/course-item/course-item",
"course-item": "./course-item/course-item",
"mp-icon": "/weui-miniprogram/icon/icon"
}
}

@ -0,0 +1,87 @@
const app = getApp();
// status:[0, 204, 205, 200]
Component({
properties: {
},
data: {
shixuns:[],
status:0,
cates:[
{text:'全部',value:""},
{text:'我学习的',value:"study"},
{text:'我管理的',value:"manage"},
{text:"我收藏的",value:"collect"}
]
},
pageLifetimes: {
show(){
this.refresh();
}
},
attached(){
this.options = {page:1, per_page:16};
this.refresh();
},
methods: {
onCateChange({detail:{value}}){
console.log(value);
this.options.category = value.value
this.pullPaths({refresh:1});
},
refresh(){
app.syncUser()
.then(res => {
if (res.user.user_id != this.user_id) {
if(res.user_id==2)
this.setData({shixuns:[]})
else
this.pullPaths({ refresh: 1 })
this.user_id = res.user.user_id;
}else if(this.data.status==200){
this.pullPaths({refresh:2});
}
})
},
setStatus(status){
this.setData({status});
},
pullPaths({refresh=0}={}){
if(refresh){
if(refresh==1){
this.options.page = 1;
var { options } = this;
}else if(refresh==2){
var {page, per_page, category=""} = this.options;
var options = {page:1, per_page: page*per_page, category};
}
//this.setStatus(1);
}else{
this.options.page++;
var {options} = this;
//this.setStatus(100);
}
return app.api("users.subjects")(options).then(({subjects})=>{
let length = subjects.length;
if (!refresh){
subjects = this.data.subjects.concat(subjects);
var status = length>0?200:204;
}else{
var status = length>0?200:205;
}
this.setData({ subjects, status});
}).catch(e=>{
this.setData({subjects:[], status:e.code});
})
},
onPullDownRefresh(){
this.pullPaths({refresh:2});
},
onReachBottom(){
console.log("onreachbottom")
if(this.data.status==200)
this.pullPaths({refresh:0});
}
}
})

@ -0,0 +1,9 @@
{
"component": true,
"usingComponents": {
"nav-bar": "/components/nav-bar/nav-bar",
"path-item":"./path-item/path-item",
"empty-page":"/components/empty-page/empty-page",
"require-login":"/components/require-login/require-login"
}
}

@ -0,0 +1,10 @@
<view class="my-path">
<require-login/>
<nav-bar list="{{cates}}" bindchange="onCateChange"/>
<scroll-view class="body" scroll-y="1" refresher-enabled="1" lower-threshold="140" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom">
<view class="path-wrap" wx:for="{{subjects}}" wx:key="id">
<path-item data="{{item}}"/>
</view>
<empty-page show="{{status==205}}"/>
</scroll-view>
</view>

@ -0,0 +1,14 @@
.my-path {
height: 100%;
display: flex;
flex-direction: column;
}
.path-wrap {
margin: 2px 0;
}
.body {
flex: 1 1 1px;
height: 1px;
}

@ -0,0 +1,20 @@
Component({
properties: {
data:{
type:Object,
observer:function(data){
//name, image_url
//console.log(data);
this.setData(data);
}
}
},
data: {
eduUrl:global.config.eduUrl
},
methods: {
}
})

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -0,0 +1,8 @@
<navigator class="path" url="/path/pages/path/path?subject_id={{id}}">
<image class="path-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}"></image>
<view class="detail">
<view class="name">
{{name}}
</view>
</view>
</navigator>

@ -0,0 +1,28 @@
.path {
background: white;
padding: 10px 8px;
overflow: hidden;
word-wrap: break-word;
display: flex;
}
.path-img {
flex: none;
width: 250rpx;
height: 170rpx;
border-radius: 4px;
background: #221f53;
}
.detail {
padding-top: 6px;
flex: auto;
width: 1px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.name {
padding-left: 8px;
}

@ -1,11 +1,19 @@
const app = getApp();
// status:[0, 204, 205, 200]
Component({
properties: {
},
data: {
shixuns:[]
shixuns:[],
status:0,
cates:[
{text:'全部',value:""},
{text:'我学习的',value:"study"},
{text:'我管理的',value:"manage"},
{text:"我收藏的",value:"collect"}
]
},
pageLifetimes: {
show(){
@ -17,6 +25,11 @@ Component({
this.refresh();
},
methods: {
onCateChange({detail:{value}}){
console.log(value);
this.options.category = value.value
this.pullShixuns({refresh:1});
},
refresh(){
app.syncUser()
.then(res => {
@ -26,35 +39,49 @@ Component({
else
this.pullShixuns({ refresh: 1 })
this.user_id = res.user.user_id;
}else if(this.data.status==200){
this.pullShixuns({refresh:2});
}
})
},
setStatus(status){
this.setData({status});
},
pullShixuns({refresh=0}={}){
if(refresh){
if(refresh==1){
this.options.page = 1;
var { options } = this;
}else if(refresh==2){
var {page, per_page} = this.options;
var options = {page:1, per_page: page*per_page};
var {page, per_page, category=""} = this.options;
var options = {page:1, per_page: page*per_page, category};
}
//this.setStatus(1);
}else{
this.options.page++;
var {options} = this;
//this.setStatus(100);
}
return app.api("users.shixuns")(options).then(({shixuns})=>{
if (!refresh)
let length = shixuns.length;
if (!refresh){
shixuns = this.data.shixuns.concat(shixuns);
this.setData({ shixuns });
var status = length>0?200:204;
}else{
var status = length>0?200:205;
}
this.setData({ shixuns, status});
}).catch(e=>{
this.setData({shixuns:[]});
this.setData({shixuns:[], status:e.code});
})
},
onPullDownRefresh(){
this.pullShixuns({refresh:2});
},
onReachBottom(){
this.pullShixuns({refresh:0});
console.log("onreachbottom")
if(this.data.status==200)
this.pullShixuns({refresh:0});
}
}
})

@ -2,7 +2,8 @@
"component": true,
"usingComponents": {
"nav-bar": "/components/nav-bar/nav-bar",
"shixun-item":"/components/shixun-item/shixun-item",
"shixun-item":"./shixun-item/shixun-item",
"empty-page":"/components/empty-page/empty-page",
"require-login":"/components/require-login/require-login"
}
}

@ -1,8 +1,10 @@
<view class="my-shixun">
<require-login/>
<scroll-view class="body" scroll-y="1" refresher-enabled="1" lower-threshold="120" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom">
<nav-bar list="{{cates}}" bindchange="onCateChange"/>
<scroll-view class="body" scroll-y="1" refresher-enabled="1" lower-threshold="140" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom">
<view class="shixun-wrap" wx:for="{{shixuns}}" wx:key="id">
<shixun-item data="{{item}}"/>
</view>
<empty-page show="{{status==205}}"/>
</scroll-view>
</view>

@ -6,10 +6,10 @@ Component({
type:Object,
observer:function(data){
//name, image_url
this.setData({shixun:data});
//console.log(data);
this.setData(data);
}
},
origin:String
}
},
data: {
eduUrl:global.config.eduUrl
@ -17,7 +17,7 @@ Component({
methods: {
onTap(){
app.navigateTo({url:"{shixun}?identifier="+this.data.shixun.identifier})
app.navigateTo({url:"{shixun}?identifier="+this.data.identifier})
}
}
})

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -0,0 +1,13 @@
<navigator class="shixun" url="/shixun/pages/shixun/shixun?identifier={{identifier}}">
<image class="shixun-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}"></image>
<view class="detail">
<view class="name">
{{name}}
</view>
<view class="progress-wrp">
<progress percent="{{finished_challenges_count/challenges_count*100}}" border-radius="4" backgroundColor="#cdcdcd" activeColor="#00b0f0">
<text class="finish-text">已完成:{{finished_challenges_count}}/{{challenges_count}}</text>
</progress>
</view>
</view>
</navigator>

@ -0,0 +1,34 @@
.shixun{
background: white;
padding: 10px 8px;
overflow: hidden;
word-wrap: break-word;
display: flex;
}
.shixun-img{
flex:none;
width: 250rpx;
height: 170rpx;
border-radius: 4px;
background: #221f53;
}
.detail{
padding-top: 6px;
flex: auto;
width: 1px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.name{
padding-left: 8px;
}
.progress-wrp{
padding: 10px;
}
.finish-text{
font-size: 12px;
font-weight: bold;
padding-left: 6px;
}

@ -9,13 +9,25 @@ Component({
},
methods: {
enterInvite(){
let {type, id} = this.data.data;
let {envVersion} = global.config;
if(envVersion!='develop'&&envVersion!='trial')
return;
if(type=='course')
app.navigateTo({url:"{course_invite}?course_id="+id});
},
enterPage(){
let {type} = this.data.data;
let {type, id, identifier} = this.data.data;
switch(type){
case 'shixun':
return app.navigateTo({ url: "{shixun}?identifier=" + this.data.data.identifier});
return app.navigateTo({ url: "{shixun}?identifier=" + identifier});
case "course":
return app.navigateTo({url:"{course}?course_id="+this.data.data.id});
return app.navigateTo({url:"{course}?course_id="+id});
case "subject":
case "path":
return app.navigateTo({url:"{path}?subject_id="+id});
}
}
}

@ -1,4 +1,4 @@
<view class="search-item" bindtap="enterPage">
<view class="search-item" bindlongpress="enterInvite" bindtap="enterPage">
<view class="title-wrap">
<rich-text class="title" nodes="{{data.title}}"></rich-text>
</view>

@ -1,9 +1,16 @@
const app = getApp();
const typeMap = {
shixun:{current:0, type:"shixun"},
path: {current:1, type:"subject"},
subject:{current:1, type:"subject"},
course:{current:2, type:"course"}
}
Page({
data: {
keyword:"",
list:[
{text:"实训项目", type:"shixun"},
{text:"实践课程", type:"subject"},
{text:"教学课堂", type:"course"}
]
},
@ -25,6 +32,7 @@ Page({
this.search({refresh:1});
},
search({refresh=0}={}){
//console.log("search", this.options);
if(refresh==1)
this.setData({loading:1});
if(refresh){
@ -39,6 +47,7 @@ Page({
this.options.page++;
var {options} = this;
}
//console.log("search2",options)
return app.api("search")(options)
.then(res=>{
console.error(res);
@ -57,15 +66,11 @@ Page({
})
},
onLoad: function (options) {
var {type="shixun", keyword=""} = options;
let {type:_type="shixun", keyword=""} = options;
let {type, current} = typeMap[_type]||typeMap["shixun"];
this.options = {page:1, per_page:20, type, keyword};
this.search({ refresh: 1 });
for (var current=this.data.list.length-1; current >=0; current--){
if(this.data.list[current].type==type)
break;
}
this.setData({keyword, current});
console.log(this.data);
},

@ -1,5 +1,5 @@
const app = getApp();
const { processObj, get, format } = require("../../js/utils");
const { processObj, get, format } = require("../../../js/utils");
const ROUTE = {
Course:{

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

@ -46,9 +46,10 @@ Page({
this.refresh();
},
onShow: function () {
let index = 2;
this.refresh({refresh:2})
wx.hideTabBarRedDot({index: 1});
wx.removeTabBarBadge({index: 1});
wx.hideTabBarRedDot({index});
wx.removeTabBarBadge({index});
},
onPullDownRefresh: function () {

@ -1,6 +1,6 @@
{
"usingComponents": {
"tiding-item":"/components/tiding-item/tiding-item",
"tiding-item":"./tiding-item/tiding-item",
"nav-bar":"/components/nav-bar/nav-bar",
"error-page":"/components/error-page/error-page"
},

@ -1,66 +1,90 @@
// miniprogram/path/pages/path/path.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
cates:[
{text:"章节"},
{text:"介绍"}
]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
onSwitch({detail}){
let {source, current} = detail
if(source=='touch'){
this.setData({current});
}
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
collect(){
let {id, is_collect} = this.data.subject;
let api_name = is_collect?"collections.cancel":"collections";
app.api(api_name)({container_type:"Subject", container_id:id})
.then(res=>{
console.log(res);
this.pullSubject({showLoading:0});
if(is_collect){
res.message = "已取消收藏";
var icon = "success";
var duration = 1500;
}else{
var icon = "none";
var duration = 3000;
}
wx.showToast({
title: res.message,
icon,
duration
})
}).catch(e=>{
//console.log(e);
app.showError(e);
})
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
scrollTo({scrollTop}){
wx.pageScrollTo({scrollTop,duration:380})
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
onLoad: function (options) {
this.subject_id = options.path_id||options.subject_id;
this.pullSubject();
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
onEnterShixun(e){
console.log(e.currentTarget);
let {currentTarget:{dataset:{allow_visit}}} = e;
if(!allow_visit)
wx.showToast({
title: '该实训暂未公开',icon:"none"
})
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
pullSubject({showLoading=1}={}){
if(showLoading)
wx.showLoading({
title: '努力加载中'
});
let {subject_id} = this;
let promise1 = app.api("paths")({subject_id})
let promise2 = app.api("paths.right_banner")({subject_id})
let promise3 = app.api("stages")({subject_id})
Promise.all([promise1, promise2, promise3])
.then(res=>{
this.setData({subject:res[0], ...res[1], ...res[2]},
res=>{
if(showLoading)
wx.hideLoading()
});
}).catch(e=>{
if(e.code==403)
e.message = "您没有权限访问"
console.log(e);
wx.hideLoading();
app.showError(e);
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
//console.log(global.config.apiRoot , this.data.subject.cover )
let {subject} = this.data;
return app.shareApp({
title: subject.name,
imageUrl: global.config.eduUrl + "/" + subject.cover
})
}
})

@ -1,3 +1,8 @@
{
"usingComponents": {}
"usingComponents": {
"nav-bar":"/components/nav-bar/nav-bar",
"rich-md":"/components/rich-md/rich-md",
"mp-icon":"/weui-miniprogram/icon/icon"
},
"navigationBarTitleText": "实践课程"
}

@ -1,2 +1,85 @@
<!--miniprogram/path/pages/path/path.wxml-->
<text>miniprogram/path/pages/path/path.wxml</text>
<wxs src="./path.wxs" module="handler" />
<view class="header">
<require-login bg="#00b0f0" bindchange="pullSubject"/>
<view class="title">
{{subject.name}}
</view>
<view class="subject-detail">
<view class="detail-item">
<view class="key">章节</view>
<view class="value">{{subject.stages_count}}</view>
</view>
<view class="detail-item">
<view class="key">实训</view>
<view class="value">{{subject.shixuns_count}}</view>
</view>
<view class="detail-item">
<view class="key">关卡</view>
<view class="value">{{subject.challenges_count}}</view>
</view>
<view class="detail-item">
<view class="key">经验值</view>
<view class="value">{{subject.subject_score}}</view>
</view>
<view class="detail-item">
<view class="key">学习人数</view>
<view class="value">{{subject.member_count}}</view>
</view>
</view>
<view class="progress-wrp">
<progress class="score-progress" stroke-width="9" percent="{{progress.my_score/progress.all_score*100}}" border-radius="10" backgroundColor="#dddddd" activeColor="#00b0f0">
<text class="score">已学:{{progress.my_score}}/{{progress.all_score}}</text>
</progress>
</view>
</view>
<nav-bar bar-class="nav-bar" bindchange="onSwitch" current="{{current}}" type="line" list="{{cates}}" />
<swiper class="body" current="{{current}}" bindchange="onSwitch">
<swiper-item>
<scroll-view class="cate-body" scroll-y="1" bindscroll="{{handler.scroll}}">
<view class="stages-list">
<view class="stage" wx:for="{{stages}}" wx:for-item="stage" wx:key="stage_id">
<view class="stage_name cate-header">
<text class="square"/><text class="cate-name">{{stage.stage_name}}</text>
</view>
<view class="shixuns-list">
<navigator class="shixun {{shixun.allow_visit?'':'forbidden'}}" hover-class="{{shixun.allow_visit?'navigator-hover':'none'}}"
wx:for="{{stage.shixuns_list}}" wx:for-item="shixun" wx:key="identifier"
url="{{shixun.allow_visit?('/shixun/pages/shixun/shixun?identifier='+shixun.identifier):''}}"
data-allow_visit="{{shixun.allow_visit}}" bindtap="onEnterShixun">
<icon wx:if="{{shixun.complete_status}}" type="success" class="shixun-icon" size="18" color="#00b0f0"/>
<mp-icon wx:else extClass="shixun-icon" icon="play2" size="18" color="#dedede" type="field"/>
<view class="shixun-name">
<text class="shixun-index">{{stage.stage_position}}-{{index+1}}</text>
{{shixun.shixun_name}}
</view>
</navigator>
</view>
</view>
</view>
</scroll-view>
</swiper-item>
<swiper-item>
<scroll-view class="cate-body" scroll-y="1" bindscroll="{{handler.scroll}}">
<view class="cate-header">
<text class="square"/><text class="cate-name">简介</text>
</view>
<rich-md nodes="{{subject.description}}" type="markdown" />
<view class="cate-header">
<text class="square"/><text class="cate-name">课程须知</text>
</view>
<rich-md nodes="{{subject.learning_notes}}" type="markdown" />
<view class="cate-header">
<text class="square"/><text class="cate-name">技能标签</text>
</view>
<view class="tags-list">
<view class="tag {{item.status?'active':''}}" wx:for="{{tags}}">
{{item.tag_name}}
</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
<view class="operations">
<button type="main" plain bindtap="collect" class="collect">{{subject.is_collect?'已收藏':'收藏'}}</button>
</view>

@ -0,0 +1,15 @@
var top = 190;
function scroll(e, ins){
//var scrollTop = e.detail.scrollTop;
var deltaY = e.detail.deltaY;
//console.log(scrollTop);
//console.log(show,scrollTop<122);
//console.log(top,scrollTop, deltaY);
if(deltaY<-4){
ins.callMethod("scrollTo", { scrollTop: top });
}
}
module.exports={
scroll: scroll
}

@ -1 +1,103 @@
/* miniprogram/path/pages/path/path.wxss */
.header{
background: white;
margin-bottom: 4px;
border-bottom: 1px #eee solid;
}
.title{
font-size: 18px;
padding: 10px;
font-weight: bold;
}
.subject-detail{
display: flex;
justify-content: space-evenly;
}
.detail-item{
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
font-size: 12px;
}
.detail-item>.key{
padding-bottom: 4px;
}
.detail-item>.value{
color: #009af0;
font-weight: bold;
}
.progress-wrp{
padding: 12px;
}
.progress-wrp .score{
padding-left: 8px;
font-size: 11px;
font-weight: bold;
}
.body{
background: white;
height: calc(100vh - 76px);
}
.cate-body{
height: 100%;
}
.shixun{
display: flex;
padding: 7px 6px 7px 12px;
align-items: center;
}
.shixun.forbidden{
color: gray;
}
.shixun-index,
.shixun-icon{
margin-right: 6px;
}
.cate-header{
padding-left: 8px;
}
.cate-header.stage_name{
margin: 5px 0;
}
.cate-header>.cate-name{
padding-left: 10px;
}
.cate-header>.square{
width: 0;
height: 0px;
border-radius: 10px;
border-left: 5px solid #00b0f0;
}
.tags-list{
display: flex;
flex-wrap: wrap;
overflow-y: scroll;
padding: 6px;
max-height: 50vh;
font-size: 12px;
margin-top: 8px;
}
.tags-list>.tag{
background: #f0f0f0;
color: #666;
border-radius: 30px;
padding: 4px 10px;
margin: 4px;
flex: none;
}
.tags-list>.tag.active{
color: white;
background: #00b0f0;
}
.operations{
position: sticky;
bottom: 0;
display: flex;
}
.operations>.collect{
background: white!important;
flex: 1;
}

@ -13,8 +13,30 @@ Page({
],
description:""
},
log(e){
console.log(e)
collect(){
let {id, is_collect} = this.data.shixun;
let api_name = is_collect?"collections.cancel":"collections";
app.api(api_name)({container_type:"Shixun", container_id:id})
.then(res=>{
console.log(res);
this.pullShixun({showLoading: 0});
if(is_collect){
res.message = "已取消收藏";
var icon = "success";
var duration = 1500;
}else{
var icon = "none";
var duration = 3000;
}
wx.showToast({
title: res.message,
icon,
duration
})
}).catch(e=>{
//console.log(e);
app.showError(e);
})
},
enterChallenge(){
wx.showLoading({
@ -42,29 +64,30 @@ Page({
let {description, challenge_list:challenges} = await this.apiChallenges({identifier:this.data.identifier});
this.setData({description, challenges});
},
async pullShixun(){
async pullShixun({showLoading=1}={}){
if(showLoading)
wx.showLoading({
title: '努力加载中'
})
let {identifier} = this.data;
let shixun = await this.apiShixun({identifier});
this.setData({shixun});
this.setData({shixun}, res=>{
if(showLoading)
wx.hideLoading()
});
},
onLoad: function (options) {
let {identifier,cate_type} = options;
let current = cateTypes[cate_type];
this.setData({identifier, current});
this.pullChallenges();
this.pullShixun();
},
onShow: function () {
app.syncUser().then(res=>{
this.setData({user:res.user});
})
},
onPullDownRefresh: function () {
this.pullChallenges().catch(e=>{
});
this.pullShixun().catch(e=>{
app.showError(e);
});
},
onReachBottom: function () {
},
onShareAppMessage: function () {
return app.shareApp({
title:this.data.shixun.name,

@ -7,5 +7,5 @@
},
"navigationBarBackgroundColor": "#0080f0",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "实训详情"
"navigationBarTitleText": "实训项目"
}

@ -1,6 +1,6 @@
<page-meta>
<!--page-meta>
<navigation-bar title="{{shixun.name}}"/>
</page-meta>
</page-meta-->
<wxs src="./shixun.wxs" module="handler"/>
<view class="header">
<view class="shixun-title">{{shixun.name}}</view>
@ -19,7 +19,7 @@
</view>
</view>
</view>
<require-login bg="#00b0f0" message="点击登陆,可以获取更多内容哦"/>
<require-login bg="#00b0f0" bindchange="pullShixun" message="点击登陆,可以获取更多内容哦"/>
<nav-bar list="{{list}}" current="{{current}}" type="line" bindchange="switchNav"/>
<swiper class="body" current="{{current}}" bindchange="switchNav" circular="1">
<swiper-item>
@ -44,5 +44,6 @@
</swiper-item>
</swiper>
<view wx:if="{{shixun.task_operation[0]}}" class="operations">
<button class="collect" bindtap="collect" type="main" plain>{{shixun.is_collect?'已收藏':'收藏'}}</button>
<button bindtap="enterChallenge" loading="{{loading}}" disabled="{{loading}}" type="main">{{shixun.task_operation[0]}}</button>
</view>

@ -1,6 +1,6 @@
var top = 126;
var top = 140;
function scroll(e, ins){
var scrollTop = e.detail.scrollTop;
//var scrollTop = e.detail.scrollTop;
var deltaY = e.detail.deltaY;
//console.log(scrollTop);
//console.log(show,scrollTop<122);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save