A 增加在线竞赛模块、省流模式

master
educoder_weapp 4 years ago
parent 222e364f48
commit 74bd7c5c9e

@ -1,3 +1,15 @@
## v0.18.0
* A 添加在线竞赛模块
* A 添加省流模式
* A 增加设置界面
* U 完善markdown网址解析功能
## v0.17.1
* A 增加分享朋友圈
* A 添加收藏时的封面图
* A 配置代码懒注入
## v0.17.0
* A 增加开源版本库查看

@ -153,7 +153,7 @@ exports.main = async (event, context) => {
value:"pageHistory" //服务器
},
character_string2:{
value: data.page.match(/\/([^\/]*$)/)[1] //数据类型
value: (data.route||data.page).match(/\/([^\/]*$)/)[1] //数据类型
},
thing4:{
value:sceneDescMap[data.scene].slice(0,20) //添加内容

@ -15,6 +15,10 @@
"name": "clearPageHistory",
"type":"timer",
"config":"0 0 3 1 * * *"
},{
"name":"attendance",
"type":"timer",
"config":"0 0 4 * * * *"
}
]
}

@ -1,4 +1,7 @@
const cloud = require('wx-server-sdk');
//const got = require("got");
//const rp = require("request-promise")
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
@ -31,6 +34,9 @@ exports.main = async (event, context) => {
case "clearPageHistory":{
return clearPageHistory({Time});
}
case "attandance":{
return attandance({Time});
}
}
}
@ -121,4 +127,16 @@ async function clearPageHistory({Time}){
console.log("remove page History result: ", res);
return {code: 0, message:"success", data:res};
}
async function attandance({Time}){
/**let postResponse = await got(url, {
method: 'GET', //post请求
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
})
})**/
}

@ -50,6 +50,34 @@ App({
});
});
},
reportPageHistory:function({page, route, scene, status, options}){
let data = {}
page = page||getCurrentPages()[getCurrentPages().length-1];
if(page){
Object.assign(data,
{
route: page.route,
page: page.route, //@desprate
scene: this.globalData.scene,
status: 200,
options: page.options
})
}
if(route){
data.page = data.route = route;
}
if(scene)
data.scene = scene;
if(status)
data.status = status;
if(options)
data.options = options;
this.cloudapi("reportPageHistory")(data).catch(e=>{
global.realTimeLog.error("report history error", e);
wx.reportMonitor('2', 1);
})
},
realTimeLog:global.realTimeLog,
api(name, config) { return client.api(name, config) },
callApi(options) { return client.callApi(options) },
@ -115,7 +143,11 @@ App({
}
}).catch(e=>{});
*/
if(global.config.saveFlow){
wx.showToast({
title: '省流模式已开启,默认不加载图片',icon:"none",duration:2600
})
}
},
onShow() {
if (client.user_id && client.user_id != 2)
@ -179,6 +211,7 @@ App({
addToFavorites({title, query, imageUrl}={}){
let db = wx.cloud.database();
let data = {
type:"addToFavorites",
title,
imageUrl,
query,
@ -187,7 +220,7 @@ App({
time: db.serverDate()
}
db.collection("shareInfo").add({
type:"addToFavorites",
data
});
return {
@ -197,6 +230,7 @@ App({
shareTimeline({title, query, imageUrl}={}){
let db = wx.cloud.database();
let data = {
type:"shareTimeline",
title,
imageUrl,
query,
@ -205,7 +239,6 @@ App({
time: db.serverDate()
}
db.collection("shareInfo").add({
type:"shareTimeline",
data
});
return {
@ -229,6 +262,7 @@ App({
path = "/" + route + (query ? ('?' + query) : '');
}
let data = {
type:"shareAppMessage",
title,
imageUrl,
path,
@ -238,7 +272,7 @@ App({
}
console.log("upload", data);
db.collection("shareInfo").add({
type:"shareAppMessage",
data
});
}
@ -278,4 +312,3 @@ function toAbsPath(current, path) {
return path;
}
*/

@ -8,16 +8,22 @@
},
"usingComponents": {
"iconfont": "/components/iconfont/iconfont",
"require-login": "/components/require-login/require-login"
"require-login": "/components/require-login/require-login",
"mp-icon": "/weui-miniprogram/icon/icon"
},
"pages": [
"pages/main/main",
"pages/findmore/findmore",
"pages/home/home",
"pages/tidings/tidings",
"competition/pages/competition/competition"
"pages/tidings/tidings"
],
"subpackages": [
{
"root":"competition",
"pages":[
"pages/competitions/competitions"
]
},
{
"root": "project",
"pages": [
@ -38,6 +44,7 @@
"account/about/about",
"account/agreement/agreement",
"account/pro_authentication/pro_authentication",
"competition/competition/competition",
"exercise/exercise/exercise",
"path/path/path",
"path/path_send/path_send",
@ -186,5 +193,5 @@
"themeLocation": "theme.json",
"lazyCodeLoading": "requiredComponents",
"style": "v2",
"debug":true
"debug": true
}

@ -1,15 +0,0 @@
import apiConfig from "../js/apiConfig"
Object.assign(apiConfig,
{
competitions:{
common_header:{url:"{identifier}/*"},
competition_staff:{url:"{identifier}/*"},
competition_modules:{url:"{identifier}/*/{module_id}"},
}
})
export default apiConfig;

@ -1,2 +0,0 @@
<!--miniprogram/competition/pages/competition/competition.wxml-->
<text>miniprogram/competition/pages/competition/competition.wxml</text>

@ -1 +0,0 @@
/* miniprogram/competition/pages/competition/competition.wxss */

@ -0,0 +1,27 @@
const app = getApp();
Component({
/**
* 组件的属性列表
*/
properties: {
data:Object
},
/**
* 组件的初始数据
*/
data: {
eduUrl: global.config.eduUrl
},
methods: {
previewImage(){
let url = this.data.eduUrl +"/"+this.data.data.image;
wx.previewImage({
urls: [url],
})
}
}
})

@ -0,0 +1,9 @@
<navigator class="item-container" hover-class="none" url="/markdown/competition/competition/competition?identifier={{data.identifier}}">
<view class="image-wrp" catchtap="previewImage">
<image class="item-image" lazy-load mode="heightFix" src="{{eduUrl}}/{{data.image}}"></image>
</view>
<view class="item-detail">
<view>{{data.name}}</view>
<view class="tip">竞赛时间:{{data.start_time}}~{{data.end_time}}</view>
</view>
</navigator>

@ -0,0 +1,30 @@
.item-container{
padding: 10px 12px;
display: flex;
background: white;
align-items: center;
}
.item-detail{
display: flex;
flex-direction: column;
font-size: 15pxs;
margin-left: 12px;
}
.tip{
font-size: 12px;
color: grey;
}
.image-wrp{
flex: none;
width: 200rpx;
height: 110rpx;
overflow:hidden;
border-radius: 4px;
}
.item-image{
height: 100%;
width: 128.2%;
background: lightblue;
}

@ -1,13 +1,20 @@
import apiConfig from "../../apiConfig"
const app = getApp();
Page({
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
app.reportPageHistory({page: this})
app.api("competitions")()
.then(res=>{
this.setData(res);
})
.catch(app.showError)
},
/**
@ -52,10 +59,12 @@ Page({
},
onShareTimeline:function(){
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
return app.shareApp({
title:"EduCoder在线竞赛"
})
}
})

@ -0,0 +1,6 @@
{
"usingComponents": {
"competition-item":"./competition-item/competition-item"
},
"navigationBarTitleText": "在线竞赛"
}

@ -0,0 +1,5 @@
<view class="list-view">
<view class="item-wrp" wx:for="{{competitions}}">
<competition-item data="{{item}}"/>
</view>
</view>

@ -0,0 +1,6 @@
.item-list{
background: #f0f0f0;
}
.item-wrp{
margin-top: 5px;
}

@ -1,11 +1,11 @@
@font-face {
font-family: 'iconfont'; /* project id 1656783 */
src: url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.eot');
src: url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.woff') format('woff'),
url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1656783_pkasgj0rzun.svg#iconfont') format('svg');
src: url('//at.alicdn.com/t/font_1656783_5uvt676wssl.eot');
src: url('//at.alicdn.com/t/font_1656783_5uvt676wssl.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1656783_5uvt676wssl.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1656783_5uvt676wssl.woff') format('woff'),
url('//at.alicdn.com/t/font_1656783_5uvt676wssl.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1656783_5uvt676wssl.svg#iconfont') format('svg');
}
.iconfont {
display: inline-block;
@ -139,4 +139,6 @@
.icon-filter:before {
content: "\e6c7";
}
.icon-jingsai:before{
content:"\e702";
}

@ -1,6 +1,6 @@
const cloudDir = "cloud://educoder.6564-educoder-1300855313/";
let _version = "0.17.0";
let _version = "0.18.0";
let { miniProgram:{ envVersion="release", version=_version}={}} = wx.getAccountInfoSync();
version = version||_version;
@ -32,13 +32,24 @@ export function switchEnv(env) {
const config = global.config = {
version,
envVersion,
saveFlow: wx.getStorageSync('saveFlow'),
env:envVersion,
get apiRoot(){return eduUrl + "/api/"},
get attachDir(){return eduUrl + "/api/attachments/"},
cloudDir,
get eduUrl(){return eduUrl},
get eduUrl(){
if(!config.saveFlow)
return eduUrl
else
return ""
},
imgDir: cloudDir + "images/",
get eduImgDir(){ return eduUrl + "/images/"},
get eduImgDir(){
if(!config.saveFlow)
return eduUrl + "/images/"
else
return ""
},
switchEnv,
pages:[
"exercise/pages/exercise_setting/exercise_setting",

@ -12,8 +12,7 @@
"join-course":"/components/modal/join-course/join-course",
"error-page":"/components/error-page/error-page",
"mp-tabbar": "weui-miniprogram/tabbar/tabbar",
"mp-halfScreenDialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog",
"mp-icon": "/weui-miniprogram/icon/icon"
"mp-halfScreenDialog": "weui-miniprogram/half-screen-dialog/half-screen-dialog"
},
"navigationStyle": "custom",
"navigationBarTextStyle": "white",

@ -30,6 +30,7 @@ export class Session{
url,
header: {...header, "Cookie": this.cookies},
success: (res) => {
console.debug("request success", res);
if (res.cookies && res.cookies.length>0)
this.setCookies(res.cookies);
else if (res.header["Set-Cookie"])
@ -122,7 +123,7 @@ export function triggerApi({session, name, data:_data = {}, success, fail, compl
if(url){
if(url._)
url = url[method||"GET"]||url._;
url = name.replace(/\.?[^\.]+$|\./g, "/") + url.replace(/\{(.*?)\}/, function (match, k) {
url = name.replace(/\.?[^\.]+$|\./g, "/") + url.replace(/\{(.*?)\}/g, function (match, k) {
return _data[k];
}).replace(/\*/g,key);
}else

@ -20,6 +20,13 @@ attachments:{url:{_:1,DELETE:'*/{attachment_id}',uploadFile:"*"},query,form:{_:1
collections:{config, query, form:{container_id: null, container_type: null},
cancel:{query, config:{method:"DELETE", form:{container_id: null, container_type: null}}},
},
competitions:{ form:{page:1, per_page:15, category:void 0}, data:{category:"nearly_published, progressing, ended"},
common_header:{url:"{identifier}/*"},
competition_staff:{url:"{identifier}/*"},
competition_modules:{url:"{identifier}/*/{module_id}"},
},
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},

@ -230,7 +230,7 @@ export function parseUrl({url}){
return '';
const route = match[1]; // 路径
// case 1:
match = route.match(/shixuns\/(.*)\/challenges\/(.*)/);
match = route.match(/shixuns\/([^\/]*)/);
if(match){
var identifier = match[1]
return `{shixun}?identifier=${identifier}&cate_type=task`
@ -239,13 +239,47 @@ export function parseUrl({url}){
}
export function navigateToUrl({url,open_type='navigateTo'}){
url = parseUrl({url});
console.log("parse url ...",url);
let path = parseUrl({url});
const app = getApp();
if(url){
app.navigateTo({url});
if(path){
app.navigateTo({url:path});
return true;
}else
}else{
var match = url.match(/api\/attachments\/([0-9]*)/);
console.log(url,match)
if(match){
wx.showLoading({
title: '加载中'
});
wx.downloadFile({
url: 'https://www.educoder.net/api/attachments/'+match[1],
success: res=>{
wx.openDocument({
filePath: res.tempFilePath,
showMenu: true,
complete: res=>{
wx.hideLoading()
},
fail:e=>{
wx.showToast({
title:"暂不支持预览",icon:"none"
})
}
})
},
fail:e=>{
wx.hideLoading();
wx.showToast({
title: '下载失败',icon:"none"
})
}
})
return true
}
return false;
}
}
export function throttle(func, wait, options) {

@ -0,0 +1,127 @@
const app = getApp();
Page({
data: {
},
onLoad: function (options) {
app.reportPageHistory({page:this});
this.pullData();
},
async pullData(){
let header = await app.api("competitions.common_header")({identifier: this.options.identifier}).catch(app.showError);
header.modules = []
for(var m of header.competition_modules){
if(m.module_type=='enroll')
continue;
m.text = m.name;
header.modules.push(m);
}
this.setData(header);
try{
wx.showLoading({title: '加载中'});
let module = await app.api("competitions.competition_modules")({
identifier: this.options.identifier,
module_id: header.modules[0].id});
this.setData({module});
}catch(e){
app.showError(e);
}
wx.hideLoading()
},
onNavChange(e){
console.log(e);
let {detail:{value:{id}}} = e;
wx.showNavigationBarLoading();
app.api("competitions.competition_modules")(
{
identifier: this.options.identifier,
module_id: id
})
.then(res=>{
this.setData({module:res});
}).finally(()=>{
wx.hideNavigationBarLoading({});
});
},
onTapAttachment(e){
console.log(e);
let {currentTarget:{dataset:{url}}} = e;
console.log(url);
url = "https://www.educoder.net"+url;
wx.downloadFile({
url,
success: res=>{
wx.openDocument({
filePath: res.tempFilePath,
showMenu: true
})
}
})
},
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
onAddToFavorites:function(){
let {name, sub_title, avatar_url} = this.data
return app.addToFavorites({
title: "「在线竞赛」"+name+(sub_title?("--"+sub_title):""),
imageUrl:global.config.eduUrl+"/"+avatar_url
})
},
onShareTimeline:function(){
let {name, sub_title, avatar_url} = this.data
return app.shareTimeline({
title: "「在线竞赛」"+name+(sub_title?("--"+sub_title):""),
imageUrl:global.config.eduUrl+"/"+avatar_url
})
},
onShareAppMessage: function () {
let {name, sub_title, avatar_url} = this.data
return app.shareApp({
title: "「在线竞赛」"+name+(sub_title?("--"+sub_title):""),
imageUrl:global.config.eduUrl+"/"+avatar_url
})
}
})

@ -0,0 +1,7 @@
{
"usingComponents": {
"nav-bar":"/components/nav-bar/nav-bar",
"rich-md":"../../components/rich-md/rich-md"
},
"navigationBarTitleText": "在线竞赛"
}

@ -0,0 +1,16 @@
<page-meta>
<navigation-bar title="{{name+(sub_title?('--'+sub_title):'')}}"/>
</page-meta>
<view>
<view class="sticky-top">
<nav-bar list="{{modules}}" type="line" bindchange="onNavChange"/>
</view>
<rich-md nodes="{{module.md_content}}" type="markdown"/>
<view class="attachments">
<view class="attachment-item" wx:for="{{module.attachments}}" bindtap="onTapAttachment" data-url="{{item.url}}">
<mp-icon icon="link" type="field" color="#002389"/>{{item.title}}
</view>
</view>
</view>

@ -0,0 +1,15 @@
.sticky-top{
position: sticky;
top: 0;
background: white;
padding-bottom: 3px;
}
.attachments{
text-decoration: underline;
font-size: 15px;
color: #003190;
}
.attachment-item{
padding: 8px;
}

@ -32,12 +32,16 @@
</view>
<view class="nav-list" bindtap="enterPage">
<navigator target="miniProgram" app-id="wx2402d86a6b534f77" class="nav gap educoder">
<navigator target="miniProgram" app-id="wx2402d86a6b534f77" class="nav educoder">
<image src="{{attachDir}}872467" class="icon"></image>
EduCoder云网
<text class="tip">推荐使用</text>
<iconfont type="jinru" color="dimgrey" size="15" class="enter"/>
</navigator>
<navigator url="/competition/pages/competitions/competitions" class="nav gap">
<iconfont class="icon" type="jingsai" size="21" />在线竞赛
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</navigator>
<view class="nav enter" data-path="change_password">
<iconfont class="icon" type="xiugaimima" size="21" />修改密码
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
@ -53,21 +57,21 @@
<button open-type="feedback" class="nav" style="width:auto">
<iconfont class="icon" type="fankui" size="21" />小程序反馈
<text class="tip">有问题,来反馈</text>
<text class="tip">有建议,来反馈</text>
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</button>
<button open-type="contact" class="nav" style="width:auto">
<iconfont class="icon" type="kefu" size="21" />小程序客服
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</button>
<navigator wx:if="{{false}}" class="nav" url="/setting/pages/setting/setting">
<navigator class="nav gap" url="/setting/pages/setting/setting">
<iconfont type="shezhi" class="icon" size="21"/>设置
<iconfont type="jinru" color="dimgrey" size="15" class="enter"/>
</navigator>
<navigator url="/markdown/account/about/about" class="nav about gap">
<!--navigator url="/markdown/account/about/about" class="nav about gap">
<iconfont class="icon" type="guanyu" size="21" />关于
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</navigator>
</navigator-->
<navigator class="nav" bindlongpress="enterUserinfo" url="/account/pages/accounts/accounts">
<iconfont class="icon" size="21" type="qiehuanzhanghao" />切换账号
<text class="tip">{{currentLogin}}</text>

@ -5,12 +5,24 @@ Page({
* 页面的初始数据
*/
data: {
saveFlow: global.config.saveFlow
},
/**
* 生命周期函数--监听页面加载
*/
onChangeSaveFlow:function(e){
console.log(e);
let {detail:{value}} = e;
global.config.saveFlow = value;
wx.setStorageSync("saveFlow", value);
wx.showToast({
title: '重启小程序后生效',icon:"none"
})
this.setData({requireRelaunch: true});
},
reLaunch(){
wx.reLaunch({
url: "/"+__wxConfig.pages[0],
})
},
onLoad: function (options) {
},
@ -49,18 +61,7 @@ Page({
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -1,2 +1,4 @@
<!--miniprogram/setting/pages/setting/setting.wxml-->
<text>miniprogram/setting/pages/setting/setting.wxml</text>
<view>
<switch class="save-flow" checked="{{saveFlow}}" color="#00b0f0" bindchange="onChangeSaveFlow">省流模式(内测功能)</switch>
</view>
<!--navigator wx:if="{{requireRelaunch}}" target="miniProgram" open-type="exit">立即重启小程序</navigator-->

@ -262,6 +262,13 @@
"pathName": "markdown/admin/git_repo/git_repo",
"query": "",
"scene": null
},
{
"id": -1,
"name": "competitions",
"pathName": "competition/pages/competitions/competitions",
"query": "course_id=7845&module_type=students",
"scene": null
}
]
}

Loading…
Cancel
Save