67 Commits
Author SHA1 Message Date
MrKBear 4c66a8974f Add login UI style 2022-06-10 12:33:38 +08:00
MrKBear 349930d438 Add login layer 2022-06-10 00:09:20 +08:00
MrKBear f9c73b25fe Optimize account page ui style 2022-06-09 20:08:27 +08:00
MrKBear d733c75371 Update project config 2022-06-09 17:23:09 +08:00
MrKBear 2fd3f5a0db (#22) Add Data Modular. 2022-01-28 08:41:22 +08:00
MrKBear f2f68c1f4a Merge branch 'master' into dev-mrkbear 2022-01-26 14:51:03 +08:00
MrKBear 1917828eab Merge pull request '(#22)(#56) Add student info data ware.' (#67) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/67
2022-01-25 17:13:12 +08:00
MrKBear afae6b7903 (#22)(#56) Add student info data ware. 2022-01-25 17:11:29 +08:00
MrKBear b2854908a4 Merge pull request '(#56) Data prototype use custrmers function.' (#65) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/65
2022-01-25 13:05:55 +08:00
MrKBear 7f86ae9fd2 Merge branch 'master' into dev-mrkbear 2022-01-25 13:05:42 +08:00
MrKBear 22188907c2 (#56) Data prototype use custrmers function. 2022-01-25 13:04:41 +08:00
MrKBear 33e49cb8be Merge pull request '(#36) Optimization popup layer modular.' (#64) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/64
2022-01-24 16:57:00 +08:00
MrKBear 1dcc09980c (#36) Optimization popup layer modular. 2022-01-24 16:55:58 +08:00
MrKBear 6a4cae757d Merge pull request '(#36) Merge mask modular & popup modular in popup layer modular.' (#63) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/63
2022-01-24 14:59:33 +08:00
MrKBear 18381aa0c4 (#36) Merge mask modular & popup modular in popup layer modular. 2022-01-24 14:58:33 +08:00
MrKBear 943798f53c (#36) Add popuplayer. 2022-01-23 20:34:52 +08:00
MrKBear a5dc26cd17 Merge pull request '(#60) Remove mixin generic paradigm.' (#62) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/62
2022-01-23 12:10:05 +08:00
MrKBear 464a9d3e59 (#60) Remove mixin generic paradigm. 2022-01-23 12:08:38 +08:00
MrKBear 292a4c26c5 (#60) Core emitter generic optimization 2022-01-22 17:50:25 +08:00
MrKBear e97514a67f (#60) Core emitter generic optimization 2022-01-22 17:49:03 +08:00
MrKBear 27ac19141f Merge pull request '(#60) Core emitter generic optimization' (#61) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/61
2022-01-22 16:13:40 +08:00
MrKBear c385965655 (#60) Core emitter generic optimization 2022-01-22 16:10:24 +08:00
MrKBear 43d87b40f7 Merge pull request '(#21) Mixin IAnyData in app' (#59) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/59
2022-01-21 17:39:13 +08:00
MrKBear 660f6921de (#21) Mixin IAnyData in app 2022-01-21 17:38:41 +08:00
MrKBear 86101e01d1 Merge pull request '(#22) Add StudentInfo file' (#58) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/58
2022-01-21 17:37:05 +08:00
MrKBear 1f2a2ad6bd (#22) Add StudentInfo file 2022-01-21 17:36:16 +08:00
MrKBear b91a9271a7 Merge pull request '(#56) Add Core Data.' (#57) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/57
2022-01-21 17:33:10 +08:00
MrKBear ec635b9ae6 (#56) Add Core Data. 2022-01-21 17:30:08 +08:00
MrKBear 6f96a69900 Merge pull request '(#35)Add mask modular event.' (#55) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/55
2022-01-21 10:43:24 +08:00
MrKBear 58d8d74158 (#35)Add mask modular event. 2022-01-21 10:38:37 +08:00
MrKBear 96b3414d22 Merge pull request '(#28)Add a api frame (incomplete file)' (#51) from dev-tamako into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/51
2022-01-20 23:52:35 +08:00
TamakoStar 529011b0dd (#28)Add Schedule API 2022-01-20 23:47:02 +08:00
TamakoStar 4da257c2e2 (#28)Add Schedule API 2022-01-20 22:19:10 +08:00
TamakoStar f11eb63ee1 Merge branch 'master' into dev-tamako 2022-01-20 21:45:30 +08:00
MrKBear 49c4f7f0d4 Merge pull request '(#52) Add EduBase API' (#53) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/53
2022-01-20 21:43:41 +08:00
MrKBear 4158887d2e (#52) Add EduBase API 2022-01-20 21:42:44 +08:00
MrKBear a8e16f5972 (#28) Add output data mod 2022-01-20 20:57:41 +08:00
TamakoStar d9825d6d68 (#28)Add a api frame (incomplete file) 2022-01-20 20:38:57 +08:00
TamakoStar fab73f00ab Merge branch 'master' into dev-tamako 2022-01-20 20:33:02 +08:00
TamakoStar edb26b3d8b Merge branch 'dev-tamako' of http://git.mrkbear.com/MrKBear/mini-dlpu-v3 into dev-tamako 2022-01-20 20:31:52 +08:00
TamakoStar 443f82ea75 (#28)Add a api frame (incomplete file) 2022-01-20 20:30:36 +08:00
TamakoStar 75adb97abb (#28)Add a api frame (incomplete file) 2022-01-20 20:17:32 +08:00
MrKBear b36996e352 Merge pull request '(#35) Add mask show hide motion' (#50) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/50
2022-01-20 17:20:42 +08:00
MrKBear 6bef08f12e (#35) Add mask show hide motion 2022-01-20 17:18:44 +08:00
MrKBear 1f24a59bd9 Merge pull request '(#48) Core Api baseUrl param can be overridden' (#49) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/49
2022-01-20 16:11:42 +08:00
MrKBear 14d0c9c123 (#48) Core Api baseUrl param can be overridden 2022-01-20 16:10:55 +08:00
MrKBear b99a3412e2 Merge pull request '(#37) Optimize Account page' (#47) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/47
2022-01-20 13:27:16 +08:00
MrKBear 63300f68f8 (#37) Optimize Account page 2022-01-20 13:26:24 +08:00
MrKBear acf4f94798 Merge pull request '(#45) Optimize Modular loading performance' (#46) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/46
2022-01-20 11:53:14 +08:00
MrKBear 87f4d220e5 (#45) Optimize Modular loading performance 2022-01-20 11:52:10 +08:00
MrKBear cf4dd727c5 Merge pull request '(#37) Optimization function list' (#44) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/44
2022-01-19 21:58:20 +08:00
MrKBear 49055e892c (#37) Optimization function list 2022-01-19 21:55:55 +08:00
MrKBear afedb81633 Merge pull request '(#37) Fix checkmark display' (#43) from dev-mrkbear into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/43
2022-01-19 21:22:03 +08:00
MrKBear 04b8bf365f Merge branch 'dev-mrkbear' of http://git.mrkbear.com/MrKBear/mini-dlpu-v3 into dev-mrkbear 2022-01-19 21:21:41 +08:00
MrKBear 874c64829a (#37) Add mask modular 2022-01-19 21:21:21 +08:00
MrKBear 82e1c0941e (#37) Fix checkmark display 2022-01-19 17:38:15 +08:00
MrKBear 3119c862b1 Merge pull request '用户页面实现 #37 dev-sanaesy' (#40) from dev-sanaesy into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/40
2022-01-18 22:34:12 +08:00
MrKBear 23f46a24c9 (#37)Add Function List 2022-01-18 22:30:05 +08:00
MrKBear fc8aa19c67 Merge 'master' into dev-sanaesy 2022-01-18 21:36:37 +08:00
MrKBear 72448038d1 Merge pull request '用户界面实现(#37)dev-gia_jie' (#41) from dev-gia_jie into master
Reviewed-on: http://git.mrkbear.com/MrKBear/mini-dlpu-v3/pulls/41
2022-01-18 21:18:46 +08:00
sanaesy 95f1f6d484 (#37) 2022-01-18 11:47:25 +08:00
sanaesy 54d87fc5db (#37) 2022-01-18 11:39:15 +08:00
sanaesy f434ad531c (#37) 2022-01-18 11:06:11 +08:00
111 a92f2d06ea (#37) 2022-01-18 00:43:38 +08:00
111 45e8ef9322 (#37) 2022-01-17 23:03:48 +08:00
sanae kochiya 7c1e4e441a (#37) 2022-01-17 22:57:05 +08:00
TamakoStar 7a5d43281b Add Schedule Api file 2022-01-17 22:52:51 +08:00
35 changed files with 2286 additions and 178 deletions
+95
View File
@@ -0,0 +1,95 @@
import { API, IAnyData, GeneralCallbackResult } from "../core/Api";
import { EventType, Emitter } from "../core/Emitter";
type ILoginEvent = {
/**
* session 过期
*/
expire: GeneralCallbackResult;
/**
* 登录失败
*/
unauthorized: GeneralCallbackResult;
/**
* 未知的问题
*/
error: GeneralCallbackResult;
/**
* 数据损坏或丢失
*/
badData: GeneralCallbackResult;
}
/**
* 教务处基础 API
* @template I API 输入数据
* @template O API 输出数据
* @template E API 中的事件
* @template U 用户自定义的输出数据
*/
abstract class EduBase<
I extends IAnyData = IAnyData,
O extends IAnyData = IAnyData,
E extends Record<EventType, any> = {}
> extends API<I, O, {
[P in (keyof ILoginEvent | keyof E)]: P extends keyof ILoginEvent ? ILoginEvent[P] : E[P]
}> {
protected useEduCallback(
parseFunction: (data: any) => O
): void {
this.addFailedCallBack();
this.on("success", (data) => {
let isSuccess = true;
let errMsg = "";
let res: O | undefined;
const info: any = data.data;
// 数据缺失检测
if(!info) {
isSuccess = false;
errMsg = "Bad Data";
(this as Emitter<IAnyData>).emit("badData", { errMsg });
}
if (isSuccess) switch (info.code) {
case (1):
res = parseFunction(info.data);
errMsg = info.err_msg ?? "Success";
(this as Emitter<IAnyData>).emit("ok", res!);
break;
case (2):
isSuccess = false;
errMsg = info.err_msg ?? "Session Expire";
(this as Emitter<IAnyData>).emit("expire", { errMsg });
break;
case (3):
isSuccess = false;
errMsg = info.err_msg ?? "Unauthorized";
(this as Emitter<IAnyData>).emit("unauthorized", { errMsg });
break;
case (4):
isSuccess = false;
errMsg = info.err_msg ?? "Error";
(this as Emitter<IAnyData>).emit("error", { errMsg });
break;
}
if (!isSuccess) (this as Emitter<IAnyData>).emit("no", { errMsg });
(this as Emitter<IAnyData>).emit("done", { errMsg, data: res });
});
}
}
export { EduBase };
export default EduBase;
+10 -81
View File
@@ -1,4 +1,5 @@
import { API, HTTPMethod, IParamSetting, GeneralCallbackResult } from "../core/Api"; import { HTTPMethod, IParamSetting } from "../core/Api";
import { EduBase } from "./EduBase";
interface ILoginInput { interface ILoginInput {
@@ -31,46 +32,18 @@ interface ILoginOutput {
*/ */
actualName: string; actualName: string;
/**
* 用户是否关注了公共号
*/
isSubscribeWxAccount: boolean;
/** /**
* 教务处的 session * 教务处的 session
*/ */
eduSession: string; eduSession: string;
} }
interface ILoginEvent {
/**
* session 过期
*/
expire: GeneralCallbackResult;
/**
* 登录失败
*/
unauthorized: GeneralCallbackResult;
/**
* 未知的问题
*/
error: GeneralCallbackResult;
/**
* 数据损坏或丢失
*/
badData: GeneralCallbackResult;
}
/** /**
* Login API * Login API
* 此 API 用来向教务处发起登录请求 * 此 API 用来向教务处发起登录请求
* 请求成功后将获得教务处返回的 session * 请求成功后将获得教务处返回的 session
*/ */
class Login extends API<ILoginInput, ILoginOutput, ILoginEvent> { class Login extends EduBase<ILoginInput, ILoginOutput> {
public override url: string = "/login"; public override url: string = "/login";
@@ -92,57 +65,13 @@ class Login extends API<ILoginInput, ILoginOutput, ILoginEvent> {
super(); super();
this.initDebugLabel("Login"); this.initDebugLabel("Login");
this.addFailedCallBack(); this.useEduCallback((data) => ({
idCardLast6: data.idCard,
this.on("success", (data) => { eduService: data.ip,
actualName: data.name,
let isSuccess = true; isSubscribeWxAccount: data.official,
let errMsg = ""; eduSession: data.session
let res: ILoginOutput | undefined; }));
const info: any = data.data;
// 数据缺失检测
if(!info) {
isSuccess = false;
errMsg = "Bad Data";
this.emit("badData", { errMsg });
}
if (isSuccess) switch (info.code) {
case (1):
res = {
idCardLast6: info.data.idCard,
eduService: info.data.ip,
actualName: info.data.name,
isSubscribeWxAccount: info.data.official,
eduSession: info.data.session
};
errMsg = info.err_msg ?? "Success";
this.emit("ok", res);
break;
case (2):
isSuccess = false;
errMsg = info.err_msg ?? "Session Expire";
this.emit("expire", { errMsg });
break;
case (3):
isSuccess = false;
errMsg = info.err_msg ?? "Unauthorized";
this.emit("unauthorized", { errMsg });
break;
case (4):
isSuccess = false;
errMsg = info.err_msg ?? "Error";
this.emit("error", { errMsg });
break;
}
if (!isSuccess) this.emit("no", { errMsg });
this.emit("done", { errMsg, data: res });
});
} }
} }
+110
View File
@@ -0,0 +1,110 @@
import { HTTPMethod, IParamSetting } from "../core/Api";
import { EduBase } from "./EduBase";
interface IScheduleInput {
/**
* session
*/
cookie: string;
/**
* 学期
*/
semester: string;
}
interface IClassData {
/**
* 课程名字
*/
name: string;
/**
* 上课地点
*/
room?: string;
/**
* 课程老师
*/
teacher?: string;
/**
* 周数
*/
week: string;
}
type IScheduleOutput = {
/**
* 课程列表
*/
classList: IClassData[];
/**
* 稀疏矩阵编号
*/
index: number;
}[];
/**
* Schedule API
* 需要session与semester
* 此 API 用来向教务处发起获取课程表的请求
* 请求成功后将获得教务处返回的课程表JSON文件
*/
class Schedlue extends EduBase<IScheduleInput, IScheduleOutput> {
public override url = "/course_timetable";
public override method: HTTPMethod = HTTPMethod.GET;
public override params: IParamSetting<IScheduleInput> = {
cookie: {
mapKey: "cookie",
isHeader: true
},
semester: {
mapKey: "semester",
}
};
public constructor() {
super();
this.initDebugLabel("Schedule");
this.useEduCallback((data) => {
const res: IScheduleOutput = [];
for( let i = 0; i < data.length; i++ ) {
const classList: IClassData[] = [];
const CTTDetails = data[i].CTTDetails ?? [];
for( let j = 0; j < CTTDetails.length; j++ ) {
classList.push({
name: CTTDetails[j].Name,
room: CTTDetails[j].Room,
teacher: CTTDetails[j].Teacher,
week: CTTDetails[j].Week,
})
}
res.push({
classList,
index: data[i].Id
})
}
return res;
});
}
}
export { Schedlue };
export default Schedlue;
+17 -2
View File
@@ -6,20 +6,27 @@ $theme-color-light-layout: #F8F8F8;
$theme-color-light-background: #f4f0f1; $theme-color-light-background: #f4f0f1;
$theme-color-light-title: rgba(0, 0, 0, .65); $theme-color-light-title: rgba(0, 0, 0, .65);
$theme-color-light-text: rgba(0, 0, 0, .5); $theme-color-light-text: rgba(0, 0, 0, .5);
$theme-color-light-line: rgba(0, 0, 0, .25);
$theme-color-dark-layout: #1f1f1f; $theme-color-dark-layout: #1f1f1f;
$theme-color-dark-background: #181615; $theme-color-dark-background: #181615;
$theme-color-dark-title: rgba(255, 255, 255, .65); $theme-color-dark-title: rgba(255, 255, 255, .65);
$theme-color-dark-text: rgba(255, 255, 255, .5); $theme-color-dark-text: rgba(255, 255, 255, .5);
$theme-color-dark-line: rgba(255, 255, 255, .25);
$black-filter: brightness(0) opacity(.65); $black-filter: brightness(0) opacity(.65);
$white-filter: brightness(100) opacity(.65); $white-filter: brightness(100) opacity(.65);
$blue-filter: opacity(1); $blue-filter: opacity(1);
$green-filter: hue-rotate(-110deg) opacity(1);
@mixin container {
width: 88%;
padding: 0 6%;
}
// 页面容器外边距 // 页面容器外边距
view.container { view.container {
width: 88%; @include container;
padding: 0 6%;
} }
// 带阴影的 card // 带阴影的 card
@@ -79,6 +86,14 @@ view.h3 {
font-size: 1em; font-size: 1em;
letter-spacing: .1em; letter-spacing: .1em;
} }
view.button {
color: white;
background-color: $theme-color-blue;
text-align: center;
padding: 10px;
border-radius: 10px;
}
@media (prefers-color-scheme: dark){ @media (prefers-color-scheme: dark){
page { page {
+2 -2
View File
@@ -1,9 +1,9 @@
import { IAppAPIParam } from "./core/Api"; import { IAppAPIParam, IAnyData } from "./core/Api";
import { IAppStorageParam, Storage, IStorageData } from "./core/Storage"; import { IAppStorageParam, Storage, IStorageData } from "./core/Storage";
import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger"; import { Logger, LevelLogLabel, LifeCycleLogLabel } from "./core/Logger";
App<IAppAPIParam & IAppStorageParam>({ App<IAppAPIParam & IAppStorageParam & IAnyData>({
/** /**
* API 模块需要的全局数据 * API 模块需要的全局数据
+24 -32
View File
@@ -1,4 +1,4 @@
import { Emitter, EventType } from "./Emitter"; import { Emitter, EventType, EventMixin } from "./Emitter";
import { API_FAILED_SHOW_MESSAGE } from "./Config"; import { API_FAILED_SHOW_MESSAGE } from "./Config";
import { Logger, LogLabel, LevelLogLabel, colorRadio, StatusLabel } from "./Logger"; import { Logger, LogLabel, LevelLogLabel, colorRadio, StatusLabel } from "./Logger";
interface IAppAPIParam { interface IAppAPIParam {
@@ -156,28 +156,20 @@ class API<
O extends IAnyData = IAnyData, O extends IAnyData = IAnyData,
E extends Record<EventType, any> = Record<EventType, any>, E extends Record<EventType, any> = Record<EventType, any>,
U extends IAnyData = IAnyData U extends IAnyData = IAnyData
> extends Emitter < > extends Emitter<EventMixin<IAPIEvent<I, O> & IAPIResultEvent<O, U>, E>> {
{
// 这个复杂的泛型是为了 MixIn 用户自定义事件类型
// 懂得如何使用就可以了
// 不要试图去理解下面这三行代码,真正的恶魔在等着你
[P in (keyof (IAPIEvent<I, O> & IAPIResultEvent<O, U>) | keyof E)] :
P extends keyof IAPIEvent<I, O> ? IAPIEvent<I, O>[P] :
P extends keyof IAPIResultEvent<O, U> ? IAPIResultEvent<O, U>[P] : E[P]
}
> {
/**
* 默认调试标签
*/
public static defaultLogLabel:LogLabel = new LogLabel(
`API:API`, colorRadio(200, 120, 222)
);
/** /**
* 基础 URL * 基础 URL
* TODO: 这里可能涉及负载均衡 * TODO: 这里可能涉及负载均衡
*/ */
public static get baseUrl():string { public baseUrl: string = "https://jwc.nogg.cn";
return "https://jwc.nogg.cn";
}
public static defaultLogLabel:LogLabel = new LogLabel(
`API:API`, colorRadio(200, 120, 222)
);
/** /**
* Logger 使用的标签 * Logger 使用的标签
@@ -315,11 +307,11 @@ class API<
} }
// 触发数据初始化事件 // 触发数据初始化事件
this.emit("initData", this.data); (this as Emitter<IAnyData>).emit("initData", this.data);
// 重置请求数据 // 重置请求数据
const requestData:IWxRequestOption<O> = this.requestData = { const requestData:IWxRequestOption<O> = this.requestData = {
url: API.baseUrl + this.url, url: this.baseUrl + this.url,
data: {}, header: {}, data: {}, header: {},
timeout: this.timeout, timeout: this.timeout,
method: this.method, method: this.method,
@@ -342,7 +334,7 @@ class API<
} }
// 触发数据解析 // 触发数据解析
this.emit("parseRequestData", this.data); (this as Emitter<IAnyData>).emit("parseRequestData", this.data);
// 数据收集 // 数据收集
for (let key in this.params) { for (let key in this.params) {
@@ -460,18 +452,18 @@ class API<
let request = () => { let request = () => {
// 触发请求发送事件 // 触发请求发送事件
this.emit("request", this.requestData!) (this as Emitter<IAnyData>).emit("request", this.requestData!)
wx.request<O>({ wx.request<O>({
...this.requestData!, ...this.requestData!,
success: (e) => { success: (e) => {
this.emit("success", e); (this as Emitter<IAnyData>).emit("success", e);
}, },
fail: (e) => { fail: (e) => {
this.emit("fail", e); (this as Emitter<IAnyData>).emit("fail", e);
}, },
complete: (e) => { complete: (e) => {
this.emit("complete", e); (this as Emitter<IAnyData>).emit("complete", e);
} }
}); });
} }
@@ -489,12 +481,12 @@ class API<
// 使用上次请求结果 // 使用上次请求结果
if (this.policy === RequestPolicy.useLastRequest) { if (this.policy === RequestPolicy.useLastRequest) {
lastAPI.on("success", (e) => { lastAPI.on("success", (e) => {
this.emit("success", e as SuccessCallbackResult<O>); (this as Emitter<IAnyData>).emit("success", e as SuccessCallbackResult<O>);
this.emit("complete", {errMsg: e.errMsg}); (this as Emitter<IAnyData>).emit("complete", {errMsg: e.errMsg});
}); });
lastAPI.on("fail", (e) => { lastAPI.on("fail", (e) => {
this.emit("fail", e); (this as Emitter<IAnyData>).emit("fail", e);
this.emit("complete", {errMsg: e.errMsg}); (this as Emitter<IAnyData>).emit("complete", {errMsg: e.errMsg});
}); });
} }
@@ -604,8 +596,8 @@ class API<
*/ */
public addFailedCallBack(): this { public addFailedCallBack(): this {
this.on("fail", (e) => { this.on("fail", (e) => {
this.emit("no", e as any); (this as Emitter<IAnyData>).emit("no", e as any);
this.emit("done", e as any); (this as Emitter<IAnyData>).emit("done", e as any);
}); });
return this; return this;
} }
@@ -697,4 +689,4 @@ enum HTTPMethod {
} }
export default API; export default API;
export { API, IParamSetting, IAppAPIParam, ICallBack, HTTPMethod, RequestPolicy, GeneralCallbackResult } export { API, IParamSetting, IAppAPIParam, IAnyData, ICallBack, HTTPMethod, RequestPolicy, GeneralCallbackResult }
+277
View File
@@ -0,0 +1,277 @@
import { Storage } from "./Storage";
/**
* 数据层键值设置
*/
interface IDataParamSettingItem {
/**
* 类型
*/
type: any;
/**
* 键值是否可以获取
*/
get?: ((...P: any) => this["type"]) | INone;
/**
* 键值是否可以设置
*/
set?: ((...P: [this["type"], ...any]) => any) | INone;
/**
* 是否仅为异步获取
*/
getAsync?: ((...P: any) => Promise<this["type"]>) | INone;
/**
* 是否仅为异步设置
*/
setAsync?: ((...P: [this["type"], ...any]) => Promise<any>) | INone;
}
/**
* 数据层参数类型
*/
interface IDataParamSetting {
[x: string]: IDataParamSettingItem
}
type INone = undefined | void;
/**
* 注册表结构
*/
type IRegistryItem<S extends IDataParamSettingItem> = {
/**
* 获取方法
*/
get: S["get"];
/**
* 异步获取方法
*/
getAsync: S["getAsync"] extends Function ? S["getAsync"] :
S["get"] extends ((...P: any) => S["type"]) ? (...param: Parameters<S["get"]>) => Promise<S["type"]> : INone;
/**
* 设置方法
*/
set: S["set"];
/**
* 异步设置方法
*/
setAsync: S["setAsync"] extends Function ? S["setAsync"] :
S["set"] extends ((...P: [S["type"], ...any]) => any) ? (...param: Parameters<S["set"]>) => Promise<ReturnType<S["set"]>> : INone;
}
/**
* 注册表参数类型
*/
type IRegistry<D extends IDataParamSetting> = {
[P in keyof D]: IRegistryItem<D[P]>;
}
type IRegistryPartial<D extends IDataParamSetting> = {
[P in keyof D]?: Partial<IRegistryItem<D[P]>>;
}
type IAutoSelect<IF extends boolean, A, B> = IF extends true ? A : B;
/**
* Core 数据层架构
*
* 使用示例:
* ```typescript
* class TestData extends Data<{
* test: {
* type: number
* get: () => number,
* set: (val: number) => void,
* getAsync: () => Promise<number>
* }
* }> {
* public onLoad() {
* let dataObject = {key: 1}
* this.getter("test", () => 1);
* this.registerKeyFromObject(dataObject, "test", "key");
* }
* }
* ```
*/
class Data<D extends IDataParamSetting> {
/**
* getter setter 注册表
*/
private registryList: IRegistryPartial<D> = {};
/**
* 加载函数
*/
public onLoad(): any {};
/**
* 注册一个 Setter 到键值上
* @param key 注册的键值
* @param setter 注册的 Setter
* @param isAsync 是否为异步函数
*/
protected setter<KEY extends keyof D> (key: KEY, setter: IRegistryItem<D[KEY]>["set"]): this
protected setter<KEY extends keyof D> (key: KEY, setter: IRegistryItem<D[KEY]>["setAsync"], isAsync: true): this
protected setter<
KEY extends keyof D,
ASYNC extends boolean
> (
key: KEY,
setter: IAutoSelect<ASYNC, IRegistryItem<D[KEY]>["setAsync"], IRegistryItem<D[KEY]>["set"]>,
isAsync?: ASYNC
): this {
// 如果此键值不存在,新建
if (!this.registryList[key]) this.registryList[key] = {};
// 设置异步 setter
if (isAsync) this.registryList[key]!.setAsync = setter as IRegistryItem<D[KEY]>["setAsync"];
// 设置同步 setter
else this.registryList[key]!.set = setter as IRegistryItem<D[KEY]>["set"];
return this;
}
/**
* 注册一个 Getter 到键值上
* @param key 注册的键值
* @param getter 注册的 Getter
* @param isAsync 是否为异步函数
*/
protected getter<KEY extends keyof D> (key: KEY, getter: IRegistryItem<D[KEY]>["get"]): this
protected getter<KEY extends keyof D> (key: KEY, getter: IRegistryItem<D[KEY]>["getAsync"], isAsync: true): this
protected getter<
KEY extends keyof D,
ASYNC extends boolean
> (
key: KEY,
getter: IAutoSelect<ASYNC, IRegistryItem<D[KEY]>["getAsync"], IRegistryItem<D[KEY]>["get"]>,
isAsync?: ASYNC
): this {
// 如果此键值不存在,新建
if (!this.registryList[key]) this.registryList[key] = {};
// 设置异步 getter
if (isAsync) this.registryList[key]!.getAsync = getter as IRegistryItem<D[KEY]>["getAsync"];
// 设置同步 getter
else this.registryList[key]!.get = getter as IRegistryItem<D[KEY]>["get"];
return this;
}
/**
* 将对象的键值关联到 Data 层中
* @param key Data 层键值
* @param keyFromObject 对象源键值
* @param object 关联对象
*/
protected registerKeyFromObject<
KEY extends keyof D,
F extends string,
O extends {[K in F]: D[KEY]["type"]}
> (object: O, key: KEY, keyFromObject: F = key as any) {
// 注册同步获取
this.getter(key, () => {
return object[keyFromObject]
});
// 注册同步设置
this.setter(key, (data: any) => {
object[keyFromObject] = data
})
}
/**
* 关联 Storage 中的 key
* @param key Data 层键值
* @param keyFromStorage StorageKey
*/
protected registerKeyFromStorage<
KEY extends keyof D,
F extends string,
S extends Storage<{[K in F]: D[KEY]["type"]}>
> (storage: S, key: KEY, keyFromStorage: F = key as any) {
// 同步获取
this.getter(key, () => {
return storage.get(keyFromStorage);
});
// 同步设置
this.setter(key, (data: any) => {
storage.set(keyFromStorage, data);
});
// 异步设置
this.setter(key, (async (data: any) => {
await storage.set(keyFromStorage, data);
}) as any, true);
}
/**
* 导出数据对象
* @returns 数据对象
*/
public export(): IRegistry<D> {
this.autoFillFunction();
return this.registryList as IRegistry<D>;
}
/**
* 自动填充缺失的异步函数
* 在注册表中搜索全部的同步函数
* 并自动填充对应的异步函数
* 此函数会在 export 前静默执行
*/
protected autoFillFunction(): void {
// 填充函数
const fillFunction = <KEY extends keyof D>(key: KEY): void => {
const item = this.registryList[key] as IRegistryItem<D[KEY]>;
if (!item) return;
// 检验 getter
if (item.get && !item.getAsync) {
item.getAsync = this.syncFn2AsyncFn(item.get) as any;
}
// 检验 setter
if (item.set && !item.setAsync) {
item.setAsync = this.syncFn2AsyncFn(item.set) as any;
}
}
// 在注册表中查找
for (const key in this.registryList) fillFunction(key);
}
/**
* 将同步函数转换为异步函数
* @param fn 同步函数
*/
protected syncFn2AsyncFn<F extends (...p: any) => any> (fn: F): (...param: Parameters<F>) => ReturnType<F> {
const asyncFn = async (...param: [D]) => {
return fn(...param);
};
return asyncFn as any;
}
}
export { Data };
export default Data;
+18 -1
View File
@@ -13,6 +13,21 @@ export type EventHandlerMap<Events extends Record<EventType, any>> = Map<
EventHandlerList<Events[keyof Events]> EventHandlerList<Events[keyof Events]>
>; >;
// Emitter function type
type IEmitParamType<E extends Record<EventType, any>, K extends keyof E> =
E[K] extends ( undefined | void ) ? [type: K] : [type: K, evt: E[K]];
// Mixin to event object
export type EventMixin<A extends Record<EventType, any>, B extends Record<EventType, any>> = {
[P in (keyof A | keyof B)] :
P extends (keyof A & keyof B) ?
A[P] :
P extends keyof A ?
A[P] :
P extends keyof B ? B[P] :
never;
}
export class Emitter<Events extends Record<EventType, any>> { export class Emitter<Events extends Record<EventType, any>> {
/** /**
@@ -74,7 +89,8 @@ export class Emitter<Events extends Record<EventType, any>> {
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
* @memberOf mitt * @memberOf mitt
*/ */
emit<Key extends keyof Events>(type: Key, evt: Events[Key]) { public emit<Key extends keyof Events>(...param: IEmitParamType<Events, Key>): this {
const [ type, evt ] = param;
let handlers = this.all!.get(type); let handlers = this.all!.get(type);
if (handlers) { if (handlers) {
(handlers as EventHandlerList<Events[keyof Events]>) (handlers as EventHandlerList<Events[keyof Events]>)
@@ -83,5 +99,6 @@ export class Emitter<Events extends Record<EventType, any>> {
handler(evt!); handler(evt!);
}); });
} }
return this;
} }
} }
+21
View File
@@ -491,6 +491,27 @@ class Manager<WXC extends AnyWXContext = AnyWXContext> {
}) })
} }
/**
* 异步页面加载
*
* *注意*
* 页面模块加载后,必须手动执行 loadAllModule
* loadAllModule Modular 才会真正的被加载
* 模块加载后可以处理逻辑绑定
*/
public static async PageAsync(): Promise<{
manager: Manager<AnyWXContext>,
query: Record<string, string | undefined>
}> {
return new Promise((solve) => {
Page({
async onLoad(query) {
let manager = new Manager(this);
await solve({ manager, query });
}
})
});
}
} }
export { Manager, Modular, AnyWXContext, WXContext, ILifetime} export { Manager, Modular, AnyWXContext, WXContext, ILifetime}
+154
View File
@@ -0,0 +1,154 @@
import { Data } from "../core/Data";
import { Storage } from "../core/Storage";
import { Login, ILoginOutput } from "../api/Login";
/**
* 登录状态
*/
enum LoginStatus {
/**
* 已认证
*/
verified = 1,
/**
* 失效的认证
* 通常为用户名密码错误
*/
invalid = 2,
/**
* 没有登录信息
*/
none = 3
}
/**
* API 返回数据
*/
type ILoginApiData = {
[P in keyof ILoginOutput]: {
type: ILoginOutput[P];
getAsync: () => Promise<ILoginOutput[P]>;
}
}
/**
* Storage 缓存数据类型
*/
type IStudentInfoStorageData = ILoginOutput & {
[P in keyof IStudentInfoData]: IStudentInfoData[P]["type"];
};
/**
* 学生信息数据结构
*/
type IStudentInfoData = {
/**
* 学号
*/
studentId: {
type: string,
};
/**
* 教务处密码
*/
password: {
type: string
};
/**
* 登录状态
*/
loginStatus: {
type: LoginStatus
}
/**
* 上次登录时间
* 时间戳
*/
lastLoginTime: {
type: number
}
/**
* 距离上次登录后
* 学号和密码是否发生过改变
*/
isUserInfoChange: {
type: boolean
}
}
/**
* 学生信息
*/
class StudentInfo extends Data<IStudentInfoData & ILoginApiData> {
/**
* 学生信息缓存
*/
private eduStorage = new Storage<IStudentInfoStorageData>("StudentInfo", {
idCardLast6: "",
eduService: "",
actualName: "",
eduSession: "",
studentId: "",
password: "",
loginStatus: LoginStatus.none,
lastLoginTime: 0,
isUserInfoChange: false
});
public override onLoad() {
}
/**
* 用户登录
*/
private async login(): Promise<boolean> {
// 获取账号密码
const stuId = this.eduStorage.get("studentId");
const pwd = this.eduStorage.get("password");
if (!stuId || !pwd) return false;
// 发送请求
const data = await new Login().param({
studentId: stuId,
password: pwd
}).request().wait();
// 请求成功
let res = data.data;
if (res) {
// 保存数据
this.eduStorage.set("actualName", res.actualName);
this.eduStorage.set("eduService", res.eduService);
this.eduStorage.set("eduSession", res.eduSession);
this.eduStorage.set("idCardLast6", res.idCardLast6);
// 记录时间
this.eduStorage.set("lastLoginTime", new Date().getTime());
return true;
} else {
return false;
}
}
/**
* 获取状态
*/
private async getStatus() {}
}
export { StudentInfo };
export default StudentInfo;
@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000047771584930258237770000008464236368807665038_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M50,0c8.69,0,17.06,2.22,24.48,6.39c2.24,1.26,3.03,4.1,1.78,6.34c-1.26,2.24-4.1,3.03-6.34,1.78
C63.84,11.08,56.98,9.29,50,9.3C27.53,9.3,9.3,27.52,9.3,50S27.53,90.7,50,90.7c22.48,0,40.7-18.22,40.7-40.7
c0-7.9-2.25-15.46-6.42-21.96c-1.39-2.16-0.76-5.04,1.4-6.43c2.16-1.39,5.04-0.76,6.43,1.4c5.17,8.05,7.91,17.42,7.9,26.99
c0,27.61-22.38,50-50,50C22.39,100,0,77.61,0,50C0,22.39,22.39,0,50,0L50,0z M50,0"/>
<path class="st6" d="M83.48,20.51c1.7-1.82,4.53-1.97,6.42-0.36c1.89,1.61,2.18,4.43,0.65,6.39l-0.33,0.38L51.09,67.99
c-1.67,1.75-4.4,1.93-6.29,0.41l-0.39-0.35L26.66,50.11c-1.75-1.75-1.82-4.58-0.16-6.41c1.67-1.84,4.48-2.04,6.4-0.47l0.37,0.34
L47.65,58.1L83.48,20.51z M83.48,20.51"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000177474060957557094400000000012443665588057228_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M50,0C22.39,0,0,22.39,0,50c0,27.61,22.39,50,50,50c27.61,0,50-22.39,50-50C100,22.39,77.61,0,50,0L50,0z
M50,8.77c22.77,0,41.23,18.46,41.23,41.23S72.77,91.23,50,91.23S8.77,72.77,8.77,50S27.23,8.77,50,8.77L50,8.77z M50,8.77"/>
<path class="st6" d="M50,43.19c3.04,0,4.56,1.52,4.56,4.56v23.72c0,3.04-1.52,4.56-4.56,4.56c-3.04,0-4.56-1.52-4.56-4.56V47.75
C45.44,44.71,46.96,43.19,50,43.19L50,43.19z M50,43.19"/>
<path class="st6" d="M43.33,30.64c0,2.38,1.27,4.58,3.33,5.77c2.06,1.19,4.6,1.19,6.67,0c2.06-1.19,3.33-3.39,3.33-5.77
c0-2.38-1.27-4.58-3.33-5.77c-2.06-1.19-4.6-1.19-6.67,0C44.6,26.05,43.33,28.25,43.33,30.64L43.33,30.64z M43.33,30.64"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000096743565441905941170000016958695224966735273_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<path class="st6" d="M99.46,50.54c-0.71-1.43-18.11-35.5-49.55-35.5c-2.62,0-5.24,0.24-7.86,0.71c-1.91,0.48-3.34,2.14-2.86,4.05
c0.48,1.91,2.14,3.34,4.05,2.86c2.14-0.48,4.29-0.48,6.43-0.48c23.35,0,38.59,23.35,42.41,29.78c-1.19,2.14-3.57,5.96-7.15,10.24
c-1.19,1.43-0.95,3.81,0.48,5c0.71,0.48,1.43,0.71,2.38,0.71c0.95,0,2.14-0.48,2.86-1.19c5.72-6.91,8.81-12.86,8.81-13.1
C100.18,52.68,100.18,51.49,99.46,50.54z M16.8,9.56c-1.43-1.43-3.57-1.43-5,0s-1.43,3.57,0,5l10.24,10.24
C8.22,35.05,0.83,49.58,0.36,50.3c-0.48,0.95-0.48,2.14,0,3.34c0.71,1.43,18.11,35.26,49.55,35.26c9.29,0,18.34-3.1,26.92-9.05
l10.72,10.72c0.71,0.71,1.67,0.95,2.62,0.95c0.95,0,1.91-0.24,2.62-0.95c1.43-1.43,1.43-3.57,0-5L16.8,9.56z M43.95,46.96
l11.67,11.67c-1.43,1.43-3.57,2.38-5.72,2.38c-4.53,0-8.34-3.81-8.34-8.34C41.57,50.54,42.53,48.39,43.95,46.96z M49.91,81.75
c-23.35,0-38.59-23.35-42.41-29.78c2.38-4.05,9.05-14.53,19.54-21.92l11.67,11.67c-2.86,2.86-4.29,6.67-4.29,10.72
c0,8.58,6.91,15.49,15.49,15.49c4.05,0,7.86-1.67,10.72-4.29L71.59,74.6C64.68,79.36,57.3,81.75,49.91,81.75z"/>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000124849447952852579110000006476751934385998486_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M50,66.23c-8.59,0-15.51-6.92-15.51-15.51S41.4,35.2,50,35.2s15.51,6.92,15.51,15.51S58.59,66.23,50,66.23z
M50,42.36c-4.53,0-8.35,3.82-8.35,8.35s3.82,8.35,8.35,8.35s8.35-3.82,8.35-8.35S54.53,42.36,50,42.36z"/>
<path class="st6" d="M50,86.99c-31.5,0-48.93-33.89-49.64-35.32c-0.48-0.95-0.48-2.15,0-3.34C1.07,46.9,18.73,13.01,50,13.01
c31.5,0,48.93,34.13,49.64,35.56c0.48,0.95,0.48,2.15,0,3.34C98.92,53.1,81.5,86.99,50,86.99z M7.51,50
C11.33,56.44,26.61,79.83,50,79.83S88.66,56.44,92.48,50C88.66,43.56,73.39,20.17,50,20.17S11.33,43.56,7.51,50z"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000091016287826886391250000017486262032961877648_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M50,0C22.39,0,0,22.39,0,50c0,27.61,22.39,50,50,50c27.61,0,50-22.39,50-50C100,22.39,77.61,0,50,0L50,0z
M50,8.77c22.77,0,41.23,18.46,41.23,41.23S72.77,91.23,50,91.23S8.77,72.77,8.77,50S27.23,8.77,50,8.77L50,8.77z M50,8.77"/>
<path class="st6" d="M53.59,61.54v-0.98c0-1.69,0.35-3.17,1.05-4.58c0.64-1.27,1.55-2.46,2.82-3.52c3.38-2.95,5.42-4.86,6.05-5.56
c1.68-2.25,2.6-5.14,2.6-8.66c0-4.3-1.41-7.67-4.22-10.13c-2.81-2.53-6.54-3.73-11.12-3.73c-5.21,0-9.29,1.48-12.32,4.43
c-3.09,2.96-4.58,7.04-4.58,12.25h8.02c0-2.95,0.56-5.28,1.76-6.89c1.34-1.97,3.52-2.89,6.61-2.89c2.39,0,4.3,0.63,5.63,1.97
c1.26,1.34,1.97,3.16,1.97,5.49c0,1.76-0.63,3.45-1.9,5l-0.85,0.98c-4.58,4.08-7.32,7.04-8.23,8.94c-0.99,1.9-1.41,4.22-1.41,6.9
v0.99H53.59z M49.51,75.61c1.54,0,2.81-0.49,3.87-1.48c1.05-0.98,1.61-2.32,1.61-3.87c0-1.55-0.56-2.81-1.54-3.8
c-1.06-0.98-2.39-1.48-3.94-1.48c-1.55,0-2.82,0.49-3.87,1.47c-1.06,0.99-1.55,2.26-1.55,3.8c0,1.55,0.49,2.81,1.55,3.8
C46.69,75.05,47.96,75.61,49.51,75.61L49.51,75.61z M49.51,75.61"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000145045565268559361070000017782594028069641132_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M80.89,59.07c7.16-4.63,11.49-13.25,9.73-22.74c-1.52-8.17-7.87-14.98-15.9-17.09
c-5.26-1.38-10.26-0.79-14.57,1.09c0.9,1.91,1.62,3.92,2.02,6.05c2.06-0.99,4.34-1.6,6.79-1.6c10,0,17.85,9.35,15.27,19.76
c-0.99,4.01-3.81,7.32-7.28,9.55l1.19-0.77c-0.86,0.56-1.6,1.32-2.12,2.28c-0.52,0.96-0.77,2-0.77,3.01v0.75
c0,1.15,0.31,2.32,0.97,3.36c0.66,1.05,1.57,1.83,2.61,2.32l-0.67-0.32c8.3,3.97,14.1,12.67,15.6,23.09H68.95
c0.26,2.06,0.42,4.16,0.42,6.31h24.27c3.79,0,6.85-3.35,6.28-7.1C97.98,74.34,90.85,63.82,80.89,59.07L80.89,59.07z M80.89,59.07"
/>
<path class="st6" d="M6.35,94.15h68.9c0-19.11-10.42-35.32-24.98-41.47c9.04-5.4,14.5-16.17,11.56-28.01
c-2.2-8.87-9.45-16.03-18.36-18.1c-16.57-3.86-31.29,8.6-31.29,24.52c0,9.21,4.99,17.19,12.37,21.59
C11.83,58.05,2.27,71.13,0.06,87.11C-0.46,90.84,2.58,94.15,6.35,94.15L6.35,94.15z M27.01,58.49l0.25-0.1
c1.11-0.47,2.09-1.25,2.8-2.32c0.71-1.07,1.05-2.29,1.05-3.48v0.26c0-1.06-0.27-2.13-0.83-3.11c-0.56-0.98-1.34-1.76-2.25-2.3
l-0.25-0.14c-5.82-3.47-9.29-9.52-9.29-16.17c0-10.44,8.48-18.92,18.92-18.92s18.92,8.48,18.92,18.92c0,6.65-3.47,12.7-9.29,16.17
l-0.25,0.14c-0.9,0.55-1.7,1.32-2.25,2.3c-0.56,0.98-0.83,2.05-0.83,3.11v-0.27c0,1.19,0.33,2.41,1.05,3.48
c0.71,1.07,1.7,1.85,2.8,2.32l0.25,0.1C58.76,63.1,66.6,74.47,68.49,87.83H6.33C8.23,74.48,16.06,63.11,27.01,58.49L27.01,58.49z
M27.01,58.49"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F4F0F1;}
.st1{fill:#FFFFFF;}
.st2{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;}
.st3{fill:#1A1A1A;}
.st4{fill:none;stroke:#1A1A1A;stroke-width:3;stroke-miterlimit:10;}
.st5{fill:none;stroke:#1A1A1A;stroke-miterlimit:10;}
.st6{fill:#3EA3D8;}
.st7{display:none;}
.st8{display:inline;}
.st9{fill:#808080;}
.st10{display:inline;fill:#808080;}
.st11{fill:none;stroke:#808080;stroke-miterlimit:10;}
.st12{fill:#7AC943;}
.st13{fill:none;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st14{fill:#FFFFFF;stroke:#E6E6E6;stroke-width:3;stroke-miterlimit:10;}
.st15{fill:none;stroke:#3EA3D8;stroke-miterlimit:10;}
.st16{fill:#CCCCCC;}
.st17{fill:none;stroke:#CCCCCC;stroke-linecap:square;stroke-miterlimit:10;}
.st18{fill:none;stroke:#CCCCCC;stroke-miterlimit:10;stroke-dasharray:1.9084,1.9084;}
.st19{fill:none;stroke:#E6E6E6;stroke-miterlimit:10;}
.st20{fill:#666666;}
.st21{fill:none;stroke:#B3B3B3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
.st22{fill:#B3B3B3;}
.st23{opacity:0.05;}
.st24{clip-path:url(#SVGID_00000067940495327550631130000006202591132779276672_);}
.st25{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
.st26{opacity:0.4;fill:#3EA3D8;}
.st27{fill:none;stroke:#3EA3D8;stroke-width:11;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;}
</style>
<g id="A3">
<g id="HEADER_x5F_BAR_00000036974300579741410940000000488572858971942531_">
</g>
</g>
<g id="A2">
<g id="HEADER_x5F_BAR_00000019648451390881128220000012673596900810320021_">
</g>
<g id="BUTTON_00000117651906535404305420000016044620869483747487_">
</g>
<g id="USER_x5F_FORM">
</g>
<g id="INTRO">
</g>
<g id="DLPU_x5F_LOGO">
</g>
</g>
<g id="A1">
<g id="NAV_x5F_BAR_00000129914889952932149030000011711506177042644156_">
</g>
<g id="HEADER_x5F_BAR_00000015351907221170818370000001589878730520391302_">
</g>
<g id="FUNC_x5F_LIST">
</g>
<g id="MAIN_x5F_FUNC">
</g>
<g id="USER_x5F_CARD">
<g id="BG" class="st23">
</g>
</g>
</g>
<g id="ICON">
<g>
<path class="st6" d="M49.92,0C22.35,0,0,22.35,0,49.92c0,27.57,22.35,49.92,49.92,49.92c27.57,0,49.92-22.35,49.92-49.92
C99.85,22.35,77.49,0,49.92,0L49.92,0z M49.92,8.76c22.74,0,41.16,18.43,41.16,41.16S72.66,91.09,49.92,91.09
S8.76,72.66,8.76,49.92S27.19,8.76,49.92,8.76L49.92,8.76z M49.92,8.76"/>
</g>
</g>
<g id="DEFAULT_x5F_AVATOR">
</g>
<g id="COLOR">
</g>
<g id="NAV_x5F_BAR">
<g id="ICON_x5F_SETTING">
</g>
<g id="ICON_x5F_INFO">
</g>
<g id="ICON_x5F_KCB">
</g>
</g>
<g id="HEADER_x5F_BAR">
<g id="BUTTON">
</g>
<g id="TOP">
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

+99
View File
@@ -0,0 +1,99 @@
@import "../app.scss";
view.mask {
position: fixed;
width: 100%;
height: 100%;
background-color: rgba($color: #000000, $alpha: .2);
z-index: 1;
}
view.layer {
position: fixed;
@include container;
height: 100%;
z-index: 2;
justify-content: center;
align-items: center;
}
view.occlude {
position: fixed;
width: 100%;
height: 100%;
z-index: 3;
}
view.mask.block, view.layer.block, view.occlude.block {
display: flex;
}
view.mask.none, view.layer.none, view.occlude.none {
display: none;
}
view.mask.show-fade, view.layer.show-fade, view.occlude.show-fade {
animation: show-fade .1s cubic-bezier(0, 0, 1, 1) both;
opacity: 1;
}
view.mask.hide-fade, view.layer.hide-fade, view.occlude.hide-fade {
animation: hide-fade .1s cubic-bezier(0, 0, 1, 1) both;
opacity: 0;
}
view.mask.show-scale, view.layer.show-scale, view.occlude.show-scale {
animation: show-scale .3s cubic-bezier(.1, .9, .2, 1) both,
show-fade .1s cubic-bezier(0, 0, 1, 1) both;
transform: scale3d(1, 1, 1);
opacity: 1;
}
view.mask.hide-scale, view.layer.hide-scale, view.occlude.hide-scale {
animation: hide-scale .3s cubic-bezier(.1, .9, .2, 1) both,
hide-fade .1s cubic-bezier(0, 0, 1, 1) both;
transform: scale3d(.9, .9, 1);
opacity: 0;
}
@media (prefers-color-scheme: dark) {
view.mask {
background-color: rgba($color: #000000, $alpha: .5);
}
}
@keyframes show-fade{
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes hide-fade{
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes show-scale{
from {
transform: scale3d(1.15, 1.15, 1);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes hide-scale{
from {
transform: scale3d(1, 1, 1);
}
to {
transform: scale3d(.9, .9, 1);
}
}
+309
View File
@@ -0,0 +1,309 @@
import { IAnyData } from "../core/Api";
import { Emitter } from "../core/Emitter";
import { Modular, Manager } from "../core/Module";
/**
* 动画类型
*/
enum AnimateType {
fade = 1,
scale = 2,
none = 3,
}
/**
* 显示层
*/
class DisplayLayer {
/**
* 类名
*/
public get className(): string {
let res = this.isDisplay ? "block" : "none";
switch (this.animateType) {
case AnimateType.fade:
res += " mask";
break;
case AnimateType.scale:
res += " layer";
break;
case AnimateType.none:
res += " occlude";
break;
}
switch (this.animateType) {
case AnimateType.fade:
res += this.isShow ? " show-fade" : " hide-fade";
break;
case AnimateType.scale:
res += this.isShow ? " show-scale" : " hide-scale";
break;
case AnimateType.none:
break;
}
return res;
}
/**
* Layer 使用的 key
*/
public key: string = "";
/**
* 使用的动画类型
*/
public animateType: AnimateType = AnimateType.scale;
/**
* 动画时间
*/
public get animateTime(): number {
switch (this.animateType) {
case AnimateType.fade:
return 100;
case AnimateType.scale:
return 300;
case AnimateType.none:
return -1;
}
};
/**
* 是否显示
*/
public isDisplay: boolean = false;
/**
* 是否显示
*/
public isShow: boolean = false;
/**
* 消失动画计时器
*/
public disappearTimer?: number;
}
/**
* 弹出层事件
*/
type IPopupLayerEvent<L extends string> = {
/**
* 点击蒙版时
*/
clickMask: void
/**
* 显示层
*/
show: L;
/**
* 隐藏层
*/
hide: L;
/**
* 层状态改变
*/
change: Readonly<DisplayLayer>;
}
type commonLayerType = "mask" | "occlude";
/**
* 弹出层
*/
class PopupLayer<
L extends string,
M extends Manager = Manager
> extends Modular<M, {}, IPopupLayerEvent<L | commonLayerType>> {
/**
* 当点击时是否自动关闭蒙版
*/
public autoCloseOnClick: boolean = true;
/**
* 关闭动画执行时是否屏蔽用户点击
*/
public showOccludeWhenHide: boolean = true;
/**
* 显示 Layer 时自动关闭其他层
*/
public hideOtherWhenShow: boolean = true;
/**
* 层列表
*/
private layers: Map<L | commonLayerType, DisplayLayer> = new Map();
/**
* 初始化层
* @param key 初始化关键字
*/
public initLayers(key: L[]) {
for (let i = 0; i < key.length; i++) {
this.render(this.getDisplayLayer(key[i]));
}
}
public onLoad(): void {
this.on("show", this.handleShowLayer);
this.on("hide", this.handleHideLayer);
this.setFunc(this.handleClickMask, "clickMask");
// 添加蒙版层
const maskLayer = this.getDisplayLayer("mask");
maskLayer.animateType = AnimateType.fade;
this.render(maskLayer);
// 添加遮蔽层
const occludeLayer = this.getDisplayLayer("occlude");
occludeLayer.animateType = AnimateType.none;
this.render(occludeLayer);
}
/**
* 渲染 Layers
*/
private render(layer: DisplayLayer) {
this.setData({ [`${ layer.key }$className`]: layer.className });
}
/**
* 获取显示层
*/
private getDisplayLayer<K extends L | commonLayerType>(e: K): DisplayLayer {
let displayLayer = this.layers.get(e);
if (!displayLayer) {
displayLayer = new DisplayLayer();
displayLayer.key = e;
this.layers.set(e, displayLayer);
}
return displayLayer;
}
/**
* 响应蒙版点击事件
*/
private handleClickMask = () => {
if (!this.autoCloseOnClick) return;
// 关闭全部开启的层
this.layers.forEach((layer) => {
if (layer.isShow) (this as Emitter<IAnyData>).emit("hide", layer.key);
});
// 关闭蒙版
(this as Emitter<IAnyData>).emit("hide", "mask");
}
/**
* 响应显示层事件
*/
private handleShowLayer = <K extends L | commonLayerType>(e: K) => {
let displayLayer = this.getDisplayLayer(e);
// 阻止未发生的变化
if (displayLayer.isShow) return;
// 关闭其他层
if (e !== "mask" && e !== "occlude" && this.hideOtherWhenShow) {
this.layers.forEach((layer) => {
if (layer.key === "mask" || layer.key === "occlude") return;
if (layer.isShow) {
(this as Emitter<IAnyData>).emit("hide", layer.key);
}
});
}
// 显示蒙版
if (e !== "mask" && e !== "occlude")
(this as Emitter<IAnyData>).emit("show", "mask");
// 取消消失定时
displayLayer.disappearTimer &&
clearTimeout(displayLayer.disappearTimer);
displayLayer.isShow = true;
displayLayer.isDisplay = true;
this.render(displayLayer);
this.emit("change", displayLayer);
};
/**
* 响应隐藏层事件
*/
private handleHideLayer = <K extends L | commonLayerType>(e: K) => {
let displayLayer = this.getDisplayLayer(e);
// 阻止未发生的变化
if (!displayLayer.isShow) return;
if (displayLayer.animateTime <= 0) {
displayLayer.isShow = false;
displayLayer.isDisplay = false;
this.render(displayLayer);
} else {
displayLayer.isShow = false;
this.render(displayLayer);
// 开启遮蔽
if (this.showOccludeWhenHide) {
(this as Emitter<IAnyData>).emit("show", "occlude");
}
displayLayer.disappearTimer = setTimeout(() => {
displayLayer.isDisplay = false;
this.render(displayLayer);
// 取消 timer
displayLayer.disappearTimer = undefined;
// 检测是否关闭遮蔽
let needOcclude = true;
this.layers.forEach((layer) => {
if (layer === displayLayer) return;
if (layer.disappearTimer) needOcclude = false;
});
// 关闭遮蔽
if (needOcclude && this.showOccludeWhenHide) {
(this as Emitter<IAnyData>).emit("hide", "occlude");
}
}, displayLayer.animateTime);
}
// 关闭蒙版
if (e !== "mask" && e !== "occlude") {
let needMask = true;
this.layers.forEach((layer) => {
if (layer === displayLayer) return;
if (layer.isShow) needMask = false;
});
if (needMask) (this as Emitter<IAnyData>).emit("hide", "mask");
}
this.emit("change", displayLayer);
}
}
export { PopupLayer };
export default PopupLayer;
+7 -2
View File
@@ -1,7 +1,12 @@
@import "./UserCard.scss"; @import "./UserCard.scss";
@import "./MainFunction.scss"; @import "./MainFunction.scss";
@import "./FunctionList.scss"; @import "./FunctionList.scss";
@import "./Login.scss";
@import "../../modular/PopupLayer.scss";
view.container { view.container{
padding-top: 20px; padding-top: 20px;
} padding-bottom: 20px;
}
+30 -3
View File
@@ -2,9 +2,36 @@ import { Manager } from "../../core/Module";
import { UserCard } from "./UserCard"; import { UserCard } from "./UserCard";
import { MainFunction } from "./MainFunction"; import { MainFunction } from "./MainFunction";
import { FunctionList } from "./FunctionList"; import { FunctionList } from "./FunctionList";
import { Login } from "./Login";
import { PopupLayer } from "../../modular/PopupLayer";
Manager.Page((manager) => { (async () => {
manager.addModule(UserCard, "userCard");
// 初始化页面
const { manager, query } = await Manager.PageAsync();
// 添加弹出层 Modular
const popupLayer: PopupLayer<"loginLayer"> = manager.addModule(PopupLayer, "mask") as any;
// 初始化弹出层
popupLayer.initLayers(["loginLayer"]);
// 添加 UserCard Modular
const userCard = manager.addModule(UserCard, "userCard");
// 添加登录模块
const loginLayer = manager.addModule(Login, "loginLayer");
userCard.on("clickChangeTheme", () => {
popupLayer.emit("show", "loginLayer");
});
// 添加 MainFunction Modular
manager.addModule(MainFunction, "mainFunction"); manager.addModule(MainFunction, "mainFunction");
// 添加 FunctionList Modular
manager.addModule(FunctionList, "functionList"); manager.addModule(FunctionList, "functionList");
});
// 初始化全部 Modular
await manager.loadAllModule(query);
})();
+105 -21
View File
@@ -1,3 +1,82 @@
<!-- 层遮蔽层 -->
<view class="{{ mask$occlude$className }}" bindtap="mask$clickMask"></view>
<!-- 蒙版 -->
<view class="{{ mask$mask$className }}" bindtap="mask$clickMask"></view>
<!-- 登录层 -->
<view class="{{ mask$loginLayer$className }}" bindtap="mask$clickMask">
<view class="card login-layer" catchtap>
<!-- 学校logo -->
<view class="school-logo">
<view>
<image src="../../image/account/School_DLPU.png"></image>
</view>
</view>
<view class="line-bg">
<view wx:for="{{ [0, 1, 2, 3, 4] }}" wx:key="item"></view>
</view>
<!-- 学生姓名 -->
<view class="student-name h2">秦浩轩</view>
<!-- 学号 -->
<view class="student-id">1806240113</view>
<!-- 状态 -->
<view class="login-state">
<view class="certified">
<view class="certifi-info">已认证</view>
<image class="text-icon" src="../../image/account/Account_OK.svg"></image>
</view>
</view>
<!-- 学号输入框 -->
<view class="student-info-input">
<view class="input-icon">
<image class="icon" src="../../image/account/Account_UserName.svg"></image>
</view>
<view class="input-view">
<input placeholder="请输入学号"/>
</view>
</view>
<!-- 密码输入框 -->
<view class="student-info-input">
<view class="input-icon">
<image class="icon" src="../../image/account/Account_PasswordHidden.svg"></image>
</view>
<view class="input-view">
<input placeholder="请输入密码"/>
</view>
</view>
<view style="height: 30px"/>
<!-- 提示语 -->
<view class="tip-info last-active">
<image src="../../image/account/Account_Info.svg"></image>
<view>账号最后活动时间: 2022.1.25-8.20</view>
</view>
<view class="tip-info agree-lic">
<image src="../../image/account/Account_Complete.svg"></image>
<view>同意<text>《用户协议》</text>和<text>《隐私政策》</text></view>
</view>
<view class="tip-info helper-link">
<image src="../../image/account/Account_Question.svg"></image>
<view>遇到问题了戳这里-><text>常见问题</text></view>
</view>
<!-- 登录按钮 -->
<view class="button save-button">
保存并验证
</view>
</view>
</view>
<!-- 顶部的阴影 --> <!-- 顶部的阴影 -->
<view class="top-shadow"></view> <view class="top-shadow"></view>
@@ -14,7 +93,9 @@
<!-- 主题变换按钮 --> <!-- 主题变换按钮 -->
<view class="theme"> <view class="theme">
<image class="icon-sub" src="../../image/account/Account_Theme.svg" /> <view bindtap="userCard$changeTheme">
<image class="icon-sub" src="../../image/account/Account_Theme.svg" />
</view>
</view> </view>
<!-- 用户昵称 --> <!-- 用户昵称 -->
@@ -27,7 +108,7 @@
<view class="name">秦浩轩</view> <view class="name">秦浩轩</view>
<view class="certified"> <view class="certified">
<view class="certifi-info">已认证</view> <view class="certifi-info">已认证</view>
<view class="text-icon">√</view> <image class="text-icon" src="../../image/account/Account_OK.svg"></image>
</view> </view>
</view> </view>
@@ -40,26 +121,29 @@
</view> </view>
<!--主要功能--> <!--主要功能-->
<view class="card main-function"><!--四个功能合在一起的容器--> <view class="card main-function">
<view class="branch-funtion"><view><!--每个功能的容器-->
<image class="icon" src="../../image/account/Account_UserInfo.svg"></image><!--每个功能的图片--> <!--每个功能的容器-->
<view>账号信息</view><!--每个功能的文字--> <view class="branch-funtion" wx:for="{{ mainFunction$mainFunctionList }}" wx:key="index">
</view></view> <view style="{{ index == (mainFunction$mainFunctionList.length - 1) ? 'border-right: 0px' : '' }}">
<!--每个功能的图片-->
<image class="icon" src="../../image/account/Account_{{ item.iconUrl }}.svg"></image>
<!--每个功能的文字-->
<view>{{ item.displayName }}</view>
</view>
</view>
</view>
<view class="branch-funtion"><view> <!-- 功能列表 -->
<image class="icon" src="../../image/account/Account_DateList.svg"></image> <view class="card function-list">
<view>课表缓存</view>
</view></view>
<view class="branch-funtion"><view>
<image class="icon" src="../../image/account/Account_Customer.svg"></image>
<view>功能定制</view>
</view></view>
<view class="branch-funtion"><view style="border-right: 0px;">
<image class="icon" src="../../image/account/Account_Settings.svg"></image>
<view>更多设置</view>
</view></view>
<!-- 每一行 -->
<view class="function" wx:for="{{ functionList$functionList }}" wx:key="index">
<view style="{{ index == (functionList$functionList.length - 1) ? 'border-bottom: 0px' : '' }}">
<image class="icon func-icon" src="../../image/account/Account_{{ item.iconUrl }}.svg" />
<view>{{ item.displayName }}</view>
<image class="icon-sub arrow" src="../../image/account/Account_Arrow.svg" />
</view>
</view>
</view> </view>
</view> </view>
+42 -1
View File
@@ -1 +1,42 @@
@import "../../app.scss"; @import "../../app.scss";
view.function-list {
margin-top: 20px;
padding: 0 0 !important;
width: 100% !important;
view.function {
padding: 0 20px;
width: calc( 100% - 40px );
height: 55px;
> view {
height: 100%;
display: flex;
align-items: center;
border-bottom: 1px solid rgba($color: #000000, $alpha: .1);
image.func-icon {
width: 26px;
height: 26px;
}
view {
margin-left: 15px;
flex-grow: 1;
font-size: .9em;
}
image.arrow {
width: 10px;
height: 10px;
}
}
}
}
@media (prefers-color-scheme: dark) {
view.function-list view.function > view {
border-bottom: 1px solid rgba($color: #ffffff, $alpha: .1);
}
}
+25
View File
@@ -1,6 +1,31 @@
import { Modular, Manager } from "../../core/Module"; import { Modular, Manager } from "../../core/Module";
interface IFunctionListItem {
/**
* 显示名称
*/
displayName: string;
/**
* 图标路径
*/
iconUrl: string;
}
class FunctionList<M extends Manager> extends Modular<M> { class FunctionList<M extends Manager> extends Modular<M> {
public static readonly functionList: IFunctionListItem[] = [
{ displayName: "赞助计划", iconUrl: "Sponsor" },
{ displayName: "公众号", iconUrl: "PubilcAccount" },
{ displayName: "自助问答", iconUrl: "FAQ" },
{ displayName: "关于我们", iconUrl: "AboutUs" },
{ displayName: "联系客服", iconUrl: "Support" }
];
public data = {
functionList: FunctionList.functionList
};
public override onLoad() { public override onLoad() {
// Do something // Do something
+170
View File
@@ -0,0 +1,170 @@
@import "../../app.scss";
$logo-height: 100px;
view.login-layer {
view.school-logo {
height: 0;
padding-top: 25px;
width: 100%;
text-align: center;
view {
z-index: 2;
display: inline-block;
position: relative;
border-radius: 1000px;
background-color: $theme-color-light-layout;
width: $logo-height;
height: $logo-height;
image {
width: 100%;
height: 100%;
}
}
}
view.line-bg {
display: flex;
box-sizing: border-box;
padding: 35px 0;
height: $logo-height;
width: calc( 100% + 40px );
position: relative;
left: -20px;
flex-direction: column;
justify-content: space-around;
view {
height: 0;
width: 100%;
opacity: .5;
border-top: 2px solid $theme-color-light-line;
}
}
view.student-name {
margin: 10px 0 1px 0;
text-align: center;
}
view.student-id {
margin-bottom: 1px;
text-align: center;
}
view.login-state {
width: 100%;
margin-bottom: 20px;
text-align: center;
view.certified {
color: $theme-color-blue;
border: 1px solid $theme-color-blue;
border-radius: 4px;
margin-left: .3em;
font-size: .85em;
height: 1.2em;
padding: 0 2px;
display: inline-flex;
justify-content: center;
align-items: center;
image.text-icon {
margin-left: .25em;
width: 10px;
height: 10px;
}
}
}
view.student-info-input {
display: flex;
justify-content: center;
padding: 8px 0;
view.input-icon {
box-sizing: border-box;
padding: 3px 12px 3px 0;
flex-shrink: 0;
width: 38px;
height: 32px;
image {
width: 100%;
height: 100%;
}
}
view.input-view {
position: relative;
bottom: 3px;
box-sizing: border-box;
border-bottom: 1.5px solid $theme-color-light-line;
flex-grow: 1;
width: 100%;
height: 32px;
input {
width: 100%;
height: 100%;
}
}
}
view.tip-info {
width: 100%;
vertical-align: middle;
padding: 1px 0;
font-size: .9em;
image {
vertical-align: middle;
width: 16px;
height: 16px;
margin-right: 5px;
}
view {
vertical-align: middle;
display: inline;
text {
color: $theme-color-blue;
text-decoration: underline;
}
}
}
view.agree-lic image {
filter: $green-filter;
}
view.save-button {
margin: 15px 0 25px 0;
}
}
@media (prefers-color-scheme: dark) {
view.login-layer {
view.school-logo view {
background-color: $theme-color-dark-layout;
image {
filter: $white-filter;
}
}
view.line-bg view {
border-top: 2px solid $theme-color-dark-line;
}
view.student-info-input view.input-view {
border-bottom: 1.5px solid $theme-color-dark-line;
}
}
}
+15
View File
@@ -0,0 +1,15 @@
import { Modular, Manager } from "../../core/Module";
type ILoginEvent = {
}
class Login<M extends Manager> extends Modular<M, {}> {
public override onLoad() {
}
}
export { Login };
export default Login;
+2 -2
View File
@@ -26,7 +26,7 @@ view.main-function {
view { view {
text-align: center; text-align: center;
margin-top: 5px; margin-top: 5px;
font-size: .8em; font-size: .9em;
} }
} }
} }
@@ -36,4 +36,4 @@ view.main-function {
view.main-function view.branch-funtion > view { view.main-function view.branch-funtion > view {
border-right: 1px solid rgba($color: #ffffff, $alpha: .1); border-right: 1px solid rgba($color: #ffffff, $alpha: .1);
} }
} }
+24
View File
@@ -1,6 +1,30 @@
import { Modular, Manager } from "../../core/Module"; import { Modular, Manager } from "../../core/Module";
interface IMainFunctionItem {
/**
* 显示名称
*/
displayName: string;
/**
* 图标路径
*/
iconUrl: string;
}
class MainFunction<M extends Manager> extends Modular<M> { class MainFunction<M extends Manager> extends Modular<M> {
public static readonly MainFunctionList: IMainFunctionItem[] = [
{ displayName: "账号信息", iconUrl: "UserInfo" },
{ displayName: "课表缓存", iconUrl: "DateList" },
{ displayName: "功能定制", iconUrl: "Customer" },
{ displayName: "更多设置", iconUrl: "Settings" }
];
public data? = {
mainFunctionList: MainFunction.MainFunctionList
}
public override onLoad() { public override onLoad() {
// Do something // Do something
+14 -3
View File
@@ -27,9 +27,17 @@ view.user-card {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
image { view {
width: 23px; width: 23px;
height: 23px; height: 23px;
padding: 20px;
margin: -20px;
border-radius: 20px;
image {
width: 100%;
height: 100%;
}
} }
} }
@@ -41,6 +49,7 @@ view.user-card {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
// 学生信息
view.student { view.student {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -57,8 +66,10 @@ view.user-card {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
view.text-icon { image.text-icon {
margin-left: .3em; margin-left: .25em;
width: 10px;
height: 10px;
} }
} }
} }
+18 -3
View File
@@ -1,9 +1,24 @@
import { Modular, Manager } from "../../core/Module"; import { Modular, Manager } from "../../core/Module";
class UserCard<M extends Manager> extends Modular<M> { type IUserCardEvent = {
/**
* 主题更换按钮点击事件
*/
clickChangeTheme: void;
}
class UserCard<M extends Manager> extends Modular<M, {}, IUserCardEvent> {
public override onLoad() { public override onLoad() {
// Do something this.setFunc(this.handleChangeTheme, "changeTheme");
}
/**
* 处理主题更换
*/
private handleChangeTheme() {
this.emit("clickChangeTheme");
} }
} }
+9 -6
View File
@@ -1,5 +1,6 @@
import { Modular, Manager, ILifetime } from "../../core/Module"; import { Modular, Manager, ILifetime } from "../../core/Module";
import { Login } from "../../api/Login"; import { Login } from "../../api/Login";
import { Schedlue } from "../../api/Schedule"
import { Storage } from "../../core/Storage"; import { Storage } from "../../core/Storage";
/** /**
@@ -28,12 +29,14 @@ implements Partial<ILifetime> {
s.set("be", 12); s.set("be", 12);
}, 1000) }, 1000)
new Login().param({studentId: "1806240113", password: "qazxsw123"}) // new Login().param({studentId: "2017060129", password: ""})
.request().wait({ // .request().wait({
ok: (w) => {console.log("ok", w)}, // ok: (w) => {console.log("ok", w)},
no: (w) => {console.log("no", w)}, // no: (w) => {console.log("no", w)},
done: (w) => {console.log("done", w)} // done: (w) => {console.log("done", w)}
}); // });
// new Schedlue().param({cookie:"C729D1AB1B17077485ACCD9279135C22",semester:"2020-2021-2"})
// .request()
} }
} }
+12 -2
View File
@@ -6,7 +6,17 @@ import { TestCore } from "./TestCore";
* 此页面使用 Manager 进行模块化管理 * 此页面使用 Manager 进行模块化管理
* 若要添加先功能请先定义 Modular 并添加至 Manager * 若要添加先功能请先定义 Modular 并添加至 Manager
*/ */
Manager.Page((manager)=>{ (async () => {
// 初始化页面
const { manager, query } = await Manager.PageAsync();
// 添加 StatusBar Modular
manager.addModule(StatusBar, "statusBar"); manager.addModule(StatusBar, "statusBar");
// 添加 TestCore Modular
manager.addModule(TestCore, "testCore"); manager.addModule(TestCore, "testCore");
})
// 初始化全部 Modular
await manager.loadAllModule(query);
})()
+11 -7
View File
@@ -1,7 +1,8 @@
{ {
"description": "项目配置文件", "description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"packOptions": { "packOptions": {
"ignore": [] "ignore": [],
"include": []
}, },
"miniprogramRoot": "miniprogram/", "miniprogramRoot": "miniprogram/",
"compileType": "miniprogram", "compileType": "miniprogram",
@@ -46,13 +47,16 @@
"useCompilerPlugins": [ "useCompilerPlugins": [
"typescript", "typescript",
"sass" "sass"
] ],
"useStaticServer": true
}, },
"simulatorType": "wechat", "simulatorType": "wechat",
"simulatorPluginLibVersion": {}, "simulatorPluginLibVersion": {},
"appid": "wx7d809f5e8955843d", "appid": "wx7d809f5e8955843d",
"scripts": { "condition": {},
"beforeCompile": "" "srcMiniprogramRoot": "miniprogram/",
}, "editorSetting": {
"condition": {} "tabIndent": "insertSpaces",
"tabSize": 2
}
} }
+6 -10
View File
@@ -1,14 +1,5 @@
{ {
"condition": { "condition": {
"plugin": {
"list": []
},
"game": {
"list": []
},
"gamePlugin": {
"list": []
},
"miniprogram": { "miniprogram": {
"list": [ "list": [
{ {
@@ -19,5 +10,10 @@
} }
] ]
} }
} },
"projectname": "mini-dlpu-v3",
"setting": {
"compileHotReLoad": true
},
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html"
} }