增加信息修改界面

master
educoder_weapp 5 years ago
parent da974380fb
commit 8bc73d7bd8

@ -1,3 +1,8 @@
## v0.13.1
* A 修改个人信息界面
* F 头像更改界面高度异常
* F 我的实训初次显示不加载
## v0.13.0
* A 菜单的删除课堂
* A 课堂动态模块

@ -51,7 +51,7 @@ Page({
var data = {login:"educoder_weapp@126.com", password:"abcdefgh"};
this.setData(data);
this.login(data);
this.setStorage({...data,save_password:1});
// this.setStorage({...data,save_password:1});
},
login({login, password, showToast=1}){
app.api("accounts.login")({login,password})

@ -1,5 +1,6 @@
page{
min-height: 100%;
overflow: hidden;
}
.head-error{
position: fixed;
@ -86,7 +87,7 @@ switch.no-login{
color:white;
}
.pos1>button[disabled]{
background: #00b0f0aa;
background-color: #00b0f0aa!important;
color: white;
}
.actions>.pos2{

File diff suppressed because one or more lines are too long

@ -1,66 +1,238 @@
const app = getApp();
var locationData;
Page({
/**
* 页面的初始数据
*/
data: {
eduImgDir:global.config.eduImgDir,
locations:[],
cities:[],
identities:[{value:"teacher", text:"教师"},{value:"student",text:"学生"},{value:"professional", text:"专业人士"}],
technicalTitles:{
0:["教授","副教授","讲师","助教"],
2:["企业管理者","部门管理者","高级工程师","工程师","助理工程师"]
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
refresh(){
console.log(locationData);
app.api("users.accounts")().then(res=>{
this.originInfo = res;
res.authen = res.authentication == "certified";
res.pro_authen = res.professional_certification == "certified";
this.setData(res);
if(!locationData)
this.readData();
this.setInfo(res);
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
setInfo(res){
let locations = Object.keys(locationData);
let location_index = locations.indexOf(res.location);
let cities = locationData[res.location] || [];
let city_index = cities.indexOf(res.location_city);
let identity_index = -1;
let { identities } = this.data;
for (var i = 0; i < identities.length; i++) {
if (identities[i].value == res.identity) {
identity_index = i;
break;
}
}
var technical_index = -1;
if (identity_index == 0 || identity_index == 2) {
let technicals = this.data.technicalTitles[identity_index];
for (var i = 0; i < technicals.length; i++) {
if (technicals[i] == res.technical_title) {
technical_index = i;
break;
}
}
}
this.setData({ locations, cities, location_index, city_index, identity_index, technical_index });
if (res.school_id) {
this.changeSchoolDepartment(res);
}
},
/**
* 生命周期函数--监听页面显示
*/
updateAccount(data){
app.api("users.accounts",{method:"PUT"})(data).then(res=>{
app.showMsg(res);
setTimeout(res=>{
wx.navigateBack({
delta:1
});
},400)
}).catch(e=>{
this.showError(e);
})
},
onGenderChange({detail:{value}}){
console.log("gender change", value);
this.setData({gender:value});
},
onLocationChange(e){
console.log(e)
let {detail:{value:[location_index, city_index]}} = e;
this.setData({location_index, city_index});
},
onCitiesChange(e){
console.log(e);
let {detail:{value,column}} = e;
if(column==0)
this.setData({cities:locationData[this.data.locations[value]],location_index:value ,city_index:0});
},
onIdentityChange(e){
console.log(e);
let {detail:{value}} = e;
this.setData({identity_index:value, technical_index:-1});
},
onTechnicalChange(e){
console.log(e);
let { detail: { value } } = e;
this.setData({technical_index: value});
},
onDepartmentChange(e){
console.log(e);
let { detail: { value } } = e;
this.setData({department_index:value});
},
changeSchoolDepartment({school_name, school_id,department_id, department_name}){
this.setData({departments:[], department_id, department_name, school_id, school_name});
app.api("schools.departments.for_option")({school_id})
.then(res=>{
let {departments} = res;
let department_index = -1;
for(var i=0; i<departments.length;i++){
if(departments[i].id==department_id){
department_index = i;
break;
}
}
this.setData({departments, department_index});
});
},
catchAvatar(){
app.navigateTo({url:"{image_crop}"});
},
readData(){
let fileManager = wx.getFileSystemManager();
let data = fileManager.readFileSync("/account/pages/profile/data.png", "utf-8");
locationData = JSON.parse(data);
console.log("readData", locationData);
},
onLoad: function (options) {
this.refresh();
},
onShow: function () {
if(this.secondShow){
app.api("users.accounts")()
.then(res=>{
let {avatar_url} = res;
this.setData({avatar_url});
})
} //@todo: better solution?
this.secondShow = 1;
let data = wx.getStorageSync("SET-SCHOOL-DEPARTMENT-KEY");
if(data){
this.changeSchoolDepartment(data);
wx.setStorageSync("SET-SCHOOL-DEPARTMENT-KEY",'');
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
checkProInfo(value){
let info = this.originInfo;
if (info.identity != value.identity)
return true;
if(info.identity=='student'){
if(info.student_id!=info.student_id)
return true;
}else{
if (info.technical_title!=info.technical_title)
return true;
}
if(info.school_id!=value.school_id||info.department_id!=value.department_id)
return true
return false;
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
onSubmit(e){
let {detail:{value}} = e;
if(!this.checkInput(value)) return;
if(this.data.pro_authen&&this.checkProInfo(value)){
wx.showModal({
title: '确认修改',
content: '您修改了职业信息,保存后认证信息会清空,\n需要重新进行职业认证',
confirmText:"保存",
success:res=>{
if(res.confirm)
this.saveInfo(value);
}
});
}else
this.saveInfo(value);
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
checkInput(value){
var showTip = key=>{
this.showError({ message: `请填写${key}`});
return false;
}
if(!value.nickname)
return showTip("昵称");
if(!value.name)
return showTip("姓名");
if(value.gender==null)
return showTip("性别");
if (!value.location)
return showTip("所在地");
if (!value.location_city)
return showTip("所在地");
if(!value.identity)
return showTip("职业");
if(value.identity=='student'){
if(!value.student_id)
return showTip("学号");
}else{
if (!value.technical_title)
return showTip("职称");
}
if(!value.school_id)
return showTip("学校/单位");
if (!value.department_id)
return showTip("院系/部门");
return true;
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
saveInfo(value){
app.api("users.accounts", { method: "PUT" })(value)
.then(res => {
res.message = "更新成功";
app.showMsg(res);
console.log("success", res);
setTimeout(() => {
wx.navigateBack({
delta: 1
})
}, 420);
}).catch(e => {
this.showError(e);
})
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
onTap(e){
console.log(e);
let { target: { id } } = e;
if (id) {
if ((id == 'name' || id == "gender") && this.data.authen)
this.showError({ message: `请重新实名认证以更改${id == "name" ? "姓名" : id == 'gender' ? "性别" : '此信息'}`, during: 1400 });
this.setData({edited:1});
}
},
showError(e){
let {message:error, during=2000} = e;
if(error){
this.setData({showError:1, error});
setTimeout(()=>{
this.setData({showError:0});
}, during);
}
},
onUnload: function () {
}
})

@ -1,3 +1,4 @@
{
"usingComponents": {}
"usingComponents": {},
"navigationBarTitleText": ""
}

@ -1,2 +1,66 @@
<!--miniprogram/account/pages/profile/profile.wxml-->
<text>miniprogram/account/pages/profile/profile.wxml</text>
<view class="profile">
<form bindtap="onTap" bindsubmit="onSubmit" bindreset="refresh">
<view class="header">
<view class="error {{showError?'show':''}}"><text class="single-line">{{error}}</text></view>
<view wx:if="{{!edited}}">点击相应项编辑信息</view>
<button wx:else form-type="reset" size="mini" type="main">重置信息</button>
<button class="submit" form-type="submit" size="mini" type="main">
<icon type="success_no_circle" color="white"></icon>
<text>保存</text>
</button>
</view>
<view class="form-item">
<text class="key">昵称头像</text>
<input class="value" id="nickname" placeholder="输入昵称" name="nickname" value="{{nickname}}"></input>
<image class="avatar" bindtap="catchAvatar" src="{{eduImgDir}}{{avatar_url}}"></image>
</view>
<view class="form-item">
<view class="key">
<text>姓名</text>
</view>
<input class="value" id="name" placeholder="输入姓名" disabled="{{authen}}" name="name" value="{{name}}"></input>
</view>
<view class="form-item">
<text class="key">显示姓名
<text class="tip">关闭后将展示您的昵称</text>
</text>
<switch color="#00b0f0" id="show_realname" name="show_realname" checked="{{show_realname}}"></switch>
</view>
<view class="form-item">
<text>性别</text>
<picker class="value" id="gender" name="gender" range="{{['男','女']}}" bindcolumnchange="log" value="{{gender}}" disabled="{{authen}}" bindchange="onGenderChange">{{gender==0?'男':gender==1?'女':'未设置'}}</picker>
</view>
<view class="form-item">
<text>所在地</text>
<picker class="value" id="location-city" bindcolumnchange="onCitiesChange" bindchange="onLocationChange" range="{{[locations,cities]}}" value="{{[location_index, city_index]}}" mode="multiSelector">{{locations[location_index]}}-{{cities[city_index]}}</picker>
<input hidden="1" disabled="1" name="location" value="{{locations[location_index]}}"></input>
<input hidden="1" disabled="1" name="location_city" value="{{cities[city_index]}}"></input>
</view>
<view class="gap"></view>
<view class="form-item">
<text class="key">职业</text>
<picker class="value" id="identity" range="{{identities}}" bindchange="onIdentityChange" range-key="text" value="{{identity_index}}">{{identities[identity_index].text||'请选择'}}</picker>
<input hidden="1" name="identity" disabled="1" value="{{identities[identity_index].value}}"/>
</view>
<view wx:if="{{identity_index==1}}" class="form-item">
<text class="key">学号</text>
<input class="value" id="school_id" type="number" name="student_id" placeholder="输入学号" cursor-spacing="100" value="{{student_id}}"></input>
</view>
<view wx:elif="{{identity_index==0||identity_index==2}}" class="form-item">
<text class="key">职称</text>
<picker class="value" id="technical_title" bindchange="onTechnicalChange" range="{{technicalTitles[identity_index]}}" value="{{technical_index}}">{{technicalTitles[identity_index][technical_index]||'请选择'}}</picker>
<input hidden="1" disabled="1" name="technical_title" value="{{technicalTitles[identity_index][technical_index]}}"></input>
</view>
<view class="form-item">
<text class="key">学校/单位</text>
<input hidden="1" disabled="1" name="school_id" type="number" value="{{school_id}}"></input>
<navigator class="value" id="school" hover-class="none" url="/account/pages/profile/school_select/school_select">{{school_name||'请选择'}}</navigator>
</view>
<view class="form-item" wx:if="{{school_id}}">
<text class="key">院系/部门</text>
<picker class="value" id="department" range="{{departments}}" range-key="name" bindchange="onDepartmentChange" value="{{department_index}}">{{departments[department_index].name||department_name||'请选择'}}</picker>
<input hidden="1" disabled="1" name="department_id" type="number" value="{{departments[department_index].id}}"></input>
</view>
</form>
</view>

@ -1 +1,71 @@
/* miniprogram/account/pages/profile/profile.wxss */
.profile,page{
background: #eeeeee;
height: 100%;
}
.header{
display: flex;
align-items: center;
justify-content: space-between;
background: #00b0f0;
color: white;
padding: 0 8px 0 16px;
position: relative;
}
.header>.error{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
transition: 0.72s all ease;
background: orange;
color: white;
padding: 0 20px;
display: flex;
justify-content: center;
align-items: center;
z-index: -1;
opacity: 0;
}
.error.show{
opacity: 1;
z-index: 100;
}
.header>button{
margin: 2px 0;
display: flex;
align-items: center;
}
.form-item{
background: #fefefe;
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
margin-bottom: 1px;
}
.form-item>.value{
text-align: right;
flex: auto;
}
.form-item>.key{
display: inline-block;
flex: none;
}
.form-item .tip{
font-size: 12px;
color: dimgray;
}
.form-item>switch{
transform: scale(0.8)
}
.gap{
height: 3px;
}
.avatar{
border-radius: 50%;
height: 30px;
width: 30px;
margin: 0 14px;
}

@ -0,0 +1,40 @@
const app = getApp();
Component({
properties: {
_id: Number,
name: String
},
data: {
departments: []
},
methods: {
onTapHeader() {
if (!this.data.departments || this.data.departments.length == 0) {
app.api("schools.departments.for_option")({
school_id: this.data._id
})
.then(res => {
let {
departments
} = res;
this.setData({
departments
});
});
}
this.setData({ showDepartments: !this.data.showDepartments });
},
onTapDepartment(e) {
console.log(e);
let { target: { dataset: { name: department_name, id: department_id } } } = e;
if (!department_id) return;
let { _id: school_id, name: school_name } = this.data;
let data = { school_id, school_name, department_id, department_name };
wx.setStorageSync("SET-SCHOOL-DEPARTMENT-KEY", data);
wx.navigateBack({
delta:1
});
}
}
})

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

@ -0,0 +1,9 @@
<view class="school">
<view class="header" bindtap="onTapHeader">
<view class="triangle {{showDepartments?'rotate':''}}"></view>
<view>{{name}}</view>
</view>
<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>
</view>

@ -0,0 +1,34 @@
.school{
background: white;
border-radius: 4px;
padding: 8px 12px;
}
.header{
display: flex;
align-items: center;
font-weight: bold;
}
.triangle{
height: 0px;
width: 0px;
border-top: solid 4px transparent;
border-bottom: solid 4px transparent;
border-left: solid 5px #222222;
transition: 1s ease all;
margin: 2px 7px 2px 5px;
}
.rotate{
transform: rotate(90deg);
}
.departments{
overflow: scroll;
max-height: 36vh;
transition: 1px all ease;
}
.departments.hidden{
max-height: 0px;
}
.department{
padding: 4px;
padding-left: 22px;
}

@ -0,0 +1,47 @@
const app = getApp();
Page({
data: {
schools:[]
},
onConfirm({detail:{value}}){
console.log(value);
if(!value) return;
this.search({keyword:value});
},
onSubmit({detail:{value}}){
console.log(value);
if(!value.keyword) return;
this.search({keyword:value.keyword});
},
search({keyword}){
return app.api("schools.for_option")({keyword})
.then(res => {
let { schools } = res;
if (schools.length > 100) {
schools = schools.slice(0, 100);
}
this.setData({ schools });
if(schools.length==0)
wx.showToast({
title:"没有相关单位",icon:"none"
})
})
},
clearKeyword(){
this.setData({schools:[],_keyword:'',keyword:''});
},
onInput({detail:{value}}){
this.setData({_keyword: value})
},
onLoad: function (options) {
let {keyword} = options;
if(keyword){
this.setData({keyword, _keyword: keyword});
this.search({keyword})
}
},
onShow: function () {
}
})

@ -0,0 +1,6 @@
{
"usingComponents": {
"school-item": "./school-item/school-item"
},
"navigationBarTitleText": "选择单位"
}

@ -0,0 +1,17 @@
<view class="body">
<form bindsubmit="onSubmit">
<view class="search">
<view class="search-bar">
<icon type="search"></icon>
<input placeholder="学校/单位" auto-focus="1" name="keyword" bindinput="onInput" value="{{keyword}}" bindconfirm="onConfirm"></input>
<icon wx:if="{{_keyword}}" type="clear" bindtap="clearKeyword"></icon>
</view>
<button form-type="submit" size="mini" type="main">搜索</button>
</view>
</form>
<scroll-view class="schools" scroll-y="1">
<view class="school-wrap" wx:for="{{schools}}" wx:key="id">
<school-item _id="{{item.id}}" name="{{item.name}}"/>
</view>
</scroll-view>
</view>

@ -0,0 +1,34 @@
.body{
display: flex;
flex-direction: column;
height: 100vh;
}
.search{
display: flex;
padding: 0 12px 2px 12px;
background: white;
flex: none;
}
.search-bar{
display: flex;
padding: 0 8px;
border-radius: 4px;
border: 1px solid #00b0f0;
flex: auto;
align-items: center;
margin-right: 16px;
}
.search-bar>input{
flex: auto;
padding: 3px;
}
.search>button{
flex: none;
}
.schools{
flex: 1 1 1px;
height: 1px;
}
.school-wrap{
margin-bottom: 1.2px;
}

@ -1,5 +1,5 @@
import config from "./config";
import {client} from "./js/client";
import { client } from "./js/client";
wx.cloud.init({
traceUser: true,
@ -7,73 +7,116 @@ wx.cloud.init({
});
App({
globalData: {
versionCode: config.versionCode,
debug: config.debug
},
client,
api(name, config){return client.api(name,config)},
callApi(options){return client.callApi(options)},
user(){ return client.user},
syncUser(options){return client.syncUser(options)},
globalData: {
versionCode: config.versionCode,
debug: config.debug
},
client,
api(name, config) { return client.api(name, config) },
callApi(options) { return client.callApi(options) },
user() { return client.user },
syncUser(options) { return client.syncUser(options) },
onLaunch: function (options) {
const db = wx.cloud.database();
if (options.referrerInfo && options.referrerInfo.appId){
let { appId, extraData } = options.referrerInfo;
let {scene, path} = options;
db.collection("referrer_info")
onLaunch: function (options) {
const db = wx.cloud.database();
if (options.referrerInfo && options.referrerInfo.appId) {
let { appId, extraData } = options.referrerInfo;
let { scene, path } = options;
db.collection("referrer_info")
.add({
data:{
data: {
appId, extraData, scene, path,
createdAt: db.serverDate()
}
})
}
},
onShow(){
if(client.user_id&&client.user_id!=2)
client.getTidingInfo();
},
onPageNotFound(res) {
console.log("page not find!! redirect",res);
this.reLaunch({url:"{main}"});
},
showError(e,duration=1500){
wx.showToast({
title: e.message,
icon:"none",
duration
})
},
showMsg(res, duration=1500){
wx.showToast({
title: res.message,duration
})
},
getPageUrl(url,root="/"){
return url.replace(/{(.*)}/, function (match, name) {
for (var u of __wxConfig.pages) {
if (u.endsWith("/"+name))
return root + u;
}
this.api("users.system_update")().then(res => {
if (res.system_update) {
let { subject = "升级服务通知", system_score} = res;
if(!system_score){
let {end_time} = res;
if(end_time){
const {getFormatDatetime} = require('./js/utils');
system_score = "为了给大家提供更优质的体验,平台正在对系统进行升级,期间系统响应会有一定延迟。系统将于"+getFormatDatetime(new Date(end_time))+"恢复正常。敬请谅解";
}else{
system_score = "为了给大家提供更优质的体验,平台正在对系统进行升级,期间系统响应会有一定延迟,敬请谅解";
}
}
return match;
});
},
reLaunch({url, success, fail, complete}){
wx.reLaunch({url: this.getPageUrl(url),success,fail,complete})
},
redirectTo({url, success, fail, complete}){
wx.redirectTo({url: this.getPageUrl(url),success,fail,complete})
},
navigateTo({url, success, fail, complete}){
wx.navigateTo({url: this.getPageUrl(url),success,fail,complete})
},
shareApp({imageUrl,path,title}){
return {
title: title||"EduCoder教学",
imageUrl:imageUrl||"",
path
wx.showModal({
title: subject,
content: system_score,
showCancel: false
})
}
}).catch(e=>{});
},
onShow() {
if (client.user_id && client.user_id != 2)
client.getTidingInfo();
},
onPageNotFound(res) {
console.log("page not find!! redirect", res);
this.reLaunch({ url: "{main}" });
},
showError(e, duration = 1500) {
wx.showToast({
title: e.message,
icon: "none",
duration
})
},
showMsg(res, duration = 1500) {
wx.showToast({
title: res.message, duration
})
},
getPageUrl(url, root = "/") {
return url.replace(/{(.*)}/, function (match, name) {
for (var u of __wxConfig.pages) {
if (u.endsWith("/" + name))
return root + u;
}
for (var u of config.pages) {
if (u.endsWith("/" + name))
return root + u;
}
return match;
});
},
reLaunch({ url, success, fail, complete }) {
wx.reLaunch({ url: this.getPageUrl(url), success, fail, complete })
},
redirectTo({ url, success, fail, complete }) {
wx.redirectTo({ url: this.getPageUrl(url), success, fail, complete })
},
navigateTo({ url, success, fail, complete }) {
wx.navigateTo({ url: this.getPageUrl(url), success, fail, complete })
},
shareApp({ imageUrl, path, title }) {
return {
title: title || "EduCoder教学",
imageUrl: imageUrl || "",
path
}
});
}
});
function getCurrentPath() {
let pages = getCurrentPages();
return pages[pages.length - 1].route;
}
function toAbsPath(current, path) {
if (path.startsWith("/"))
current = ".";
else
current = current + "/../";
path = current + path;
while (path.indexOf("..") != -1) {
path = path.replace(/[^\/]*\/\.\.\//g, "")
}
while (path.indexOf(".") != -1) {
path = path.replace(/\.\//, "");
}
return path;
}

@ -22,7 +22,8 @@
"pages/change_password/change_password",
"pages/profile/profile",
"pages/account/account",
"pages/signUp/signUp"
"pages/signUp/signUp",
"pages/profile/school_select/school_select"
]
},
{
@ -35,26 +36,16 @@
"root": "course",
"pages": [
"pages/course/course",
"pages/course_invite/course_invite",
"pages/course_setting/course_setting"
"pages/course_invite/course_invite"
]
},
{
"root": "exercise",
"pages": [
"pages/exercise/exercise",
"pages/exercise_grade/exercise_grade",
"pages/exercise_setting/exercise_setting",
"pages/question_setting/question_setting",
"pages/exercise_cover/exercise_cover"
]
},
{
"root": "common-homework",
"pages": [
"pages/common-homework/common-homework"
]
},
{
"root": "shixun_homework",
"pages": [
@ -85,10 +76,6 @@
"pages": [
"search"
]
},
{
"root": "develop",
"pages": []
}
],
"preloadRule": {

@ -1,52 +1,33 @@
import WeCropper from '../../we-cropper/dist/we-cropper.min.js'
const device = wx.getSystemInfoSync()
const width = device.windowWidth
const height = device.windowHeight - 60
const app = getApp();
Page({
data: {
cropperOpt: {
id: 'cropper',
width,
height,
scale: 2.5,
zoom: 8,
cut: {
x: (width - 300) / 2,
y: (height - 300) / 2,
width: 300,
height: 300
}
}
},
touchStart(e) {
console.log(e);
//console.log(e);
this.mycropper.touchStart(e)
},
touchMove(e) {
console.log(e);
//console.log(e);
this.mycropper.touchMove(e)
},
touchEnd(e) {
console.log(e);
//console.log(e);
this.mycropper.touchEnd(e)
},
upload_avartar(filePath){
return new Promise((resolve, reject)=>{
upload_avartar(filePath) {
return new Promise((resolve, reject) => {
wx.getFileSystemManager().readFile({
filePath,
encoding: "base64",
success: res => {
let image = "data:image/jpeg;base64," + res.data;
app.api("users.accounts.avatar")({image}).then(resolve);
app.api("users.accounts.avatar")({ image }).then(resolve);
},
fail:reject
fail: reject
});
});
},
@ -60,34 +41,33 @@ Page({
wx.showLoading({
title: '上传中',
});
this.upload_avartar(avatar).then(res=>{
console.log("upload avatar success");
console.log(res);
wx.navigateBack({
delta: 1
});
wx.showToast({
title: '更改成功',
});
wx.hideLoading();
}).catch(error=>{
console.error(error);
wx.showToast({
title: '失败',
icon: "none"
});
wx.hideLoading();
this.upload_avartar(avatar).then(res => {
console.log("upload avatar success");
console.log(res);
wx.navigateBack({
delta: 1
});
wx.hideLoading();
wx.showToast({
title: '更改成功',
});
}).catch(error => {
console.error(error);
wx.showToast({
title: '失败',
icon: "none"
});
wx.hideLoading();
});
} else {
wx.showToast({
title: '获取图片失败',
icon:"none"
icon: "none"
});
}
})
},
uploadTap() {
const self = this
wx.chooseImage({
@ -98,36 +78,62 @@ Page({
}
})
},
initCrop(src) {
const { cropperOpt } = this.data;
Object.assign(cropperOpt, { src });
this.mycropper = new WeCropper(cropperOpt);
this.mycropper
.on('beforeImageLoad', (ctx) => {
console.info("beforeImageLoad");
wx.showLoading({
title: '上传中'
})
})
.on('imageLoad', (ctx) => {
console.info("imageLoad")
wx.hideLoading();
})
.updateCanvas();
},
onLoad(option) {
const {cropperOpt} = this.data
const {src} = option
let device = wx.getSystemInfoSync();
let width = device.windowWidth;
let height = device.windowHeight - 42;
let cropperOpt = {
id: 'cropper',
scale: 2.6,
zoom: 8,
width,
height,
cut: {
x: (width - 300) / 2,
y: (height - 300) / 2,
width: 300,
height: 300
}
}
this.setData({ cropperOpt});
const { src } = option;
if (src) {
Object.assign(cropperOpt, {src})
this.mycropper = new WeCropper(cropperOpt);
this.mycropper
.on('ready', function (ctx) {
console.info("ready");
console.info(ctx);
})
.on('beforeImageLoad', (ctx) => {
console.info("beforeImageLoad");
wx.showToast({
title: '上传中',
icon: 'loading',
duration: 3000
})
})
.on('imageLoad', (ctx) => {
console.info("imageLoad")
wx.hideToast()
})
.on('beforeDraw', (ctx, instance) => {
console.log(`before canvas draw,i can do something`)
console.log(`current canvas context:`, ctx)
})
.updateCanvas();
this.initCrop(src);
} else {
wx.chooseImage({
count: 1,
success: res => {
const src = res.tempFilePaths[0];
if (src)
this.initCrop(src);
else
wx.navigateBack({
delta: 1
});
},
fail: e => {
wx.navigateBack({
delta: 1
});
}
})
}
}
})

@ -1,12 +1,14 @@
<import src="/avatar/we-cropper/dist/we-cropper.wxml"/>
<view class="cropper-wrapper">
<template is="we-cropper" data="{{...cropperOpt}}" />
<view class="operation flex-wrap">
<button class="upload" bindtap="uploadTap">
重新选择
<import src="/avatar/we-cropper/dist/we-cropper.wxml" />
<block wx:if="{{cropperOpt}}">
<view class="cropper-wrapper">
<template is="we-cropper" data="{{...cropperOpt}}" />
</view>
<view class="operations flex-row">
<button class="upload" type="main" plain="1" bindtap="uploadTap">
重选图片
</button>
<button type="primary" class="getCropperImage" bindtap="getCropperImage">
确定
<button type="main" class="getCropperImage" bindtap="getCropperImage">
确定
</button>
</view>
</view>
</block>

@ -2,21 +2,18 @@ page{
height: 100%
}
.cropper{
position: absolute;
top: 0;
left: 0;
position: absolute;
top: 0;
left: 0;
}
.operation{
.operations{
position: fixed;
bottom: 0;
width: 100%;
height: 50px;
align-items: center
height: 42px;
}
.operation button{
width: 49%;
.operations>button{
flex: auto
}

@ -10,7 +10,7 @@ const actions = {
},
"邀请成员":{
cb:"share",
cd:{"course_identity":[2]}
cd:{"course_identity":[2,3,4]}
},
"停用邀请码":{
cb: "set_invite_code_halt",

@ -115,7 +115,7 @@ Component({
app[this.data.opentype]({
url: `{course}?course_id=${res.course_id}`
});
},800);
},640);
}
this.triggerEvent("success");
this.cancel();

@ -65,8 +65,8 @@ Component({
this.scroll();
},
scroll(){
if(this.data.current>=0&&this.data.autoscroll&&this.data.itemWidth>0){
let scrollLeft = (this.data.current+0.5)*this.data.itemWidth+0.5*this.data.width;
if(this.data.cur>=0&&this.data.autoscroll&&this.data.itemWidth>0){
let scrollLeft = (this.data.cur+0.5)*this.data.itemWidth-0.5*this.data.width;
this.setData({scrollLeft})
}
},

@ -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':''}} ">
<text class="text common {{type}} item-class {{current == index ?'active':''}}">{{item.text}}</text>
<text class="text common {{type}} item-class {{cur == index ?'active':''}}">{{item.text}}</text>
</view>
</scroll-view>

@ -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.13.0";
let _version = "0.13.1";
var eduUrl = releaseUrl;
/**
*
*/
export function switchEnv(env) {
@ -38,9 +37,14 @@ const config = global.config = {
get eduUrl(){return eduUrl},
imgDir: cloudDir + "images/",
get eduImgDir(){return eduUrl + "/images/"},
switchEnv
switchEnv,
pages:[
"exercise/pages/exercise_setting/exercise_setting",
"common-homework/pages/common-homework/common-homework"
]
};
switchEnv(envVersion=="develop"?"trial":"release");
module.exports = config;

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

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

@ -0,0 +1,10 @@
<view class="attendance" bindtap="onTap">
<view class="header">
<text class="title">{{data.name}}</text>
<text class="attendance-button" catchtap="onTapButton">签到</text>
</view>
<view class="footer">
<text>签到时间:{{data.start_time}}-{{data.end_time}}</text>
<text>{{data.mode=='QUICK'?'快捷签到':data.mode=='QRCODE'?'扫码签到':'数字签到'}}</text>
</view>
</view>

@ -0,0 +1,27 @@
.header{
display: flex;
justify-content: space-between;
}
.title{
font-weight: bold;
}
.attendance{
background: #f4f4f4;
box-shadow: 2px 2px 6px #d0d0d0;
border-radius: 4px;
padding: 12px;
}
.attendance-button{
background: #00b0f0;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
color: white;
padding: 3px 6px;
}
.footer{
font-size: 13px;
display: flex;
justify-content: space-between;
}

@ -0,0 +1,30 @@
const app = getApp();
Component({
properties: {
course_id: {
type: Number
},
id_: {
type: Number
},
refresh: {
type: Boolean,
observer: function (v) {
if (v) {
this.refresh({refresh:1});
this.setData({ refresh: false });
}
}
}
},
data: {
},
methods: {
async refresh({refresh=1}){
let {course_id} = this.data;
let data = await app.api("weapps.courses.attendances.student_attendances")({course_id});
this.setData(data);
}
}
})

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"attendance-item":"./attendance-item/attendance-item"
}
}

@ -0,0 +1,19 @@
<view class="module">
<view class="info-display">
<view class="info nomal">
正常签到:{{normal_count}}
</view>
<view class="info leave">
请假:{{leave_count}}
</view>
<view class="info absence">
旷课:{{absence_count}}
</view>
</view>
<nav-bar type="line" list="{{list}}"/>
<scroll-view scroll-y="1">
<view class="attendance-wrap" wx:for="{{current_attendance}}">
<attendance-item data="{{item}}"/>
</view>
</scroll-view>
</view>

@ -0,0 +1,27 @@
.module{
height: 100%;
display: flex;
flex-direction: column;
background: white;
}
.info-display{
display: flex;
margin: 16px 4px;
}
.info{
flex: auto;
text-align: center;
}
.nomal{
color: rgb(38, 199, 201);
}
.leave{
color:rgb(234, 174, 78);
}
.absence{
color: rgb(255, 131, 92);
}
.attendance-wrap{
margin: 12px 8px;
}

@ -67,27 +67,7 @@ Component({
methods: {
switchNav({detail:{current,value}}){
this.setData({ current_status: value.exercise_status});
},
exercise_result: function ({ currentTarget: { dataset } }) {
app.navigateTo({
url: `{exercise_result}?exercise_id=${dataset.exercise_id}`,
})
},
see_grade: function ({ currentTarget: { dataset } }) {
app.navigateTo({
url: `{exercise_grade}?exercise_id=${dataset.exercise_id}`,
})
},
edit_exercise: function ({ currentTarget: { dataset } }) {
app.navigateTo({
url: `{exercise_setting}?course_id=${this.data.course_id}&exercise_id=${dataset.exercise_id}`,
})
},
create_exercise: function () {
app.navigateTo({
url: `{exercise_setting}?course_id=${this.data.course_id}`,
})
},
},
pull_exercise: function () {
app.api("courses.exercises")({ course_id: this.data.course_id })
.then(res => {

@ -9,6 +9,5 @@
<exercise-item data="{{item}}"/>
</view>
</block>
<button hidden="no-pass-code-check" type="primary" wx:if="{{course.is_admin}}" bindtap="create_exercise">发布试卷</button>
</scroll-view>
</view>

@ -1,7 +1,7 @@
const app = getApp();
//status:[0,401,409]
const defaultModules=[{type:"activity", name:"课堂动态"}];
const supportModules = ["activity", "attachment", "exercise","common_homework","shixun_homework"];
const supportModules = ["activity", "attachment", "exercise","shixun_homework"];
Component({
properties:{
course_id:Number,

@ -6,6 +6,7 @@
"common-homework":"/course/modules/common-homework/common-homework",
"shixun-homework": "/course/modules/shixun_homework/shixun_homework",
"activity":"/course/modules/activity/activity",
"attendance":"/course/modules/attendance/attendance",
"join-course":"/components/modal/join-course/join-course",
"error-page":"/components/error-page/error-page"
},

@ -63,9 +63,7 @@
<common-homework wx:elif="{{module.type=='common_homework'}}" id_="{{module.id}}" course_id="{{module.main_id}}" refresh="{{refresh}}"/>
<shixun-homework wx:elif="{{module.type=='shixun_homework'}}" id_="{{module.id}}" course_id="{{module.main_id}}" refresh="{{refresh}}"/>
<activity wx:elif="{{module.type=='activity'}}" course_id="{{course_id}}" refresh="{{refresh}}"/>
<!--view wx:else class="empty">
由于技术限制<br></br>小程序端暂不提供[{{module.name}}]模块,请进入官方网站操作
</view-->
<attendance wx:elif="{{module.type=='attendance'}}" course_id="{{course_id}}" refresh="{{refresh}}"/>
</view>
</view>
</view>

@ -11,6 +11,8 @@
}
.page-content{
padding-top: 100rpx;
overflow-y: scroll;
height: 100vh;
}
.page-top{
height: 100%;
@ -150,9 +152,3 @@ text.sep{
flex: 1 1 1px;
height: 1px;
}
.empty{
padding: 14px;
text-align: center;
}

@ -103,6 +103,8 @@ Page({
onReachBottom: function () {
},
onShareAppMessage(){
}
})

@ -1,3 +1,6 @@
<page-meta>
<navigation-bar title="hihihi"/>
</page-meta>
<view class="container">
<view class="top">
<form class="exercise" bindsubmit="create_exercise">

@ -0,0 +1,8 @@
class Record{
}
export default function Api(options){
}

@ -17,7 +17,7 @@ accounts:{
attachments:{url:{_:1,DELETE:'*/{attachment_id}',uploadFile:"*"},query,form:{_:1,uploadFile:{file:null},DELETE:{}},config:{method:"uploadFile", name:"file"}},
courses:{ url:{_:"*", DELETE:"*/{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}},
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}},
all_course_groups:{url:"{course_id}/*", query},
apply_to_join_course:{query,form:{invite_code:null, professor:void 0,assistant_professor:void 0,student:void 0}, config},
exercises:{url:"{course_id}/*", query, form:{_:1, GET:{page:1,limit:15},POST:{exercise_name:null, exercise_description:""}},
@ -91,7 +91,11 @@ myshixuns:{
},
paths:{url:""},
schools:{
school_list:{query, form:{search:null}}
school_list:{query, form:{search:null}},
for_option:{query,form:{keyword:void 0}},
departments:{
for_option:{url:"../{school_id}/departments/*",query}
}
},
search:{query,form:{type:null, keyword:null, page:1, per_page:20}, data:{type:"subject, course, shixun, memo"}},
@ -119,9 +123,8 @@ tasks:{url:"*/{identifier}",query,
sync_codes:{url:"{identifier}/*",query, res:{path:"newpath"}},
},
users:{
accounts: { url: "*/{login}", query, form:{school:1},
accounts: { url: "*/{login}", 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}},
avatar:{url:"{login}/*",query, form:{image:null} ,config:{method:"PUT"}},
password: { url: "{login}/*", query, form:{old_password:null, password:null} ,config:{method:"PUT"}},
},
@ -131,6 +134,7 @@ users:{
homepage_info:{url:"{login}/*",query},
shixuns: { url: "{login}/*", query, form: {sort_by:"updated_at" ,page:1, sort_direction:"desc",per_page:16}},
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:"",page:1,per_page:10}, data:"type:course,project,interaction,apply,notice"},
unread_message_info:{url:"{login}/*", query}
},
@ -138,13 +142,13 @@ users:{
weapps:{
check_account: { query,form: {login: null, type: "login" }, config, data: { type: ["login"] } },
courses:{
attendances:{url:"{course_id}/*",query,form:{_:1, POST:{attendance_date:null,end_time:null,group_ids:void 0,mode:null, name:null, start_time:null},GET:{}},data:{POST:{mode:["QUICK"]}},
student_attendances: {url:"../{course_id}/attendances/*",query}
attendances:{url:"{course_id}/*",query,form:{_:1, POST:{attendance_date:null,end_time:null,group_ids:void 0,mode:null, name:null, start_time:null},GET:{}},data:{POST:{mode:["QUICK","NUMBER",""]}},
student_attendances: {url:"../{course_id}/attendances/*",form:{page:1, limit:10},query, disp:"获取学生的课堂签到列表"}
},
basic_info:{url:"{course_id}/*",query,disp:"课堂基本信息"},
course_activities:{url:"{course_id}/*",query,form:{page:1, limit:20}},
},
course_member_attendances:{query, form:{attendance_id:null, attendance_mode:null}, config},
course_member_attendances:{query, form:{attendance_id:null, attendance_mode:null}, config, disp:"课堂成员签到"},
challenges: {
is_play: {}
},

@ -60,6 +60,10 @@ export default class Client{
this.save_cookies();
this.getTidingInfo({login:res.login});
});
this.on("success", "accounts.register", res => {
this.synch = 0;
this.save_cookies();
});
this.on("success","first_stamp", res=>{
this.randomcode=res.message;
this.client_key = key(this.randomcode);

@ -16,7 +16,6 @@ export function getFormatDate(date){
}
export function getFormatTime(date){
deprecate();
date = date || new Date();
let hour = date.getHours();
let minu = date.getMinutes();

@ -1,4 +1,5 @@
const app = getApp();
Page({
data: {
version: global.config.version,
@ -76,7 +77,7 @@ Page({
switch (res.tapIndex) {
case 0:
wx.previewImage({
urls: [global.eduImgDir + dataset.src],
urls: [global.eduImgDir + dataset.url],
});
break;
case 1:

@ -5,7 +5,7 @@
</navigator>
<block wx:if="{{user.id}}">
<navigator hover-class="none" class="user-info p4">
<navigator hover-class="none" url="/account/pages/profile/profile" class="user-info p4">
<image src="{{eduImgDir}}{{user.avatar_url}}" class="avatar fl m4" catchtap="onTapAvatar" data-url="{{user.avatar_url}}"></image>
<view class="user-detail fl">
<text>{{user.name}}</text>
@ -30,8 +30,6 @@
<view class="nav-list" bindtap="enterPage">
<view class="nav" data-path="change_password">修改密码</view>
<view class="nav addclass" catchtap="showModal">加入课程</view>
<view class="nav createclass" data-path="course_setting">创建课程</view>
<button open-type="feedback" class="nav" style="width:auto">小程序反馈</button>
<button open-type="contact" class="nav" style="width:auto">小程序客服</button>
<view class="nav" catchtap="onTapVersion">当前版本:{{version}}</view>

@ -111,6 +111,7 @@ navigator[hidden] {
}
.auto-attendance{
transform: scale(0.60);
white-space: nowrap;
}
button.attendance{
font-size: 13px!important;

@ -9,19 +9,23 @@ Component({
},
pageLifetimes: {
show(){
app.syncUser()
.then(res=>{
if(res.user.user_id!=this.user_id){
this.pullShixuns({refresh:1});
this.user_id = res.user.user_id;
}
})
this.refresh();
}
},
attached(){
this.options = {page:1, per_page:16};
this.refresh();
},
methods: {
refresh(){
app.syncUser()
.then(res => {
if (res.user.user_id != this.user_id) {
this.pullShixuns({ refresh: 1 });
this.user_id = res.user.user_id;
}
})
},
async pullShixuns({refresh=0}={}){
if(refresh){
if(refresh==1){

@ -62,95 +62,17 @@
"miniprogram": {
"current": -1,
"list": [
{
"id": 0,
"name": "course/pages/course/course",
"pathName": "course/pages/course/course",
"query": "course_id=5141&module_type=activity",
"scene": 1011
},
{
"id": 6,
"name": "exercise",
"pathName": "exercise/pages/exercise/exercise",
"query": "exercise_id=4178",
"scene": null
},
{
"id": 8,
"name": "pages/my/my",
"pathName": "pages/my/my",
"query": "exercise_id=3970",
"scene": null
},
{
"id": -1,
"name": "pages/tidings/tidings",
"pathName": "pages/tidings/tidings",
"query": "course_id=3518",
"scene": null
},
{
"id": 6,
"name": "shixun",
"pathName": "shixun/pages/shixun/shixun",
"query": "identifier=tb7hw62n",
"scene": null
},
{
"id": -1,
"name": "pages/tidings/tidings",
"pathName": "pages/tidings/tidings",
"query": "",
"scene": null
},
{
"id": -1,
"name": "pages/search/search",
"pathName": "pages/search/search",
"query": "",
"name": "account/pages/profile/profile",
"pathName": "account/pages/profile/profile",
"scene": null
},
{
"id": 8,
"name": "task/pages/task/task",
"pathName": "task/pages/task/task",
"query": "identifier=i6qlxhw8a74m",
"scene": null
},
{
"id": 9,
"name": "home",
"pathName": "pages/home/home",
"query": "",
"scene": null
},
{
"id": -1,
"name": "account",
"pathName": "account/pages/account/account",
"query": "",
"scene": null
},
{
"id": 10,
"name": "course/pages/course_invite/course_invite",
"pathName": "course/pages/course_invite/course_invite",
"query": "course_id=5876",
"scene": null
},
{
"id": -1,
"name": "shixun_homework/pages/shixun_homework/shixun_homework",
"pathName": "shixun_homework/pages/shixun_homework/shixun_homework",
"query": "homework_id=110877",
"scene": null
},
{
"id": -1,
"name": "course/pages/course/course",
"pathName": "course/pages/course/course",
"query": "course_id=5141",
"id": 1,
"name": "account/pages/profile/school_select/school_select",
"pathName": "account/pages/profile/school_select/school_select",
"query": "keyword=国",
"scene": null
}
]

Loading…
Cancel
Save