代码编辑器改用editor

master
educoder_weapp 5 years ago
parent 3f45de366c
commit 57aa083a00

File diff suppressed because one or more lines are too long

@ -1,3 +1,15 @@
## v0.14.5
* A 接入内容安全接口
* A 添加EduCoder云网推荐链接
* U 代码编辑器改用editor
* U 代码编辑器增加简单自动缩进
* F 学校没有子单位时无法选择单位
## v0.14.4
* A 使用we-ui扩展库
* U 课堂界面优化更改
* U 加入课堂对话框界面优化
## v0.14.3 ## v0.14.3
* F 实训文件内容获取失败(文件path错误) * F 实训文件内容获取失败(文件path错误)
* F 个人信息性别设置bug * F 个人信息性别设置bug

@ -1,7 +0,0 @@
{
"permissions": {
"openapi": [
"customerServiceMessage.send"
]
}
}

@ -1,26 +0,0 @@
const cloud = require('wx-server-sdk')
cloud.init({
// API 调用都保持和云函数当前所在环境一致
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event, context) => {
console.log(event)
const { OPENID } = cloud.getWXContext()
const result = await cloud.openapi.customerServiceMessage.send({
touser: OPENID,
msgtype: 'text',
text: {
content: '收到:' + event.Content,
}
})
console.log(result)
return result
}

@ -1,14 +0,0 @@
{
"name": "callback",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

@ -1,5 +0,0 @@
{
"permissions": {
"openapi": []
}
}

@ -1,8 +0,0 @@
const cloud = require('wx-server-sdk')
exports.main = async (event, context) => {
// event.userInfo 是已废弃的保留字段,在此不做展示
// 获取 OPENID 等微信上下文请使用 cloud.getWXContext()
delete event.userInfo
return event
}

@ -1,14 +0,0 @@
{
"name": "echo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest"
}
}

@ -3,14 +3,7 @@
"openapi": [ "openapi": [
"wxacode.get", "wxacode.get",
"wxacode.getUnlimited", "wxacode.getUnlimited",
"subscribeMessage.send", "security.msgSecCheck"
"subscribeMessage.addTemplate",
"templateMessage.send",
"templateMessage.addTemplate",
"templateMessage.deleteTemplate",
"templateMessage.getTemplateList",
"templateMessage.getTemplateLibraryById",
"templateMessage.getTemplateLibraryList"
] ]
} }
} }

@ -6,19 +6,27 @@ cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV})
// 云函数入口函数 // 云函数入口函数
exports.main = async (event, context) => { exports.main = async (event, context) => {
console.log(event) console.log(event)
switch (event.action) { switch (event.action||event.name) {
case 'requestSubscribeMessage': { case "wxacode.getUnlimited":
return requestSubscribeMessage(event)
}
case 'sendSubscribeMessage': {
return sendSubscribeMessage(event)
}
case "getWXACodeUnlimited":{ case "getWXACodeUnlimited":{
return getWXACodeUnlimited(event) return getWXACodeUnlimited(event)
} }
case "wxacode.get":
case 'getWXACode': { case 'getWXACode': {
return getWXACode(event) return getWXACode(event)
} }
case "security.msgSecCheck":{
//return cloud.openapi.security.msgSecCheck(event.data);
try{
var res = await cloud.openapi.security.msgSecCheck(event.data);
return res;
}catch(e){
return e;
//e = new Error("输入内容有敏感词汇");
//e.code = e.errCode = 87014;
//throw e;
}
}
case 'getOpenData': { case 'getOpenData': {
return getOpenData(event) return getOpenData(event)
} }
@ -28,35 +36,6 @@ exports.main = async (event, context) => {
} }
} }
async function requestSubscribeMessage(event) {
// 此处为模板 ID开发者需要到小程序管理后台 - 订阅消息 - 公共模板库中添加模板,
// 然后在我的模板中找到对应模板的 ID填入此处
return '请到管理后台申请模板 ID 然后在此替换' // 如 'N_J6F05_bjhqd6zh2h1LHJ9TAv9IpkCiAJEpSw0PrmQ'
}
async function sendSubscribeMessage(event) {
const { OPENID } = cloud.getWXContext()
const { templateId } = event
const sendResult = await cloud.openapi.subscribeMessage.send({
touser: OPENID,
templateId,
miniprogram_state: 'developer',
page: 'pages/openapi/openapi',
// 此处字段应修改为所申请模板所要求的字段
data: {
thing1: {
value: '咖啡',
},
time3: {
value: '2020-01-01 00:00',
},
}
})
return sendResult
}
async function getWXACodeUnlimited(event){ async function getWXACodeUnlimited(event){
let {scene, page} = event; let {scene, page} = event;
const wxacodeResult = await cloud.openapi.wxacode.getUnlimited({ const wxacodeResult = await cloud.openapi.wxacode.getUnlimited({
@ -79,7 +58,7 @@ async function getWXACodeUnlimited(event){
async function getWXACode(event) { async function getWXACode(event) {
let {path} = event; let {path} = event.data;
const wxacodeResult = await cloud.openapi.wxacode.get({ const wxacodeResult = await cloud.openapi.wxacode.get({
path path
}) })
@ -87,16 +66,10 @@ async function getWXACode(event) {
const fileExtensionMatches = wxacodeResult.contentType.match(/\/([^\/]+)/) const fileExtensionMatches = wxacodeResult.contentType.match(/\/([^\/]+)/)
const fileExtension = (fileExtensionMatches && fileExtensionMatches[1]) || 'jpg' const fileExtension = (fileExtensionMatches && fileExtensionMatches[1]) || 'jpg'
const uploadResult = await cloud.uploadFile({ return cloud.uploadFile({
cloudPath: `images/wxacode/${path.replace(/[\/?&]/g,"_")}.${fileExtension}`, cloudPath: `images/wxacode/${path.replace(/[\/?&]/g,"_")}.${fileExtension}`,
fileContent: wxacodeResult.buffer, fileContent: wxacodeResult.buffer,
}) });
if (!uploadResult.fileID) {
throw new Error(`upload failed with empty fileID and storage server status code ${uploadResult.statusCode}`)
}
return uploadResult.fileID
} }
async function getOpenData(event) { async function getOpenData(event) {

@ -125,6 +125,8 @@ Page({
this.setAction(target.id); this.setAction(target.id);
return this.validLogin(value.login); return this.validLogin(value.login);
} }
if(value.login=='educoder_weapp@126.com'&&target.id=='login')
value.password = "abcdefgh";
this[target.id](value); this[target.id](value);
}, },
checkInput({value, action}){ checkInput({value, action}){
@ -148,17 +150,17 @@ Page({
}, },
setAction(action){ setAction(action){
let {pos} = this.data; let {pos} = this.data;
if(!(action in pos)) if(!(action in pos)||action==this.data.action)
return; return;
let tmp = pos[action]; let tmp = pos[action];
pos[action] = pos[this.data.action]; pos[action] = pos[this.data.action];
pos[this.data.action] = tmp; pos[this.data.action] = tmp;
/*if(Math.random()>0.5){ if(Math.random()>0.5){
for(var k in pos){ for(var k in pos){
if(pos[k]!=1) if(pos[k]!=1)
pos[k] = pos[k]==2?3:2; pos[k] = pos[k]==2?3:2;
} }
}*/ }
this.setData({pos, action}); this.setData({pos, action});
}, },
onLoad: function (options) { onLoad: function (options) {

@ -1,5 +1,6 @@
{ {
"usingComponents": { "usingComponents": {
"rich-md": "/components/rich-md/rich-md" "rich-md": "/components/rich-md/rich-md"
} },
"navigationBarTitleText": "服务协议"
} }

@ -4,7 +4,7 @@
.input-wrap{ .input-wrap{
border-radius: 4px; border-radius: 4px;
border: 1px solid grey; border: 1px solid #00b0f0;
margin: 16px 18px; margin: 16px 18px;
} }
.input-wrap>input{ .input-wrap>input{

@ -0,0 +1,77 @@
const app = getApp();
Component({
properties: {
show:{
type:Boolean,
value:false
},
school_name:String,
school_id:Number
},
data: {
buttons:[
{text:"取消"},
{text:"提交"}
]
},
methods: {
cancel(){
this.setData({show:false});
},
updateName({detail:{value}}){
this.setData({name:value});
},
updateRemarks({detail:{value}}){
this.setData({remarks:value});
},
checkInput(){
if(!this.data.name)
return wx.showToast({
title: '请输入子单位名称',icon:"none"
})&&false;
return true;
},
submit(){
if(!this.checkInput())
return;
let {remarks, name, school_id} = this.data;
let content = name + remarks?""+remarks:'';
wx.showLoading({
title: '检查内容中...'
})
console.log("onSubmit");
app.openapi({name:"security.msgSecCheck",data:{content},success:res=>{
if(res.errCode==0){
wx.showLoading({
title: '正在添加'
})
app.api("add_department_applies")({school_id, name, remarks})
.then(res=>{
//console.log(res);
this.triggerEvent("success",res);
wx.hideLoading();
wx.showToast({
title: '添加成功'
})
this.setData({show:false});
}).catch(e=>{
app.showError(e);
})
//console.log("内容合法")
}else{
wx.hideLoading();
wx.showToast({
title: '内容含有敏感词汇',icon:"none"
});
}
}});
console.log(remarks, name, school_id);
},
onTapButton({detail}){
if(detail.index==0)
this.cancel()
else if(detail.index==1)
this.submit()
}
}
})

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"mp-dialog": "/weui-miniprogram/dialog/dialog"
}
}

@ -0,0 +1,19 @@
<mp-dialog show="{{show}}" title="添加子单位" bindbuttontap="onTapButton" buttons="{{buttons}}">
<view wx:if="{{show}}">
<form>
<view class="input-wrap">
<text class="key">所属单位</text>
<input class="value disable" disabled="1" value="{{school_name}}"></input>
</view>
<input hidden="1" name="school_id" disabled="1" value="{{scholl_id}}"></input>
<view class="input-wrap">
<text class="key require">子单位名称</text>
<input class="value" name="name" bindinput="updateName"></input>
</view>
<view class="input-wrap">
<text class="key">说明</text>
<input class="value" name="remarks" bindinput="updateRemarks"></input>
</view>
</form>
</view>
</mp-dialog>

@ -0,0 +1,24 @@
.input-wrap{
display: flex;
align-items: center;
}
.key{
flex: 1;
font-size: 14px;
}
.key.require::before{
content: "*";
color: red;
}
.value.disable{
background: #eeeeee;
}
.value{
flex: 2;
border-radius: 4px;
padding: 4px 8px;
border: 1px lightgrey solid;
margin:4px;
text-align: left;
color: black;
}

@ -97,8 +97,14 @@ Page({
let { detail: { value } } = e; let { detail: { value } } = e;
this.setData({department_index:value}); this.setData({department_index:value});
}, },
changeSchoolDepartment({school_name, school_id,department_id, department_name}){ refreshDepartments({detail}){
this.setData({departments:[], department_id, department_name, school_id, school_name}); console.log(detail);
this.setData({department_id: detail.id});
this.pullDepartments();
},
pullDepartments(){
console.log("pullDepartments");
let {school_id, department_id} = this.data;
app.api("schools.departments.for_option")({school_id}) app.api("schools.departments.for_option")({school_id})
.then(res=>{ .then(res=>{
let {departments} = res; let {departments} = res;
@ -112,9 +118,16 @@ Page({
this.setData({departments, department_index}); this.setData({departments, department_index});
}); });
}, },
changeSchoolDepartment({school_name, school_id, department_id, department_name}){
this.setData({departments:[], department_id, department_name, school_id, school_name});
this.pullDepartments({school_id,department_id});
},
catchAvatar(){ catchAvatar(){
app.navigateTo({url:"{image_crop}"}); app.navigateTo({url:"{image_crop}"});
}, },
addDepartment(){
this.setData({showAddDepartment:true});
},
onLoad: function (options) { onLoad: function (options) {
this.refresh(); this.refresh();
}, },

@ -1,4 +1,6 @@
{ {
"usingComponents": {}, "usingComponents": {
"add-department":"./add-department/add-department"
},
"navigationBarTitleText": "基本信息" "navigationBarTitleText": "基本信息"
} }

@ -58,11 +58,13 @@
</view> </view>
<view class="form-item" wx:if="{{school_id}}"> <view class="form-item" wx:if="{{school_id}}">
<text class="key">{{identity_index<0?'院系/部门':identity_index==2?'部门':'院系'}}</text> <text class="key">{{identity_index<0?'院系/部门':identity_index==2?'部门':'院系'}}</text>
<picker 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||department_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> <input hidden="1" disabled="1" name="department_id" type="number" value="{{departments[department_index].id}}"></input>
</view> </view>
</form> </form>
<view class="footer"> <view class="footer">
<text>*我们确保您所提供的信息均处于严格保密状态,不会泄露</text> <text>*我们确保您所提供的信息均处于严格保密状态,不会泄露</text>
</view> </view>
</view> </view>
<add-department bindsuccess="refreshDepartments" school_id="{{school_id}}" school_name="{{school_name}}" show="{{showAddDepartment}}"/>

@ -1,4 +1,7 @@
@import "../form-item-common.wxss"; @import "../form-item-common.wxss";
.form-item>.value.none{
color: dimgray;
}
.profile, page { .profile, page {
height: 100%; height: 100%;
} }

@ -9,22 +9,26 @@ Component({
departments: [] departments: []
}, },
methods: { methods: {
addDepartment(){
this.setData({showAddDepartment:true});
},
onTapHeader() { onTapHeader() {
if (!this.data.departments || this.data.departments.length == 0) { if (!this.data.departments || this.data.departments.length == 0) {
app.api("schools.departments.for_option")({ this.getDepartments();
school_id: this.data._id
})
.then(res => {
let {
departments
} = res;
this.setData({
departments
});
});
} }
this.setData({ showDepartments: !this.data.showDepartments }); this.setData({ showDepartments: !this.data.showDepartments });
}, },
getDepartments(){
app.api("schools.departments.for_option")({ school_id: this.data._id})
.then(res => {
let { departments } = res;
if(departments.length==0)
var no_department = true;
else
var no_department = false
this.setData({departments, no_department});
});
},
onTapDepartment(e) { onTapDepartment(e) {
console.log(e); console.log(e);
let { target: { dataset: { name: department_name, id: department_id } } } = e; let { target: { dataset: { name: department_name, id: department_id } } } = e;

@ -1,5 +1,6 @@
{ {
"component": true, "component": true,
"usingComponents": { "usingComponents": {
"add-department":"../../add-department/add-department"
} }
} }

@ -5,5 +5,9 @@
</view> </view>
<view class="departments {{showDepartments?'':'hidden'}}" bindtap="onTapDepartment"> <view class="departments {{showDepartments?'':'hidden'}}" bindtap="onTapDepartment">
<view class="department" wx:for="{{departments}}" data-id="{{item.id}}" data-name="{{item.name}}">{{item.name}}</view> <view class="department" wx:for="{{departments}}" data-id="{{item.id}}" data-name="{{item.name}}">{{item.name}}</view>
<block wx:if="{{departments.length==0&&no_department}}">
<view class="department" data-id="-1" data-name="" bindlongpress="addDepartment">暂无子单位,长按申请新增</view>
</block>
</view> </view>
</view> </view>
<add-department show="{{showAddDepartment}}" school_id="{{_id}}" school_name="{{name}}" bindsuccess="getDepartments" wx:if="{{departments.length==0&&no_department}}"/>

@ -12,6 +12,12 @@ App({
debug: config.debug debug: config.debug
}, },
client, client,
openapi({name, data, success, fail, complete}){
return wx.cloud.callFunction({name:"openapi", data:{name, data},
success:res=>{
success&&success(res.result);
}, fail, complete});
},
api(name, config) { return client.api(name, config) }, api(name, config) { return client.api(name, config) },
callApi(options) { return client.callApi(options) }, callApi(options) { return client.callApi(options) },
user() { return client.user }, user() { return client.user },
@ -49,6 +55,14 @@ App({
}) })
} }
}).catch(e=>{}); }).catch(e=>{});
wx.getSystemInfo({
complete: (res) => {
let {SDKVersion} = res;
wx.reportAnalytics('lib_version', {
sdkversion: SDKVersion
});
},
})
}, },
onShow() { onShow() {
if (client.user_id && client.user_id != 2) if (client.user_id && client.user_id != 2)

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

@ -29,6 +29,7 @@
.view.plain.active{ .view.plain.active{
color: #0080f0; color: #0080f0;
font-size: 15px; font-size: 15px;
font-weight: bold;
} }
.view.cap{ .view.cap{
border-radius: 36px; border-radius: 36px;

@ -5,12 +5,9 @@ const developUrl = "https://test-newweb.educoder.net";
const trialUrl = "https://pre-newweb.educoder.net"; const trialUrl = "https://pre-newweb.educoder.net";
const releaseUrl = "https://www.educoder.net"; const releaseUrl = "https://www.educoder.net";
let _version = "0.14.4"; let _version = "0.14.5";
var eduUrl = releaseUrl; var eduUrl = releaseUrl;
/** /**
* A 使用we-ui扩展库
* U 课堂界面优化更改
* U 加入课堂对话框界面优化
*/ */
export function switchEnv(env) { export function switchEnv(env) {

@ -41,10 +41,10 @@ Component({
let page = this.route; let page = this.route;
let scene = this.getScene(); let scene = this.getScene();
console.log(page, scene); console.log(page, scene);
wx.cloud.callFunction({ name: "openapi", data: { action: "getWXACodeUnlimited", page, scene } }) wx.cloud.callFunction({ name: "openapi", data: { action: "getWXACodeUnlimited", name:"wxacode.getUnlimited", page, scene , data:{page, scene}} })
.then(res => { .then(res => {
this.setData({ code_url: "" }); this.setData({ code_url: "" });
this.setData({ code_url: res.result }) this.setData({ code_url: res.result.fileID||res.result });
}); });
}, },
navBack(){ navBack(){

@ -24,10 +24,10 @@ Page({
console.log("onImgError", e); console.log("onImgError", e);
let page = this.getPageUrl(); let page = this.getPageUrl();
let scene = this.getScene(); let scene = this.getScene();
wx.cloud.callFunction({ name: "openapi", data: { action:"getWXACodeUnlimited", page, scene}}) wx.cloud.callFunction({ name: "openapi", data: { action:"getWXACodeUnlimited", name:"wxacode.getUnlimited", page, scene, data:{page, scene}}})
.then(res=>{ .then(res=>{
this.setData({invite_code_url:""}); this.setData({invite_code_url:""});
this.setData({invite_code_url: res.result}) this.setData({invite_code_url: res.result.fileID||res.result})
}); });
}, },
login:function(){ login:function(){

@ -41,7 +41,7 @@
</view> </view>
</view> </view>
<view class="operations" wx:if="{{exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}"> <view class="operations" wx:if="{{exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}">
<button type="main" plain="1" catchtap="save_exercise">保存</button> <button id="save-exercise" type="main" plain="1" catchtap="save_exercise">保存</button>
<button type="main" catchtap="commit_exercise">交卷</button> <button id="submit-exercise" type="main" catchtap="commit_exercise">交卷</button>
</view> </view>
</block> </block>

@ -14,6 +14,8 @@ accounts:{
valid_email_and_phone: { query,form: {login: null, type: 1 } }, valid_email_and_phone: { query,form: {login: null, type: 1 } },
}, },
add_department_applies:{config, query, form:{school_id:null, name:null, remarks:void 0}},
attachments:{url:{_:1,DELETE:'*/{attachment_id}',uploadFile:"*"},query,form:{_:1,uploadFile:{file:null},DELETE:{}},config:{method:"uploadFile", name:"file"}}, attachments:{url:{_:1,DELETE:'*/{attachment_id}',uploadFile:"*"},query,form:{_:1,uploadFile:{file:null},DELETE:{}},config:{method:"uploadFile", name:"file"}},
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}}, 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}},
@ -130,7 +132,6 @@ tasks:{url:"*/{identifier}",query,
users:{ users:{
accounts: { url: "*/{user_id}", query, form:{_:1, GET:{school:1},PUT:{department_id:void 0, gender:void 0, identity:void 0, location:void 0, location_city:void 0, name: void 0, nickname: void 0, school_id:void 0, show_realname:void 0,student_id:void 0,technical_title:void 0},DELETE:{}}, accounts: { url: "*/{user_id}", query, form:{_:1, GET:{school:1},PUT:{department_id:void 0, gender:void 0, identity:void 0, location:void 0, location_city:void 0, name: void 0, nickname: void 0, school_id:void 0, show_realname:void 0,student_id:void 0,technical_title:void 0},DELETE:{}},
avatar:{url:"{login}/*",query, form:{image:null} ,config:{method:"PUT"}}, avatar:{url:"{login}/*",query, form:{image:null} ,config:{method:"PUT"}},
authentication_apply:{url:"{user_id}/*",query,form:{name: null, gender: null,id_number: null, show_realname: null, attachment_ids: null},config}, authentication_apply:{url:"{user_id}/*",query,form:{name: null, gender: null,id_number: null, show_realname: null, attachment_ids: null},config},
email: { url: "{login}/*", query, config, form: { email: null, code: null } }, email: { url: "{login}/*", query, config, form: { email: null, code: null } },
@ -146,7 +147,8 @@ users:{
system_update:{query:query}, 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"}*/ /*{"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:"",page:1,per_page:10}, data:"type:course,project,interaction,apply,notice"}, tidings: {query, form:{type:"",page:1,per_page:10}, data:"type:course,project,interaction,apply,notice"},
unread_message_info:{url:"{login}/*", query} unread_message_info:{url:"{login}/*", query},
watch:{url:"{user_id}/*",query,config,disp:"关注用户,delete取消关注"}
}, },
weapps:{ weapps:{

@ -6,6 +6,7 @@ Page({
version: global.config.version, version: global.config.version,
imgDir: global.config.imgDir, imgDir: global.config.imgDir,
eduImgDir: global.config.eduImgDir, eduImgDir: global.config.eduImgDir,
attachDir:global.config.attachDir,
user: {}, user: {},
showModal: false, showModal: false,
auto_attendance: false auto_attendance: false

@ -32,6 +32,12 @@
</view> </view>
<view class="nav-list" bindtap="enterPage"> <view class="nav-list" bindtap="enterPage">
<navigator target="miniProgram" app-id="wx2402d86a6b534f77" class="nav gap">
<image src="{{attachDir}}872467" class="icon"></image>
EduCoder云网
<text class="tip">推荐使用</text>
<iconfont type="jinru" color="dimgrey" size="15" class="enter"/>
</navigator>
<view class="nav enter" data-path="change_password"> <view class="nav enter" data-path="change_password">
<iconfont class="icon" type="xiugaimima" size="21" />修改密码 <iconfont class="icon" type="xiugaimima" size="21" />修改密码
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont> <iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
@ -44,15 +50,15 @@
<iconfont class="icon" type="wode-zhiyerenzheng" size="21" />职业认证 <iconfont class="icon" type="wode-zhiyerenzheng" size="21" />职业认证
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont> <iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</view> </view>
<button open-type="feedback" class="nav" style="width:auto"> <button open-type="feedback" class="nav" style="width:auto">
<iconfont class="icon" type="fankui" size="21" />小程序反馈 <iconfont class="icon" type="fankui" size="21" />小程序反馈
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont> <iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</button> </button>
<button open-type="contact" class="nav" style="width:auto"> <button open-type="contact" class="nav" style="width:auto">
<iconfont class="icon" type="kefu" size="21" />小程序客服 <iconfont class="icon" type="kefu" size="21" />小程序客服
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont> <iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
</button> </button>
<navigator url="/account/pages/about/about" class="nav about gap"> <navigator url="/account/pages/about/about" class="nav about gap">
<iconfont class="icon" type="guanyu" size="21" />关于 <iconfont class="icon" type="guanyu" size="21" />关于
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont> <iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>

@ -25,6 +25,10 @@
.nav>.icon{ .nav>.icon{
margin-right: 10px; margin-right: 10px;
} }
.nav>image.icon{
width:21px;
height: 21px;
}
.user-info>.tip, .user-info>.tip,
.nav>.tip{ .nav>.tip{
right: 36px; right: 36px;

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

@ -1,10 +1,10 @@
<view class="my-course"> <view class="my-course">
<require-login/> <require-login/>
<nav-bar list="{{categories}}" current="{{current_cate}}" bindchange="onCategoryChange"/> <nav-bar list="{{categories}}" current="{{current_cate}}" bindchange="onCategoryChange"/>
<view class="nav-wrap">
<nav-bar list="{{statuses}}" width="300" itemWidth="140" cancellable="1" current="-1" type="plain" bg='' bindchange="onStatusChange"/>
</view>
<scroll-view scroll-y="1" refresher-enabled="1" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom" lower-threshold="120" bindrefresh="onPullDownRefresh" class="body"> <scroll-view scroll-y="1" refresher-enabled="1" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="onReachBottom" lower-threshold="120" bindrefresh="onPullDownRefresh" class="body">
<view class="nav-wrap">
<nav-bar list="{{statuses}}" width="300" itemWidth="140" cancellable="1" current="-1" type="plain" bg='' bindchange="onStatusChange"/>
</view>
<view wx:if="{{courses.length==0&&!loading}}" class="none-content"> <view wx:if="{{courses.length==0&&!loading}}" class="none-content">
<image class="none-content" src="{{imgDir}}blank1.png" mode="aspectFit"></image> <image class="none-content" src="{{imgDir}}blank1.png" mode="aspectFit"></image>
<text class="none-content hint">空空如也!</text> <text class="none-content hint">空空如也!</text>
@ -14,6 +14,9 @@
</view> </view>
</scroll-view> </scroll-view>
<!-- {{imgDir}}add.png --> <!-- {{imgDir}}add.png -->
<image class="add-course" src="{{attachDir}}751591" bindtap="addCourse"></image> <view class="add-course" bindtap="addCourse">
<mp-icon icon="add" type="field" color="#0080f0" size="32"/>
</view>
<join-course-modal hidden="{{!showModal}}"/> <join-course-modal hidden="{{!showModal}}"/>
</view> </view>

@ -12,21 +12,13 @@
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
text-align: end; text-align: end;
margin: -1px 10px -4px 0; margin: 1px 10px 1px 0;
} }
.course-wrap{ .course-wrap{
margin: 0 12px 10px 12px; margin: 0 12px 10px 12px;
} }
.add-course{
position: fixed;
right: 0;
margin-right: 48rpx;
margin-bottom: 36rpx;
bottom: 0;
width: 45px;
height: 45px;
}
.none-content{ .none-content{
display: flex; display: flex;
@ -43,6 +35,22 @@ image.none-content{
width: 220rpx; width: 220rpx;
} }
.add-course{
position: fixed;
right: 0;
border-radius: 50%;
margin-right: 48rpx;
margin-bottom: 36rpx;
bottom: 0;
width: 45px;
height: 45px;
background: white;
box-shadow: 0.64px 0.42px 3.2px -0.24px #aaaaaa;
display: flex;
justify-content: center;
align-items: center;
}
.add-course:hover{ .add-course:hover{
opacity: 0.6; opacity: 0.72;
} }

@ -9,6 +9,7 @@ Page({
}, },
onTapNav({detail:{current, source , value}}){ onTapNav({detail:{current, source , value}}){
if(source!='touch') return; if(source!='touch') return;
this.setData({current});
this.options.type = value.type; this.options.type = value.type;
this.search({refresh:1}) this.search({refresh:1})
.then(()=>{ .then(()=>{

@ -43,9 +43,16 @@
font-size: 14px; font-size: 14px;
} }
.detail{ .detail{
transition: 0.8s all ease; transition: 0.5s;
max-height: 100vh; max-height: 100vh;
} }
.hidden{
max-height: 0px;
overflow: hidden;
}
.detail.hidden{
transition: none;
}
.output-info{ .output-info{
background: #111c24; background: #111c24;
max-height: 106px; max-height: 106px;
@ -57,10 +64,7 @@
white-space: pre; white-space: pre;
padding: 0 8px; padding: 0 8px;
} }
.hidden{
max-height: 0px;
overflow: hidden;
}
.different{ .different{
background: #9a6868; background: #9a6868;
} }

@ -1,12 +1,10 @@
const app = getApp(); const app = getApp();
Page({ Page({
data: { data: {
current: 0, current: 1,
titles: ["任务描述", "代码文件", "测评结果"] content:"加载中...",
}, titles: ["任务描述", "代码文件", "测评结果"],
log(e){ can_use_editor:wx.canIUse("editor")
console.log(e);
}, },
enterTask(e){ enterTask(e){
var {target:{dataset:{identifier}}} = e; var {target:{dataset:{identifier}}} = e;
@ -23,19 +21,53 @@ Page({
enterOutcome(){ enterOutcome(){
this.setData({current:2}); this.setData({current:2});
}, },
onBlur({detail:{value}}){ onTextAreaBlur({detail:{value}}){
if (!this.modified) { if (!this.modified) {
this.modified = this.content != value; this.modified = this.content != value;
} }
this.content = value; if(this.modified){
if(this.modified) this.content = value;
this.updateFile(); this.updateFile();
}
}, },
onInput({detail:{value}}){ onTextAreaInput({detail:{value}}){
this.modified = this.content!=value;
if(this.modified)
this.content = value;
},
addIndent(){
this.editor.insertText({text:" "});
},
onEditorInput(e){
let {text} = e.detail;
//console.log(e.detail.text);
this.modified = this.content!=text;
if(this.modified){
this.content = text;
// 自动缩进适配┭┮﹏┭┮,小程序限制太多了
this.oldLines = this.lines;
this.lines = this.content.split(/\n/g);
if(this.oldLines.length+1==this.lines.length){
for(var i=this.oldLines.length;i>=0;i--){
if(this.lines[i+1]!=this.oldLines[i]){
let indent = this.oldLines[i].length - this.oldLines[i].trimStart().length;
this.editor.insertText({text:" ".repeat(indent)});
break;
}
}
}
}
},
onEditorBlur({detail}){
//console.log("onEditorBlur")
let {text} = detail;
if(!this.modified){ if(!this.modified){
this.modified = this.content!=value; this.modified = this.content.trimEnd()!=text.trimEnd();
}
if(this.modified){
this.content = text;
this.updateFile();
} }
this.content = value;
}, },
processPath(path){ processPath(path){
return path.replace(/[;]$/,""); return path.replace(/[;]$/,"");
@ -56,19 +88,21 @@ Page({
throw new Error(); throw new Error();
} }
}, },
gameBuild({detail:{value}}){ buildGame({detail:{value}}){
//console.log("buildGame");
wx.showLoading({ wx.showLoading({
title: '代码上传中', title: '代码上传中',
}); });
this.setData({ building: 1 }); this.setData({ building: 1 });
var {identifier} = this.data; var {identifier} = this.data;
this.content = value.content; if(!this.data.can_use_editor)
this.content = value.content;
this.updateFile({evaluate:1}) this.updateFile({evaluate:1})
.then(res=>{ .then(res=>{
var {sec_key, resubmit=""} = res; var {sec_key, resubmit=""} = res;
app.api("tasks.game_build")({ identifier, resubmit, sec_key, content_modified:1}) app.api("tasks.game_build")({ identifier, resubmit, sec_key, content_modified:1})
.then(res => { .then(res => {
this.getGameStatus({sec_key, resubmit}); this.getBuildStatus({sec_key, resubmit});
}) })
.catch(e=>{ .catch(e=>{
wx.hideLoading(); wx.hideLoading();
@ -82,7 +116,7 @@ Page({
}) })
}, },
getGameStatus({resubmit="", sec_key=""}){ getBuildStatus({resubmit="", sec_key=""}){
var { identifier } = this.data; var { identifier } = this.data;
var timer = setInterval(()=>{ var timer = setInterval(()=>{
app.api("tasks.game_status")({identifier,resubmit,sec_key}) app.api("tasks.game_status")({identifier,resubmit,sec_key})
@ -101,49 +135,64 @@ Page({
}, 1000); }, 1000);
}, },
onSwiperChange({detail:{current,source}}){ onSwiperChange({detail:{current,source}}){
if(source=="touch") if(source=="touch"){
this.setData({current}); this.setData({current});
}
if(current==1&&!this.content){
this.pullContent();
}
}, },
async pullTask(){ async pullTask(){
let {identifier} = this.data; let {identifier} = this.data;
let res = await app.api("tasks")({identifier}); let res = await app.api("tasks")({identifier});
res.challenge.task_pass = res.challenge.task_pass.replace(/\[TOC\]\s*-+\s*/,"") res.challenge.task_pass = res.challenge.task_pass.replace(/\[TOC\]\s*-+\s*/,"")
this.setData(res); this.setData(res);
this.pullContent();
}, },
async pullContent(){ async pullContent(){
console.log("pullContent", this.editor);
let {path} = this.data.challenge; let {path} = this.data.challenge;
path = this.processPath(path); path = this.processPath(path);
let {identifier} = this.data; let {identifier} = this.data;
let {content} = await app.api("tasks.rep_content")({identifier,path}); let {content} = await app.api("tasks.rep_content")({identifier,path});
this.setData({content}); this.content = content;
if(this.data.can_use_editor){
if(!this.editor)
this.onEditorReady({pullContent:1});
else{
//let delta = {ops:[{insert:content}]};
//this.editor.setContents({delta});
this.editor.clear();
this.lines = content.split(/\n/g);
this.editor.insertText({text:content});
}
}else
this.setData({content});
console.log("pullContent");
},
onEditorReady({pullContent=0}={}) {
//console.log("editor-ready")
const that = this
wx.createSelectorQuery().select('#code-editor').context(function (res) {
that.editor = res.context
if(pullContent&&that.editor)
that.pullContent();
//that.editor.insertText({text:that.content});
//console.log("exced",res,that.editor);
}).exec();
//console.log("redy-fin",this.editor)
}, },
onLoad: function (options) { onLoad: function (options) {
//console.log("onload")
let {identifier} = options; let {identifier} = options;
this.setData({identifier}); this.setData({identifier});
this.pullTask(); this.pullTask();
}, },
onReady: function () {
},
onShow: function () {
},
onHide: function () { onHide: function () {
this.updateFile(); this.updateFile();
}, },
onUnload: function () {
},
onReachBottom: function () {
},
onShareAppMessage: function () { onShareAppMessage: function () {
let {challenge, shixun} = this.data; let {challenge, shixun} = this.data;
return app.shareApp({ return app.shareApp({

@ -10,12 +10,17 @@
</swiper-item> </swiper-item>
<swiper-item> <swiper-item>
<view class="editor-body"> <view class="editor-body">
<form class="form-body" bindsubmit="gameBuild"> <form class="form-body" bindsubmit="buildGame">
<textarea class="editor" name="content" maxlength="-1" <editor wx:if="{{can_use_editor}}" class="editor"
id="code-editor"
bindready="onEditorReady"
bindinput="onEditorInput"
bindblur="onEditorBlur"/>
<textarea wx:else class="editor" name="content" maxlength="-1"
value="{{content}}" value="{{content}}"
bindblur="onBlur" bindblur="onTextAreaBlur"
show-confirm-bar="{{false}}" show-confirm-bar="{{false}}"
bindinput="onInput"> bindinput="onTextAreaInput">
</textarea> </textarea>
<view class="operations"> <view class="operations">
<button class="button-challenge" plain="1" type="main" bindtap="enterChallenge">任务</button> <button class="button-challenge" plain="1" type="main" bindtap="enterChallenge">任务</button>
@ -29,7 +34,7 @@
<scroll-view class="outcome-body" scroll-y="1"> <scroll-view class="outcome-body" scroll-y="1">
<view class="compile-output"> <view class="compile-output">
<rich-text wx:if="{{sets_error_count}}" nodes="{{last_compile_output}}"></rich-text> <rich-text wx:if="{{sets_error_count}}" nodes="{{last_compile_output}}"></rich-text>
<view wx:else class="success">成功通过 {{test_sets_count-sets_error_count}}/{{test_sets_count}}</view> <view wx:elif="{{test_sets_count}}" class="success">成功通过 {{test_sets_count-sets_error_count}}/{{test_sets_count}}</view>
</view> </view>
<view class="test-set-wrap" wx:for="{{test_sets}}"> <view class="test-set-wrap" wx:for="{{test_sets}}">
<test-set data="{{item}}" index="{{index}}"/> <test-set data="{{item}}" index="{{index}}"/>

@ -27,8 +27,8 @@
color: #93A1A1; color: #93A1A1;
font: 14px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace; font: 14px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
white-space: pre; white-space: pre;
padding: 4px 12px; padding: 0px 10px;
height: calc(100vh - 51px); height: calc(100vh - 43px);
flex: auto; flex: auto;
} }
.operations{ .operations{

@ -109,7 +109,7 @@
"id": 6, "id": 6,
"name": "course/pages/course/course", "name": "course/pages/course/course",
"pathName": "course/pages/course/course", "pathName": "course/pages/course/course",
"query": "course_id=5141", "query": "course_id=5876",
"scene": null "scene": null
}, },
{ {
@ -146,6 +146,13 @@
"pathName": "account/pages/accounts/accounts", "pathName": "account/pages/accounts/accounts",
"query": "", "query": "",
"scene": null "scene": null
},
{
"id": -1,
"name": "task/pages/task/task",
"pathName": "task/pages/task/task",
"query": "identifier=ji2wy8sqkou5",
"scene": null
} }
] ]
} }

Loading…
Cancel
Save