///
declare namespace tools {
export interface Entity {
}
export interface Result {
code?: number | string,
desc?: string,
data?: T | T[]
}
export interface UpyunResult {
code: number,
message?: string,
time: number,
url: string
}
export interface CheckQrResult extends Entity {
/**
* 课程ID
*/
courseId: number,
/**
* 课程名称
*/
courseName: string,
/**
* 考试记录DataID
*/
examRecordDataId: number,
/**
* 考生ID
*/
examStudentId: number,
/**
* 考试试题大题号
*/
questionMainNumber: number,
/**
* 考试试题题序
*/
questionOrder: number,
/**
* 登录信息key
*/
key: string,
/**
* 登录信息token
*/
token: string,
subNumber: number,
}
export interface SignResult extends Entity {
accessUrl: string,
formUrl: string,
fsType: string,
uploadUrl: string,
formParams: object,
signIdentifier: string
}
export interface NotifyResult extends Entity {
filePath: string,
result: boolean
}
export interface AudioAnswer extends Entity {
examRecordDataId: number,
mainNumber: number,
order: number,
studentAnswer: string,
subNumber: string
}
}
interface ApiConfigOption {
ver: number,
versionName: string,
baseUrl: string
}
interface RequestOption {
url: string,
parameter: any
}
type TokenValidCallback = () => void;
interface API {
configOption: ApiConfigOption
version(): string
setTokenValidCallback(callback: TokenValidCallback): void
checkQrcode(secret: string): Promise
getPaperStruct(examRecordDataId: number) : Promise
getSign(examRecordDataId: number, examStudentId: number, order: number, fileMd5: string, suffix: string) : Promise
uploadFile(filePath: string, formParams: object, uploadUrl: string) : Promise
notifyServer(examRecordDataId: number, examStudentId: number, order: number, filePath: string, transferFileType: string) : Promise
getNotifyResult(acknowledgeId: string) : Promise
getUploadedAudioAnswerList(examRecordDataId: number) : Promise
getRequest(option: RequestOption, auth: boolean): Promise
postRequest(option: RequestOption, auth: boolean): Promise
}
export class Api implements API {
//ecs.qmth.com.cn:8878
//http://192.168.10.39:8003
//https://ecs.qmth.com.cn:8878
//ecs-test.qmth.com.cn
//http://ecs-dev.qmth.com.cn
//'https://org0.ea100.com.cn'
//https://ecs-test.ea100.com.cn https://ecs-test.ea100.com.cn
configOption: ApiConfigOption = { ver: 1, versionName: 'v1.0.0', baseUrl: 'http://192.168.10.41:8003' }
private key: string = ''
private token: string = ''
private tokenValidCallback: TokenValidCallback = () => {}
version(): string {
return this.configOption.versionName
}
init(config: ApiConfigOption) {
this.configOption = config
}
initBaseUrl(baseUrl: string) {
this.configOption.baseUrl = baseUrl.replace(':443', '')
console.log("initBaseUri:" + this.configOption.baseUrl)
}
/**
* 授权成功后配置
* @param {number} uid
* @param {string} token
* @param {number} partitionId
*/
configAuthorize(key: string, token: string) {
this.key = key
this.token = token
}
setTokenValidCallback(callback: TokenValidCallback): void {
this.tokenValidCallback = callback
}
checkQrcode(secret: string): Promise {
const that = this
return new Promise((resolve, reject) => {
return this.postRequest({
url: '/api/ecs_oe_student/examControl/checkQrCode',
parameter: {
qrCode: secret
}
}, false).then(res => {
console.log('then')
if (res.key && res.token) {
that.configAuthorize(res.key, res.token)
// model transformer
var result = {
courseId: res.courseId,
courseName: res.courseName,
examRecordDataId: res.examRecordDataId,
examStudentId: res.examStudentId,
questionMainNumber: res.questionMainNumber,
questionOrder: res.questionOrder,
subNumber: res.subNumber
}
resolve((result as tools.CheckQrResult))
} else {
reject('二维码已失效')
}
}, error => {
reject(error)
}).catch( exceptions => {
reject(exceptions)
})
})
}
getPaperStruct(examRecordDataId: number) : Promise {
return new Promise((resovle, reject) => {
return this.getRequest({
url: '/api/ecs_oe_student/examRecordPaperStruct/getExamRecordPaperStruct',
parameter: {
examRecordDataId: examRecordDataId
}
}).then( res => {
resovle(res)
}, error => {
reject(error)
}).catch( exceptions => {
reject(exceptions)
})
})
}
getSign(examRecordDataId: number, examStudentId: number, order: number, fileMd5: string, suffix: string) : Promise {
return new Promise((resolve, reject) => {
return this.postRequest({
url: '/api/ecs_oe_student/examControl/yunSignature',
parameter: {
examRecordDataId: examRecordDataId,
examStudentId: examStudentId,
order: order,
fileMd5: fileMd5,
fileSuffix: suffix
}
}).then(res => {
var result = {
accessUrl: res.accessUrl,
formUrl: res.formUrl,
fsType: res.fsType,
uploadUrl: res.uploadUrl,
formParams: res.formParams,
signIdentifier: res.signIdentifier,
}
resolve(result)
}, error => {
reject(error)
})
})
}
uploadFile(filePath: string, formParams: object, uploadUrl: string) : Promise {
return new Promise(function (resolve, reject) {
wx.uploadFile({
url: uploadUrl,
filePath: filePath,
name: 'file',
formData: formParams,
success: res => {
resolve(res)
},
fail: error => {
if (error.errMsg == 'uploadFile:fail url not in domain list') {
reject('请点击右上角"•••"按钮开启调试模式')
} else {
reject(error.errMsg)
}
}
})
})
}
notifyServer(examRecordDataId: number, examStudentId: number,
order: number, filePath: string, transferFileType: string) : Promise {
return new Promise((resovle, reject) => {
return this.postRequest({
url: '/api/ecs_oe_student/examControl/saveUploadedFile',
parameter: {
examRecordDataId: examRecordDataId,
examStudentId: examStudentId,
order: order,
filePath: filePath,
transferFileType: transferFileType
}
}).then( res => {
resovle(res)
}, error => {
console.log('===================')
reject(error)
}).catch( exceptions => {
console.log('===================')
reject(exceptions)
})
})
}
getNotifyResult(acknowledgeId: string) : Promise {
return new Promise((resovle, reject) => {
return this.postRequest({
url: '/api/ecs_oe_student/examControl/getUploadedFileAcknowledgeStatus',
parameter: {
acknowledgeId: acknowledgeId
}
}).then( res => {
resovle(res)
}, error => {
reject(error)
}).catch( exceptions => {
reject(exceptions)
})
})
}
getUploadedAudioAnswerList(examRecordDataId: number) : Promise {
return new Promise((resolve, reject) => {
return this.postRequest({
url: '/api/ecs_oe_student/examControl/getUploadedAudioAnswerList',
parameter: {
examRecordDataId: examRecordDataId
}
}).then( res => {
resolve(res as tools.AudioAnswer[])
}, error => {
reject(error)
}).catch(e => {
reject(e)
})
})
}
getRequest(option: RequestOption, auth: boolean = true): Promise {
const that = this
const header = auth ? {
'Content-Type': 'application/x-www-form-urlencoded',
key: that.key,
token: that.token
} : {
'Content-Type': 'application/x-www-form-urlencoded',
}
return new Promise(function (resolve, reject) {
wx.request({
url: that.configOption.baseUrl + option.url,
method: 'GET',
header: header,
data: option.parameter,
success: res => {
console.log("request success", res);
if (that.isTokenInValidCode(res.statusCode)) {
reject('token失效')
// token失效
if (that.tokenValidCallback) {
that.tokenValidCallback()
}
} else if (res.statusCode !== 200) {
reject((res.data as tools.Result).desc)
} else {
resolve(res.data)
}
},
fail: function (res) {
console.log("request fail", res);
if (res.errMsg == 'request:fail url not in domain list') {
reject('请点击右上角"•••"按钮开启调试模式')
} else if (res.errMsg == 'request:fail ') {
reject("网络请求失败");
} else {
reject(res.errMsg);
}
}
})
})
}
postRequest(option: RequestOption, auth: boolean = true): Promise {
const that = this
const header = auth ? {
'Content-Type': 'application/x-www-form-urlencoded',
key: that.key,
token: that.token
} : {
'Content-Type': 'application/x-www-form-urlencoded',
}
console.log(that.configOption.baseUrl + option.url);
console.log(option)
return new Promise(function (resolve, reject) {
wx.request({
url: that.configOption.baseUrl + option.url,
method: 'POST',
header: header,
data: option.parameter,
success: res => {
console.log("request success", res);
if (that.isTokenInValidCode(res.statusCode)) {
reject('token失效')
// token失效
if (that.tokenValidCallback) {
that.tokenValidCallback()
}
} else if (res.statusCode == 503) { //接口限流,自动重试
that._postRequest(option, auth, 0, resolve, reject)
} else if (res.statusCode !== 200) {
reject((res.data as tools.Result).desc)
} else {
resolve(res.data)
}
},
fail: function (res) {
console.log("request fail", res);
if (res.errMsg == 'request:fail url not in domain list') {
reject('请点击右上角"•••"按钮开启调试模式')
} else if (res.errMsg == 'request:fail ') {
reject("网络请求失败");
} else {
reject(res.errMsg);
}
}
})
})
}
_postRequest(option: RequestOption, auth: boolean = true, retry: number = 0, resolve: (value?: any | PromiseLike) => void, reject: (reason?: any) => void) {
const that = this
const header = auth ? {
'Content-Type': 'application/x-www-form-urlencoded',
key: that.key,
token: that.token
} : {
'Content-Type': 'application/x-www-form-urlencoded',
}
console.log(option)
if (retry > 0) {
console.log('正在重试'+retry)
}
wx.request({
url: that.configOption.baseUrl + option.url,
method: 'POST',
header: header,
data: option.parameter,
success: res => {
console.log("request success", res);
if (that.isTokenInValidCode(res.statusCode)) {
reject('token失效')
// token失效
if (that.tokenValidCallback) {
that.tokenValidCallback()
}
} else if (res.statusCode == 503) { //接口限流,自动重试
if (retry < 10) {
console.log('200ms重试')
setTimeout(() => {
that._postRequest(option, auth, retry+1, resolve, reject)
}, 200);
} else {
reject('服务器繁忙,请稍后重试!')
}
} else if (res.statusCode !== 200) {
reject((res.data as tools.Result).desc)
} else {
resolve(res.data)
}
},
fail: function (res) {
console.log("request fail", res);
if (res.errMsg == 'request:fail url not in domain list') {
reject('请点击右上角"•••"按钮开启调试模式')
} else if (res.errMsg == 'request:fail ') {
reject("网络请求失败");
} else {
reject(res.errMsg);
}
}
})
}
private isTokenInValidCode(code: number) : boolean {
return code === 401 || code === 403
}
}