A 开源版本库查看

master
educoder_weapp 5 years ago
parent 7c07e356a3
commit bf9169a08d

@ -1,5 +1,9 @@
## v0.17.0
* A 增加开源版本库查看
## v0.16.10
* U 登录界面优化
* U 优化登录注册的信息校验
* U 优化分享
## v0.16.9

@ -95,7 +95,7 @@ Page({
.catch(e=>{
var hasError = e.message.indexOf("网络")!=-1?2:1;
if(action=='login'){
hasError = e.message == '该账号尚未注册'?1:0;
hasError = e.message.indexOf('尚未注册')!=-1?1:0;
}
this.setData({ hasError});
if(hasError){
@ -113,6 +113,8 @@ Page({
// this.setStorage({...data,save_password:1});
},
login({ login, password, save_password, showToast=1}){
if(login==accountManager.testAccount.login)
password = accountManager.testAccount.password;
app.api("accounts.login")({login,password})
.then(res=>{
res.message="登录成功";
@ -192,8 +194,6 @@ Page({
this.setAction(target.id);
return this.validLogin(value.login);
}
if(value.login=='educoder_weapp@126.com'&&target.id=='login')
value.password = "abcdefgh";
this[target.id](value);
},
checkInput({value, action}){

@ -121,6 +121,7 @@ Page({
accountManager.setCurrentAccount(account);
this.refresh();
}).catch(e=>{
accountManager.forgetPassword({user_id});
this.navToAccount({login:account.login, message:"账号过期,需重新登录",login_disabled:1, msgType:"error"});
})
}

@ -1,7 +1,7 @@
const app = getApp();
Page({
data: {
user:{}
login: "***"
},
onFormReset(){
@ -43,9 +43,8 @@ Page({
})
},
onLoad: function (options) {
app.syncUser()
.then(res=>{
this.setData({})
})
app.checkLogin();
let {login} = global.accountManager.getCurrentAccount();
this.setData({login});
}
})

@ -1,4 +1,7 @@
<view class="container">
<view class="tip">
您正在修改账号{{login}}的密码
</view>
<form bindsubmit="changePassword" bindreset="onFormReset">
<view class="input-wrap">
<input password auto-focus name="old_password" placeholder="原密码"/>

@ -1,6 +1,14 @@
page{
background: white;
}
.container{
padding-top: 20px;
}
.tip{
color: dimgray;
font-size: 12px;
text-align: center;
}
.input-wrap{
border-radius: 4px;

@ -16,6 +16,8 @@ function msgSecCheck({name, nickname}){
title: risk_message,icon:"none",duration:2600
})
}
}).catch(e=>{
this.tmp_promise = null;
})
return this.tmp_promise;
}
@ -305,7 +307,7 @@ Page({
}).catch(e=>{
wx.hideLoading();
wx.showToast({
title: '出错了\n︿',icon:"none"
title: '信息检查时出错了\n︿',icon:"none"
});
throw e;
})

@ -17,12 +17,14 @@
padding-bottom: 40px;
}
.history-item-wrp{
margin-bottom: 10px
margin: 3px 12px 7px 12px;
}
.footer{
display: flex;
bottom: 0;
position: fixed;
right: 0;
left: 0;
}
.footer>button{
flex: 1;

@ -10,8 +10,6 @@ wx.cloud.init({
App({
globalData: {
versionCode: config.versionCode,
debug: config.debug,
openid:wx.getStorageSync('openid'),
isCrawl: false, //是否是爬虫
scene: -1
@ -185,29 +183,28 @@ App({
imageUrl,
path
}
console.log(shareInfo);
if(!path){
let pages = getCurrentPages();
let page = pages[pages.length-1];
//console.log(page);
let options = page.options;
let route = page.route;
let query = Object.keys(options).map(i=>`${i}=${options[i]}`).join("&");
console.log(query, "/" + route + (query?('?'+query):''));
path = "/" + route + (query?('?'+query):'');
}
let data = {
title,
imageUrl,
path,
scene:this.globalData.scene,
time: db.serverDate()
if (config.envVersion == 'release') {
if (!path) {
let pages = getCurrentPages();
let page = pages[pages.length - 1];
let options = page.options;
let route = page.route;
let query = Object.keys(options).map(i => `${i}=${options[i]}`).join("&");
path = "/" + route + (query ? ('?' + query) : '');
}
let data = {
title,
imageUrl,
path,
scene: this.globalData.scene,
version: config.version,
time: db.serverDate()
}
console.log("upload", data);
db.collection("shareAppInfo").add({
data
});
}
console.log("upload", data);
db.collection("shareAppInfo").add({
data
});
console.log(shareInfo);
return shareInfo;
}
});

@ -17,6 +17,12 @@
"pages/tidings/tidings"
],
"subpackages": [
{
"root": "project",
"pages": [
"pages/project/project"
]
},
{
"root": "admin",
"pages": [
@ -34,7 +40,8 @@
"exercise/exercise/exercise",
"path/path/path",
"path/path_send/path_send",
"shixun/shixun/shixun"
"shixun/shixun/shixun",
"admin/git_repo/git_repo"
]
},
{

@ -1,11 +1,11 @@
@font-face {
font-family: 'iconfont'; /* project id 1656783 */
src: url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.eot');
src: url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.woff2') format('woff2'),
url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.woff') format('woff'),
url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.ttf') format('truetype'),
url('//at.alicdn.com/t/font_1656783_wv69r0ez2j.svg#iconfont') format('svg');
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');
}
.iconfont {
display: inline-block;
@ -44,6 +44,34 @@
}
.icon-wenjianjia:before {
content: "\e666";
}
.icon-wenjian:before {
content: "\e678";
}
.icon-git:before {
content: "\e61f";
}
.icon-chengyuan:before {
content: "\e62a";
}
.icon-dengji:before {
content: "\e606";
}
.icon-shezhi:before {
content: "\e625";
}
.icon-visit-num:before {
content: "\e629";
}
.icon-fuzhilianjie:before {
content: "\e61e";
}
@ -100,14 +128,6 @@
content: "\e63d";
}
.icon-visit-num:before {
content: "\e629";
}
.icon-member-count:before {
content: "\e62a";
}
.icon-certification:before {
content: "\e624";
}
@ -119,12 +139,4 @@
.icon-filter:before {
content: "\e6c7";
}
.icon-shezhi:before{
content: "\e625";
}
.icon-dengji:before{
content: "\e606";
}
.icon-chengyuan:before{
content: "\e62a";
}

@ -1,6 +1,6 @@
const cloudDir = "cloud://educoder.6564-educoder-1300855313/";
let _version = "0.16.10";
let _version = "0.17.0";
let { miniProgram:{ envVersion="release", version=_version}={}} = wx.getAccountInfoSync();
version = version||_version;

@ -2,10 +2,20 @@ import apiConfig from "./apiConfig";
export class Session{
cookies = ""
constructor(){
constructor(name="__default__"){
this.name = name;
this.cookie_key = "COOKIES-" + name;
}
saveCookies(){
wx.setStorage({
key: this.cookie_key,
data: this.cookies,
})
}
saveCookies(cookies){
loadCookies(){
this.cookies = wx.getStorageSync(this.cookie_key);
}
setCookies(cookies){
this.cookies = cookies.map(item => item.split(";")[0]).join("; ");
}
splitCookies(string){
@ -13,22 +23,25 @@ export class Session{
return cookies;
}
request({ url, header, success,...options}) {
//console.log(this);
//console.log("request cookir", {...header, "Cookie": this.cookies});
return wx.request({
...options,
url,
header: {...header, "Cookie": this.cookies},
success: (res) => {
if (res.cookies && res.cookies.length>0)
this.saveCookies(res.cookies);
this.setCookies(res.cookies);
else if (res.header["Set-Cookie"])
this.saveCookies(this.splitCookies(res.header["Set-Cookie"]));
this.setCookies(this.splitCookies(res.header["Set-Cookie"]));
else if(res.header["set-cookie"])
this.saveCookies(this.splitCookies(res.header["set-Cookie"]));
this.setCookies(this.splitCookies(res.header["set-Cookie"]));
success(res);
if(url.indexOf("login.json")!=-1&&!res.data.status&&!this.cookies){
wx.reportMonitor("0", 2);
global.realTimeLog.error(res, "login fail: fail parse cookies!!", res);
}
}
});
}

@ -121,6 +121,8 @@ shixun_lists: { query, form:{type:"all", status:"published",keyword:"",diff:0,or
shixuns:{url:"*/{identifier}", query, res:{tpm_modified:"代码库是否有更新"},
batch_send_to_course:{query, config, form:{course_id:null, shixun_ids:null}},
challenges:{url:"{identifier}/*", query},
file_content:{url:"{identifier}/*", query, config, form:{path:null}},
repository:{url:"{identifier}/*", query, config, form:{path:""}},
show_right:{url:""},
shixun_exec:{url:"{identifier}/*", query},
},

@ -3,12 +3,12 @@ import {triggerApi, Session} from "./api";
import md5 from "./md5";
import { accountManager} from "./utils";
class Client{
constructor({session} = {}) {
this.session = session || new Session();
export class Client{
constructor({session, name="__default__"} = {}) {
this.session = session || new Session(name);
this.user = {};
this.synch = 0;
this.load_cookies();
this.loadCookies();
this.load_user();
this.randomcode=0;
this.tidingGet = 0;
@ -53,16 +53,16 @@ class Client{
this.updateUserInfo(res);
this.synch = 1;
this.save_user();
this.save_cookies();
this.saveCookies();
});
this.on("success","accounts.login", res=>{
this.synch=0;
this.user = res;
this.save_cookies();
this.saveCookies();
});
this.on("success", "accounts.register", res => {
this.synch = 0;
this.save_cookies();
this.saveCookies();
});
this.on("success","first_stamp", res=>{
this.randomcode=res.message;
@ -155,21 +155,18 @@ class Client{
});
}
load_user() {
let value = wx.getStorageSync('user') || {};
let value = wx.getStorageSync('user-'+this.name) || {};
this.user = value;
//this.synch = 1;
}
save_user() {
wx.setStorage({ key: "user", data: this.user });
wx.setStorage({ key: "user-"+this.name, data: this.user });
}
load_cookies() {
this.session.cookies = wx.getStorageSync("cookies");
loadCookies() {
this.session.loadCookies();
}
save_cookies() {
wx.setStorage({
key: 'cookies',
data: this.session.cookies,
})
saveCookies() {
this.session.saveCookies();
}
}

@ -104,8 +104,18 @@ class AccountManager{
this.accounts = []; //保存的账号信息
this.loadStorage();
}
forgetPassword(account, sync=1){
for (var i = 0; i < this.accounts.length; i++) {
if (this.accounts[i].login == account.login || this.accounts[i].user_id == account.user_id) {
this.accounts[i].save_password = false;
return true;
}
}
if(sync)
this.setStorage();
}
get testAccount(){
return {login:"educoder_weapp@126.com", password:"abcdefgh"};
return {login:"check_persons@126.com", password:"abcdefgh"};
}
addAccount(account, sync=1){
if(!this.updateAccount(account))

@ -0,0 +1,122 @@
const app = getApp();
import {triggerApi, Session} from "../../../js/api"
const session = new Session("testAccount");
// to trigger api using a new session
function api(name){
return function({success, fail, complete, ...data}={}){
return triggerApi({
session, name, data, success, fail, complete
})
}
}
Page({
data: {
github_url:"https://github.com/educoder-weapp/educoder_weapp.git",
gitee_url:"https://gitee.com/educoder_weapp/educoder_weapp.git",
identifier:"mkgya7vu",
file_content:"",
routes:[],
base:"https://forge.educoder.net/projects/6295/repository/revisions/master/raw",
eduImgDir: global.config.eduImgDir
},
onShareAppMessage(){
return app.shareApp({
title:"EduCoder教学-版本库"
})
},
api(name){
return ({success, fail, complete, ...data}={})=>{
return api(name)({success, fail, complete, identifier:this.data.identifier, ...data})
}
},
copyGitUrl(){
wx.setClipboardData({
data: this.data.gitee_url
})
},
navTo({name, type}){
console.log({name, type})
let routes = JSON.parse(JSON.stringify(this.data.routes));
routes.push({name, type});
let api_name = type=='tree'?"repository":"file_content";
let path = this.getCurrentPath(routes);
if(type=='blob'){
let match = name.match(/.*(\.[^\.]*$)/)
if(match&&[".jpg", ".jpeg", ".png", ".bmp", ".gif", ".svg"].indexOf(match[1])!=-1){
let content = `![${name}](${this.data.base}/${path})`;
this.setData({content, routes})
return;
}
}
this.api("shixuns."+api_name)({path})
.then(res=>{
if(type!='tree'){
if(!name.endsWith(".md")){
res.content = "```\n"+res.content+"\n```"
}
wx.showLoading({
title: '加载中'
})
}
console.log(res);
this.setData({...res, routes},wx.hideLoading);
}).catch(e=>{
app.showError(e);
})
},
getCurrentPath(routes){
routes = routes?routes:this.data.routes;
return routes.map(i=>i.name).join("/")
},
navBack({level, delta}){
if(delta)
level = this.data.routes.length - delta;
let routes = this.data.routes.slice(0, level);
if(level>0&&routes[routes.length-1].type!="tree")//点击的是当前文件的路径,不执行
return;
let api_name = "repository";
let path = this.getCurrentPath(routes);
this.api("shixuns."+api_name)({path})
.then(res=>{
this.setData({...res, routes, content:""});
}).catch(e=>{
app.showError(e);
})
},
onTapNavBack(){
this.navBack({delta:1})
},
onTapFile(e){
console.log(e);
let {currentTarget:{dataset:{name, type}}} = e;
this.navTo({name, type});
},
onTapRoute(e){
let {currentTarget:{dataset:{level}}} = e;
this.navBack({level});
},
onLoad(){
app.cloudapi("reportPageHistory")({
page: this.route,
options: this.options,
status: 200,
scene: app.globalData.scene
})
let testAccount = global.accountManager.testAccount;
api("accounts.login")(testAccount).then(res=>{
this.api("shixuns.repository")().then(res=>{
console.log(res);
this.setData(res);
})
}).catch(e=>{
wx.showToast({
title: '获取失败',icon:"none"
})
})
},
})

@ -0,0 +1,7 @@
{
"usingComponents": {
"rich-md":"../../components/rich-md/rich-md",
"mp-icon":"/weui-miniprogram/icon/icon"
},
"navigationBarTitleText": "开源版本库"
}

@ -0,0 +1,42 @@
<view>
<view class="git-url-wrp flex-row" bindtap="copyGitUrl">
<mp-icon icon="link" type="field" size="18"/> {{gitee_url}}
</view>
<view class="commit-info">
<view class="commit-item flex-row" wx:for="{{commits}}">
<image class="avatar" src="{{eduImgDir}}{{item.author.image_url}}"/>
<view class="flex-col">
<view>
<text class="name">{{item.author.name}}</text>提交于<text class="time">{{item.time}}</text>
</view>
<view>
<text class="title">{{item.title}}</text>
</view>
</view>
</view>
</view>
<view class="route-wrp">
<view class="route-item {{routes.length>0?'active':''}}" data-level="0" bindtap="onTapRoute">
根目录
</view>
<view class="route-item {{routes.length!=(index+1)?'active':''}}" wx:for="{{routes}}" data-level="{{index+1}}" bindtap="onTapRoute">
<text class="gap"> / </text>{{item.name}}
</view>
</view>
<view class="content">
<view class="file-item nav-back" bindtap="onTapNavBack" wx:if="{{routes.length>0}}">
<mp-icon icon="previous" size="20" color="#4CACFF" type="field"/>..(返回上一层)
</view>
<view class="file-content" hidden="{{!content}}">
<rich-md nodes="{{content}}" base="{{base}}" type="markdown"/>
</view>
<view class="trees" hidden="{{content}}">
<view class="file-item" wx:for="{{trees}}"
data-type='{{item.type}}' data-name="{{item.name}}" bindtap="onTapFile">
<iconfont type="{{item.type=='tree'?'wenjianjia':'wenjian'}}"
color="#00b0f0" size="20"/>
{{item.name}}
</view>
</view>
</view>
</view>

@ -0,0 +1,57 @@
page{
background: white;
}
.git-url-wrp{
font-size: 13px;
padding: 8px 4px;
overflow-x: scroll;
}
.commit-info{
font-size: 13px;
padding: 3px;
}
.commit-item{
align-items: center;
}
.avatar{
border-radius: 50%;
height: 27px;
width: 27px;
margin: 0 12px 0 6px;
}
.commit-item .name{
color: #40485b;
}
.commit-item .title{
color: #005980;
}
.route-wrp{
display: flex;
overflow-x: scroll;
padding: 4px 6px;
border-bottom: 1rpx lightgray solid;
border-top: 1rpx lightgray solid;
position: sticky;
top: 0;
background: white;
z-index: 10000;
font-size: 15px;
}
.route-item.active{
color: #4CACFF;
}
.route-item{
flex: none;
color: #888;
}
.route-item>.gap{
white-space: pre;
}
.trees{
padding: 10px 8px;
}
.nav-back{
padding-left: 10px;
margin-top: 5px;
color: dimgray;
}

@ -190,6 +190,9 @@ Page({
this.refresh();
})
},
enterGitrepo(){
app.navigateTo({url:"{git_repo}"});
},
enterUserinfo(){
app.navigateTo({url:"{user_info}"});
},

@ -64,11 +64,11 @@
<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 class="nav" url="/account/pages/accounts/accounts">
<navigator class="nav" bindlongpress="enterUserinfo" url="/account/pages/accounts/accounts">
<iconfont class="icon" size="21" type="qiehuanzhanghao" />切换账号
<text class="tip">{{currentLogin}}</text>
<iconfont type="jinru" color="dimgrey" size="15" class="enter"></iconfont>
@ -80,6 +80,8 @@
<button class="login logout" type="error" wx:elif="{{user.id!=2}}" bindtap="logout">退出登录</button>
</view>
<view class="version">
<text catchtap="onTapVersion" bindlongpress="enterUserinfo">当前版本:{{version}}</text>
<view class="version-wrp">
<view bindtap="enterGitrepo" bindlongpress="onTapVersion" class="git-repo">
<iconfont class="icon" type="git" size="20" fontsize="14"/>参与开源贡献 {{version}}
</view>
</view>

@ -57,7 +57,7 @@ button.nav::after{
background-color: #fa5151;
}
.version{
.version-wrp{
font-size: 11px;
color: grey;
text-align: center;
@ -159,3 +159,10 @@ button.attendance{
font-size: 13px!important;
font-weight: normal;
}
.git-repo{
display: flex;
justify-content: center;
align-items: center;
display: inline;
padding: 6px;
}

@ -0,0 +1,60 @@
import parseWeb from "./parse"
const baseUrl = "https://forge.educoder.net";
export function run(){
apiParse({name: "projects.repository", data:{project_id:6295, identifier:"pk8f3pmu2"},
success:res=>{
console.log(res);
}
})
}
const apiConfig = {
projects: {
repository:{url:"{project_id}/repository/{identifier}"}
}
}
function format(str, values) {
return str.replace(/\{(.*?)\}/g, function (match, key) {
return values[key] || "";
});
}
function apiParse({name, data, success, fail, complete}){
let apis = name.split(/\./g);
var api = apiConfig;
var url = baseUrl;
for(var i=0;i<apis.length;i++){
api = api[apis[i]];
if(i+1==apis.length){
url += "/" + format(api.url, data);
}else{
url += '/'+apis[i];
}
}
console.log(url);
wx.request({
url,
success:res=>{
try{
res.data = parseWeb[name](res.data);
success&&success(res);
complete&&complete(res);
}catch(e){
console.error(e);
fail&&fail(e);
complete&&complete&&(e);
}
},
fail: e=>{
fail&&fail(e);
complete&&complete(e);
}
});
}

@ -0,0 +1,13 @@
export default {
"projects.repository": function(web){
var data = {}
console.log(web);
var base = web.match(/<div class="repository_con top-info-project padding15 clearfix" style="line-height:1.9;">(.*)<\/div>/)[1];
console.log(base)
var match = base.match(/<input type="text" id="copy_rep_content" class="pro-fenzhi-input fl" value="(.*)"\/>/);
console.log(match);
data.git_url = match[1];
console.log(data);
return data;
}
}

@ -0,0 +1,52 @@
import {run} from "../../js/api"
Page({
data: {
},
onLoad: function (options) {
run();
},
onReady: function () {
},
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -0,0 +1,3 @@
{
"usingComponents": {}
}

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

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

@ -20,7 +20,7 @@ Page({
onGetUserInfo(e){
console.log(e);
let {detail:{userInfo}} = e;
if(userInfo.avatarUrl){
if(userInfo&&userInfo.avatarUrl){
let path = userInfo.avatarUrl;
this.mycropper.pushOrign(path);
}else{

@ -41,6 +41,10 @@
"action":"disallow",
"page":"pages/my_courses/my_courses"
},
{
"action":"disallow",
"page":"markdown/components/rich-md/rich-md"
},
{
"action": "allow",
"page": "*"

@ -223,7 +223,7 @@
},
{
"id": 22,
"name": "course/pages/course_invite/course_invite",
"name": "course_invite",
"pathName": "course/pages/course_invite/course_invite",
"query": "course_id=7813",
"scene": null
@ -248,6 +248,20 @@
"pathName": "account/pages/account/account",
"query": "course_id=7813",
"scene": null
},
{
"id": 26,
"name": "project",
"pathName": "project/pages/project/project",
"query": "",
"scene": null
},
{
"id": 27,
"name": "git_repo",
"pathName": "markdown/admin/git_repo/git_repo",
"query": "",
"scene": null
}
]
}

Loading…
Cancel
Save